Commit Graph

213 Commits

Author SHA1 Message Date
Marius Strobl
f33856104f Flag mpt(4) as supporting unmapped I/O; all necessary conversion actually
already has been done as part of r246713 except for a comment update.

MFC after:	3 days
2013-06-24 21:27:15 +00:00
Xin LI
cb5a918317 Explicitly use a pair of parentheses to ensure correct evaluation
ordering for bitwise operation.

Submitted by:	swildner (DragonFly)
MFC after:	2 weeks
2013-05-31 17:27:44 +00:00
Alexander Motin
c33c978915 Move hptmv and mpt drivers shutdown a bit later to the SHUTDOWN_PRI_LAST
stage of shutdown_post_sync.  That should allow CAM to do final cache flush
at the SHUTDOWN_PRI_DEFAULT without using polling magic.

MFC after:	3 days
2013-04-24 19:00:45 +00:00
Alexander Motin
e5dfa058da MFprojects/camlock r248982:
Stop abusing xpt_periph in random plases that really have no periph related
to CCB, for example, bus scanning.  NULL value is fine in such cases and it
is correctly logged in debug messages as "noperiph".  If at some point we
need some real XPT periphs (alike to pmpX now), quite likely they will be
per-bus, and not a single global instance as xpt_periph now.
2013-04-14 09:55:48 +00:00
Konstantin Belousov
dd0b4fb6d5 Reform the busdma API so that new types may be added without modifying
every architecture's busdma_machdep.c.  It is done by unifying the
bus_dmamap_load_buffer() routines so that they may be called from MI
code.  The MD busdma is then given a chance to do any final processing
in the complete() callback.

The cam changes unify the bus_dmamap_load* handling in cam drivers.

The arm and mips implementations are updated to track virtual
addresses for sync().  Previously this was done in a type specific
way.  Now it is done in a generic way by recording the list of
virtuals in the map.

Submitted by:	jeff (sponsored by EMC/Isilon)
Reviewed by:	kan (previous version), scottl,
	mjacob (isp(4), no objections for target mode changes)
Discussed with:	     ian (arm changes)
Tested by:	marius (sparc64), mips (jmallet), isci(4) on x86 (jharris),
	amd64 (Fabian Keil <freebsd-listen@fabiankeil.de>)
2013-02-12 16:57:20 +00:00
Marius Strobl
ab42d234d1 Remove support for using Giant for locking within mpt(4). Finer grained
locking has been working fine for ~5.5 years by now.

MFC after:	1 week
2012-10-22 10:53:59 +00:00
Marius Strobl
4b847ffaa3 After r241858, remove the remainder of FreeBSD ~4 support from mpt(4).
MFC after:	1 week
2012-10-22 10:42:59 +00:00
Eitan Adler
c39df7897f Now that device disabling is generic, remove the non-standard
implementation from mpt

Don't MFC this to retain backwards compatibility.

Reviewed by:	des, mjacob
Approved by:	cperciva
2012-10-22 04:18:17 +00:00
Eitan Adler
6fbce2500a Remove unused code since the 5.x days
Reviewed by:	des, scottl
Approved by:	cperciva
MFC after:	1 week
2012-10-22 03:41:24 +00:00
Kenneth D. Merry
b79dc8a8da Fix an issue that caused the kernel to panic inside CTL when trying
to attach to target capable HBAs that implement the old immediate
notify (XPT_IMMED_NOTIFY) and notify acknowledge (XPT_NOTIFY_ACK)
CCBs.  The new API has been in place since SVN change 196008 in
2009.

The solution is two-fold:  fix CTL to handle the responses from the
HBAs, and convert the HBA drivers in question to use the new API.

These drivers have not been tested with CTL, so how well they will
interoperate with CTL is unknown.

scsi_target.c:	Update the userland target example code to use the
		new immediate notify API.

scsi_ctl.c:	Detect when an immediate notify CCB is returned
		with CAM_REQ_INVALID or CAM_PROVIDE_FAIL status,
		and just free it.

		Fix a duplicate assignment.

aic79xx.c,
aic79xx_osm.c:	Update the aic79xx driver to use the new API.
		Target mode is not enabled on for this driver, so
		the changes will have no practical effect.

aic7xxx.c,
aic7xxx_osm.c:	Update the aic7xxx driver to use the new API.

