From: Michael Reed <mdr@sgi.com>
To: linux-scsi@vger.kernel.org
Subject: [PATCH 4/4] fusion: fibre channel: don't sync cache if remote port deleted
Date: Mon, 31 Jul 2006 12:20:00 -0500 [thread overview]
Message-ID: <44CE3BC0.8020901@sgi.com> (raw)
[-- 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)) {
next reply other threads:[~2006-07-31 17:20 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2006-07-31 17:20 Michael Reed [this message]
2006-08-01 14:58 ` [PATCH 4/4] fusion: fibre channel: don't sync cache if remote port deleted James Bottomley
2006-08-01 15:37 ` Michael Reed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=44CE3BC0.8020901@sgi.com \
--to=mdr@sgi.com \
--cc=linux-scsi@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.