linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/10] mptfusion : Transport Layer Retry support
@ 2006-07-11 23:21 Eric Moore
  2006-07-12  1:20 ` Douglas Gilbert
  2006-07-12 15:32 ` James Bottomley
  0 siblings, 2 replies; 18+ messages in thread
From: Eric Moore @ 2006-07-11 23:21 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley

Transport Layer Retry support for SAS Tapes.
Detects whether firmware supports TLR, then
issues special scsi opcode to enable TLR in
the end device.

Signed-off-by: Eric Moore <Eric.Moore@lsil.com>


diff -uarpN b/drivers/message/fusion/mptsas.c a/drivers/message/fusion/mptsas.c
--- b/drivers/message/fusion/mptsas.c	2006-07-11 16:38:27.000000000 -0600
+++ a/drivers/message/fusion/mptsas.c	2006-07-11 16:47:23.000000000 -0600
@@ -646,16 +646,68 @@ mptsas_sas_enclosure_pg0(MPT_ADAPTER *io
 	return error;
 }
 
+/*
+ * Enabling Transport Layer Retries
+ */
+static void
+mptsas_issue_tlr(MPT_SCSI_HOST *hd, struct scsi_device *sdev)
+{
+	INTERNAL_CMD	*iocmd;
+	VirtDevice	*vdev = sdev->hostdata;
+	u8		retries;
+	u8		rc;
+
+	if ( sdev->inquiry[8]  == 'H' &&
+	     sdev->inquiry[9]  == 'P' &&
+	     sdev->inquiry[10] == ' ' &&
+	     sdev->inquiry[11] == ' ' &&
+	     sdev->inquiry[12] == ' ' &&
+	     sdev->inquiry[13] == ' ' &&
+	     sdev->inquiry[14] == ' ' &&
+	     sdev->inquiry[15] == ' ' ) {
+
+		iocmd = kzalloc(sizeof(INTERNAL_CMD), GFP_KERNEL);
+		if (!iocmd) {
+			printk(MYIOC_s_ERR_FMT "%s: kzalloc(%zd) FAILED!\n",
+			__FUNCTION__, hd->ioc->name, sizeof(INTERNAL_CMD));
+			return;
+		}
+		iocmd->id = vdev->vtarget->target_id;
+		iocmd->bus = vdev->vtarget->bus_id;
+		iocmd->lun = vdev->lun;
+		iocmd->physDiskNum = -1;
+		iocmd->cmd = TRANSPORT_LAYER_RETRIES;
+		iocmd->data_dma = -1;
+		for (retries = 0, rc = -1; retries < 3; retries++) {
+			rc = mptscsih_do_cmd(hd, iocmd);
+			if (!rc)
+				break;
+		}
+		if (rc != 0)
+			printk(MYIOC_s_INFO_FMT "unable to enable TLR on"
+			   " channel=%d id=%d lun=%d\n",
+			   hd->ioc->name, sdev->channel, sdev->id, sdev->lun);
+		kfree(iocmd);
+	}
+}
+
 static int
 mptsas_slave_configure(struct scsi_device *sdev)
 {
+	struct Scsi_Host	*host = sdev->host;
+	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)host->hostdata;
 
 	if (sdev->channel == MPTSAS_RAID_CHANNEL)
 		goto out;
 
 	sas_read_port_mode_page(sdev);
 
- out:
+	if (sdev->type == TYPE_TAPE &&
+		    (hd->ioc->facts.IOCCapabilities &
+		    MPI_IOCFACTS_CAPABILITY_TLR ))
+			mptsas_issue_tlr(hd, sdev);
+
+out:
 	return mptscsih_slave_configure(sdev);
 }
 
diff -uarpN b/drivers/message/fusion/mptscsih.c a/drivers/message/fusion/mptscsih.c
--- b/drivers/message/fusion/mptscsih.c	2006-07-10 11:28:52.000000000 -0600
+++ a/drivers/message/fusion/mptscsih.c	2006-07-11 12:44:08.000000000 -0600
@@ -100,20 +100,6 @@ typedef struct _BIG_SENSE_BUF {
 #define MPT_ICFLAG_DID_RESET	0x20	/* Bus Reset occurred with this command */
 #define MPT_ICFLAG_RESERVED	0x40	/* Reserved has been issued */
 
-typedef struct _internal_cmd {
-	char		*data;		/* data pointer */
-	dma_addr_t	data_dma;	/* data dma address */
-	int		size;		/* transfer size */
-	u8		cmd;		/* SCSI Op Code */
-	u8		bus;		/* bus number */
-	u8		id;		/* SCSI ID (virtual) */
-	u8		lun;
-	u8		flags;		/* Bit Field - See above */
-	u8		physDiskNum;	/* Phys disk number, -1 else */
-	u8		rsvd2;
-	u8		rsvd;
-} INTERNAL_CMD;
-
 /*
  *  Other private/forward protos...
  */
@@ -138,7 +124,6 @@ static void	mptscsih_initTarget(MPT_SCSI
 static void	mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
 static int	mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
 int		mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
-static int	mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
 static void	mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
 
 void 		mptscsih_remove(struct pci_dev *);
@@ -3003,6 +2988,8 @@ mptscsih_scandv_complete(MPT_ADAPTER *io
 				completionCode = MPT_SCANDV_DID_RESET;
 			else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
 				completionCode = MPT_SCANDV_DID_RESET;
+			else if (scsi_status == MPI_SCSI_STATUS_BUSY)
+				completionCode = MPT_SCANDV_SOME_ERROR;
 			else {
 				completionCode = MPT_SCANDV_GOOD;
 				hd->pLocal->scsiStatus = scsi_status;
@@ -3109,7 +3096,7 @@ mptscsih_timer_expired(unsigned long dat
  *
  *		 > 0 if command complete but some type of completion error.
  */
-static int
+int
 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
 {
 	MPT_FRAME_HDR	*mf;
@@ -3120,7 +3107,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTER
 	int		in_isr;
 	char		 cmdLen;
 	char		 CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-	char		 cmd = io->cmd;
+	u8		 cmd = io->cmd;
 
 	in_isr = in_interrupt();
 	if (in_isr) {
@@ -3219,6 +3206,14 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTER
 		cmdTimeout = 10;
 		break;
 
+	case TRANSPORT_LAYER_RETRIES:
+		CDB[0] = cmd;
+		CDB[1] = 0x01;
+		cmdLen = 6;
+		dir = MPI_SCSIIO_CONTROL_READ;
+		cmdTimeout = 10;
+		break;
+
 	default:
 		/* Error Case */
 		return -EFAULT;
@@ -3401,5 +3396,5 @@ EXPORT_SYMBOL(mptscsih_ioc_reset);
 EXPORT_SYMBOL(mptscsih_change_queue_depth);
 EXPORT_SYMBOL(mptscsih_timer_expired);
 EXPORT_SYMBOL(mptscsih_TMHandler);
-
+EXPORT_SYMBOL(mptscsih_do_cmd);
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff -uarpN b/drivers/message/fusion/mptscsih.h a/drivers/message/fusion/mptscsih.h
--- b/drivers/message/fusion/mptscsih.h	2006-06-17 19:49:35.000000000 -0600
+++ a/drivers/message/fusion/mptscsih.h	2006-07-11 12:01:03.000000000 -0600
@@ -69,9 +69,23 @@
 #define MPTSCSIH_SAF_TE                 0
 #define MPTSCSIH_PT_CLEAR               0
 
-
+#define TRANSPORT_LAYER_RETRIES		0xC2
 #endif
 
+typedef struct _internal_cmd {
+	char		*data;		/* data pointer */
+	dma_addr_t	data_dma;	/* data dma address */
+	int		size;		/* transfer size */
+	u8		cmd;		/* SCSI Op Code */
+	u8		bus;		/* bus number */
+	u8		id;		/* SCSI ID (virtual) */
+	u8		lun;
+	u8		flags;		/* Bit Field - See above */
+	u8		physDiskNum;	/* Phys disk number, -1 else */
+	u8		rsvd2;
+	u8		rsvd;
+} INTERNAL_CMD;
+
 extern void mptscsih_remove(struct pci_dev *);
 extern void mptscsih_shutdown(struct pci_dev *);
 #ifdef CONFIG_PM
@@ -101,3 +115,4 @@ extern void mptscsih_timer_expired(unsig
 extern int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
 extern int mptscsih_raid_id_to_num(MPT_SCSI_HOST *hd, uint physdiskid);
 extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
+extern int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/10] mptfusion : Transport Layer Retry support
  2006-07-11 23:21 Eric Moore
@ 2006-07-12  1:20 ` Douglas Gilbert
  2006-07-12 15:32 ` James Bottomley
  1 sibling, 0 replies; 18+ messages in thread
From: Douglas Gilbert @ 2006-07-12  1:20 UTC (permalink / raw)
  To: Eric Moore; +Cc: linux-scsi, James.Bottomley

Eric Moore wrote:
> Transport Layer Retry support for SAS Tapes.
> Detects whether firmware supports TLR, then
> issues special scsi opcode to enable TLR in
> the end device.

Eric,
The "protocol specific logical unit mode page for SAS
SSP - short format" has a 'transport layer retries'
bit. I thought that SAS tape drives would implement
that mode page (0x18,0x0) and allow that bit to be
changeable.

The "special scsi opcode to enable TLR" seems to imply
another technique.

Doug Gilbert




^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH 1/10] mptfusion : Transport Layer Retry support
@ 2006-07-12 15:15 Eric Moore
  0 siblings, 0 replies; 18+ messages in thread
From: Eric Moore @ 2006-07-12 15:15 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, dougg

-- Tuesday, July 11, 2006 7:21 PM, Douglas Gilbert wrote:

> 
> Eric Moore wrote:
> > Transport Layer Retry support for SAS Tapes.
> > Detects whether firmware supports TLR, then
> > issues special scsi opcode to enable TLR in
> > the end device.
> 
> Eric,
> The "protocol specific logical unit mode page for SAS
> SSP - short format" has a 'transport layer retries'
> bit. I thought that SAS tape drives would implement
> that mode page (0x18,0x0) and allow that bit to be
> changeable.
> 
> The "special scsi opcode to enable TLR" seems to imply
> another technique.
> 


Yes.  The direction we got from HP was do issue this oem
specific opcode.  The original plan was the reading
and writing mode pages, but for some reason they encountered
issues. Here is the email with the direction from HP:

Email follows:

---

Due to numerous technical issues with the original plan to enable TLR via host drivers, HP has changed direction and implemented a vendor-unique command to do the enable.  This command completes immediately (not blocked waiting for the drive to become ready) and does not clear unit attentions.  Here's the whole description again, modified for this new vendor unique command (changes in Red):

* * * * *
Steps to turn on TLR for HP tape drives:

For SAS devices only:

1) Check IOCFacts->IOCCapabilities for F/W support of TLR (bit 11 set).
	(#define MPI_IOCFACTS_CAPABILITY_TLR  (0x800))
    NOTE: This bit is available only in 07.09 or later F/W.

2) Snoop completed Inquiry commands to detect an HP SAS tape drive (returned Inquiry data):
    - Check flag (see below) to see if TLR enabling has already been done on this device.  If not,
	- Inquiry vendor field = "HP      "  (HP + 6 spacess)
	- Byte 0 (peripheral device type and qualifier) = 0x01 (Sequential access device)
    NOTE: Tape drives can have multiple LUNs, and the "sequential access device" LUN may not be LUN 0.

If HP SAS tape drive and flag not already set:

3) Note target ID and LUN

4) Issue an HP vendor-unique command to this target ID/LUN:
	- CDB = 0xC2, 0x01, 0x00, 0x00, 0x00, 0x00 (the 0x01 is enabling TLR)
	- Data buffer will be 0 bytes in length (no data transfer)
	- If command doesn't complete successfully, retry only 1 time
	- In the Windows driver, if TLR enabling fails an error is logged to the Event Log

5) A successful completion of the vendor-unique command indicates that TLR is enabled
    - No further commands or checking is necessary.

Despite any failures or success, always set a flag associated with the target that TLR enabling has been done.
This is needed so the host driver will do the above actions only once (during initial bus scan, or rescan after
a SAS tape drive is powered on or added).

When a SAS tape drive is removed from the SAS domain (SAS device removal event) clear the TLR enable flag.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/10] mptfusion : Transport Layer Retry support
  2006-07-11 23:21 Eric Moore
  2006-07-12  1:20 ` Douglas Gilbert
@ 2006-07-12 15:32 ` James Bottomley
  1 sibling, 0 replies; 18+ messages in thread
From: James Bottomley @ 2006-07-12 15:32 UTC (permalink / raw)
  To: Eric Moore; +Cc: linux-scsi

On Tue, 2006-07-11 at 17:21 -0600, Eric Moore wrote:
> Transport Layer Retry support for SAS Tapes.
> Detects whether firmware supports TLR, then
> issues special scsi opcode to enable TLR in

If I understand what this does correctly, you snoop the inquiry field in
slave configure and then send a vendor specific opcode that the tape
understands (in the event that it reports TLR in its PSLU page)?

Really, no, this isn't appropriate for code in a driver, since I assume
enabling TLR via this command on these things should be independent of
the particular SAS HBA, so it should probably be a transport specific
blacklist.

The next thing ... since TLR is a per port setting in the protocol
specific LU page is that we should probe it and keep its setting within
the transport class as well.

James



^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH 1/10] mptfusion : Transport Layer Retry support
@ 2006-07-12 17:05 Eric Moore
  2006-07-12 17:40 ` James Bottomley
  2006-07-13  2:33 ` Douglas Gilbert
  0 siblings, 2 replies; 18+ messages in thread
