public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] SCSI hotplug support
@ 2002-10-14  5:40 Erik Andersen
  2002-10-14  7:06 ` Matthew Dharm
  2002-10-14 15:57 ` James Bottomley
  0 siblings, 2 replies; 42+ messages in thread
From: Erik Andersen @ 2002-10-14  5:40 UTC (permalink / raw)
  To: linux-scsi

Using the following patch I am able to make ieee1394 properly
connect and disconnect SBP-2 devices to/from the SCSI subsystem.
Without this patch, firewire devices are only registered with the
SCSI subsystem if they are connected when the host adaptor is
registered, and are only unregistered from the SCSI subsystem
when the firewire driver modules are removed from the kernel.
This is far from desirable...

This patch works by exporting within the kernel the functionality
already provided to userspace via /proc/scsi/scsi, i.e.:
	echo "scsi add-single-device 0 1 2 3" >/proc/scsi/scsi
and 
	echo "scsi remove-single-device 0 1 2 3" >/proc/scsi/scsi
is exported within the kernel as scsi_add_single_device() and 
scsi_remove_single_device().  A separate patch to the sbp2 driver
then uses these interfaces when devices are plugged or unplugged.
After looking though the current code, there does not seem to be
any other way to accomplish the same thing using the current SCSI
infrastructure.  Anyone have any objections to such a patch?  For
2.4.x?  Comments? 

Please CC me as I am not subscribed to linux-scsi, thanks,

 -Erik

--
Erik B. Andersen             http://codepoet-consulting.com/
--This message was written using 73% post-consumer electrons--


--- orig/drivers/scsi/hosts.h	2002-10-09 04:41:10.000000000 -0600
+++ linux-2.4.19/drivers/scsi/hosts.h	2002-10-09 04:41:10.000000000 -0600
@@ -532,6 +532,13 @@
 int scsi_register_device(struct Scsi_Device_Template * sdpnt);
 void scsi_deregister_device(struct Scsi_Device_Template * tpnt);
 
+/* Support for hot plugging and unplugging devices -- safe for 
+ * ieee1394 or USB devices, but probably not for normal SCSI... */
+extern int scsi_add_single_device(struct Scsi_Host *shpnt, 
+	int channel, int id, int lun);
+extern int scsi_remove_single_device(struct Scsi_Host *shpnt, 
+	int channel, int id, int lun);
+
 /* These are used by loadable modules */
 extern int scsi_register_module(int, void *);
 extern int scsi_unregister_module(int, void *);
--- orig/drivers/scsi/scsi.c	2002-10-09 04:41:10.000000000 -0600
+++ linux-2.4.19/drivers/scsi/scsi.c	2002-10-09 04:41:10.000000000 -0600
@@ -1553,6 +1553,96 @@
     }
 }
 