sbp_targ.c:	Update the firewire target code to work with the
		new API.

mpt_cam.c:	Update the mpt(4) driver to work with the new API.
		Target mode is only enabled for Fibre Channel
		mpt(4) devices.

MFC after:	3 days
2012-06-26 14:51:35 +00:00
Kevin Lo
c61325d009 Correct sizeof usage
Obtained from:	DragonFly
2012-06-25 05:41:16 +00:00
Marius Strobl
bb16310a44 Refine r233827; as it turns out, controllers with a device ID of 0x0059
can be upgraded to MegaRAID mode, in which case mfi(4) should attach to
these based on the sub-vendor and -device ID instead (not currently done).
Therefore, let mpt_pci_probe() return BUS_PROBE_LOW_PRIORITY.
While it, let mpt_pci_probe() return BUS_PROBE_DEFAULT instead of 0 in
the default case.

MFC after:	3 days
2012-04-04 20:42:45 +00:00
Marius Strobl
6fe8be540f Fix probing of SAS1068E with a device ID of 0x0059 after r232411.
Reported by:	infofarmer

MFC after:	3 days
2012-04-03 08:28:43 +00:00
Marius Strobl
12af29abfd Consistently update to the MPI header set version 01.05.20 after r224761.
Requested by:	mjacob

MFC after:	1 week
2012-03-24 16:23:21 +00:00
Marius Strobl
24a0e7eeab As it turns out, mpi_cnfg.h already is included by mpt.h. 2012-03-24 00:37:56 +00:00
Marius Strobl
fd61f4215c - Use the PCI ID macros from mpi_cnfg.h rather than duplicating them here.
Note that this driver additionally probes some device IDs for the most
  part not know to other MPT drivers, if at all. So rename the macros not
  present in mpi_cnfg.h to match the naming scheme in the latter and but
  suffix them with a _FB in order to not cause conflicts.
- Like mpt_set_config_regs(), comment out mpt_read_config_regs() as the
  content of the registers read isn't actually used and both functions
  aren't exactly up to date regarding the possible layouts of the BARs
  (these function might be helpful for debugging though, so don't remove
  them completely).
- Use DEVMETHOD_END.
- Use NULL rather than 0 for pointers.
- Remove an unusual check for the softc being NULL.
- Remove redundant zeroing of the softc.
- Remove an overly banal and actually partly incorrect as well as partly
  outdated comment regarding the allocation of the memory resource.

MFC after:	3 days
2012-03-24 00:30:17 +00:00
Kenneth D. Merry
aa6e8dfdd5 Fix a problem that was causing the mpt(4) driver to attach to MegaRAID
cards that should be handled by the mfi(4) driver.

The root of the problem is that the mpt(4) driver was masking off the
bottom bit of the PCI device ID when deciding which cards to attach to.

It appears that a number of the mpt(4) Fibre Channel cards had a LAN
variant whose PCI device ID was just one bit off from the FC card's device
ID.  The FC cards were even and the LAN cards were odd.

The problem was that this pattern wasn't carried over on the SAS and
parallel SCSI mpt(4) cards.  Luckily the SAS and parallel SCSI PCI device
IDs were either even numbers, or they would get masked to a supported
adjacent PCI device ID, and everything worked well.

Now LSI is using some of the odd-numbered PCI device IDs between the 3Gb
SAS device IDs for their new MegaRAID cards.  This is causing the mpt(4)
driver to attach to the RAID cards instead of the mfi(4) driver.

The solution is to stop masking off the bottom bit of the device ID, and
explicitly list the PCI device IDs of all supported cards.

This change should be a no-op for mpt(4) hardware.  The only intended
functional change is that for the 929X, the is_fc variable gets set.  It
wasn't being set previously, but needs to be because the 929X is a Fibre
Channel card.

Reported by:	Kashyap Desai <Kashyap.Desai@lsi.com>
MFC After:	3 days
2012-03-02 22:00:40 +00:00
Tijl Coosemans
265f940acc Change some headers such that lang/gcc* ports no longer patch them.
The lang/gcc* ports patch headers where they think something is
non-standard. These patched headers override the system headers which means
you have to rebuild these ports whenever you do installworld to make sure
they contain the latest changes.
2012-02-14 12:50:20 +00:00
Marius Strobl
04016bcf93 Flesh out support for SAS1078 and SAS1078DE (which are said to actually
be the same chip):
- The I/O port resource may not be available with these. However, given
  that we actually only need this resource for some controllers that
  require their firmware to be up- and downloaded (which excludes the
  SAS1078{,DE}) just handle failure to allocate this resource gracefully
  when possible. While at it, generally put non-fatal resource allocation
  failures under bootverbose.