From: Eric Moore @ 2006-07-12 17:05 UTC (permalink / raw)
  To: linux-scsi, James.Bottomley, dougg

--  Wednesday, July 12, 2006 9:32 AM, James Bottomley wrote:

> If I understand what this does correctly, you snoop the 
> inquiry field in
> slave configure and then send a vendor specific opcode that the tape
> understands (in the event that it reports TLR in its PSLU page)?
> 
> Really, no, this isn't appropriate for code in a driver, 
> since I assume
> enabling TLR via this command on these things should be independent of
> the particular SAS HBA, so it should probably be a transport specific
> blacklist.
> 

Response from co-worker that implemented this:

--

The reason HP switched from using a standard Mode Page setting to using a vendor unique CDB is due to SCSI protocol problems.

The primary issue is that with standard Mode Sense and Mode Select commands, these commands are blocked when either the device has reservations against it or if the device is busy.  TLR needs to be enabled when the device is discovered, which is done using an Inquiry command.  But, let's look at this example:

The tape cartridge was read previously then the drive turned off (so the tape device is removed from the SAS domain and all device objects are deleted).  Later on, the tape drive is turned back on.  It will be discovered and an event sent to the host driver.  This will kick off an enumeration (Inquiry commands).  With the Inquiry, we detect that this is an HP SAS tape drive and TLR needs to be enabled.  The host driver then sends a Mode Sense to read the SAS protocol page so we can enable TLR.  However, the tape cartridge is rewinding.  The Inquriy commands completed because they are "immediate" commands that the drive can service at any time.  But, the Mode Sense (and Mode Select) commands are blocked (pended) while the tape drive is busy.  I can take more than 5 minutes for a tape cartridge to rewind and become ready, at which time the Mode Sense would be completed.  It isn't that the 
 Mode Sense is returned with Busy, it is pended so it remains outstanding and no other commands can be sent to the drive.

A similar problem occurs with reservations.  The Inquiry will always complete no matter who has reservations on the drive.  But, a Mode Sense (and Mode Select) will fail if another initiator has reservations.

I found the long Busy problem (just because the drive takes up to and even longer than 30 seconds to come Ready after a power on, no matter where the tape is).  I was trying to piggy-back on the OS Inquiry command (which has a timeout of 4 seconds) and this was failing.  I modified my driver to perform the Mode Sense outside of the OS Inquiry command, but HP came back with the above scenarios (tape rewind and reservations) and that's when they wanted to switch to a vendor-unique CDB (much easier for them F/W wise).

The usage of Mode Sense and Mode Select will still work with the HP tape drives, if you can find a way around the above issues.  But I would suggest discussing any solution with the HP-Bristol tape drive folks.


^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH 1/10] mptfusion : Transport Layer Retry support
  2006-07-12 17:05 [PATCH 1/10] mptfusion : Transport Layer Retry support Eric Moore
@ 2006-07-12 17:40 ` James Bottomley
  2006-07-13  2:33 ` Douglas Gilbert
  1 sibling, 0 replies; 18+ messages in thread
From: James Bottomley @ 2006-07-12 17:40 UTC (permalink / raw)
  To: Eric Moore; +Cc: linux-scsi, dougg

On Wed, 2006-07-12 at 11:05 -0600, Eric Moore wrote:
> Response from co-worker that implemented this:

> The reason HP switched from using a standard Mode Page setting to
> using a vendor unique CDB is due to SCSI protocol problems.

I haven't objected to the vendor specific CDB yet ... although if
everyone implemented one of these the first time they found a difficulty
with one of the SCSI standards, the storage world would be in a bit of a
mess.

What I did say is that you can't do this in the driver ... it has to be
in the transport layer because it's not a driver problem.  Any other SAS
driver would have the same issue.

> The usage of Mode Sense and Mode Select will still work with the HP
> tape drives, if you can find a way around the above issues.  But I
> would suggest discussing any solution with the HP-Bristol tape drive
> folks.

Yes ... someone at HP is asking them about this ...

James



^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH 1/10] mptfusion : Transport Layer Retry support
@ 2006-07-12 19:18 Moore, Eric
  2006-07-12 19:25 ` James Bottomley
  0 siblings, 1 reply; 18+ messages in thread
From: Moore, Eric @ 2006-07-12 19:18 UTC (permalink / raw)
  To: James Bottomley; +Cc: linux-scsi, dougg

--  Wednesday, July 12, 2006 11:40 AM, James Bottomley wrote:

> 
> I haven't objected to the vendor specific CDB yet ... although if
> everyone implemented one of these the first time they found a 
> difficulty
> with one of the SCSI standards, the storage world would be in 
> a bit of a
> mess.

If the mode pages method worked properly, they wouldn't had to go this
other route.  

> 
> What I did say is that you can't do this in the driver ... it 
> has to be
> in the transport layer because it's not a driver problem.  
> Any other SAS
> driver would have the same issue.
> 

Ok, since this patch was the head of the queue, will you need
a respin of all the other patchs I posted yesterday?


> > The usage of Mode Sense and Mode Select will still work with the HP
> > tape drives, if you can find a way around the above issues.  But I
> > would suggest discussing any solution with the HP-Bristol tape drive
> > folks.
> 
> Yes ... someone at HP is asking them about this ...
> 

Are they aware of the problems we faced?




^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH 1/10] mptfusion : Transport Layer Retry support
  2006-07-12 19:18 Moore, Eric
@ 2006-07-12 19:25 ` James Bottomley
  0 siblings, 0 replies; 18+ messages in thread
From: James Bottomley @ 2006-07-12 19:25 UTC (permalink / raw)
  To: Moore, Eric; +Cc: linux-scsi, dougg

On Wed, 2006-07-12 at 13:18 -0600, Moore, Eric wrote:
> If the mode pages method worked properly, they wouldn't had to go this
> other route.  

Well .. yes ... however, it does look like they should be able to get at
this via the mode pages of the Report Luns W-LUN, which wouldn't suffer
either the reservations issue and should be immune from the busy
wait ...

