linux-scsi.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 4/4] fusion: fibre channel: don't sync cache if remote port deleted
@ 2006-07-31 17:20 Michael Reed
  2006-08-01 14:58 ` James Bottomley
  0 siblings, 1 reply; 3+ messages in thread
From: Michael Reed @ 2006-07-31 17:20 UTC (permalink / raw)
  To: linux-scsi

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

mptscsih_slave_destroy issues an unconditional synchronize cache.
It is not necessary for fibre channel devices for which the rport
has been deleted.  This patch creates a new function,
mptfc_slave_destroy(), which implements the appropriate test.

Additionally, Eric's review of the original version of this patch
pointed me at some unnecessary tests of the rport dd_data field.
I've removed one and made two others bugs.

Signed-off-by: Michael Reed <mdr@sgi.com>



[-- Attachment #2: fusion_sync_cache.patch --]
[-- Type: text/x-patch, Size: 6296 bytes --]

--- srfu/drivers/message/fusion/mptscsih.h	2006-07-19 11:12:34.000000000 -0500
+++ srf/drivers/message/fusion/mptscsih.h	2006-07-28 16:57:49.720602724 -0500
@@ -101,3 +101,5 @@ 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 void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
+extern void mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
--- srfu/drivers/message/fusion/mptscsih.c	2006-07-19 11:12:34.000000000 -0500
+++ srf/drivers/message/fusion/mptscsih.c	2006-07-28 16:57:49.704603374 -0500
@@ -140,7 +140,7 @@ static void	mptscsih_setTargetNegoParms(
 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_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
 
 void 		mptscsih_remove(struct pci_dev *);
 void 		mptscsih_shutdown(struct pci_dev *);
@@ -936,7 +936,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOS
  *
  *	Called from slave_destroy.
  */
-static void
+void
 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
 {
 	SCSIIORequest_t	*mf = NULL;
@@ -3436,7 +3436,7 @@ mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTER
  *	MUST be single-threaded.
  *
  */
-static void
+void
 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
 {
 	INTERNAL_CMD		 iocmd;
@@ -3460,6 +3460,8 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST
 		mptscsih_do_cmd(hd, &iocmd);
 }
 
+EXPORT_SYMBOL(mptscsih_search_running_cmds);
+EXPORT_SYMBOL(mptscsih_synchronize_cache);
 EXPORT_SYMBOL(mptscsih_remove);
 EXPORT_SYMBOL(mptscsih_shutdown);
 #ifdef CONFIG_PM
--- srfu/drivers/message/fusion/mptfc.c	2006-07-28 16:57:34.189233269 -0500
+++ srf/drivers/message/fusion/mptfc.c	2006-07-28 16:59:31.192409766 -0500
@@ -96,6 +96,7 @@ static int mptfc_qcmd(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);
+static void mptfc_slave_destroy(struct scsi_device *sdev);
 
 static struct scsi_host_template mptfc_driver_template = {
 	.module				= THIS_MODULE,
@@ -108,7 +109,7 @@ static struct scsi_host_template mptfc_d
 	.slave_alloc			= mptfc_slave_alloc,
 	.slave_configure		= mptscsih_slave_configure,
 	.target_destroy			= mptfc_target_destroy,
-	.slave_destroy			= mptscsih_slave_destroy,
+	.slave_destroy			= mptfc_slave_destroy,
 	.change_queue_depth 		= mptscsih_change_queue_depth,
 	.eh_abort_handler		= mptscsih_abort,
 	.eh_device_reset_handler	= mptscsih_dev_reset,
@@ -433,8 +434,8 @@ mptfc_target_destroy(struct scsi_target 
 	rport = starget_to_rport(starget);
 	if (rport) {
 		ri = *((struct mptfc_rport_info **)rport->dd_data);
-		if (ri)	/* better be! */
-			ri->starget = NULL;
+		BUG_ON(ri==NULL);
+		ri->starget = NULL;
 	}
 	if (starget->hostdata)
 		kfree(starget->hostdata);
@@ -463,12 +464,11 @@ mptfc_target_alloc(struct scsi_target *s
 	rport = starget_to_rport(starget);
 	if (rport) {
 		ri = *((struct mptfc_rport_info **)rport->dd_data);
-		if (ri) {	/* better be! */
-			vtarget->target_id = ri->pg0.CurrentTargetID;
-			vtarget->bus_id = ri->pg0.CurrentBus;
-			ri->starget = starget;
-			rc = 0;
-		}
+		BUG_ON(ri==NULL);
+		vtarget->target_id = ri->pg0.CurrentTargetID;
+		vtarget->bus_id = ri->pg0.CurrentBus;
+		ri->starget = starget;
+		rc = 0;
 	}
 	if (rc != 0) {
 		kfree(vtarget);
@@ -492,13 +492,18 @@ mptfc_slave_alloc(struct scsi_device *sd
 	VirtDevice		*vdev;
 	struct scsi_target	*starget;
 	struct fc_rport		*rport;
+	unsigned long		flags;
 
 
 	starget = scsi_target(sdev);
 	rport = starget_to_rport(starget);
 
-	if (!rport || fc_remote_port_chkready(rport))
+	spin_lock_irqsave(sdev->host->host_lock, flags);
+	if (!rport || fc_remote_port_chkready(rport)) {
+		spin_unlock_irqrestore(sdev->host->host_lock, flags);
 		return -ENXIO;
+	}
+	spin_unlock_irqrestore(sdev->host->host_lock, flags);
 
 	hd = (MPT_SCSI_HOST *)sdev->host->hostdata;
 
@@ -548,10 +553,42 @@ mptfc_slave_alloc(struct scsi_device *sd
 	return 0;
 }
 
+/*
+ *	OS entry point to allow for host driver to free allocated memory
+ *	Called if no device present or device being unloaded
+ */
+static void
+mptfc_slave_destroy(struct scsi_device *sdev)
+{
+	struct Scsi_Host	*host = sdev->host;
+	MPT_SCSI_HOST		*hd = (MPT_SCSI_HOST *)host->hostdata;
+	VirtTarget		*vtarget;
+	VirtDevice		*vdev;
+	struct scsi_target 	*starget;
+	struct fc_rport		*rport = starget_to_rport(scsi_target(sdev));
+	struct mptfc_rport_info	*ri;
+
+	starget = scsi_target(sdev);
+	vtarget = starget->hostdata;
+	vdev = sdev->hostdata;
+
+	mptscsih_search_running_cmds(hd, vdev);
+	vtarget->luns[0] &= ~(1 << vdev->lun);
+	vtarget->num_luns--;
+	if (vtarget->num_luns == 0)
+		hd->Targets[sdev->id] = NULL;
+
+	ri = *((struct mptfc_rport_info **)rport->dd_data);
+	if (ri && ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)
+		mptscsih_synchronize_cache(hd, vdev);
+
+	kfree(vdev);
+	sdev->hostdata = NULL;
+}
+
 static int
 mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
 {
-	struct mptfc_rport_info	*ri;
 	struct fc_rport	*rport = starget_to_rport(scsi_target(SCpnt->device));
 	int		err;
 
@@ -562,19 +599,6 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void
 		return 0;
 	}
 
-	/* dd_data is null until finished adding target */
-	ri = *((struct mptfc_rport_info **)rport->dd_data);
-	if (unlikely(!ri)) {
-		dfcprintk ((MYIOC_s_INFO_FMT
-			"mptfc_qcmd.%d: %d:%d, dd_data is null.\n",
-			((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->name,
-			((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->sh->host_no,
-			SCpnt->device->id,SCpnt->device->lun));
-		SCpnt->result = DID_IMM_RETRY << 16;
-		done(SCpnt);
-		return 0;
-	}
-
 	err = mptscsih_qcmd(SCpnt,done);
 #ifdef DMPT_DEBUG_FC
 	if (unlikely(err)) {


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

* Re: [PATCH 4/4] fusion: fibre channel: don't sync cache if remote port deleted
  2006-07-31 17:20 [PATCH 4/4] fusion: fibre channel: don't sync cache if remote port deleted Michael Reed
@ 2006-08-01 14:58 ` James Bottomley
  2006-08-01 15:37   ` Michael Reed
  0 siblings, 1 reply; 3+ messages in thread
From: James Bottomley @ 2006-08-01 14:58 UTC (permalink / raw)
  To: Michael Reed; +Cc: linux-scsi

On Mon, 2006-07-31 at 12:20 -0500, Michael Reed wrote:
> mptscsih_slave_destroy issues an unconditional synchronize cache.

A) mptscsih_slave_destroy shouldn't be doing this ... it should be
relying on the functionality in the mid-layer.

> It is not necessary for fibre channel devices for which the rport
> has been deleted.  This patch creates a new function,
> mptfc_slave_destroy(), which implements the appropriate test.

So, this is really code that shouldn't be in a driver, it should be
higher up.

The other three patches look fine.

James



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

* Re: [PATCH 4/4] fusion: fibre channel: don't sync cache if remote port deleted
  2006-08-01 14:58 ` James Bottomley
