1. 11 6月, 2012 2 次提交
    • M
      edac: Rename the parent dev to pdev · fd687502
      Mauro Carvalho Chehab 提交于
      As EDAC doesn't use struct device itself, it created a parent dev
      pointer called as "pdev".  Now that we'll be converting it to use
      struct device, instead of struct devsys, this needs to be fixed.
      
      No functional changes.
      Reviewed-by: NAristeu Rozanski <arozansk@redhat.com>
      Acked-by: NChris Metcalf <cmetcalf@tilera.com>
      Cc: Doug Thompson <norsk5@yahoo.com>
      Cc: Borislav Petkov <borislav.petkov@amd.com>
      Cc: Mark Gross <mark.gross@intel.com>
      Cc: Jason Uhlenkott <juhlenko@akamai.com>
      Cc: Tim Small <tim@buttersideup.com>
      Cc: Ranganathan Desikan <ravi@jetztechnologies.com>
      Cc: "Arvind R." <arvino55@gmail.com>
      Cc: Olof Johansson <olof@lixom.net>
      Cc: Egor Martovetsky <egor@pasemi.com>
      Cc: Michal Marek <mmarek@suse.cz>
      Cc: Jiri Kosina <jkosina@suse.cz>
      Cc: Joe Perches <joe@perches.com>
      Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
      Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
      Cc: Hitoshi Mitake <h.mitake@gmail.com>
      Cc: Andrew Morton <akpm@linux-foundation.org>
      Cc: "Niklas Söderlund" <niklas.soderlund@ericsson.com>
      Cc: Shaohui Xie <Shaohui.Xie@freescale.com>
      Cc: Josh Boyer <jwboyer@gmail.com>
      Cc: linuxppc-dev@lists.ozlabs.org
      Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
      fd687502
    • M
      RAS: Add a tracepoint for reporting memory controller events · 53f2d028
      Mauro Carvalho Chehab 提交于
      Add a new tracepoint-based hardware events report method for
      reporting Memory Controller events.
      
      Part of the description bellow is shamelessly copied from Tony
      Luck's notes about the Hardware Error BoF during LPC 2010 [1].
      Tony, thanks for your notes and discussions to generate the
      h/w error reporting requirements.
      
      [1] http://lwn.net/Articles/416669/
      
          We have several subsystems & methods for reporting hardware errors:
      
          1) EDAC ("Error Detection and Correction").  In its original form
          this consisted of a platform specific driver that read topology
          information and error counts from chipset registers and reported
          the results via a sysfs interface.
      
          2) mcelog - x86 specific decoding of machine check bank registers
          reporting in binary form via /dev/mcelog. Recent additions make use
          of the APEI extensions that were documented in version 4.0a of the
          ACPI specification to acquire more information about errors without
          having to rely reading chipset registers directly. A user level
          programs decodes into somewhat human readable format.
      
          3) drivers/edac/mce_amd.c - this driver hooks into the mcelog path and
          decodes errors reported via machine check bank registers in AMD
          processors to the console log using printk();
      
          Each of these mechanisms has a band of followers ... and none
          of them appear to meet all the needs of all users.
      
      As part of a RAS subsystem, let's encapsulate the memory error hardware
      events into a trace facility.
      
      The tracepoint printk will be displayed like:
      
      mc_event: [quant] (Corrected|Uncorrected|Fatal) error:[error msg] on [label] ([location] [edac_mc detail] [driver_detail]
      
      Where:
             	[quant] is the quantity of errors
      	[error msg] is the driver-specific error message
      		    (e. g. "memory read", "bus error", ...);
      	[location] is the location in terms of memory controller and
      		   branch/channel/slot, channel/slot or csrow/channel;
      	[label] is the memory stick label;
      	[edac_mc detail] describes the address location of the error
      			 and the syndrome;
      	[driver detail] is driver-specifig error message details,
      			when needed/provided (e. g. "area:DMA", ...)
      
      For example:
      
      mc_event: 1 Corrected error:memory read on memory stick DIMM_1A (mc:0 location:0:0:0 page:0x586b6e offset:0xa66 grain:32 syndrome:0x0 area:DMA)
      
      Of course, any userspace tools meant to handle errors should not parse
      the above data. They should, instead, use the binary fields provided by
      the tracepoint, mapping them directly into their Management Information
      Base.
      
      NOTE: The original patch was providing an additional mechanism for
      MCA-based trace events that also contained MCA error register data.
      However, as no agreement was reached so far for the MCA-based trace
      events, for now, let's add events only for memory errors.
      A latter patch is planned to change the tracepoint, for those types
      of event.
      
      Cc: Aristeu Rozanski <arozansk@redhat.com>
      Cc: Doug Thompson <norsk5@yahoo.com>
      Cc: Steven Rostedt <rostedt@goodmis.org>
      Cc: Frederic Weisbecker <fweisbec@gmail.com>
      Cc: Ingo Molnar <mingo@redhat.com>
      Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
      53f2d028
  2. 29 5月, 2012 7 次提交
    • M
      edac: Initialize the dimm label with the known information · 5926ff50
      Mauro Carvalho Chehab 提交于
      While userspace doesn't fill the dimm labels, add there the dimm location,
      as described by the used memory model. This could eventually match what
      is described at the dmidecode, making easier for people to identify the
      memory.
      
      For example, on an Intel motherboard where the DMI table is reliable,
      the first memory stick is described as:
      
      Memory Device
      	Array Handle: 0x0029
      	Error Information Handle: Not Provided
      	Total Width: 64 bits
      	Data Width: 64 bits
      	Size: 2048 MB
      	Form Factor: DIMM
      	Set: 1
      	Locator: A1_DIMM0
      	Bank Locator: A1_Node0_Channel0_Dimm0
      	Type: <OUT OF SPEC>
      	Type Detail: Synchronous
      	Speed: 800 MHz
      	Manufacturer: A1_Manufacturer0
      	Serial Number: A1_SerNum0
      	Asset Tag: A1_AssetTagNum0
      	Part Number: A1_PartNum0
      
      The memory named as "A1_DIMM0" is physically located at the first
      memory controller (node 0), at channel 0, dimm slot 0.
      
      After this patch, the memory label will be filled with:
      	/sys/devices/system/edac/mc/csrow0/ch0_dimm_label:mc#0channel#0slot#0
      
      And (after the new EDAC API patches) as:
      	/sys/devices/system/edac/mc/mc0/dimm0/dimm_label:mc#0channel#0slot#0
      
      So, even if the memory label is not initialized on userspace, an useful
      information with the error location is filled there, expecially since
      several systems/motherboards are provided with enough info to map from
      channel/slot (or branch/channel/slot) into the DIMM label. So, letting the
      EDAC core fill it by default is a good thing.
      
      It should noticed that, as the label filling happens at the
      edac_mc_alloc(), drivers can override it to better describe the memories
      (and some actually do it).
      
      Cc: Aristeu Rozanski <arozansk@redhat.com>
      Cc: Doug Thompson <norsk5@yahoo.com>
      Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
      5926ff50
    • M
      edac: Remove the legacy EDAC ABI · ca0907b9
      Mauro Carvalho Chehab 提交于
      Now that all drivers got converted to use the new ABI, we can
      drop the old one.
      Acked-by: NChris Metcalf <cmetcalf@tilera.com>
      Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
      ca0907b9
    • M
      edac: Change internal representation to work with layers · 4275be63
      Mauro Carvalho Chehab 提交于
      Change the EDAC internal representation to work with non-csrow
      based memory controllers.
      
      There are lots of those memory controllers nowadays, and more
      are coming. So, the EDAC internal representation needs to be
      changed, in order to work with those memory controllers, while
      preserving backward compatibility with the old ones.
      
      The edac core was written with the idea that memory controllers
      are able to directly access csrows.
      
      This is not true for FB-DIMM and RAMBUS memory controllers.
      
      Also, some recent advanced memory controllers don't present a per-csrows
      view. Instead, they view memories as DIMMs, instead of ranks.
      
      So, change the allocation and error report routines to allow
      them to work with all types of architectures.
      
      This will allow the removal of several hacks with FB-DIMM and RAMBUS
      memory controllers.
      
      Also, several tests were done on different platforms using different
      x86 drivers.
      
      TODO: a multi-rank DIMMs are currently represented by multiple DIMM
      entries in struct dimm_info. That means that changing a label for one
      rank won't change the same label for the other ranks at the same DIMM.
      This bug is present since the beginning of the EDAC, so it is not a big
      deal. However, on several drivers, it is possible to fix this issue, but
      it should be a per-driver fix, as the csrow => DIMM arrangement may not
      be equal for all. So, don't try to fix it here yet.
      
      I tried to make this patch as short as possible, preceding it with
      several other patches that simplified the logic here. Yet, as the
      internal API changes, all drivers need changes. The changes are
      generally bigger in the drivers for FB-DIMMs.
      
      Cc: Aristeu Rozanski <arozansk@redhat.com>
      Cc: Doug Thompson <norsk5@yahoo.com>
      Cc: Borislav Petkov <borislav.petkov@amd.com>
      Cc: Mark Gross <mark.gross@intel.com>
      Cc: Jason Uhlenkott <juhlenko@akamai.com>
      Cc: Tim Small <tim@buttersideup.com>
      Cc: Ranganathan Desikan <ravi@jetztechnologies.com>
      Cc: "Arvind R." <arvino55@gmail.com>
      Cc: Olof Johansson <olof@lixom.net>
      Cc: Egor Martovetsky <egor@pasemi.com>
      Cc: Chris Metcalf <cmetcalf@tilera.com>
      Cc: Michal Marek <mmarek@suse.cz>
      Cc: Jiri Kosina <jkosina@suse.cz>
      Cc: Joe Perches <joe@perches.com>
      Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
      Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
      Cc: Hitoshi Mitake <h.mitake@gmail.com>
      Cc: Andrew Morton <akpm@linux-foundation.org>
      Cc: "Niklas Söderlund" <niklas.soderlund@ericsson.com>
      Cc: Shaohui Xie <Shaohui.Xie@freescale.com>
      Cc: Josh Boyer <jwboyer@gmail.com>
      Cc: linuxppc-dev@lists.ozlabs.org
      Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
      4275be63
    • M
      edac: rewrite edac_align_ptr() · 93e4fe64
      Mauro Carvalho Chehab 提交于
      The edac_align_ptr() function is used to prepare data for a single
      memory allocation kzalloc() call. It counts how many bytes are needed
      by some data structure.
      
      Using it as-is is not that trivial, as the quantity of memory elements
      reserved is not there, but, instead, it is on a next call.
      
      In order to avoid mistakes when using it, move the number of allocated
      elements into it, making easier to use it.
      Reviewed-by: NBorislav Petkov <bp@amd64.org>
      Cc: Aristeu Rozanski <arozansk@redhat.com>
      Cc: Doug Thompson <norsk5@yahoo.com>
      Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
      93e4fe64
    • M
      edac: move nr_pages to dimm struct · a895bf8b
      Mauro Carvalho Chehab 提交于
      The number of pages is a dimm property. Move it to the dimm struct.
      
      After this change, it is possible to add sysfs nodes for the DIMM's that
      will properly represent the DIMM stick properties, including its size.
      
      A TODO fix here is to properly represent dual-rank/quad-rank DIMMs when
      the memory controller represents the memory via chip select rows.
      Reviewed-by: NAristeu Rozanski <arozansk@redhat.com>
      Acked-by: NBorislav Petkov <borislav.petkov@amd.com>
      Acked-by: NChris Metcalf <cmetcalf@tilera.com>
      Cc: Doug Thompson <norsk5@yahoo.com>
      Cc: Mark Gross <mark.gross@intel.com>
      Cc: Jason Uhlenkott <juhlenko@akamai.com>
      Cc: Tim Small <tim@buttersideup.com>
      Cc: Ranganathan Desikan <ravi@jetztechnologies.com>
      Cc: "Arvind R." <arvino55@gmail.com>
      Cc: Olof Johansson <olof@lixom.net>
      Cc: Egor Martovetsky <egor@pasemi.com>
      Cc: Michal Marek <mmarek@suse.cz>
      Cc: Jiri Kosina <jkosina@suse.cz>
      Cc: Joe Perches <joe@perches.com>
      Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
      Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
      Cc: Hitoshi Mitake <h.mitake@gmail.com>
      Cc: Andrew Morton <akpm@linux-foundation.org>
      Cc: "Niklas Söderlund" <niklas.soderlund@ericsson.com>
      Cc: Shaohui Xie <Shaohui.Xie@freescale.com>
      Cc: Josh Boyer <jwboyer@gmail.com>
      Cc: linuxppc-dev@lists.ozlabs.org
      Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
      a895bf8b
    • M
      edac: move dimm properties to struct dimm_info · 084a4fcc
      Mauro Carvalho Chehab 提交于
      On systems based on chip select rows, all channels need to use memories
      with the same properties, otherwise the memories on channels A and B
      won't be recognized.
      
      However, such assumption is not true for all types of memory
      controllers.
      
      Controllers for FB-DIMM's don't have such requirements.
      
      Also, modern Intel controllers seem to be capable of handling such
      differences.
      
      So, we need to get rid of storing the DIMM information into a per-csrow
      data, storing it, instead at the right place.
      
      The first step is to move grain, mtype, dtype and edac_mode to the
      per-dimm struct.
      Reviewed-by: NAristeu Rozanski <arozansk@redhat.com>
      Reviewed-by: NBorislav Petkov <borislav.petkov@amd.com>
      Acked-by: NChris Metcalf <cmetcalf@tilera.com>
      Cc: Doug Thompson <norsk5@yahoo.com>
      Cc: Borislav Petkov <borislav.petkov@amd.com>
      Cc: Mark Gross <mark.gross@intel.com>
      Cc: Jason Uhlenkott <juhlenko@akamai.com>
      Cc: Tim Small <tim@buttersideup.com>
      Cc: Ranganathan Desikan <ravi@jetztechnologies.com>
      Cc: "Arvind R." <arvino55@gmail.com>
      Cc: Olof Johansson <olof@lixom.net>
      Cc: Egor Martovetsky <egor@pasemi.com>
      Cc: Michal Marek <mmarek@suse.cz>
      Cc: Jiri Kosina <jkosina@suse.cz>
      Cc: Joe Perches <joe@perches.com>
      Cc: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
      Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
      Cc: Hitoshi Mitake <h.mitake@gmail.com>
      Cc: Andrew Morton <akpm@linux-foundation.org>
      Cc: James Bottomley <James.Bottomley@parallels.com>
      Cc: "Niklas Söderlund" <niklas.soderlund@ericsson.com>
      Cc: Shaohui Xie <Shaohui.Xie@freescale.com>
      Cc: Josh Boyer <jwboyer@gmail.com>
      Cc: Mike Williams <mike@mikebwilliams.com>
      Cc: linuxppc-dev@lists.ozlabs.org
      Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
      084a4fcc
    • M
      edac: Create a dimm struct and move the labels into it · a7d7d2e1
      Mauro Carvalho Chehab 提交于
      The way a DIMM is currently represented implies that they're
      linked into a per-csrow struct. However, some drivers don't see
      csrows, as they're ridden behind some chip like the AMB's
      on FBDIMM's, for example.
      
      This forced drivers to fake^Wvirtualize a csrow struct, and to create
      a mess under csrow/channel original's concept.
      
      Move the DIMM labels into a per-DIMM struct, and add there
      the real location of the socket, in terms of csrow/channel.
      Latter patches will modify the location to properly represent the
      memory architecture.
      
      All other drivers will use a per-csrow type of location.
      Some of those drivers will require a latter conversion, as
      they also fake the csrows internally.
      
      TODO: While this patch doesn't change the existing behavior, on
      csrows-based memory controllers, a csrow/channel pair points to a memory
      rank. There's a known bug at the EDAC core that allows having different
      labels for the same DIMM, if it has more than one rank. A latter patch
      is need to merge the several ranks for a DIMM into the same dimm_info
      struct, in order to avoid having different labels for the same DIMM.
      
      The edac_mc_alloc() will now contain a per-dimm initialization loop that
      will be changed by latter patches in order to match other types of
      memory architectures.
      Reviewed-by: NAristeu Rozanski <arozansk@redhat.com>
      Reviewed-by: NBorislav Petkov <borislav.petkov@amd.com>
      Cc: Doug Thompson <norsk5@yahoo.com>
      Cc: Ranganathan Desikan <ravi@jetztechnologies.com>
      Cc: "Arvind R." <arvino55@gmail.com>
      Cc: "Niklas Söderlund" <niklas.soderlund@ericsson.com>
      Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
      a7d7d2e1
  3. 22 3月, 2012 1 次提交
    • M
      edac: rename channel_info to rank_info · a4b4be3f
      Mauro Carvalho Chehab 提交于
      What it is pointed by a csrow/channel vector is a rank information, and
      not a channel information.
      
      On a traditional architecture, the memory controller directly access the
      memory ranks, via chip select rows. Different ranks at the same DIMM is
      selected via different chip select rows. So, typically, one
      csrow/channel pair means one different DIMM.
      
      On FB-DIMMs, there's a microcontroller chip at the DIMM, called Advanced
      Memory Buffer (AMB) that serves as the interface between the memory
      controller and the memory chips.
      
      The AMB selection is via the DIMM slot, and not via a csrow.
      
      It is up to the AMB to talk with the csrows of the DRAM chips.
      
      So, the FB-DIMM memory controllers see the DIMM slot, and not the DIMM
      rank. RAMBUS is similar.
      
      Newer memory controllers, like the ones found on Intel Sandy Bridge and
      Nehalem, even working with normal DDR3 DIMM's, don't use the usual
      channel A/channel B interleaving schema to provide 128 bits data access.
      
      Instead, they have more channels (3 or 4 channels), and they can use
      several interleaving schemas. Such memory controllers see the DIMMs
      directly on their registers, instead of the ranks, which is better for
      the driver, as its main usageis to point to a broken DIMM stick (the
      Field Repleceable Unit), and not to point to a broken DRAM chip.
      
      The drivers that support such such newer memory architecture models
      currently need to fake information and to abuse on EDAC structures, as
      the subsystem was conceived with the idea that the csrow would always be
      visible by the CPU.
      
      To make things a little worse, those drivers don't currently fake
      csrows/channels on a consistent way, as the concepts there don't apply
      to the memory controllers they're talking with. So, each driver author
      interpreted the concepts using a different logic.
      
      In order to fix it, let's rename the data structure that points into a
      DIMM rank to "rank_info", in order to be clearer about what's stored
      there.
      
      Latter patches will provide a better way to represent the memory
      hierarchy for the other types of memory controller.
      Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
      a4b4be3f
  4. 20 3月, 2012 1 次提交
  5. 15 12月, 2011 1 次提交
  6. 27 5月, 2011 1 次提交
  7. 31 3月, 2011 1 次提交
  8. 07 1月, 2011 1 次提交
  9. 09 12月, 2010 1 次提交
    • B
      EDAC: Fix workqueue-related crashes · bb31b312
      Borislav Petkov 提交于
      00740c58 changed edac_core to
      un-/register a workqueue item only if a lowlevel driver supplies a
      polling routine. Normally, when we remove a polling low-level driver, we
      go and cancel all the queued work. However, the workqueue unreg happens
      based on the ->op_state setting, and edac_mc_del_mc() sets this to
      OP_OFFLINE _before_ we cancel the work item, leading to NULL ptr oops on
      the workqueue list.
      
      Fix it by putting the unreg stuff in proper order.
      
      Cc: <stable@kernel.org> #36.x
      Reported-and-tested-by: NTobias Karnat <tobias.karnat@googlemail.com>
      LKML-Reference: <1291201307.3029.21.camel@Tobias-Karnat>
      Signed-off-by: NBorislav Petkov <borislav.petkov@amd.com>
      bb31b312
  10. 24 10月, 2010 4 次提交
    • M
      i7core_edac: don't use a freed mci struct · accf74ff
      Mauro Carvalho Chehab 提交于
      This is a nasty bug. Since kobject count will be reduced by zero by
      edac_mc_del_mc(), and this triggers the kobj release method, the
      mci memory will be freed automatically. So, all we have left is ctl_name,
      as shown by enabling debug:
      
      [   80.822186] EDAC DEBUG: in drivers/edac/edac_mc_sysfs.c, line at 1020: edac_remove_sysfs_mci_device()  remove_link
      [   80.832590] EDAC DEBUG: in drivers/edac/edac_mc_sysfs.c, line at 1024: edac_remove_sysfs_mci_device()  remove_mci_instance
      [   80.843776] EDAC DEBUG: in drivers/edac/edac_mc_sysfs.c, line at 640: edac_mci_control_release() mci instance idx=0 releasing
      [   80.855163] EDAC MC: Removed device 0 for i7core_edac.c i7 core #0: DEV 0000:3f:03.0
      [   80.862936] EDAC DEBUG: in drivers/edac/i7core_edac.c, line at 2089: (null): free structs
      [   80.871134] EDAC DEBUG: in drivers/edac/edac_mc.c, line at 238: edac_mc_free()
      [   80.878379] EDAC DEBUG: in drivers/edac/edac_mc_sysfs.c, line at 726: edac_mc_unregister_sysfs_main_kobj()
      [   80.888043] EDAC DEBUG: in drivers/edac/i7core_edac.c, line at 1232: drivers/edac/i7core_edac.c: i7core_put_devices()
      
      Also, kfree(mci) shouldn't happen at the kobj.release, as it happens
      when edac_remove_sysfs_mci_device() is called, but the logic is:
      	edac_remove_sysfs_mci_device(mci);
      	edac_printk(KERN_INFO, EDAC_MC,
      		"Removed device %d for %s %s: DEV %s\n", mci->mc_idx,
      		mci->mod_name, mci->ctl_name, edac_dev_name(mci));
      So, as the edac_printk() needs the mci struct, this generates an OOPS.
      Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
      accf74ff
    • M
      edac_core: Print debug messages at release calls · bbc560ae
      Mauro Carvalho Chehab 提交于
      This is important to track a nasty bug at the free logic.
      Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
      bbc560ae
    • M
      edac_core: Do a better job with node removal · 6fe1108f
      Mauro Carvalho Chehab 提交于
      Make sure we remove groups at the right order
      Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
      6fe1108f
    • M
      i7core_edac: Be sure that the edac pci handler will be properly released · 939747bd
      Mauro Carvalho Chehab 提交于
      With multi-sockets, more than one edac pci handler is enabled. Be sure to
      un-register all instances.
      Signed-off-by: NMauro Carvalho Chehab <mchehab@redhat.com>
      939747bd
  11. 27 9月, 2010 1 次提交
    • B
      amd64_edac: Fix driver module removal · 00740c58
      Borislav Petkov 提交于
      f4347553 removed the edac polling
      mechanism in favor of using a notifier chain for conveying MCE
      information to edac. However, the module removal path didn't test
      whether the driver had setup the polling function workqueue at all and
      the rmmod process was hanging in the kernel at try_to_del_timer_sync()
      in the cancel_delayed_work() path, trying to cancel an uninitialized
      work struct.
      
      Fix that by adding a balancing check to the workqueue removal path.
      Signed-off-by: NBorislav Petkov <borislav.petkov@amd.com>
      00740c58
  12. 08 12月, 2009 1 次提交
  13. 24 9月, 2009 1 次提交
  14. 14 4月, 2009 1 次提交
  15. 07 1月, 2009 1 次提交
  16. 06 5月, 2008 1 次提交
  17. 29 4月, 2008 2 次提交
  18. 27 7月, 2007 1 次提交
  19. 20 7月, 2007 11 次提交