> Ok, since this patch was the head of the queue, will you need
> a respin of all the other patchs I posted yesterday?

As long as they all apply without this one, I should be OK.

James



^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH 1/10] mptfusion : Transport Layer Retry support
@ 2006-07-12 20:22 Eric Moore
  0 siblings, 0 replies; 18+ messages in thread
From: Eric Moore @ 2006-07-12 20:22 UTC (permalink / raw)
  To: James.Bottomley; +Cc: linux-scsi

-- Wednesday, Julyl 12, 2006 1:26PM, James Bottomley wrote:

> As long as they all apply without this one, I should be OK.

James - I removed the TLR patch. And here I've combined all the other
patch's into this single patch.  This applies over this weeks two mptsas
patchs for backlink and integrated raid channel fix.  Breaking everything
out into seperate patchs will take a long time.

Signed-off-by: Eric Moore <Eric.Moore@lsil.com>


diff -uarpN b/drivers/message/fusion/Kconfig a/drivers/message/fusion/Kconfig
--- b/drivers/message/fusion/Kconfig	2006-07-12 13:50:57.000000000 -0600
+++ a/drivers/message/fusion/Kconfig	2006-07-11 16:39:39.000000000 -0600
@@ -48,10 +48,8 @@ config FUSION_SAS
 	  List of supported controllers:
 
 	  LSISAS1064
-	  LSISAS1066
 	  LSISAS1068
 	  LSISAS1064E
-	  LSISAS1066E
 	  LSISAS1068E
 
 config FUSION_MAX_SGE
diff -uarpN b/drivers/message/fusion/mptbase.c a/drivers/message/fusion/mptbase.c
--- b/drivers/message/fusion/mptbase.c	2006-07-12 13:50:57.000000000 -0600
+++ a/drivers/message/fusion/mptbase.c	2006-07-11 16:39:39.000000000 -0600
@@ -436,8 +436,6 @@ mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRA
 		 */
 		if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
 			freereq = 0;
-			devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n",
-				ioc->name, pEvReply));
 		} else {
 			devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
 				ioc->name, pEvReply));
@@ -678,19 +676,19 @@ int
 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
 {
 	MPT_ADAPTER	*ioc;
+	const struct pci_device_id *id;
 
-	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) {
+	if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
 		return -EINVAL;
-	}
 
 	MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
 
 	/* call per pci device probe entry point */
 	list_for_each_entry(ioc, &ioc_list, list) {
-		if(dd_cbfunc->probe) {
-			dd_cbfunc->probe(ioc->pcidev,
-			  ioc->pcidev->driver->id_table);
-  		}
+		id = ioc->pcidev->driver ?
+		    ioc->pcidev->driver->id_table : NULL;
+		if (dd_cbfunc->probe)
+			dd_cbfunc->probe(ioc->pcidev, id);
 	 }
 
 	return 0;
@@ -1056,9 +1054,8 @@ mpt_host_page_alloc(MPT_ADAPTER *ioc, pI
 
 				dinitprintk((MYIOC_s_INFO_FMT
 				    "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
-				    ioc->name,
-				    ioc->HostPageBuffer,
-				    ioc->HostPageBuffer_dma,
+				    ioc->name, ioc->HostPageBuffer,
+				    (u32)ioc->HostPageBuffer_dma,
 				    host_page_buffer_sz));
 				ioc->alloc_total += host_page_buffer_sz;
 				ioc->HostPageBuffer_sz = host_page_buffer_sz;
@@ -1380,6 +1377,7 @@ mpt_attach(struct pci_dev *pdev, const s
 		printk(KERN_WARNING MYNAM
 		  ": WARNING - %s did not initialize properly! (%d)\n",
 		  ioc->name, r);
+
 		list_del(&ioc->list);
 		if (ioc->alt_ioc)
 			ioc->alt_ioc->alt_ioc = NULL;
@@ -1762,9 +1760,9 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u3
 						 * chips (mpt_adapter_disable,
 						 * mpt_diag_reset)
 						 */
-						ioc->cached_fw = NULL;
 						ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload:  alt_%s has cached_fw=%p \n",
 							ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
+						ioc->alt_ioc->cached_fw = NULL;
 					}
 				} else {
 					printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
@@ -1885,7 +1883,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u3
 		/* FIXME?  Examine results here? */
 	}
 
-out:
+ out:
 	if ((ret != 0) && irq_allocated) {
 		free_irq(ioc->pci_irq, ioc);
 		if (mpt_msi_enable)
@@ -2670,6 +2668,7 @@ SendIocInit(MPT_ADAPTER *ioc, int sleepF
 	dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
 			ioc->name, count));
 
+	ioc->aen_event_read_flag=0;
 	return r;
 }
 
@@ -2737,6 +2736,8 @@ mpt_alloc_fw_memory(MPT_ADAPTER *ioc, in
 	if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
 		ioc->cached_fw = ioc->alt_ioc->cached_fw;  /* use alt_ioc's memory */
 		ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
+		ioc->alloc_total += size;
+		ioc->alt_ioc->alloc_total -= size;
 	} else {
 		if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
 			ioc->alloc_total += size;
@@ -3166,6 +3167,7 @@ KickStart(MPT_ADAPTER *ioc, int force, i
 static int
 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
 {
+	MPT_ADAPTER	*iocp=NULL;
 	u32 diag0val;
 	u32 doorbell;
 	int hard_reset_done = 0;
@@ -3301,17 +3303,23 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ign
 			/* FIXME?  Examine results here? */
 		}
 
-		if (ioc->cached_fw) {
+		if (ioc->cached_fw)
+			iocp = ioc;
+		else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
+			iocp = ioc->alt_ioc;
+		if (iocp) {
 			/* If the DownloadBoot operation fails, the
 			 * IOC will be left unusable. This is a fatal error
 			 * case.  _diag_reset will return < 0
 			 */
 			for (count = 0; count < 30; count ++) {
-				diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
+				diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic);
 				if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
 					break;
 				}
 
+				dprintk((MYIOC_s_INFO_FMT "cached_fw: diag0val=%x count=%d\n",
+					iocp->name, diag0val, count));
 				/* wait 1 sec */
 				if (sleepFlag == CAN_SLEEP) {
 					msleep (1000);
@@ -3320,7 +3328,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ign
 				}
 			}
 			if ((count = mpt_downloadboot(ioc,
-				(MpiFwHeader_t *)ioc->cached_fw, sleepFlag)) < 0) {
+				(MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) {
 				printk(KERN_WARNING MYNAM
 					": firmware downloadboot failure (%d)!\n", count);
 			}
@@ -3907,18 +3915,18 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int
 
 	if (sleepFlag == CAN_SLEEP) {
 		while (--cntdn) {
+			msleep (1);
 			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
 			if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
 				break;
-			msleep (1);
 			count++;
 		}
 	} else {
 		while (--cntdn) {
+			mdelay (1);
 			intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
 			if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
 				break;
-			mdelay (1);
 			count++;
 		}
 	}
@@ -4883,6 +4891,7 @@ mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
 		pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
 		if (!pIoc4)
 			return;
+		ioc->alloc_total += iocpage4sz;
 	} else {
 		ioc4_dma = ioc->spi_data.IocPg4_dma;
 		iocpage4sz = ioc->spi_data.IocPg4Sz;
@@ -4899,6 +4908,7 @@ mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
 	} else {
 		pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
 		ioc->spi_data.pIocPg4 = NULL;
+		ioc->alloc_total -= iocpage4sz;
 	}
 }
 
@@ -5030,19 +5040,18 @@ SendEventAck(MPT_ADAPTER *ioc, EventNoti
 	EventAck_t	*pAck;
 
 	if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
-		printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK "
-			"request frame for Event=%x EventContext=%x EventData=%x!\n",
-			ioc->name, evnp->Event, le32_to_cpu(evnp->EventContext),
-			le32_to_cpu(evnp->Data[0]));
+		dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
+		    ioc->name,__FUNCTION__));
 		return -1;
 	}
-	memset(pAck, 0, sizeof(*pAck));
 
-	dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
+	devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
 
 	pAck->Function     = MPI_FUNCTION_EVENT_ACK;
 	pAck->ChainOffset  = 0;
+	pAck->Reserved[0]  = pAck->Reserved[1] = 0;
 	pAck->MsgFlags     = 0;
+	pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
 	pAck->Event        = evnp->Event;
 	pAck->EventContext = evnp->EventContext;
 