- SAS1078{,DE} use a different hard reset protocol.
- Add workarounds for the 36GB physical address limitation of scatter/
  gather elements of these controllers.

Tested by:	Slawa Olhovchenkov

PR:	149220 (remaining part)
2012-02-11 12:03:44 +00:00
Marius Strobl
4349d27828 Remove extra newlines from panic messages. 2012-02-08 21:40:54 +00:00
Marius Strobl
84ceb5f6d3 Increase the IOC port initialization timeouts by ten times to what the
corresponding Linux driver uses. This allows mpt(4) to still recognize
all good SATA devices in presence of a defective one, which takes about
45 seconds.
In the long term we probably should implement the logic used by mpt2sas(4)
allowing IOC port initialization to complete at a later time.

Submitted by:	Andrew Boyer
MFC after:	3 days
2011-11-01 18:28:33 +00:00
Marius Strobl
50e66535b9 Sync with ahc(4)/ahd(4)/sym(4) etc:
Zero any sense not transferred by the device as the SCSI specification
mandates that any untransferred data should be assumed to be zero.

Reviewed by:	ken
2011-10-07 21:23:42 +00:00
Kenneth D. Merry
1cc052e80f Add descriptor sense support to CAM, and honor sense residuals properly in
CAM.

Desriptor sense is a new sense data format that originated in SPC-3.  Among
other things, it allows for an 8-byte info field, which is necessary to
pass back block numbers larger than 4 bytes.

This change adds a number of new functions to scsi_all.c (and therefore
libcam) that abstract out most access to sense data.

This includes a bump of CAM_VERSION, because the CCB ABI has changed.
Userland programs that use the CAM pass(4) driver will need to be
recompiled.

camcontrol.c:	Change uses of scsi_extract_sense() to use
		scsi_extract_sense_len().

		Use scsi_get_sks() instead of accessing sense key specific
		data directly.

scsi_modes:	Update the control mode page to the latest version (SPC-4).

scsi_cmds.c,
scsi_target.c:	Change references to struct scsi_sense_data to struct
		scsi_sense_data_fixed.  This should be changed to allow the
		user to specify fixed or descriptor sense, and then use
		scsi_set_sense_data() to build the sense data.

ps3cdrom.c:	Use scsi_set_sense_data() instead of setting sense data
		manually.

cam_periph.c:	Use scsi_extract_sense_len() instead of using
		scsi_extract_sense() or accessing sense data directly.

cam_ccb.h:	Bump the CAM_VERSION from 0x15 to 0x16.  The change of
		struct scsi_sense_data from 32 to 252 bytes changes the
		size of struct ccb_scsiio, but not the size of union ccb.
		So the version must be bumped to prevent structure
		mis-matches.

scsi_all.h:	Lots of updated SCSI sense data and other structures.

		Add function prototypes for the new sense data functions.

		Take out the inline implementation of scsi_extract_sense().
		It is now too large to put in a header file.

		Add macros to calculate whether fields are present and
		filled in fixed and descriptor sense data