+/* Support for plugging/unplugging SCSI devices.  This feature is
+ * probably unsafe for standard SCSI devices, but is perfectly
+ * normal for things like ieee1394 or USB drives since these
+ * busses are designed for hotplugging.  Use at your own risk.... */
+int scsi_add_single_device(struct Scsi_Host *shpnt, 
+	int channel, int id, int lun)
+{
+	Scsi_Device *scd;
+
+	/* Do a bit of sanity checking */
+	if (shpnt==NULL) {
+		return  -ENXIO;
+	}
+
+	/* Check if they asked us to add an already existing device.
+	 * If so, ignore their misguided efforts. */
+	for (scd = shpnt->host_queue; scd; scd = scd->next) {
+		if ((scd->channel == channel && scd->id == id && scd->lun == lun)) {
+			break;
+		}
+	}
+	if (scd) {
+		return -ENOSYS;
+	}
+
+	scan_scsis(shpnt, 1, channel, id, lun);
+	return 0;
+}
+
+/* Support for plugging/unplugging SCSI devices.  This feature is
+ * probably unsafe for standard SCSI devices, but is perfectly
+ * normal for things like ieee1394 or USB drives since these
+ * busses are designed for hotplugging.  Use at your own risk.... */
+int scsi_remove_single_device(struct Scsi_Host *shpnt, 
+	int channel, int id, int lun)
+{
+	Scsi_Device *scd;
+	struct Scsi_Device_Template *SDTpnt;
+
+	/* Do a bit of sanity checking */
+	if (shpnt==NULL) {
+		return  -ENODEV;
+	}
+
+	/* Make sure the specified device is in fact present */
+	for (scd = shpnt->host_queue; scd; scd = scd->next) {
+		if ((scd->channel == channel && scd->id == id && scd->lun == lun)) {
+			break;
+		}
+	}
+	if (scd==NULL) {
+		return -ENODEV;
+	}
+
+	/* See if the specified device is busy */
+	if (scd->access_count)
+		return -EBUSY;
+
+	SDTpnt = scsi_devicelist;
+	while (SDTpnt != NULL) {
+		if (SDTpnt->detach)
+			(*SDTpnt->detach) (scd);
+		SDTpnt = SDTpnt->next;
+	}
+
+	if (scd->attached == 0) {
+		/* Nobody is using this device, so we
+		 * can now free all command structures.  */
+		if (shpnt->hostt->revoke)
+			shpnt->hostt->revoke(scd);
+		devfs_unregister (scd->de);
+		scsi_release_commandblocks(scd);
+
+		/* Now we can remove the device structure */
+		if (scd->next != NULL)
+			scd->next->prev = scd->prev;
+
+		if (scd->prev != NULL)
+			scd->prev->next = scd->next;
+
+		if (shpnt->host_queue == scd) {
+			shpnt->host_queue = scd->next;
+		}
+		blk_cleanup_queue(&scd->request_queue);
+		kfree((char *) scd);
+	}
+
+	return 0;
+}
+
 #ifdef CONFIG_PROC_FS
 static int scsi_proc_info(char *buffer, char **start, off_t offset, int length)
 {
@@ -1605,8 +1695,6 @@
 static int proc_scsi_gen_write(struct file * file, const char * buf,
                               unsigned long length, void *data)
 {
-	struct Scsi_Device_Template *SDTpnt;
-	Scsi_Device *scd;
 	struct Scsi_Host *HBA_ptr;
 	char *p;
 	int host, channel, id, lun;
@@ -1745,33 +1833,11 @@
 				break;
 			}
 		}
-		err = -ENXIO;
-		if (!HBA_ptr)
-			goto out;
-
-		for (scd = HBA_ptr->host_queue; scd; scd = scd->next) {
-			if ((scd->channel == channel
-			     && scd->id == id
-			     && scd->lun == lun)) {
-				break;
-			}
-		}
-
-		err = -ENOSYS;
-		if (scd)
-			goto out;	/* We do not yet support unplugging */
-
-		scan_scsis(HBA_ptr, 1, channel, id, lun);
-
-		/* FIXME (DB) This assumes that the queue_depth routines can be used
-		   in this context as well, while they were all designed to be
-		   called only once after the detect routine. (DB) */
-		/* queue_depth routine moved to inside scan_scsis(,1,,,) so
-		   it is called before build_commandblocks() */
-
-		err = length;
+		if ((err=scsi_add_single_device(HBA_ptr, channel, id, lun))==0)
+		    err = length;
 		goto out;
 	}
+
 	/*
 	 * Usage: echo "scsi remove-single-device 0 1 2 3" >/proc/scsi/scsi
 	 * with  "0 1 2 3" replaced by your "Host Channel Id Lun".
@@ -1797,58 +1863,8 @@
 				break;
 			}
 		}
-		err = -ENODEV;
-		if (!HBA_ptr)
-			goto out;
-
-		for (scd = HBA_ptr->host_queue; scd; scd = scd->next) {
-			if ((scd->channel == channel
-			     && scd->id == id
-			     && scd->lun == lun)) {
-				break;
-			}
-		}
-
-		if (scd == NULL)
-			goto out;	/* there is no such device attached */
-
-		err = -EBUSY;
-		if (scd->access_count)
-			goto out;
-
-		SDTpnt = scsi_devicelist;
-		while (SDTpnt != NULL) {
-			if (SDTpnt->detach)
-				(*SDTpnt->detach) (scd);
-			SDTpnt = SDTpnt->next;
-		}
-
-		if (scd->attached == 0) {
-			/*
-			 * Nobody is using this device any more.
-			 * Free all of the command structures.
-			 */
-                        if (HBA_ptr->hostt->revoke)
-                                HBA_ptr->hostt->revoke(scd);
-			devfs_unregister (scd->de);
-			scsi_release_commandblocks(scd);
-
-			/* Now we can remove the device structure */
-			if (scd->next != NULL)
-				scd->next->prev = scd->prev;
-
-			if (scd->prev != NULL)
-				scd->prev->next = scd->next;
-
-			if (HBA_ptr->host_queue == scd) {
-				HBA_ptr->host_queue = scd->next;
-			}
-			blk_cleanup_queue(&scd->request_queue);
-			kfree((char *) scd);
-		} else {
-			goto out;
-		}
-		err = 0;
+		err=scsi_remove_single_device(HBA_ptr, channel, id, lun);
+		goto out;
 	}
 out:
 	
--- orig/drivers/scsi/scsi_syms.c	2002-10-09 04:41:10.000000000 -0600
+++ linux-2.4.19/drivers/scsi/scsi_syms.c	2002-10-09 04:41:10.000000000 -0600
@@ -103,3 +103,9 @@
 extern int scsi_delete_timer(Scsi_Cmnd *);
 EXPORT_SYMBOL(scsi_add_timer);
 EXPORT_SYMBOL(scsi_delete_timer);
+
+/* Support for hot plugging and unplugging devices -- safe for 
+ * ieee1394 or USB devices, but probably not for normal SCSI... */
+EXPORT_SYMBOL(scsi_add_single_device);
+EXPORT_SYMBOL(scsi_remove_single_device);
+

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

end of thread, other threads:[~2002-10-18 11:28 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-10-14  5:40 [PATCH] SCSI hotplug support Erik Andersen
2002-10-14  7:06 ` Matthew Dharm
2002-10-14  7:12   ` Erik Andersen
2002-10-14 15:47     ` Kurt Garloff
2002-10-14 16:19       ` Mike Anderson
2002-10-14 20:41         ` Erik Andersen
2002-10-14 22:10           ` Mike Anderson
2002-10-14 20:46       ` Erik Andersen
2002-10-14 15:57 ` James Bottomley
2002-10-14 17:22   ` Mike Anderson
2002-10-14 17:30   ` Matthew Dharm
2002-10-14 17:39     ` James Bottomley
2002-10-14 19:11       ` Oliver Xymoron
2002-10-15  0:42       ` Kurt Garloff
2002-10-14 20:37   ` Erik Andersen
2002-10-14 21:07     ` James Bottomley
2002-10-14 21:54       ` Erik Andersen
2002-10-14 22:25         ` Doug Ledford
2002-10-15  5:25           ` Erik Andersen
2002-10-15 15:33             ` Doug Ledford
2002-10-15 18:18               ` Erik Andersen
2002-10-15 18:22             ` Doug Ledford
2002-10-15 18:45               ` Erik Andersen
2002-10-15 19:13                 ` Doug Ledford
2002-10-15 19:32                   ` Erik Andersen
2002-10-15 19:45                     ` James Bottomley
2002-10-15 19:50                     ` Scott Merritt
2002-10-15 19:55                     ` Doug Ledford
2002-10-15 22:07                       ` Erik Andersen
2002-10-16  2:40                         ` Doug Ledford
2002-10-18 11:28                           ` Erik Andersen
2002-10-15 21:43                 ` Oliver Neukum
2002-10-15 22:07                   ` Erik Andersen
2002-10-14 22:19       ` Oliver Neukum
2002-10-15  0:22         ` Doug Ledford
2002-10-15  7:53           ` Oliver Neukum
2002-10-15 14:35             ` Doug Ledford
2002-10-15 15:19               ` Oliver Neukum
2002-10-15 15:40                 ` James Bottomley
2002-10-15 17:47               ` Erik Andersen
2002-10-15 18:34                 ` Doug Ledford
2002-10-15 18:22               ` Scott Merritt

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