From: Chris Wright Date: Tue, 4 Oct 2005 02:19:16 +0000 (-0700) Subject: Add ieee1394/sbp2 fixes from Stefan Richter X-Git-Tag: v2.6.13.4~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=eb53ce5e696daee918be3cb2ff724bfc0cef4cb4;p=thirdparty%2Fkernel%2Fstable-queue.git Add ieee1394/sbp2 fixes from Stefan Richter --- diff --git a/queue/ieee1394-sbp2-fixes-for-hot-unplug-and-module-unloading.patch b/queue/ieee1394-sbp2-fixes-for-hot-unplug-and-module-unloading.patch new file mode 100644 index 00000000000..e8804cd85a7 --- /dev/null +++ b/queue/ieee1394-sbp2-fixes-for-hot-unplug-and-module-unloading.patch @@ -0,0 +1,132 @@ +From stable-bounces@linux.kernel.org Sat Oct 1 10:58:10 2005 +Date: Sat, 1 Oct 2005 19:57:47 +0200 (CEST) +From: Stefan Richter +Subject: [PATCH] ieee1394/sbp2: fixes for hot-unplug and module unloading +To: stable@kernel.org +Cc: chrisw@osdl.org, bcollins@debian.org, greg@kroah.com + +Fixes for reference counting problems, deadlocks, and delays when SBP-2 devices +are unplugged or unbound from sbp2, or when unloading of sbp2/ ohci1394/ pcilynx +is attempted. + +Most often reported symptoms were hotplugs remaining undetected once a FireWire +disk was unplugged since the knodemgrd kernel thread went to uninterruptible +sleep, and "modprobe -r sbp2" being unable to complete because still being in +use. + +Patch is equivalent to commit abd559b1052e28d8b9c28aabde241f18fa89090b in +2.6.14-rc3 plus a fix which is necessary together with 2.6.13's scsi core API +(linux1394.org commit r1308 by Ben Collins). + +Signed-off-by: Stefan Richter +Cc: Ben Collins +Signed-off-by: Chris Wright +--- + + drivers/ieee1394/sbp2.c | 38 +++++++++++++++++++++++++++++++++++--- + 1 files changed, 35 insertions(+), 3 deletions(-) + +Index: linux-2.6.13.y/drivers/ieee1394/sbp2.c +=================================================================== +--- linux-2.6.13.y.orig/drivers/ieee1394/sbp2.c ++++ linux-2.6.13.y/drivers/ieee1394/sbp2.c +@@ -596,6 +596,11 @@ static void sbp2util_mark_command_comple + spin_unlock_irqrestore(&scsi_id->sbp2_command_orb_lock, flags); + } + ++static inline int sbp2util_node_is_available(struct scsi_id_instance_data *scsi_id) ++{ ++ return scsi_id && scsi_id->ne && !scsi_id->ne->in_limbo; ++} ++ + + + /********************************************* +@@ -631,11 +636,23 @@ static int sbp2_remove(struct device *de + { + struct unit_directory *ud; + struct scsi_id_instance_data *scsi_id; ++ struct scsi_device *sdev; + + SBP2_DEBUG("sbp2_remove"); + + ud = container_of(dev, struct unit_directory, device); + scsi_id = ud->device.driver_data; ++ if (!scsi_id) ++ return 0; ++ ++ /* Trigger shutdown functions in scsi's highlevel. */ ++ if (scsi_id->scsi_host) ++ scsi_unblock_requests(scsi_id->scsi_host); ++ sdev = scsi_id->sdev; ++ if (sdev) { ++ scsi_id->sdev = NULL; ++ scsi_remove_device(sdev); ++ } + + sbp2_logout_device(scsi_id); + sbp2_remove_device(scsi_id); +@@ -944,6 +961,7 @@ alloc_fail: + SBP2_ERR("scsi_add_device failed"); + return PTR_ERR(sdev); + } ++ scsi_device_put(sdev); + + return 0; + } +@@ -2480,7 +2498,7 @@ static int sbp2scsi_queuecommand(struct + * If scsi_id is null, it means there is no device in this slot, + * so we should return selection timeout. + */ +- if (!scsi_id) { ++ if (!sbp2util_node_is_available(scsi_id)) { + SCpnt->result = DID_NO_CONNECT << 16; + done (SCpnt); + return 0; +@@ -2683,6 +2701,18 @@ static void sbp2scsi_complete_command(st + } + + ++static int sbp2scsi_slave_alloc(struct scsi_device *sdev) ++{ ++ ((struct scsi_id_instance_data *)sdev->host->hostdata[0])->sdev = sdev; ++ return 0; ++} ++ ++static void sbp2scsi_slave_destroy(struct scsi_device *sdev) ++{ ++ ((struct scsi_id_instance_data *)sdev->host->hostdata[0])->sdev = NULL; ++ return; ++} ++ + static int sbp2scsi_slave_configure (struct scsi_device *sdev) + { + blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); +@@ -2705,7 +2735,7 @@ static int sbp2scsi_abort(struct scsi_cm + SBP2_ERR("aborting sbp2 command"); + scsi_print_command(SCpnt); + +- if (scsi_id) { ++ if (sbp2util_node_is_available(scsi_id)) { + + /* + * Right now, just return any matching command structures +@@ -2749,7 +2779,7 @@ static int __sbp2scsi_reset(struct scsi_ + + SBP2_ERR("reset requested"); + +- if (scsi_id) { ++ if (sbp2util_node_is_available(scsi_id)) { + SBP2_ERR("Generating sbp2 fetch agent reset"); + sbp2_agent_reset(scsi_id, 0); + } +@@ -2817,7 +2847,9 @@ static struct scsi_host_template scsi_dr + .eh_device_reset_handler = sbp2scsi_reset, + .eh_bus_reset_handler = sbp2scsi_reset, + .eh_host_reset_handler = sbp2scsi_reset, ++ .slave_alloc = sbp2scsi_slave_alloc, + .slave_configure = sbp2scsi_slave_configure, ++ .slave_destroy = sbp2scsi_slave_destroy, + .this_id = -1, + .sg_tablesize = SG_ALL, + .use_clustering = ENABLE_CLUSTERING, diff --git a/queue/series b/queue/series new file mode 100644 index 00000000000..fa4159f2824 --- /dev/null +++ b/queue/series @@ -0,0 +1 @@ +ieee1394-sbp2-fixes-for-hot-unplug-and-module-unloading.patch