scsi_all.c:	In scsi_op_desc(), allow the user to pass in NULL inquiry
		data, and we'll assume a direct access device in that case.

		Changed the SCSI RESERVED sense key name and description
		to COMPLETED, as it is now defined in the spec.

		Change the error recovery action for a number of read errors
		to prevent lots of retries when the drive has said that the
		block isn't accessible.  This speeds up reconstruction of
		the block by any RAID software running on top of the drive
		(e.g. ZFS).

		In scsi_sense_desc(), allow for invalid sense key numbers.
		This allows calling this routine without checking the input
		values first.

		Change scsi_error_action() to use scsi_extract_sense_len(),
		and handle things when invalid asc/ascq values are
		encountered.

		Add a new routine, scsi_desc_iterate(), that will call the
		supplied function for every descriptor in descriptor format
		sense data.

		Add scsi_set_sense_data(), and scsi_set_sense_data_va(),
		which build descriptor and fixed format sense data.  They
		currently default to fixed format sense data.

		Add a number of scsi_get_*() functions, which get different
		types of sense data fields from either fixed or descriptor
		format sense data, if the data is present.

		Add a number of scsi_*_sbuf() functions, which print
		formatted versions of various sense data fields.  These
		functions work for either fixed or descriptor sense.

		Add a number of scsi_sense_*_sbuf() functions, which have a
		standard calling interface and print the indicated field.
		These functions take descriptors only.

		Add scsi_sense_desc_sbuf(), which will print a formatted
		version of the given sense descriptor.

		Pull out a majority of the scsi_sense_sbuf() function and
		put it into scsi_sense_only_sbuf().  This allows callers
		that don't use struct ccb_scsiio to easily utilize the
		printing routines.  Revamp that function to handle
		descriptor sense and use the new sense fetching and
		printing routines.

		Move scsi_extract_sense() into scsi_all.c, and implement it
		in terms of the new function, scsi_extract_sense_len().
		The _len() version takes a length (which should be the
		sense length - residual) and can indicate which fields are
		present and valid in the sense data.

		Add a couple of new scsi_get_*() routines to get the sense
		key, asc, and ascq only.

mly.c:		Rename struct scsi_sense_data to struct
		scsi_sense_data_fixed.

sbp_targ.c:	Use the new sense fetching routines to get sense data
		instead of accessing it directly.

sbp.c:		Change the firewire/SCSI sense data transformation code to
		use struct scsi_sense_data_fixed instead of struct
		scsi_sense_data.  This should be changed later to use
		scsi_set_sense_data().

ciss.c:		Calculate the sense residual properly.  Use
		scsi_get_sense_key() to fetch the sense key.

mps_sas.c,
mpt_cam.c:	Set the sense residual properly.

iir.c:		Use scsi_set_sense_data() instead of building sense data by
		hand.

iscsi_subr.c:	Use scsi_extract_sense_len() instead of grabbing sense data
		directly.

umass.c:	Use scsi_set_sense_data() to build sense data.

		Grab the sense key using scsi_get_sense_key().

		Calculate the sense residual properly.

isp_freebsd.h:	Use scsi_get_*() routines to grab asc, ascq, and sense key
		values.

		Calculate and set the sense residual.

MFC after:	3 days
Sponsored by:	Spectra Logic Corporation
2011-10-03 20:32:55 +00:00
Marius Strobl
1bf5a6cf3c o Improve 224494:
- Ignore some more internal SAS device status change events.
  - Correct inverted Bus and TargetID arguments in a warning.
o Add a warning for MPI_EVENT_SAS_DISCOVERY_ERROR events, which can help
  identifying broken disks.

Submitted by:	Andrew Boyer
Approved by:	re (kib)
Committed from: Chaos Communication Camp 2011
2011-08-10 19:05:22 +00:00
Marius Strobl
ec3e6e77a1 - Send the RELSIM_ADJUST_OPENINGS in response to a MPI_EVENT_QUEUE_FULL using
the right SIM in case the HBA is RAID-capable but the target in question is
  not a hot spare or member of a RAID volume.
- Report the loss and addition of SAS and SATA targets detected via PHY link
  status changes and signalled by MPI_EVENT_SAS_DEVICE_STATUS_CHANGE to cam(4)
  as lost devices and trigger rescans as appropriate. Without this it can take
  quite some time until a lost device actually is no longer tried to be used,
  if it ever stops. [1]
- Handle MPI_EVENT_IR2, MPI_EVENT_LOG_ENTRY_ADDED, MPI_EVENT_SAS_DISCOVERY
  and MPI_EVENT_SAS_PHY_LINK_STATUS silently as these serve no additional
  purpose beyond adding cryptic entries to logs.

Thanks to Hans-Joerg Sirtl for providing one of the HBAs these changes were
developed with and RIP to the mainboard that didn't survive testing them.

PR:		157534 [1]
Approved by:	re (kib)
MFC after:	2 weeks
2011-07-29 18:38:31 +00:00
Marius Strobl
87e255ac52 - Staticize functions as appropriate and comment out unused ones.
- Sprinkle some const where appropriate.
- Consistently use target_id_t for the target parameter of mpt_map_physdisk()
  and mpt_is_raid_volume().
- Fix some whitespace bugs.