@ 2006-08-01 15:37   ` Michael Reed
  0 siblings, 0 replies; 3+ messages in thread
From: Michael Reed @ 2006-08-01 15:37 UTC (permalink / raw)
  To: James Bottomley; +Cc: linux-scsi

The mid-layer appears to be inconsistent with regard to sync cache.
I agree the sync should not be in the lldd.  It's been in fusion for
a long time and I'm just fixing the implementation for fibre channel.
This isn't a new feature, just a fix to an existing one.

I refer you to two threads which discussed the issue.

http://marc.theaimsgroup.com/?l=linux-scsi&m=115386616817044&w=2
http://marc.theaimsgroup.com/?l=linux-scsi&m=115266599732078&w=2

Mike


James Bottomley wrote:
> On Mon, 2006-07-31 at 12:20 -0500, Michael Reed wrote:
>> mptscsih_slave_destroy issues an unconditional synchronize cache.
> 
> A) mptscsih_slave_destroy shouldn't be doing this ... it should be
> relying on the functionality in the mid-layer.
> 
>> It is not necessary for fibre channel devices for which the rport
>> has been deleted.  This patch creates a new function,
>> mptfc_slave_destroy(), which implements the appropriate test.
> 
> So, this is really code that shouldn't be in a driver, it should be
> higher up.
> 
> The other three patches look fine.
> 
> James
> 

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

end of thread, other threads:[~2006-08-01 15:37 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-07-31 17:20 [PATCH 4/4] fusion: fibre channel: don't sync cache if remote port deleted Michael Reed
2006-08-01 14:58 ` James Bottomley
2006-08-01 15:37   ` Michael Reed

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).