public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH] add SPI transport class to fusion
@ 2006-01-31  4:42 Moore, Eric
  0 siblings, 0 replies; 6+ messages in thread
From: Moore, Eric @ 2006-01-31  4:42 UTC (permalink / raw)
  To: James Bottomley; +Cc: SCSI Mailing List, hch

I wrote:

> So for channel=0, for all target_ids equal to pIocPg3->PhysDisk[].PhysDiskID, then 
> `vdev->vtarget->tflags` equal to MPT_TARGET_FLAGS_RAID_COMPONENT , 
> and we set sdev->no_uld_attach = 1.  For non-raided devices on this
> channel, we set sdev->no_uld_attach = 0. 
> All queue_command request for hidden devices with tflags set for RAID_COMPONENT, 
> will be sent with function=MPI_FUNCTION_SCSI_IO_REQUEST.
> 
My mistake, I meant

All queue_command request for hidden devices with tflags set for RAID_COMPONENT, 
will be sent with function=MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH



^ permalink raw reply	[flat|nested] 6+ messages in thread
* RE: [PATCH] add SPI transport class to fusion
@ 2006-01-31 16:04 Moore, Eric
  0 siblings, 0 replies; 6+ messages in thread
From: Moore, Eric @ 2006-01-31 16:04 UTC (permalink / raw)
  To: James Bottomley; +Cc: SCSI Mailing List, hch

I wrote: 

> > Yes ... it's the job of whoever is issuing passthrough I/O 
> to ensure the
> > RAID is quiesced (if they need it ... there are plenty of 
> commands that
> > could be usefully executed even with the RAID running), so 
> really, we
> > only need it for the DV because additional I/O could interfere with
> > that.
> > 

James:  I asked around about my quiesce-io concern this morning.  This 
particular concern can be dropped.   They agree with your
implementation,
whereas we only do this from dv.   Thanks...

Eric Moore