Approved by:	re (kib)
2011-07-29 18:35:10 +00:00
Marius Strobl
caa59dc8b8 - For SAS but neither FC nor SPI controllers default to using MSI (still
allowing their use to be disabled via device hints though). This matches
  what the corresponding Linux driver provided by LSI does. Tested with
  SAS1064.
- There's no need to keep track of the RIDs used.
- Don't allocate MSI/MSI-X as RF_SHAREABLE.
- Remove a comment which no longer applies since r209599.
- Assign NULL rather than 0 to pointers.

MFC after:	1 month
2011-07-13 18:48:51 +00:00
Marius Strobl
82b263787e Remove extra empty lines. 2011-07-13 14:10:28 +00:00
Marius Strobl
5ab13afc94 Correct spelling.
Submitted by:	brucec
2011-04-22 09:59:16 +00:00
Marius Strobl
6c5276c828 - Allocate the DMA memory shared between the host and the controller as
coherent.
- Add some missing bus_dmamap_sync() calls. This includes putting such
  calls before calling reply handlers instead of calling bus_dmamap_sync()
  for the request queue from individual reply handlers as these handlers
  generally read back updates by the controller.

Tested on amd64 and sparc64.

MFC after:	2 weeks
2011-03-06 12:48:15 +00:00
Matthew D Fleming
6dc7dc9a3e sysctl(9) cleanup checkpoint: amd64 GENERIC builds cleanly.
Commit the rest of the devices.
2011-01-12 19:53:56 +00:00
Marius Strobl
8929ea6f2e Remove a redundant variable assignment found with the clang static analyzer.
MFC after:	1 week
2011-01-05 14:33:48 +00:00
John Baldwin
e58ed10207 Use bus_alloc_resource_any().
MFC after:	2 weeks
2010-12-28 16:57:29 +00:00
Marius Strobl
d6a4eec458 Use the correct variable for determining the verbosity level in mpt_lprtc().
While at it, fix the whitespace of that macro.

PR:		149502
Submitted by:	Andrew Boyer
MFC after:	1 week
2010-11-14 22:34:33 +00:00
Marius Strobl
cd23a6e019 Take mpt_req_on_{free,pending}_list() out from under INVARIANTS as these
are generally useful and not just for debugging.
2010-09-24 23:54:03 +00:00
Marius Strobl
67a1357c25 Improve r56796; the reply handler actually may remove the request from
the chain in which case it shouldn't be removed twice.
Reported by:	Staale Kristoffersen

MFC after:	1 week
2010-09-24 16:40:46 +00:00
Matt Jacob
c97bb67a70 Figure which is the IO and MEM bars- do not assume that they are in
a fixed order.

PR:		149220
Obtained from:	John Baldwin
MFC after:	1 month
2010-08-06 17:27:00 +00:00
Marius Strobl
fd435d5c06 Correct inverted parent DMA tag parameters.
Reviewed by:	ken
MFC after:	3 days
2010-07-12 23:01:21 +00:00
Marius Strobl
cac33e16cf - Make the maxsize parameter of the data buffer DMA tag match maxio, which
was missed in r209599.
  Reported and tested by: Michael Moll
- Declare mpt_dma_buf_alloc() static just like mpt_dma_buf_free(), both are
  used in mpt.c only.

Reviewed by:	ken
MFC after:	r209599
2010-07-12 22:57:57 +00:00
Kenneth D. Merry
4201341ff7 Change the mpt driver to allow larger I/O sizes.
The mpt driver previously didn't report a 'maxio' size to CAM, and so the
da(4) driver limited I/O sizes to DFLTPHYS (64K) by default.  The number
of scatter gather segments allowed, as reported to busdma, was
(128K / PAGE_SIZE) + 1, or 33 on architectures with 4K pages.

Change things around so that we wait until we've determined how many
segments the adapter can support before creating the busdma tag used for
buffers, so we can potentially support more S/G segments and therefore
larger I/O sizes.

Also, fix some things that were broken about the module unload path.  It
still gets hung up inside CAM, though.

mpt.c:		Move some busdma initialization calls in here, and call
		them just after we've gotten the IOCFacts, and know how
		many S/G segments this adapter can support.

mpt.h:		Get rid of MPT_MAXPHYS, it is no longer used.

		Add max_cam_seg_cnt, which is used to report our maximum
		I/O size up to CAM.

mpt_cam.c:	Use max_cam_seg_cnt to report our maximum I/O size to CAM.

		Fix the locking in mpt_cam_detach().

mpt_pci.c:	Pull some busdma initialization and teardown out and put
		it in mpt.c.  We now delay it until we know many scatter
		gather segments the adapter can support, and therefore
		how to setup our busdma tags.

mpt_raid.c:	Make sure we wake up the right wait channel to get the
		raid thread to wake up when we're trying to shut it down.

Reviewed by:	gibbs, mjacob
MFC after:	2 weeks
2010-06-29 22:07:53 +00:00
Matt Jacob
5eb6cd0263 Print IR_RESYNC updates informatively.
Obtained from:	pluknet
MFC after:	1 week
2010-05-02 22:48:27 +00:00
Marius Strobl
8ba5efbd6f On sparc64 obtain the initiator ID to be used for SPI HBAs from the
Open Firmware device tree in order to match what the PROM built-in
driver uses. This is especially important when netbooting Fujitsu
Siemens PRIMEPOWER250 as in that case the built-in driver isn't used
and the port facts PortSCSIID defaults to 0, conflicting with the
disk at the same address.
2010-04-27 18:41:16 +00:00
Marius Strobl
a8217f5c2e Replace a magic value with the appropriate macro. 2010-04-27 18:06:54 +00:00
Matt Jacob
f0b41ca4fc nit: xpt_bus_deregister has to be called with the sim lock held.
MFC after:	1 month
2010-03-30 20:39:57 +00:00
Alexander Motin
2dc59e87e6 Store path for rescan to the right place. This should fix panic on boot,
introduced by r203108.
2010-02-26 12:31:16 +00:00
Alexander Motin
e28a47de96 Do not release device, when changing number of openings. 2010-02-04 08:54:14 +00:00
Alexander Motin
83c5d981ac MFp4: Large set of CAM inprovements.
- Unify bus reset/probe sequence. Whenever bus attached at boot or later,
CAM will automatically reset and scan it. It allows to remove duplicate
code from many drivers.
- Any bus, attached before CAM completed it's boot-time initialization,
will equally join to the process, delaying boot if needed.
- New kern.cam.boot_delay loader tunable should help controllers that
are still unable to register their buses in time (such as slow USB/
PCCard/ CardBus devices), by adding one more event to wait on boot.
- To allow synchronization between different CAM levels, concept of
requests priorities was extended. Priorities now split between several
"run levels". Device can be freezed at specified level, allowing higher
priority requests to pass. For example, no payload requests allowed,
until PMP driver enable port. ATA XPT negotiate transfer parameters,
periph driver configure caching and so on.
- Frozen requests are no more counted by request allocation scheduler.
It fixes deadlocks, when frozen low priority payload requests occupying
slots, required by higher levels to manage theit execution.
- Two last changes were holding proper ATA reinitialization and error
recovery implementation. Now it is done: SATA controllers and Port
Multipliers now implement automatic hot-plug and should correctly
recover from timeouts and bus resets.
- Improve SCSI error recovery for devices on buses without automatic sense
reporting, such as ATAPI or USB. For example, it allows CAM to wait, while
CD drive loads disk, instead of immediately return error status.
- Decapitalize diagnostic messages and make them more readable and sensible.
- Teach PMP driver to limit maximum speed on fan-out ports.
- Make boot wait for PMP scan completes, and make rescan more reliable.
- Fix pass driver, to return CCB to user level in case of error.
- Increase number of retries in cd driver, as device may return several UAs.
2010-01-28 08:41:30 +00:00
John Baldwin
ef36004841 Use a constant instead of a magic number for the flag that enables decoding
of a device ROM.
2009-12-30 19:42:27 +00:00
Alexander Kabaev
363b8ed74f Use callout_init_mtx on FreeBSD versions recent enough. This closes
the race where interrupt thread can complete the request for which
timeout has fired and while mpt_timeout has blocked on mpt_lock.

Do a best effort to keep 4.x ang Giant-locked configurartions
compiling still.

Reported by: ups
Reviewed by: scottl
2009-10-20 02:35:12 +00:00
Poul-Henning Kamp
6778431478 Revert previous commit and add myself to the list of people who should
know better than to commit with a cat in the area.
2009-09-08 13:19:05 +00:00