@@ -5704,9 +5713,9 @@ EventDescriptionStr(u8 event, u32 evData
 		break;
 	case MPI_EVENT_EVENT_CHANGE:
 		if (evData0)
-			ds = "Events(ON) Change";
+			ds = "Events ON";
 		else
-			ds = "Events(OFF) Change";
+			ds = "Events OFF";
 		break;
 	case MPI_EVENT_INTEGRATED_RAID:
 	{
@@ -5777,8 +5786,27 @@ EventDescriptionStr(u8 event, u32 evData
 			break;
 		case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
 			snprintf(evStr, EVENT_DESCR_STR_SZ,
-			    "SAS Device Status Change: No Persistancy "
-			    "Added: id=%d", id);
+			    "SAS Device Status Change: No Persistancy: id=%d", id);
+			break;
+		case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
+			snprintf(evStr, EVENT_DESCR_STR_SZ,
+			    "SAS Device Status Change: Internal Device Reset : id=%d", id);
+			break;
+		case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
+			snprintf(evStr, EVENT_DESCR_STR_SZ,
+			    "SAS Device Status Change: Internal Task Abort : id=%d", id);
+			break;
+		case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
+			snprintf(evStr, EVENT_DESCR_STR_SZ,
+			    "SAS Device Status Change: Internal Abort Task Set : id=%d", id);
+			break;
+		case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
+			snprintf(evStr, EVENT_DESCR_STR_SZ,
+			    "SAS Device Status Change: Internal Clear Task Set : id=%d", id);
+			break;
+		case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
+			snprintf(evStr, EVENT_DESCR_STR_SZ,
+			    "SAS Device Status Change: Internal Query Task : id=%d", id);
 			break;
 		default:
 			snprintf(evStr, EVENT_DESCR_STR_SZ,
@@ -6034,7 +6062,7 @@ ProcessEventNotification(MPT_ADAPTER *io
  *	@ioc: Pointer to MPT_ADAPTER structure
  *	@log_info: U32 LogInfo reply word from the IOC
  *
- *	Refer to lsi/fc_log.h.
+ *	Refer to lsi/mpi_log_fc.h.
  */
 static void
 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
@@ -6131,8 +6159,10 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 l
 		"Invalid SAS Address",				/* 01h */
 		NULL,						/* 02h */
 		"Invalid Page",					/* 03h */
-		NULL,						/* 04h */
-		"Task Terminated"				/* 05h */
+		"Diag Message Error",				/* 04h */
+		"Task Terminated",				/* 05h */
+		"Enclosure Management",				/* 06h */
+		"Target Mode"					/* 07h */
 	};
 	static char *pl_code_str[] = {
 		NULL,						/* 00h */
@@ -6158,7 +6188,7 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 l
 		"IO Executed",					/* 14h */
 		"Persistant Reservation Out Not Affiliation Owner", /* 15h */
 		"Open Transmit DMA Abort",			/* 16h */
-		NULL,						/* 17h */
+		"IO Device Missing Delay Retry",		/* 17h */
 		NULL,						/* 18h */
 		NULL,						/* 19h */
 		NULL,						/* 1Ah */
@@ -6238,7 +6268,7 @@ static void
 mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
 {
 	u32 status = ioc_status & MPI_IOCSTATUS_MASK;
-	char *desc = "";
+	char *desc = NULL;
 
 	switch (status) {
 	case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
@@ -6348,7 +6378,7 @@ mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 io
 		desc = "Others";
 		break;
 	}
-	if (desc != "")
+	if (desc != NULL)
 		printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
 }
 
@@ -6386,7 +6416,6 @@ EXPORT_SYMBOL(mpt_alloc_fw_memory);
 EXPORT_SYMBOL(mpt_free_fw_memory);
 EXPORT_SYMBOL(mptbase_sas_persist_operation);
 
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *	fusion_init - Fusion MPT base driver initialization routine.
diff -uarpN b/drivers/message/fusion/mptbase.h a/drivers/message/fusion/mptbase.h
--- b/drivers/message/fusion/mptbase.h	2006-07-12 13:54:19.000000000 -0600
+++ a/drivers/message/fusion/mptbase.h	2006-07-11 16:39:39.000000000 -0600
@@ -75,8 +75,8 @@
 #define COPYRIGHT	"Copyright (c) 1999-2005 " MODULEAUTHOR
 #endif
 
-#define MPT_LINUX_VERSION_COMMON	"3.04.00"
-#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.04.00"
+#define MPT_LINUX_VERSION_COMMON	"3.04.01"
+#define MPT_LINUX_PACKAGE_NAME		"@(#)mptlinux-3.04.01"
 #define WHAT_MAGIC_STRING		"@" "(" "#" ")"
 
 #define show_mptmod_ver(s,ver)  \
@@ -307,8 +307,8 @@ typedef struct _SYSIF_REGS
 	u32	HostIndex;	/* 50     Host Index register        */
 	u32	Reserved4[15];	/* 54-8F                             */
 	u32	Fubar;		/* 90     For Fubar usage            */
-	u32     Reserved5[1050];/* 94-10F8                           */
-	u32     Reset_1078;     /* 10FC   Reset 1078                 */
+	u32	Reserved5[1050];/* 94-10F8                           */
+	u32	Reset_1078;	/* 10FC   Reset 1078                 */
 } SYSIF_REGS;
 
 /*
@@ -363,6 +363,7 @@ typedef struct _VirtDevice {
 #define MPT_TARGET_FLAGS_VALID_56	0x10
 #define MPT_TARGET_FLAGS_SAF_TE_ISSUED	0x20
 #define MPT_TARGET_FLAGS_RAID_COMPONENT	0x40
+#define MPT_TARGET_FLAGS_LED_ON		0x80
 
 /*
  *	/proc/mpt interface
@@ -980,7 +981,7 @@ typedef struct _MPT_SCSI_HOST {
 	wait_queue_head_t	  scandv_waitq;
 	int			  scandv_wait_done;
 	long			  last_queue_full;
-	u8		 	  mpt_pq_filter;
+	u16			  tm_iocstatus;
 } MPT_SCSI_HOST;
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff -uarpN b/drivers/message/fusion/mptctl.c a/drivers/message/fusion/mptctl.c
--- b/drivers/message/fusion/mptctl.c	2006-07-12 13:50:57.000000000 -0600
+++ a/drivers/message/fusion/mptctl.c	2006-07-11 16:39:39.000000000 -0600
@@ -2332,7 +2332,7 @@ done_free_mem:
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* Prototype Routine for the HP HOST INFO command.
+/* Prototype Routine for the HOST INFO command.
  *
  * Outputs:	None.
  * Return:	0 if successful
@@ -2568,7 +2568,7 @@ mptctl_hp_hostinfo(unsigned long arg, un
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* Prototype Routine for the HP TARGET INFO command.
+/* Prototype Routine for the TARGET INFO command.
  *
  * Outputs:	None.
  * Return:	0 if successful
diff -uarpN b/drivers/message/fusion/mptctl.h a/drivers/message/fusion/mptctl.h
--- b/drivers/message/fusion/mptctl.h	2006-07-12 13:50:57.000000000 -0600
+++ a/drivers/message/fusion/mptctl.h	2006-07-11 16:39:39.000000000 -0600
@@ -354,9 +354,6 @@ struct mpt_ioctl_command32 {
 
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *	HP Specific IOCTL Defines and Structures
- */
 
 #define CPQFCTS_IOC_MAGIC 'Z'
 #define HP_IOC_MAGIC 'Z'
@@ -364,8 +361,6 @@ struct mpt_ioctl_command32 {
 #define HP_GETHOSTINFO1		_IOR(HP_IOC_MAGIC, 20, hp_host_info_rev0_t)
 #define HP_GETTARGETINFO	_IOR(HP_IOC_MAGIC, 21, hp_target_info_t)
 
-/* All HP IOCTLs must include this header
- */
 typedef struct _hp_header {
 	unsigned int iocnum;
 	unsigned int host;
diff -uarpN b/drivers/message/fusion/mptfc.c a/drivers/message/fusion/mptfc.c
--- b/drivers/message/fusion/mptfc.c	2006-07-12 13:50:57.000000000 -0600
+++ a/drivers/message/fusion/mptfc.c	2006-07-11 16:39:39.000000000 -0600
@@ -77,10 +77,6 @@ MODULE_DESCRIPTION(my_NAME);
 MODULE_LICENSE("GPL");
 
 /* Command line args */
-static int mpt_pq_filter = 0;
-module_param(mpt_pq_filter, int, 0);
-MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1  (default=0)");
-
 #define MPTFC_DEV_LOSS_TMO (60)
 static int mptfc_dev_loss_tmo = MPTFC_DEV_LOSS_TMO;	/* reasonable default */
 module_param(mptfc_dev_loss_tmo, int, 0);
@@ -513,8 +509,7 @@ mptfc_slave_alloc(struct scsi_device *sd
 
 	if (vtarget->num_luns == 0) {
 		vtarget->ioc_id = hd->ioc->id;
-		vtarget->tflags = MPT_TARGET_FLAGS_Q_YES |
-		    		  MPT_TARGET_FLAGS_VALID_INQUIRY;
+		vtarget->tflags = MPT_TARGET_FLAGS_Q_YES;
 		hd->Targets[sdev->id] = vtarget;
 	}
 
@@ -1129,13 +1124,6 @@ mptfc_probe(struct pci_dev *pdev, const 
 	hd->timer.data = (unsigned long) hd;
 	hd->timer.function = mptscsih_timer_expired;
 
-	hd->mpt_pq_filter = mpt_pq_filter;
-
-	ddvprintk((MYIOC_s_INFO_FMT
-		"mpt_pq_filter %x\n",
-		ioc->name, 
-		mpt_pq_filter));
-
 	init_waitqueue_head(&hd->scandv_waitq);
 	hd->scandv_wait_done = 0;
 	hd->last_queue_full = 0;
diff -uarpN b/drivers/message/fusion/mptsas.c a/drivers/message/fusion/mptsas.c
--- b/drivers/message/fusion/mptsas.c	2006-07-12 13:54:30.000000000 -0600
+++ a/drivers/message/fusion/mptsas.c	2006-07-12 14:12:19.000000000 -0600
@@ -76,16 +76,10 @@ MODULE_AUTHOR(MODULEAUTHOR);
 MODULE_DESCRIPTION(my_NAME);
 MODULE_LICENSE("GPL");
 
-static int mpt_pq_filter;
-module_param(mpt_pq_filter, int, 0);
-MODULE_PARM_DESC(mpt_pq_filter,
-		"Enable peripheral qualifier filter: enable=1  "
-		"(default=0)");
-
 static int mpt_pt_clear;
 module_param(mpt_pt_clear, int, 0);
 MODULE_PARM_DESC(mpt_pt_clear,
-		"Clear persistency table: enable=1  "
+		" Clear persistency table: enable=1  "
 		"(default=MPTSCSIH_PT_CLEAR=0)");
 
 static int	mptsasDoneCtx = -1;
@@ -655,7 +649,7 @@ mptsas_slave_configure(struct scsi_devic
 
 	sas_read_port_mode_page(sdev);
 
- out:
+out:
 	return mptscsih_slave_configure(sdev);
 }
 
@@ -2707,7 +2701,6 @@ mptsas_probe(struct pci_dev *pdev, const
 	hd->timer.data = (unsigned long) hd;
 	hd->timer.function = mptscsih_timer_expired;
 
-	hd->mpt_pq_filter = mpt_pq_filter;
 	ioc->sas_data.ptClear = mpt_pt_clear;
 
 	if (ioc->sas_data.ptClear==1) {
@@ -2715,12 +2708,6 @@ mptsas_probe(struct pci_dev *pdev, const
 		    ioc, MPI_SAS_OP_CLEAR_ALL_PERSISTENT);
 	}
 
-	ddvprintk((MYIOC_s_INFO_FMT
-		"mpt_pq_filter %x mpt_pq_filter %x\n",
-		ioc->name,
-		mpt_pq_filter,
-		mpt_pq_filter));
-
 	init_waitqueue_head(&hd->scandv_waitq);
 	hd->scandv_wait_done = 0;
 	hd->last_queue_full = 0;
diff -uarpN b/drivers/message/fusion/mptscsih.c a/drivers/message/fusion/mptscsih.c
--- b/drivers/message/fusion/mptscsih.c	2006-07-12 13:50:57.000000000 -0600
+++ a/drivers/message/fusion/mptscsih.c	2006-07-12 14:22:12.000000000 -0600
@@ -66,6 +66,7 @@
 
 #include "mptbase.h"
 #include "mptscsih.h"
+#include "lsi/mpi_log_sas.h"
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 #define my_NAME		"Fusion MPT SCSI Host driver"
@@ -127,7 +128,7 @@ static void	mptscsih_freeChainBuffers(MP
 static void	mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
 static int	mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
 static int	mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
-static u32	SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
+static int	SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
 
 static int	mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
 
@@ -138,7 +139,6 @@ static void	mptscsih_initTarget(MPT_SCSI
 static void	mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *vtarget, struct scsi_device *sdev);
 static int	mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
 int		mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
-static int	mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
 static void	mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
 
 void 		mptscsih_remove(struct pci_dev *);
@@ -497,6 +497,34 @@ nextSGEset:
 	return SUCCESS;
 } /* mptscsih_AddSGE() */
 
+static void
+mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
+    U32 SlotStatus)
+{
+	MPT_FRAME_HDR *mf;
+	SEPRequest_t 	 *SEPMsg;
+
+	if (ioc->bus_type == FC)
+		return;
+
+	if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
+		dfailprintk((MYIOC_s_WARN_FMT "%s: no msg frames!!\n",
+		    ioc->name,__FUNCTION__));
+		return;
+	}
+
+	SEPMsg = (SEPRequest_t *)mf;
+	SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
+	SEPMsg->Bus = vtarget->bus_id;
+	SEPMsg->TargetID = vtarget->target_id;
+	SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS;
+	SEPMsg->SlotStatus = SlotStatus;
+	devtverboseprintk((MYIOC_s_WARN_FMT
+	    "Sending SEP cmd=%x id=%d bus=%d\n",
+	    ioc->name, SlotStatus, SEPMsg->TargetID, SEPMsg->Bus));
+	mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *	mptscsih_io_done - Main SCSI IO callback routine registered to
@@ -520,6 +548,8 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_F
 	SCSIIORequest_t	*pScsiReq;
 	SCSIIOReply_t	*pScsiReply;
 	u16		 req_idx, req_idx_MR;
+	VirtDevice	 *vdev;
+	VirtTarget	 *vtarget;
 
 	hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
 
@@ -538,6 +568,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_F
 	}
 
 	sc = hd->ScsiLookup[req_idx];
+	hd->ScsiLookup[req_idx] = NULL;
 	if (sc == NULL) {
 		MPIHeader_t *hdr = (MPIHeader_t *)mf;
 
@@ -553,6 +584,12 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_F
 		return 1;
 	}
 
+	if ((unsigned char *)mf != sc->host_scribble) {
+		mptscsih_freeChainBuffers(ioc, req_idx);
+		return 1;
+	}
+ 
+	sc->host_scribble = NULL;
 	sc->result = DID_OK << 16;		/* Set default reply as OK */
 	pScsiReq = (SCSIIORequest_t *) mf;
 	pScsiReply = (SCSIIOReply_t *) mr;
@@ -640,10 +677,36 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_F
 
 			if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
 				hd->sel_timeout[pScsiReq->TargetID]++;
+
+			vdev = sc->device->hostdata;
+			if (!vdev)
+				break;
+			vtarget = vdev->vtarget;
+			if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) {
+				mptscsih_issue_sep_command(ioc, vtarget,
+				    MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED);
+				vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON;
+			}
 			break;
 
-		case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:	/* 0x0048 */
 		case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:		/* 0x004B */
+			if ( ioc->bus_type == SAS ) {
+				u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus);
+				if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
+					u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
+					log_info &=SAS_LOGINFO_MASK;
+					if (log_info == SAS_LOGINFO_NEXUS_LOSS) {
+						sc->result = (DID_BUS_BUSY << 16);
+						break;
+					}
+				}
+			}
+
+			/*
+			 * Allow non-SAS & non-NEXUS_LOSS to drop into below code
+			 */
+
+		case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:	/* 0x0048 */
 		case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:		/* 0x004C */
 			/* Linux handles an unsolicited DID_RESET better
 			 * than an unsolicited DID_ABORT.
@@ -658,7 +721,7 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_F
 				sc->result=DID_SOFT_ERROR << 16;
 			else /* Sufficient data transfer occurred */
 				sc->result = (DID_OK << 16) | scsi_status;
-			dreplyprintk((KERN_NOTICE 
+			dreplyprintk((KERN_NOTICE
 			    "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id));
 			break;
 
@@ -784,8 +847,6 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_F
 				sc->request_bufflen, sc->sc_data_direction);
 	}
 
-	hd->ScsiLookup[req_idx] = NULL;
-
 	sc->scsi_done(sc);		/* Issue the command callback */
 
 	/* Free Chain buffers */
@@ -827,9 +888,17 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOS
 			dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
 					mf, SCpnt));
 
+			/* Free Chain buffers */
+			mptscsih_freeChainBuffers(ioc, ii);
+
+			/* Free Message frames */
+			mpt_free_msg_frame(ioc, mf);
+
+			if ((unsigned char *)mf != SCpnt->host_scribble)
+				continue;
+
 			/* Set status, free OS resources (SG DMA buffers)
 			 * Do OS callback
-			 * Free driver resources (chain, msg buffers)
 			 */
 			if (SCpnt->use_sg) {
 				pci_unmap_sg(ioc->pcidev,
@@ -845,12 +914,6 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOS
 			SCpnt->result = DID_RESET << 16;
 			SCpnt->host_scribble = NULL;
 
-			/* Free Chain buffers */
-			mptscsih_freeChainBuffers(ioc, ii);
-
-			/* Free Message frames */
-			mpt_free_msg_frame(ioc, mf);
-
 			SCpnt->scsi_done(SCpnt);	/* Issue the command callback */
 		}
 	}
@@ -887,10 +950,10 @@ mptscsih_search_running_cmds(MPT_SCSI_HO
 		if ((sc = hd->ScsiLookup[ii]) != NULL) {
 
 			mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
-
+			if (mf == NULL)
+				continue;
 			dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
 					hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
-
 			if ((mf->TargetID != ((u8)vdevice->vtarget->target_id)) || (mf->LUN[1] != ((u8) vdevice->lun)))
 				continue;
 
@@ -899,6 +962,8 @@ mptscsih_search_running_cmds(MPT_SCSI_HO
 			hd->ScsiLookup[ii] = NULL;
 			mptscsih_freeChainBuffers(hd->ioc, ii);
 			mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
+			if ((unsigned char *)mf != sc->host_scribble)
+				continue;
 			if (sc->use_sg) {
 				pci_unmap_sg(hd->ioc->pcidev,
 				(struct scatterlist *) sc->request_buffer,
@@ -1341,8 +1406,8 @@ mptscsih_qcmd(struct scsi_cmnd *SCpnt, v
 			goto fail;
 	}
 
+	SCpnt->host_scribble = (unsigned char *)mf;
 	hd->ScsiLookup[my_idx] = SCpnt;
-	SCpnt->host_scribble = NULL;
 
 	mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf);
 	dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
@@ -1529,6 +1594,12 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8
 		rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
 	}
 
+	/*
+	 * Check IOCStatus from TM reply message
+	 */
+	 if (hd->tm_iocstatus != MPI_IOCSTATUS_SUCCESS)
+		rc = FAILED;
+
 	dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
 
 	return rc;
@@ -1654,6 +1725,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
 	int		 scpnt_idx;
 	int		 retval;
 	VirtDevice	 *vdev;
+	ulong	 	 sn = SCpnt->serial_number;
 
 	/* If we can't locate our host adapter structure, return FAILED status.
 	 */
@@ -1707,6 +1779,11 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
 		vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun,
 		ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
 
+	if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
+	    SCpnt->serial_number == sn) {
+		retval = FAILED;
+	}
+
 	printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
 		hd->ioc->name,
 		((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
@@ -2023,6 +2100,7 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *
 		DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
 
 		iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
+		hd->tm_iocstatus = iocstatus;
 		dtmprintk((MYIOC_s_WARN_FMT "  SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
 			ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
 		/* Error?  (anything non-zero?) */
@@ -2401,6 +2479,13 @@ mptscsih_copy_sense_data(struct scsi_cmn
 				ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
 
 				ioc->eventContext++;
+				if (hd->ioc->pcidev->vendor ==
+				    PCI_VENDOR_ID_IBM) {
+					mptscsih_issue_sep_command(hd->ioc,
+					    vdev->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
+					vdev->vtarget->tflags |=
+					    MPT_TARGET_FLAGS_LED_ON;
+				}
 			}
 		}
 	} else {
@@ -2409,7 +2494,7 @@ mptscsih_copy_sense_data(struct scsi_cmn
 	}
 }
 
-static u32
+static int
 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
 {
 	MPT_SCSI_HOST *hd;
@@ -3003,6 +3088,8 @@ mptscsih_scandv_complete(MPT_ADAPTER *io
 				completionCode = MPT_SCANDV_DID_RESET;
 			else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
 				completionCode = MPT_SCANDV_DID_RESET;
+			else if (scsi_status == MPI_SCSI_STATUS_BUSY)
+				completionCode = MPT_SCANDV_SOME_ERROR;
 			else {
 				completionCode = MPT_SCANDV_GOOD;
 				hd->pLocal->scsiStatus = scsi_status;
@@ -3120,7 +3207,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTER
 	int		in_isr;
 	char		 cmdLen;
 	char		 CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-	char		 cmd = io->cmd;
+	u8		 cmd = io->cmd;
 
 	in_isr = in_interrupt();
 	if (in_isr) {
@@ -3401,5 +3488,4 @@ EXPORT_SYMBOL(mptscsih_ioc_reset);
 EXPORT_SYMBOL(mptscsih_change_queue_depth);
 EXPORT_SYMBOL(mptscsih_timer_expired);
 EXPORT_SYMBOL(mptscsih_TMHandler);
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
diff -uarpN b/drivers/message/fusion/mptspi.c a/drivers/message/fusion/mptspi.c
--- b/drivers/message/fusion/mptspi.c	2006-07-12 13:50:58.000000000 -0600
+++ a/drivers/message/fusion/mptspi.c	2006-07-11 16:39:39.000000000 -0600
@@ -83,10 +83,6 @@ static int mpt_saf_te = MPTSCSIH_SAF_TE;
 module_param(mpt_saf_te, int, 0);
 MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1  (default=MPTSCSIH_SAF_TE=0)");
 
-static int mpt_pq_filter = 0;
-module_param(mpt_pq_filter, int, 0);
-MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1  (default=0)");
-
 static void mptspi_write_offset(struct scsi_target *, int);
 static void mptspi_write_width(struct scsi_target *, int);
 static int mptspi_write_spi_device_pg1(struct scsi_target *,
@@ -1047,14 +1043,12 @@ mptspi_probe(struct pci_dev *pdev, const
 	hd->timer.function = mptscsih_timer_expired;
 
 	ioc->spi_data.Saf_Te = mpt_saf_te;
-	hd->mpt_pq_filter = mpt_pq_filter;
 
 	hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
 	ddvprintk((MYIOC_s_INFO_FMT
-		"saf_te %x mpt_pq_filter %x\n",
+		"saf_te %x\n",
 		ioc->name,
-		mpt_saf_te,
-		mpt_pq_filter));
+		mpt_saf_te));
 	ioc->spi_data.noQas = 0;
 
 	init_waitqueue_head(&hd->scandv_waitq);

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/10] mptfusion : Transport Layer Retry support
  2006-07-12 17:05 [PATCH 1/10] mptfusion : Transport Layer Retry support Eric Moore
  2006-07-12 17:40 ` James Bottomley
@ 2006-07-13  2:33 ` Douglas Gilbert
  2006-07-13 17:22   ` Andrew Patterson
  1 sibling, 1 reply; 18+ messages in thread
From: Douglas Gilbert @ 2006-07-13  2:33 UTC (permalink / raw)
  To: Eric Moore; +Cc: linux-scsi, James.Bottomley, elliott

Eric Moore wrote:
> --  Wednesday, July 12, 2006 9:32 AM, James Bottomley wrote:
> 
> 
>>If I understand what this does correctly, you snoop the 
>>inquiry field in
>>slave configure and then send a vendor specific opcode that the tape
>>understands (in the event that it reports TLR in its PSLU page)?
>>
>>Really, no, this isn't appropriate for code in a driver, 
>>since I assume
>>enabling TLR via this command on these things should be independent of
>>the particular SAS HBA, so it should probably be a transport specific
>>blacklist.
>>
> 
> 
> Response from co-worker that implemented this:
> 
> --
> 
> The reason HP switched from using a standard Mode Page setting to using a vendor unique CDB is due to SCSI protocol problems.
> 
> The primary issue is that with standard Mode Sense and Mode Select commands, these commands are blocked when either the device has reservations against it or if the device is busy.  TLR needs to be enabled when the device is discovered, which is done using an Inquiry command.  But, let's look at this example:
> 
> The tape cartridge was read previously then the drive turned off (so the tape device is removed from the SAS domain and all device objects are deleted).  Later on, the tape drive is turned back on.  It will be discovered and an event sent to the host driver.  This will kick off an enumeration (Inquiry commands).  With the Inquiry, we detect that this is an HP SAS tape drive and TLR needs to be enabled.  The host driver then sends a Mode Sense to read the SAS protocol page so we can enable TLR.  However, the tape cartridge is rewinding.  The Inquriy commands completed because they are "immediate" commands that the drive can service at any time.  But, the Mode Sense (and Mode Select) commands are blocked (pended) while the tape drive is busy.  I can take more than 5 minutes for a tape cartridge to rewind and become ready, at which time the Mode Sense would be completed.  It isn't that th
 e Mode Sense is returned with Busy, it is pended so it remains outstanding and no other co
mmands can be sent to the drive.
> 
> A similar problem occurs with reservations.  The Inquiry will always complete no matter who has reservations on the drive.  But, a Mode Sense (and Mode Select) will fail if another initiator has reservations.
> 
> I found the long Busy problem (just because the drive takes up to and even longer than 30 seconds to come Ready after a power on, no matter where the tape is).  I was trying to piggy-back on the OS Inquiry command (which has a timeout of 4 seconds) and this was failing.  I modified my driver to perform the Mode Sense outside of the OS Inquiry command, but HP came back with the above scenarios (tape rewind and reservations) and that's when they wanted to switch to a vendor-unique CDB (much easier for them F/W wise).
> 
> The usage of Mode Sense and Mode Select will still work with the HP tape drives, if you can find a way around the above issues.  But I would suggest discussing any solution with the HP-Bristol tape drive folks.

Eric,
Slightly off topic but this reminded me of the LOG SENSE
behaviour I have noticed with a SAS ST336754SS disk.
When the disk is spun down all requests for log pages
apart from the protocol specific port log page (0x18)
fail with a sense key of NOT READY. The protocol specific
port log page works irrespective of the power condition
state. Strangely Seagate reject the port specific _mode_
pages (0x18 and 0x19) when the disk is spun down.

I can't see anything in SPC-4 or SBC-3 that says MODE
SENSE/SELECT and LOG SENSE/SELECT shall not work if
the power condition state is STOPPED. Transport related
mode and log pages are good examples of why the power
condition state should be ignored.

The unit attention delivery and reservations are thorny issues.
Perhaps the HP-Bristol tape drive folks should be talking
to Rob Elliott (also from HP) who is the SAS t10 techical editor.

Doug Gilbert


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/10] mptfusion : Transport Layer Retry support
  2006-07-13  2:33 ` Douglas Gilbert
@ 2006-07-13 17:22   ` Andrew Patterson
  2006-07-14 23:02     ` Andrew Patterson
  0 siblings, 1 reply; 18+ messages in thread
From: Andrew Patterson @ 2006-07-13 17:22 UTC (permalink / raw)
  To: dougg; +Cc: Eric Moore, linux-scsi, James.Bottomley, elliott

On Wed, 2006-07-12 at 22:33 -0400, Douglas Gilbert wrote:
> Eric Moore wrote:
> > --  Wednesday, July 12, 2006 9:32 AM, James Bottomley wrote:
> > 
> > 
> >>If I understand what this does correctly, you snoop the 
> >>inquiry field in
> >>slave configure and then send a vendor specific opcode that the tape
> >>understands (in the event that it reports TLR in its PSLU page)?
> >>
> >>Really, no, this isn't appropriate for code in a driver, 
> >>since I assume
> >>enabling TLR via this command on these things should be independent of
> >>the particular SAS HBA, so it should probably be a transport specific
> >>blacklist.
> >>
> > 
> > 
> > Response from co-worker that implemented this:
> > 
> > --
> > 
> > The reason HP switched from using a standard Mode Page setting to using a vendor unique CDB is due to SCSI protocol problems.
> > 
> > The primary issue is that with standard Mode Sense and Mode Select commands, these commands are blocked when either the device has reservations against it or if the device is busy.  TLR needs to be enabled when the device is discovered, which is done using an Inquiry command.  But, let's look at this example:
> > 
> > The tape cartridge was read previously then the drive turned off (so the tape device is removed from the SAS domain and all device objects are deleted).  Later on, the tape drive is turned back on.  It will be discovered and an event sent to the host driver.  This will kick off an enumeration (Inquiry commands).  With the Inquiry, we detect that this is an HP SAS tape drive and TLR needs to be enabled.  The host driver then sends a Mode Sense to read the SAS protocol page so we can enable TLR.  However, the tape cartridge is rewinding.  The Inquriy commands completed because they are "immediate" commands that the drive can service at any time.  But, the Mode Sense (and Mode Select) commands are blocked (pended) while the tape drive is busy.  I can take more than 5 minutes for a tape cartridge to rewind and become ready, at which time the Mode Sense would be completed.  It isn't that 
 the Mode Sense is returned with Busy, it is pended so it remains outstanding and no other 
 co
> mmands can be sent to the drive.
> > 
> > A similar problem occurs with reservations.  The Inquiry will always complete no matter who has reservations on the drive.  But, a Mode Sense (and Mode Select) will fail if another initiator has reservations.
> > 
> > I found the long Busy problem (just because the drive takes up to and even longer than 30 seconds to come Ready after a power on, no matter where the tape is).  I was trying to piggy-back on the OS Inquiry command (which has a timeout of 4 seconds) and this was failing.  I modified my driver to perform the Mode Sense outside of the OS Inquiry command, but HP came back with the above scenarios (tape rewind and reservations) and that's when they wanted to switch to a vendor-unique CDB (much easier for them F/W wise).
> > 
> > The usage of Mode Sense and Mode Select will still work with the HP tape drives, if you can find a way around the above issues.  But I would suggest discussing any solution with the HP-Bristol tape drive folks.
> 
> Eric,
> Slightly off topic but this reminded me of the LOG SENSE
> behaviour I have noticed with a SAS ST336754SS disk.
> When the disk is spun down all requests for log pages
> apart from the protocol specific port log page (0x18)
> fail with a sense key of NOT READY. The protocol specific
> port log page works irrespective of the power condition
> state. Strangely Seagate reject the port specific _mode_
> pages (0x18 and 0x19) when the disk is spun down.
> 
> I can't see anything in SPC-4 or SBC-3 that says MODE
> SENSE/SELECT and LOG SENSE/SELECT shall not work if
> the power condition state is STOPPED. Transport related
> mode and log pages are good examples of why the power
> condition state should be ignored.
> 
> The unit attention delivery and reservations are thorny issues.
> Perhaps the HP-Bristol tape drive folks should be talking
> to Rob Elliott (also from HP) who is the SAS t10 techical editor.

I am in a discusion with both Rob and the HP-Bristol folks about this.
We are exploring work-arounds.  Everyone agrees that the vendor specific
command solution is "less than optimal".

Andrew




^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH 1/10] mptfusion : Transport Layer Retry support
@ 2006-07-13 20:45 Moore, Eric
  2006-07-13 20:52 ` James Bottomley
  0 siblings, 1 reply; 18+ messages in thread
From: Moore, Eric @ 2006-07-13 20:45 UTC (permalink / raw)
  To: James Bottomley; +Cc: linux-scsi, dougg

-- Wednesday, July 12, 2006 1:26 PM, James Bottomley: 


> On Wed, 2006-07-12 at 13:18 -0600, Moore, Eric wrote:
> > If the mode pages method worked properly, they wouldn't had 
> to go this
> > other route.  
> 
> Well .. yes ... however, it does look like they should be 
> able to get at
> this via the mode pages of the Report Luns W-LUN, which 
> wouldn't suffer
> either the reservations issue and should be immune from the busy
> wait ...
> 


SPC-3 Section 8, of spc3r23.pdf, says W-LUN only covers
inquiry, report luns, request sense, and test unit ready.

I couldn't find where it says it worked for mode page 18h,
protocol-specfic lu page.

Eric

^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH 1/10] mptfusion : Transport Layer Retry support
  2006-07-13 20:45 Moore, Eric
@ 2006-07-13 20:52 ` James Bottomley
  0 siblings, 0 replies; 18+ messages in thread
From: James Bottomley @ 2006-07-13 20:52 UTC (permalink / raw)
  To: Moore, Eric; +Cc: linux-scsi, dougg

On Thu, 2006-07-13 at 14:45 -0600, Moore, Eric wrote:
> SPC-3 Section 8, of spc3r23.pdf, says W-LUN only covers
> inquiry, report luns, request sense, and test unit ready.
> 
> I couldn't find where it says it worked for mode page 18h,
> protocol-specfic lu page.

Yes, sorry, forget that ... I was just looking for an easy way around
this without altering the standards ... although it looks like HP is
beginning that route.  In my haste I misread REQUEST SENSE for MODE
SENSE.

James



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/10] mptfusion : Transport Layer Retry support
  2006-07-13 17:22   ` Andrew Patterson
@ 2006-07-14 23:02     ` Andrew Patterson
  2006-07-14 23:25       ` James Bottomley
  0 siblings, 1 reply; 18+ messages in thread
From: Andrew Patterson @ 2006-07-14 23:02 UTC (permalink / raw)
  To: dougg; +Cc: Eric Moore, linux-scsi, James.Bottomley, elliott

On Thu, 2006-07-13 at 11:22 -0600, Andrew Patterson wrote:
> On Wed, 2006-07-12 at 22:33 -0400, Douglas Gilbert wrote:
> > Eric Moore wrote:
> > > --  Wednesday, July 12, 2006 9:32 AM, James Bottomley wrote:
> > > 
> > > 
> > >>If I understand what this does correctly, you snoop the 
> > >>inquiry field in
> > >>slave configure and then send a vendor specific opcode that the tape
> > >>understands (in the event that it reports TLR in its PSLU page)?
> > >>
> > >>Really, no, this isn't appropriate for code in a driver, 
> > >>since I assume
> > >>enabling TLR via this command on these things should be independent of
> > >>the particular SAS HBA, so it should probably be a transport specific
> > >>blacklist.
> > >>
> > > 
> > > 
> > > Response from co-worker that implemented this:
> > > 
> > > --
> > > 
> > > The reason HP switched from using a standard Mode Page setting to using a vendor unique CDB is due to SCSI protocol problems.
> > > 
> > > The primary issue is that with standard Mode Sense and Mode Select commands, these commands are blocked when either the device has reservations against it or if the device is busy.  TLR needs to be enabled when the device is discovered, which is done using an Inquiry command.  But, let's look at this example:
> > > 
> > > The tape cartridge was read previously then the drive turned off (so the tape device is removed from the SAS domain and all device objects are deleted).  Later on, the tape drive is turned back on.  It will be discovered and an event sent to the host driver.  This will kick off an enumeration (Inquiry commands).  With the Inquiry, we detect that this is an HP SAS tape drive and TLR needs to be enabled.  The host driver then sends a Mode Sense to read the SAS protocol page so we can enable TLR.  However, the tape cartridge is rewinding.  The Inquriy commands completed because they are "immediate" commands that the drive can service at any time.  But, the Mode Sense (and Mode Select) commands are blocked (pended) while the tape drive is busy.  I can take more than 5 minutes for a tape cartridge to rewind and become ready, at which time the Mode Sense would be completed.  It isn't tha
 t the Mode Sense is returned with Busy, it is pended so it remains outstanding and no othe
 r 
>  co
> > mmands can be sent to the drive.
> > > 
> > > A similar problem occurs with reservations.  The Inquiry will always complete no matter who has reservations on the drive.  But, a Mode Sense (and Mode Select) will fail if another initiator has reservations.
> > > 
> > > I found the long Busy problem (just because the drive takes up to and even longer than 30 seconds to come Ready after a power on, no matter where the tape is).  I was trying to piggy-back on the OS Inquiry command (which has a timeout of 4 seconds) and this was failing.  I modified my driver to perform the Mode Sense outside of the OS Inquiry command, but HP came back with the above scenarios (tape rewind and reservations) and that's when they wanted to switch to a vendor-unique CDB (much easier for them F/W wise).
> > > 
> > > The usage of Mode Sense and Mode Select will still work with the HP tape drives, if you can find a way around the above issues.  But I would suggest discussing any solution with the HP-Bristol tape drive folks.
> > 
> > Eric,
> > Slightly off topic but this reminded me of the LOG SENSE
> > behaviour I have noticed with a SAS ST336754SS disk.
> > When the disk is spun down all requests for log pages
> > apart from the protocol specific port log page (0x18)
> > fail with a sense key of NOT READY. The protocol specific
> > port log page works irrespective of the power condition
> > state. Strangely Seagate reject the port specific _mode_
> > pages (0x18 and 0x19) when the disk is spun down.
> > 
> > I can't see anything in SPC-4 or SBC-3 that says MODE
> > SENSE/SELECT and LOG SENSE/SELECT shall not work if
> > the power condition state is STOPPED. Transport related
> > mode and log pages are good examples of why the power
> > condition state should be ignored.
> > A _standard_ command would be fine - a vendor-specific command, however,
is not a good idea (beyond the prototype stage).  Software is not going
to want to have 7 ways to enable this basic functionality for 7 vendors.
It wouldn't take long to get that through the committee, especially if
the HBA vendors and tape vendors agreed on the solution ahead of time.
SAS-2 could define a SAS-specific command just like it defines
SAS-specific mode pages and log pages (although a protocol-specific
command would be new to SCSI; the closest we have now is the
modification to how the START STOP UNIT command works in SAS to interact
with the NOTIFY (ENABLE SPINUP) primitive).

As discussed long ago, we could also add a field in the SSP frame header
to confirm that an HBA supports TLR; if not set, then the drive would
know not to attempt TLR.  Right now, the target sets a RETRY DATA FRAMES
bit in the frame header for XFER_RDY frames to let the initiator know
that retrying DATA frames is allowed - this way it doesn't have to
remember the mode page setting for that target.  The initiator could set
a similar bit in COMMAND and TASK frames to let the target know that it
is safe to retry frames for the whole command.  Is LSI able to set such
a bit in their COMMAND frames today?
> > The unit attention delivery and reservations are thorny issues.
> > Perhaps the HP-Bristol tape drive folks should be talking
> > to Rob Elliott (also from HP) who is the SAS t10 techical editor.
> 
> I am in a discusion with both Rob and the HP-Bristol folks about this.
> We are exploring work-arounds.  Everyone agrees that the vendor specific
> command solution is "less than optimal".
> 
> Andrew
> 

Here are Rob's thoughts about how to fix TLR.  My comments in [[]]

"A _standard_ command would be fine - a vendor-specific command,
however, is not a good idea (beyond the prototype stage).  Software is
not going to want to have 7 ways to enable this basic functionality for
7 vendors. [[This is Jame's argument as well]]
It wouldn't take long to get that through the committee, especially if
the HBA vendors and tape vendors agreed on the solution ahead of time.
SAS-2 could define a SAS-specific command just like it defines
SAS-specific mode pages and log pages (although a protocol-specifA
_standard_ command would be fine - a vendor-specific command, however,
is not a good idea (beyond the prototype stage).  Software is not going
to want to have 7 ways to enable this basic functionality for 7 vendors.
It wouldn't take long to get that through the committee, especially if
the HBA vendors and tape vendors agreed on the solution ahead of time.
SAS-2 could define a SAS-specific command just like it defines
SAS-specific mode pages and log pages (although a protocol-specific
command would be new to SCSI; the closest we have now is the
modification to how the START STOP UNIT command works in SAS to interact
with the NOTIFY (ENABLE SPINUP) primitive).

As discussed long ago, we could also add a field in the SSP frame header
to confirm that an HBA supports TLR; if not set, then the drive would
know not to attempt TLR.  Right now, the target sets a RETRY DATA FRAMES
bit in the frame header for XFER_RDY frames to let the initiator know
that retrying DATA frames is allowed - this way it doesn't have to
remember the mode page setting for that target.  The initiator could set
a similar bit in COMMAND and TASK frames to let the target know that it
is safe to retry frames for the whole command.  Is LSI able to set such
a bit in their COMMAND frames today?ic command would be new to SCSI; the
closest we have now is the modification to how the START STOP UNIT
command works in SAS to interact with the NOTIFY (ENABLE SPINUP)
primitive).
[[Future standard changes will/may not help us with existing hardware]]

As discussed long ago, we could also add a field in the SSP frame header
to confirm that an HBA supports TLR; if not set, then the drive would
know not to attempt TLR.  Right now, the target sets a RETRY DATA FRAMES
bit in the frame header for XFER_RDY frames to let the initiator know
that retrying DATA frames is allowed - this way it doesn't have to
remember the mode page setting for that target.  The initiator could set
a similar bit in COMMAND and TASK frames to let the target know that it
is safe to retry frames for the whole command.  Is LSI able to set such
a bit in their COMMAND frames today?"
[[This might work as existing hardware that didn't implement TLR would
just ignore the contents of the field, and if both drive and HBA
implemented it as a temporary "extension" to SAS 1.1, a vendor specific
command would not be needed.]]

Andrew

-- 
Andrew Patterson
Hewlett-Packard


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH 1/10] mptfusion : Transport Layer Retry support
  2006-07-14 23:02     ` Andrew Patterson
@ 2006-07-14 23:25       ` James Bottomley
  0 siblings, 0 replies; 18+ messages in thread
From: James Bottomley @ 2006-07-14 23:25 UTC (permalink / raw)
  To: Andrew Patterson; +Cc: dougg, Eric Moore, linux-scsi, elliott

On Fri, 2006-07-14 at 17:02 -0600, Andrew Patterson wrote:
> As discussed long ago, we could also add a field in the SSP frame
> header
> to confirm that an HBA supports TLR; if not set, then the drive would
> know not to attempt TLR.  Right now, the target sets a RETRY DATA
> FRAMES
> bit in the frame header for XFER_RDY frames to let the initiator know
> that retrying DATA frames is allowed - this way it doesn't have to
> remember the mode page setting for that target.  The initiator could
> set
> a similar bit in COMMAND and TASK frames to let the target know that
> it
> is safe to retry frames for the whole command.  Is LSI able to set
> such
> a bit in their COMMAND frames today?"
> [[This might work as existing hardware that didn't implement TLR would
> just ignore the contents of the field, and if both drive and HBA
> implemented it as a temporary "extension" to SAS 1.1, a vendor
> specific
> command would not be needed.]]

This looks fine to me ... I think it's fairly simple to implement in the
aic94xx just by changing the driver ... there needs to be an additional
abstraction because the driver controls the ssp frame header but the
transport wants to control the TLR flag ... however, that can be done
simply by extending the task flags.

I have no idea about the fusion ... the frame control is embedded deeply
in the firmware, so I think it would probably require a firmware
upgrade.  Eric can comment on this better than I.

James



^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH 1/10] mptfusion : Transport Layer Retry support
@ 2006-07-17 18:38 Moore, Eric
  2006-07-17 19:22 ` James Bottomley
  2006-07-17 20:17 ` Elliott, Robert (Server Storage)
  0 siblings, 2 replies; 18+ messages in thread
From: Moore, Eric @ 2006-07-17 18:38 UTC (permalink / raw)
  To: James Bottomley, Andrew Patterson
  Cc: dougg, linux-scsi, elliott, Johnson, Steve, Rivera, Peter,
	Besmer, Brad, Shirron, Stephen

On Friday, July 14, 2006 5:25 PM, James Bottomley wrote: 
> I have no idea about the fusion ... the frame control is 
> embedded deeply
> in the firmware, so I think it would probably require a firmware
> upgrade.  Eric can comment on this better than I.
> 

Yes, frame creation is in the firmware, not driver.  
Currently the linux driver knows TLR is implmented in firmware by
looking
at IOCFacts->IOCCapabilities (bit 11).

>From sas2r04a.pdf, section 9.2.1 ssp_frame_format, there is
RETRY_DATA_FRAME (byte 10, bit 2) - write data frames retried (xfer_rdy)
RETRANSMIT (byte 10, bit 1) - control frame retried (task, response,
xfer_rdy)

Rob Elliot wrote: "the initiator could set a similar bit in 
COMMAND and TASK frames to let the target know that it is 
safe to retry frames for the whole command."

Which bit is in consideration for being set? In the ssp frame header or
IU?


^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH 1/10] mptfusion : Transport Layer Retry support
  2006-07-17 18:38 Moore, Eric
@ 2006-07-17 19:22 ` James Bottomley
  2006-07-17 20:17 ` Elliott, Robert (Server Storage)
  1 sibling, 0 replies; 18+ messages in thread
From: James Bottomley @ 2006-07-17 19:22 UTC (permalink / raw)
  To: Moore, Eric
  Cc: Andrew Patterson, dougg, linux-scsi, elliott, Johnson, Steve,
	Rivera, Peter, Besmer, Brad, Shirron, Stephen

On Mon, 2006-07-17 at 12:38 -0600, Moore, Eric wrote:
> Which bit is in consideration for being set? In the ssp frame header
> or
> IU?

Well, the way I read it, the IU isn't part of the frame header, so I was
assuming it would be using one of the five reserved bits of byte 10 of
the SSP header.

I assume you're asking because the fusion doesn't need a firmware change
to place this in the IU?

James



^ permalink raw reply	[flat|nested] 18+ messages in thread

* RE: [PATCH 1/10] mptfusion : Transport Layer Retry support
  2006-07-17 18:38 Moore, Eric
  2006-07-17 19:22 ` James Bottomley
@ 2006-07-17 20:17 ` Elliott, Robert (Server Storage)
  1 sibling, 0 replies; 18+ messages in thread
From: Elliott, Robert (Server Storage) @ 2006-07-17 20:17 UTC (permalink / raw)
  To: Moore, Eric, James Bottomley, Patterson, Andrew D (Linux R&D)
  Cc: dougg, linux-scsi, Johnson, Steve, Rivera, Peter, Besmer, Brad,
	Shirron, Stephen

[-- Attachment #1: Type: text/plain, Size: 1698 bytes --]

If one place is more palatable than another, we can favor that location.

My first inclination would be next to the Retry Data Frames bit, which is in
the basic frame header outside of the information unit portion.



--
Rob Elliott, elliott@hp.com
Hewlett-Packard Industry Standard Server Storage Advanced Technology
https://ecardfile.com/id/RobElliott


 

> -----Original Message-----
> From: Moore, Eric [mailto:Eric.Moore@lsil.com] 
> Sent: Monday, July 17, 2006 1:39 PM
> To: James Bottomley; Patterson, Andrew D (Linux R&D)
> Cc: dougg@torque.net; linux-scsi@vger.kernel.org; Elliott, 
> Robert (Server Storage); Johnson, Steve; Rivera, Peter; 
> Besmer, Brad; Shirron, Stephen
> Subject: RE: [PATCH 1/10] mptfusion : Transport Layer Retry support
> 
> On Friday, July 14, 2006 5:25 PM, James Bottomley wrote: 
> > I have no idea about the fusion ... the frame control is 
> > embedded deeply
> > in the firmware, so I think it would probably require a firmware
> > upgrade.  Eric can comment on this better than I.
> > 
> 
> Yes, frame creation is in the firmware, not driver.  
> Currently the linux driver knows TLR is implmented in firmware by
> looking
> at IOCFacts->IOCCapabilities (bit 11).
> 
> From sas2r04a.pdf, section 9.2.1 ssp_frame_format, there is
> RETRY_DATA_FRAME (byte 10, bit 2) - write data frames retried 
> (xfer_rdy)
> RETRANSMIT (byte 10, bit 1) - control frame retried (task, response,
> xfer_rdy)
> 
> Rob Elliot wrote: "the initiator could set a similar bit in 
> COMMAND and TASK frames to let the target know that it is 
> safe to retry frames for the whole command."
> 
> Which bit is in consideration for being set? In the ssp frame 
> header or
> IU?
> 
> 

[-- Attachment #2: smime.p7s --]
[-- Type: application/x-pkcs7-signature, Size: 4789 bytes --]

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2006-07-17 20:18 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-07-12 17:05 [PATCH 1/10] mptfusion : Transport Layer Retry support Eric Moore
2006-07-12 17:40 ` James Bottomley
2006-07-13  2:33 ` Douglas Gilbert
2006-07-13 17:22   ` Andrew Patterson
2006-07-14 23:02     ` Andrew Patterson
2006-07-14 23:25       ` James Bottomley
  -- strict thread matches above, loose matches on Subject: below --
2006-07-17 18:38 Moore, Eric
2006-07-17 19:22 ` James Bottomley
2006-07-17 20:17 ` Elliott, Robert (Server Storage)
2006-07-13 20:45 Moore, Eric
2006-07-13 20:52 ` James Bottomley
2006-07-12 20:22 Eric Moore
2006-07-12 19:18 Moore, Eric
2006-07-12 19:25 ` James Bottomley
2006-07-12 15:15 Eric Moore
2006-07-11 23:21 Eric Moore
2006-07-12  1:20 ` Douglas Gilbert
2006-07-12 15:32 ` James Bottomley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).