^ permalink raw reply	[flat|nested] 6+ messages in thread
* RE: [PATCH] add SPI transport class to fusion
@ 2006-01-31  0:48 Moore, Eric
  2006-01-31  1:18 ` James Bottomley
  0 siblings, 1 reply; 6+ messages in thread
From: Moore, Eric @ 2006-01-31  0:48 UTC (permalink / raw)
  To: James Bottomley; +Cc: SCSI Mailing List, hch

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

On Sunday, January 29, 2006 12:19 PM, James Bottomley wrote:

> This patch adds the transport class to the fusion mptspi.  I've fixed
> the problems with sas and virtual channels (the use of virtual channel
> number is now local to mptspi).  I've also extracted the GEM processor
> work arounds ... since these things are visible to all HBA's, 
> this needs
> to be resurrected as a mid-layer blacklist item.

I'm not sure what is getting broke when these GEM workarounds are being
removed.  These hacks were added by someone else.  


> 
> James
> 
> [PATCH] Add SPI Transport class to mptfusion
> 
> This patch adds the transport class to mptspi, makes sure RAID devices
> don't attach and exposes the underlying devices of RAID volumes on a
> virtual channel with the no_uld_attach flag set (so they can be
> addressed by sg and have DV performed on them).
> 

My comments below:


> +static int mptspi_read_page0(struct scsi_target *starget,
> +			     struct _CONFIG_PAGE_SCSI_DEVICE_0 
> *pass_pg0)


Cosmetic, but Id rather this function be called 
mptspi_read_spi_device_page0(), so I know which page we 
are reading.


> +	if (sdev->channel) {
> +		VirtDevice *vdev = sdev->hostdata;
> +		sdev->no_uld_attach = 1;
> +		vdev->vtarget->tflags |=
MPT_TARGET_FLAGS_RAID_COMPONENT;
> +		/* The real channel for this device is zero */
> +		vdev->bus_id = 0;
> +	}

Id rather we being creating a virtual channel for the RAID volumes on
channel=1, and leave the hidden disks on channel=0 along with all other
real devices.   That is what we are doing in mptsas.c, and I would like
to keep similar logic so we are not confusing the customer where the
raid
volumes are located.  For instance, the 1068 has upto 8 ports, so we
put the virtual channel out on channel=8.   I'm not sure how the
sdev->no_uld_attach flag works, e.g my concern is whether this flag
would work when we mix real exposed devices and hidden disk on 
the same channel? If that works, would it be possible for you to change
this?

> +static int
> +mptscsih_quiesce_raid(MPT_SCSI_HOST *hd, int quiesce, int disk)
 
I would like all the raid related functions, such as this one,
and mptspi_get_resyn, mptspi_get_state, and mptspi_is_raid moved
out of the mptspi driver, and over into a generic api, such as inside
mptscsih.c.  These same functions will be needed for SAS RAID Transport
Class, and I don't what to have to replicate the code over there in
mptsas.c

> +static int mptspi_write_page1(struct scsi_target *starget,
> +			       struct 

Cosmetic, but Id rather this function be called 
mptspi_write_spi_device_page0(), so I know which page we 
are writing.

>  		/* 4. Renegotiate to all devices, if SPI
>  		 */
> -		if (ioc->bus_type == SPI) {
> -			dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
> -			mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS
| MPT_SCSICFG_USE_NVRAM);
> -		}

We  can't be removed !!!!  
If you do host_reset - via eh_threads or IOCTL = MPTHARDRESET, 
all the devices will go to asyn-narrow.  The
negotiation parameters need to be updated.   My suggestion is we can
hook
the reset handler chain from mptspi. This is done by over riding the 
mpt_reset_register() call with local function.  Then from it during 
the correct "reset phase", call mptspi_dv_device.

> -	pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
> +	if (vdev->vtarget->tflags &  MPT_TARGET_FLAGS_RAID_COMPONENT)
> +		pScsiReq->Function = >
MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
> +	else
> +		pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
>  	pScsiReq->CDBLength = SCpnt->cmd_len;

YOur only queise io when commands are issued in the context of
mptspi_dv_device,
meaning  mptscsih_quiese_raid() is called over there.
But what about someone opening a /dev/sg0 handle, and sending data
across?  Do you think
we should be queuiese io for all io doing RAID_PASSTHRU from
queue_command entry point,
instead of only handling the dv case.  But what about the performance
hit of loading
driver when dv is going on.  Any thoughts on this?


> -	/* F/W not running */
> -	if(!CHIPREG_READ32(&ioc->chip->Doorbell)) {
> -		/* enable domain validation flags */
> -		for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
> -			ioc->spi_data.dvStatus[ii] |= 
> MPT_SCSICFG_NEED_DV;
> -		}
> -	}

You have deleted the code in mpt_resume() that issues domain validation.
Are you handling power managment from transport layer?  There is no
gareentee
that device were removed and added during standby/hybernation, thus
what happens when initiator is running packatized, and the device having
power cut off is running non-packatized?

>
>
>
>

Attached is a patch that apply over your patch.  What this does it addes
the SAS and misc fix' patches that were missed from two weeks back. I
also:
(1) deleted the spi performance bug code "mpt_bringup_adapter", which is
not 
need for generic dv
(2) changed the RAID events to KERN_DEBUG, as you requested earlier
today.

James: I would like to get this pushed thru this time. Your help is
greatly appriecated.

Eric Moore 

  


[-- Attachment #2: dv-merged.patch --]
[-- Type: application/octet-stream, Size: 20884 bytes --]

diff -uarN b/drivers/message/fusion/mptbase.c a/drivers/message/fusion/mptbase.c
--- b/drivers/message/fusion/mptbase.c	2006-01-30 10:42:17.000000000 -0700
+++ a/drivers/message/fusion/mptbase.c	2006-01-30 16:53:18.000000000 -0700
@@ -81,6 +81,10 @@
 /*
  *  cmd line parameters
  */
+static int mpt_msi_enable = 0;
+module_param(mpt_msi_enable, int, 0);
+MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)");
+
 #ifdef MFCNT
 static int mfcounter = 0;
 #define PRINT_MF_COUNT 20000
@@ -174,7 +178,7 @@
 static int	ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
 static void	mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
 static void	mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
-static void	mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info);
+static void	mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
 static void	mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
 
 /* module entry point */
@@ -313,7 +317,7 @@
 		if (ioc->bus_type == FC)
 			mpt_fc_log_info(ioc, log_info);
 		else if (ioc->bus_type == SPI)
-			mpt_sp_log_info(ioc, log_info);
+			mpt_spi_log_info(ioc, log_info);
 		else if (ioc->bus_type == SAS)
 			mpt_sas_log_info(ioc, log_info);
 	}
@@ -1117,65 +1121,6 @@
 	return -1;
 }
 
-int
-mpt_alt_ioc_wait(MPT_ADAPTER *ioc)
-{
-	int loop_count = 30 * 4;  /* Wait 30 seconds */
-	int status = -1; /* -1 means failed to get board READY */
-
-	do {
-		spin_lock(&ioc->initializing_hba_lock);
-		if (ioc->initializing_hba_lock_flag == 0) {
-			ioc->initializing_hba_lock_flag=1;
-			spin_unlock(&ioc->initializing_hba_lock);
-			status = 0;
-			break;
-		}
-		spin_unlock(&ioc->initializing_hba_lock);
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(HZ/4);
-	} while (--loop_count);
-
-	return status;
-}
-
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/*
- *	mpt_bringup_adapter - This is a wrapper function for mpt_do_ioc_recovery
- *	@ioc: Pointer to MPT adapter structure
- *	@sleepFlag: Use schedule if CAN_SLEEP else use udelay.
- *
- *	This routine performs all the steps necessary to bring the IOC
- *	to a OPERATIONAL state.
- *
- *      Special Note: This function was added with spin lock's so as to allow
- *      the dv(domain validation) work thread to succeed on the other channel
- *      that maybe occuring at the same time when this function is called.
- *      Without this lock, the dv would fail when message frames were
- *      requested during hba bringup on the alternate ioc.
- */
-static int
-mpt_bringup_adapter(MPT_ADAPTER *ioc, int sleepFlag)
-{
-	int r;
-
-	if(ioc->alt_ioc) {
-		if((r=mpt_alt_ioc_wait(ioc->alt_ioc)!=0))
-			return r;
-	}
-
-	r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
-	    CAN_SLEEP);
-
-	if(ioc->alt_ioc) {
-		spin_lock(&ioc->alt_ioc->initializing_hba_lock);
-		ioc->alt_ioc->initializing_hba_lock_flag=0;
-		spin_unlock(&ioc->alt_ioc->initializing_hba_lock);
-	}
-
-return r;
-}
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *	mpt_attach - Install a PCI intelligent MPT adapter.
@@ -1444,6 +1389,12 @@
 
 	ioc->pci_irq = -1;
 	if (pdev->irq) {
+
+		if (mpt_msi_enable && pci_enable_msi(pdev))
+			printk(MYIOC_s_INFO_FMT
+			    "PCI-MSI enabled for this hotplug controller\n",
+			    ioc->name);
+
 		r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc);
 
 		if (r < 0) {
@@ -1476,13 +1427,18 @@
 	 */
 	mpt_detect_bound_ports(ioc, pdev);
 
-	if ((r = mpt_bringup_adapter(ioc, CAN_SLEEP)) != 0){
+	if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
+	    CAN_SLEEP)) != 0){
 		printk(KERN_WARNING MYNAM
 		  ": WARNING - %s did not initialize properly! (%d)\n",
 		  ioc->name, r);
 
 		list_del(&ioc->list);
 		free_irq(ioc->pci_irq, ioc);
+		if (mpt_msi_enable == 1)
+			pci_disable_msi(pdev);
+		if (ioc->alt_ioc)
+			ioc->alt_ioc->alt_ioc = NULL;
 		iounmap(mem);
 		kfree(ioc);
 		pci_set_drvdata(pdev, NULL);
@@ -2127,6 +2083,8 @@
 
 	if (ioc->pci_irq != -1) {
 		free_irq(ioc->pci_irq, ioc);
+		if (mpt_msi_enable == 1)
+			pci_disable_msi(ioc->pcidev);
 		ioc->pci_irq = -1;
 	}
 
@@ -2148,6 +2106,10 @@
 	sz_last = ioc->alloc_total;
 	dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
 			ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
+
+	if (ioc->alt_ioc)
+		ioc->alt_ioc->alt_ioc = NULL;
+
 	kfree(ioc);
 }
 
@@ -2761,13 +2723,16 @@
 
 	/* RAID FW may take a long time to enable
 	 */
-	if ( (ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
-			> MPI_FW_HEADER_PID_PROD_TARGET_SCSI ) {
-		rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
-				reply_sz, (u16*)&reply_buf, 300 /*seconds*/, sleepFlag);
+	if (((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
+	    > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) ||
+	    (ioc->bus_type == SAS)) {
+		rc = mpt_handshake_req_reply_wait(ioc, req_sz,
+		(u32*)&port_enable, reply_sz, (u16*)&reply_buf,
+		300 /*seconds*/, sleepFlag);
 	} else {
-		rc = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&port_enable,
-				reply_sz, (u16*)&reply_buf, 30 /*seconds*/, sleepFlag);
+		rc = mpt_handshake_req_reply_wait(ioc, req_sz,
+		(u32*)&port_enable, reply_sz, (u16*)&reply_buf,
+		30 /*seconds*/, sleepFlag);
 	}
 	return rc;
 }
@@ -4378,6 +4343,138 @@
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+
+static void
+mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
+    MpiEventDataRaid_t * pRaidEventData)
+{
+	int 	volume;
+	int 	reason;
+	int 	disk;
+	int 	status;
+	int 	flags;
+	int 	state;
+
+	volume	= pRaidEventData->VolumeID;
+	reason	= pRaidEventData->ReasonCode;
+	disk	= pRaidEventData->PhysDiskNum;
+	status	= le32_to_cpu(pRaidEventData->SettingsStatus);
+	flags	= (status >> 0) & 0xff;
+	state	= (status >> 8) & 0xff;
+
+	if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
+		return;
+	}
+
+	if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
+	     reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
+	    (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
+		printk(MYIOC_s_DEBUG_FMT "RAID STATUS CHANGE for PhysDisk %d\n",
+			ioc->name, disk);
+	} else {
+		printk(MYIOC_s_DEBUG_FMT "RAID STATUS CHANGE for VolumeID %d\n",
+			ioc->name, volume);
+	}
+
+	switch(reason) {
+	case MPI_EVENT_RAID_RC_VOLUME_CREATED:
+		printk(MYIOC_s_DEBUG_FMT "  volume has been created\n",
+			ioc->name);
+		break;
+
+	case MPI_EVENT_RAID_RC_VOLUME_DELETED:
+
+		printk(MYIOC_s_DEBUG_FMT "  volume has been deleted\n",
+			ioc->name);
+		break;
+
+	case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
+		printk(MYIOC_s_DEBUG_FMT "  volume settings have been changed\n",
+			ioc->name);
+		break;
+
+	case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
+		printk(MYIOC_s_DEBUG_FMT "  volume is now %s%s%s%s\n",
+			ioc->name,
+			state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
+			 ? "optimal"
+			 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
+			  ? "degraded"
+			  : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
+			   ? "failed"
+			   : "state unknown",
+			flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
+			 ? ", enabled" : "",
+			flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
+			 ? ", quiesced" : "",
+			flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
+			 ? ", resync in progress" : "" );
+		break;
+
+	case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
+		printk(MYIOC_s_DEBUG_FMT "  volume membership of PhysDisk %d has changed\n",
+			ioc->name, disk);
+		break;
+
+	case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
+		printk(MYIOC_s_DEBUG_FMT "  PhysDisk has been created\n",
+			ioc->name);
+		break;
+
+	case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
+		printk(MYIOC_s_DEBUG_FMT "  PhysDisk has been deleted\n",
+			ioc->name);
+		break;
+
+	case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
+		printk(MYIOC_s_DEBUG_FMT "  PhysDisk settings have been changed\n",
+			ioc->name);
+		break;
+
+	case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
+		printk(MYIOC_s_DEBUG_FMT "  PhysDisk is now %s%s%s\n",
+			ioc->name,
+			state == MPI_PHYSDISK0_STATUS_ONLINE
+			 ? "online"
+			 : state == MPI_PHYSDISK0_STATUS_MISSING
+			  ? "missing"
+			  : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
+			   ? "not compatible"
+			   : state == MPI_PHYSDISK0_STATUS_FAILED
+			    ? "failed"
+			    : state == MPI_PHYSDISK0_STATUS_INITIALIZING
+			     ? "initializing"
+			     : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
+			      ? "offline requested"
+			      : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
+			       ? "failed requested"
+			       : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
+			        ? "offline"
+			        : "state unknown",
+			flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
+			 ? ", out of sync" : "",
+			flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
+			 ? ", quiesced" : "" );
+		break;
+
+	case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
+		printk(MYIOC_s_DEBUG_FMT "  Domain Validation needed for PhysDisk %d\n",
+			ioc->name, disk);
+		break;
+
+	case MPI_EVENT_RAID_RC_SMART_DATA:
+		printk(MYIOC_s_DEBUG_FMT "  SMART data received, ASC/ASCQ = %02xh/%02xh\n",
+			ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
+		break;
+
+	case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
+		printk(MYIOC_s_DEBUG_FMT "  replacement of PhysDisk %d has started\n",
+			ioc->name, disk);
+		break;
+	}
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
  *	GetIoUnitPage2 - Retrieve BIOS version and boot order information.
  *	@ioc: Pointer to MPT_ADAPTER structure
@@ -4589,6 +4686,14 @@
 				SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t  *) pbuf;
 				MpiDeviceInfo_t	*pdevice = NULL;
 
+				/*
+				 * Save "Set to Avoid SCSI Bus Resets" flag
+				 */
+				ioc->spi_data.bus_reset =
+				    (le32_to_cpu(pPP2->PortFlags) &
+			        MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
+				    0 : 1 ;
+
 				/* Save the Port Page 2 data
 				 * (reformat into a 32bit quantity)
 				 */
@@ -5958,6 +6063,10 @@
 			}
 		}
 		break;
+	case MPI_EVENT_INTEGRATED_RAID:
+		mptbase_raid_process_event_data(ioc,
+		    (MpiEventDataRaid_t *)pEventReply->Data);
+		break;
 	default:
 		break;
 	}
@@ -6037,7 +6146,7 @@
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /*
- *	mpt_sp_log_info - Log information returned from SCSI Parallel IOC.
+ *	mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
  *	@ioc: Pointer to MPT_ADAPTER structure
  *	@mr: Pointer to MPT reply frame
  *	@log_info: U32 LogInfo word from the IOC
@@ -6045,7 +6154,7 @@
  *	Refer to lsi/sp_log.h.
  */
 static void
-mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
+mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
 {
 	u32 info = log_info & 0x00FF0000;
 	char *desc = "unknown";
@@ -6373,7 +6482,6 @@
 EXPORT_SYMBOL(mpt_alloc_fw_memory);
 EXPORT_SYMBOL(mpt_free_fw_memory);
 EXPORT_SYMBOL(mptbase_sas_persist_operation);
-EXPORT_SYMBOL(mpt_alt_ioc_wait);
 EXPORT_SYMBOL(mptbase_GetFcPortPage0);
 
 
diff -uarN b/drivers/message/fusion/mptbase.h a/drivers/message/fusion/mptbase.h
--- b/drivers/message/fusion/mptbase.h	2006-01-30 10:42:17.000000000 -0700
+++ a/drivers/message/fusion/mptbase.h	2006-01-30 16:51:39.000000000 -0700
@@ -123,7 +123,7 @@
 #define  MPT_MAX_FRAME_SIZE		128
 #define  MPT_DEFAULT_FRAME_SIZE		128
 
-#define  MPT_REPLY_FRAME_SIZE		0x40  /* Must be a multiple of 8 */
+#define  MPT_REPLY_FRAME_SIZE		0x50  /* Must be a multiple of 8 */
 
 #define  MPT_SG_REQ_128_SCALE		1
 #define  MPT_SG_REQ_96_SCALE		2
@@ -187,6 +187,7 @@
 #define MYIOC_s_INFO_FMT		KERN_INFO MYNAM ": %s: "
 #define MYIOC_s_NOTE_FMT		KERN_NOTICE MYNAM ": %s: "
 #define MYIOC_s_WARN_FMT		KERN_WARNING MYNAM ": %s: WARNING - "
+#define MYIOC_s_DEBUG_FMT		KERN_DEBUG MYNAM ": %s: "
 #define MYIOC_s_ERR_FMT			KERN_ERR MYNAM ": %s: ERROR - "
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
@@ -1024,7 +1025,6 @@
 extern int	 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
 extern int	 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
 extern int	 mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum);
-extern int	 mpt_alt_ioc_wait(MPT_ADAPTER *ioc);
 
 /*
  *  Public data decl's...
diff -uarN b/drivers/message/fusion/mptfc.c a/drivers/message/fusion/mptfc.c
--- b/drivers/message/fusion/mptfc.c	2006-01-30 10:26:56.000000000 -0700
+++ a/drivers/message/fusion/mptfc.c	2006-01-25 17:23:40.000000000 -0700
@@ -97,6 +97,7 @@
 static int mptfc_slave_alloc(struct scsi_device *sdev);
 static int mptfc_qcmd(struct scsi_cmnd *SCpnt,
 		      void (*done)(struct scsi_cmnd *));
+
 static void mptfc_target_destroy(struct scsi_target *starget);
 static void mptfc_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout);
 static void __devexit mptfc_remove(struct pci_dev *pdev);
@@ -154,7 +155,7 @@
 
 static struct scsi_transport_template *mptfc_transport_template = NULL;
 
-struct fc_function_template mptfc_transport_functions = {
+static struct fc_function_template mptfc_transport_functions = {
 	.dd_fcrport_size = 8,
 	.show_host_node_name = 1,
 	.show_host_port_name = 1,
@@ -514,7 +515,7 @@
  *	Return non-zero if allocation fails.
  *	Init memory once per LUN.
  */
-int
+static int
 mptfc_slave_alloc(struct scsi_device *sdev)
 {
 	MPT_SCSI_HOST		*hd;
diff -uarN b/drivers/message/fusion/mptscsih.c a/drivers/message/fusion/mptscsih.c
--- b/drivers/message/fusion/mptscsih.c	2006-01-30 10:42:17.000000000 -0700
+++ a/drivers/message/fusion/mptscsih.c	2006-01-30 13:56:18.000000000 -0700
@@ -140,7 +140,7 @@
 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);
-static void	mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget);
+static void	mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
 
 void 		mptscsih_remove(struct pci_dev *);
 void 		mptscsih_shutdown(struct pci_dev *);
@@ -521,11 +521,24 @@
 	MPT_SCSI_HOST	*hd;
 	SCSIIORequest_t	*pScsiReq;
 	SCSIIOReply_t	*pScsiReply;
-	u16		 req_idx;
+	u16		 req_idx, req_idx_MR;
 
 	hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
 
 	req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
+	req_idx_MR = (mr != NULL) ?
+	    le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
+	if ((req_idx != req_idx_MR) ||
+	    (mf->u.frame.linkage.arg1 == 0xdeadbeaf)) {
+		printk(MYIOC_s_ERR_FMT "Received a mf that was already freed\n",
+		    ioc->name);
+		printk (MYIOC_s_ERR_FMT
+		    "req_idx=%x req_idx_MR=%x mf=%p mr=%p sc=%p\n",
+		    ioc->name, req_idx, req_idx_MR, mf, mr,
+		    hd->ScsiLookup[req_idx_MR]);
+		return 0;
+	}
+
 	sc = hd->ScsiLookup[req_idx];
 	if (sc == NULL) {
 		MPIHeader_t *hdr = (MPIHeader_t *)mf;
@@ -685,6 +698,8 @@
 
 			break;
 
+		case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:		/* 0x0044 */
+			sc->resid=0;
 		case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR:	/* 0x0040 */
 		case MPI_IOCSTATUS_SUCCESS:			/* 0x0000 */
 			if (scsi_status == MPI_SCSI_STATUS_BUSY)
@@ -744,7 +759,6 @@
 		case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES:	/* 0x0006 */
 		case MPI_IOCSTATUS_INVALID_FIELD:		/* 0x0007 */
 		case MPI_IOCSTATUS_INVALID_STATE:		/* 0x0008 */
-		case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:		/* 0x0044 */
 		case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:		/* 0x0046 */
 		case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:	/* 0x004A */
 		default:
@@ -1607,6 +1621,20 @@
 	return retval;
 }
 
+static int
+mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
+{
+	switch (ioc->bus_type) {
+	case FC:
+		return 40;
+	case SAS:
+		return 10;
+	case SPI:
+	default:
+		return 5;
+	}
+}
+
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *	mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
@@ -1676,9 +1704,10 @@
 	hd->abortSCpnt = SCpnt;
 
 	vdev = SCpnt->device->hostdata;
+	/* set timeout in seconds */
 	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
 		vdev->bus_id, vdev->target_id, vdev->lun,
-		ctx2abort, 2 /* 2 second timeout */);
+		ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
 
 	printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
 		hd->ioc->name,
@@ -1729,7 +1758,7 @@
 	vdev = SCpnt->device->hostdata;
 	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
 		vdev->bus_id, vdev->target_id,
-		0, 0, 5 /* 5 second timeout */);
+		0, 0, mptscsih_get_tm_timeout(hd->ioc));
 
 	printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n",
 		hd->ioc->name,
@@ -1779,7 +1808,7 @@
 
 	vdev = SCpnt->device->hostdata;
 	retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
-		vdev->bus_id, 0, 0, 0, 5 /* 5 second timeout */);
+		vdev->bus_id, 0, 0, 0, mptscsih_get_tm_timeout(hd->ioc));
 
 	printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n",
 		hd->ioc->name,
@@ -1902,6 +1931,42 @@
 }
 
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+static void
+mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
+{
+	char *desc;
+
+	switch (response_code) {
+	case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
+		desc = "The task completed.";
+		break;
+	case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
+		desc = "The IOC received an invalid frame status.";
+		break;
+	case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
+		desc = "The task type is not supported.";
+		break;
+	case MPI_SCSITASKMGMT_RSP_TM_FAILED:
+		desc = "The requested task failed.";
+		break;
+	case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
+		desc = "The task completed successfully.";
+		break;
+	case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
+		desc = "The LUN request is invalid.";
+		break;
+	case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
+		desc = "The task is in the IOC queue and has not been sent to target.";
+		break;
+	default:
+		desc = "unknown";
+		break;
+	}
+	printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
+		ioc->name, response_code, desc);
+}
+
+/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 /**
  *	mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
  *	@ioc: Pointer to MPT_ADAPTER structure
@@ -1950,6 +2015,11 @@
 		/* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
 		tmType = pScsiTmReq->TaskType;
 
+		if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
+		    pScsiTmReply->ResponseCode)
+			mptscsih_taskmgmt_response_code(ioc,
+			    pScsiTmReply->ResponseCode);
+
 		dtmprintk((MYIOC_s_WARN_FMT "  TaskType = %d, TerminationCount=%d\n",
 				ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
 		DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
@@ -2157,7 +2227,7 @@
 	vtarget->luns[0] &= ~(1 << vdevice->lun);
 	vtarget->num_luns--;
 	if (vtarget->num_luns == 0) {
-		mptscsih_negotiate_to_asyn_narrow(hd, vtarget);
+		mptscsih_negotiate_to_asyn_narrow(hd, vdevice);
 		hd->Targets[sdev->id] = NULL;
 	}
 	mptscsih_synchronize_cache(hd, vdevice);
@@ -3330,8 +3400,9 @@
  *
  */
 static void
-mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget)
+mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
 {
+	VirtTarget		*vtarget = vdevice->vtarget;
 	MPT_ADAPTER		*ioc= hd->ioc;
 	SCSIDevicePage1_t	*pcfg1Data;
 	CONFIGPARMS		 cfg;
@@ -3341,7 +3412,8 @@
 	int			 requested, configuration, data,i;
 	u8			 flags, factor;
 
-	if (ioc->bus_type != SPI)
+	if ((ioc->bus_type != SPI) ||
+		(!vdevice->configured_lun))
 		return;
 
 	if (!ioc->spi_data.sdp1length)
@@ -3377,7 +3449,7 @@
 			}
 			mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
 				&configuration, flags);
-			dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
+			dnegoprintk(("nego asyn narrow: id=%d width=0 factor=MPT_ASYNC "
 				"offset=0 negoFlags=%x request=%x config=%x\n",
 				id, flags, requested, configuration));
 			pcfg1Data->RequestedParameters = cpu_to_le32(requested);
@@ -3390,7 +3462,7 @@
 		flags = vtarget->negoFlags;
 		mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
 				&configuration, flags);
-		dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
+		dnegoprintk(("nego asyn narrow: id=%d width=0 factor=MPT_ASYNC "
 			"offset=0 negoFlags=%x request=%x config=%x\n",
 			vtarget->target_id, flags, requested, configuration));
 		pcfg1Data->RequestedParameters = cpu_to_le32(requested);
diff -uarN b/drivers/message/fusion/mptspi.c a/drivers/message/fusion/mptspi.c
--- b/drivers/message/fusion/mptspi.c	2006-01-30 10:42:17.000000000 -0700
+++ a/drivers/message/fusion/mptspi.c	2006-01-30 14:01:58.000000000 -0700
@@ -936,6 +936,14 @@
 		goto out_mptspi_probe;
 	}
 
+	/*
+	 * issue internal bus reset
+	 */
+	if (ioc->spi_data.bus_reset)
+		mptscsih_TMHandler(hd,
+		    MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
+		    0, 0, 0, 0, 5);
+
 	scsi_scan_host(sh);
 	return 0;
 

^ permalink raw reply	[flat|nested] 6+ messages in thread
* [PATCH] add SPI transport class to fusion
@ 2006-01-29 19:19 James Bottomley
  0 siblings, 0 replies; 6+ messages in thread
From: James Bottomley @ 2006-01-29 19:19 UTC (permalink / raw)
  To: Moore, Eric Dean; +Cc: SCSI Mailing List

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

[sigh, resend as a compressed attachment to get under the scsi reflector
size limit]

This patch adds the transport class to the fusion mptspi.  I've fixed
the problems with sas and virtual channels (the use of virtual channel
number is now local to mptspi).  I've also extracted the GEM processor
work arounds ... since these things are visible to all HBA's, this needs
to be resurrected as a mid-layer blacklist item.

James

[PATCH] Add SPI Transport class to mptfusion

This patch adds the transport class to mptspi, makes sure RAID devices
don't attach and exposes the underlying devices of RAID volumes on a
virtual channel with the no_uld_attach flag set (so they can be
addressed by sg and have DV performed on them).




[-- Attachment #2: mptscsi-domain-validation.diff.gz --]
[-- Type: application/x-gzip, Size: 25342 bytes --]

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

end of thread, other threads:[~2006-01-31 16:05 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-01-31  4:42 [PATCH] add SPI transport class to fusion Moore, Eric
  -- strict thread matches above, loose matches on Subject: below --
2006-01-31 16:04 Moore, Eric
2006-01-31  0:48 Moore, Eric
2006-01-31  1:18 ` James Bottomley
2006-01-31  4:39   ` Moore, Eric
2006-01-29 19:19 James Bottomley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox