public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] add sysfs attributes to scan and delete scsi_devices
@ 2003-07-08 20:40 Patrick Mansfield
  2003-07-08 20:41 ` examples using " Patrick Mansfield
                   ` (3 more replies)
  0 siblings, 4 replies; 10+ messages in thread
From: Patrick Mansfield @ 2003-07-08 20:40 UTC (permalink / raw)
  To: linux-scsi, James Bottomley

This patch against recent 2.5 bk adds a sysfs attribute to allow scanning
(or rescanning) and deletion of scsi_devices.

It also allows scanning of entire hosts, channels, or targets.

diff -purN -X /home/patman/dontdiff bleed-2.5/drivers/scsi/scsi_priv.h scan-del-attr-bl-2.5/drivers/scsi/scsi_priv.h
--- bleed-2.5/drivers/scsi/scsi_priv.h	Wed Jul  2 13:40:54 2003
+++ scan-del-attr-bl-2.5/drivers/scsi/scsi_priv.h	Mon Jul  7 12:45:29 2003
@@ -107,6 +107,8 @@ extern void scsi_forget_host(struct Scsi
 extern void scsi_free_sdev(struct scsi_device *);
 extern void scsi_free_shost(struct Scsi_Host *);
 extern void scsi_rescan_device(struct device *);
+extern int scsi_scan(const char *);
+extern int scsi_remove(const char *);
 
 /* scsi_sysfs.c */
 extern int scsi_device_register(struct scsi_device *);
diff -purN -X /home/patman/dontdiff bleed-2.5/drivers/scsi/scsi_scan.c scan-del-attr-bl-2.5/drivers/scsi/scsi_scan.c
--- bleed-2.5/drivers/scsi/scsi_scan.c	Mon Jul  7 11:10:22 2003
+++ scan-del-attr-bl-2.5/drivers/scsi/scsi_scan.c	Mon Jul  7 12:45:29 2003
@@ -49,6 +49,12 @@
 #define SCSI_UID_UNKNOWN 'Z'
 
 /*
+ * Special value for scanning to specify scanning or rescanning of all
+ * possible channels, (target) ids, or luns on a given host.
+ */
+#define SCAN_WILD_CARD	~0
+
+/*
  * Return values of some of the scanning functions.
  *
  * SCSI_SCAN_NO_RESPONSE: no valid response received from the target, this
@@ -679,13 +685,32 @@ static int scsi_add_lun(struct scsi_devi
  **/
 static int scsi_probe_and_add_lun(struct Scsi_Host *host,
 		uint channel, uint id, uint lun, int *bflagsp,
-		struct scsi_device **sdevp)
+		struct scsi_device **sdevp, int rescan)
 {
 	struct scsi_device *sdev;
 	struct scsi_request *sreq;
 	unsigned char *result;
 	int bflags, res = SCSI_SCAN_NO_RESPONSE;
 
+	/*
+	 * The rescan flag is used as an optimization, the first scan of a
+	 * host adapter calls into here with rescan == 0.
+	 */
+	if (rescan) {
+		sdev = scsi_find_device(host, channel, id, lun);
+		if (sdev) {
+			SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO
+				"scsi scan: device exists on <%d:%d:%d:%d>\n",
+				host->host_no, channel, id, lun));
+			if (sdevp)
+				*sdevp = sdev;
+			if (bflagsp)
+				*bflagsp = scsi_get_device_flags(sdev->vendor,
+								 sdev->model);
+			return SCSI_SCAN_LUN_PRESENT;
+		}
+	}
+
 	sdev = scsi_alloc_sdev(host, channel, id, lun);
 	if (!sdev)
 		goto out;
@@ -760,7 +785,7 @@ static int scsi_probe_and_add_lun(struct
  *     Modifies sdevscan->lun.
  **/
 static void scsi_sequential_lun_scan(struct Scsi_Host *shost, uint channel,
-		uint id, int bflags, int lun0_res, int scsi_level)
+		uint id, int bflags, int lun0_res, int scsi_level, int rescan)
 {
 	unsigned int sparse_lun, lun, max_dev_lun;
 
@@ -829,7 +854,8 @@ static void scsi_sequential_lun_scan(str
 	 */
 	for (lun = 1; lun < max_dev_lun; ++lun)
 		if ((scsi_probe_and_add_lun(shost, channel, id, lun,
-		      NULL, NULL) != SCSI_SCAN_LUN_PRESENT) && !sparse_lun)
+		      NULL, NULL, rescan) != SCSI_SCAN_LUN_PRESENT) &&
+		    !sparse_lun)
 			return;
 }
 
@@ -880,7 +906,8 @@ static int scsilun_to_int(struct scsi_lu
  *     0: scan completed (or no memory, so further scanning is futile)
  *     1: no report lun scan, or not configured
  **/
-static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags)
+static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
+				int rescan)
 {
 	char devname[64];
 	unsigned char scsi_cmd[MAX_COMMAND_SIZE];
@@ -1034,7 +1061,7 @@ static int scsi_report_lun_scan(struct s
 			int res;
 
 			res = scsi_probe_and_add_lun(sdev->host, sdev->channel,
-				sdev->id, lun, NULL, NULL);
+				sdev->id, lun, NULL, NULL, rescan);
 			if (res == SCSI_SCAN_NO_RESPONSE) {
 				/*
 				 * Got some results, but now none, abort.
@@ -1060,7 +1087,7 @@ static int scsi_report_lun_scan(struct s
 	return 0;
 }
 #else
-# define scsi_report_lun_scan(sdev, blags)	(1)
+# define scsi_report_lun_scan(sdev, blags, rescan)	(1)
 #endif	/* CONFIG_SCSI_REPORT_LUNS */
 
 struct scsi_device *scsi_add_device(struct Scsi_Host *shost,
@@ -1069,7 +1096,11 @@ struct scsi_device *scsi_add_device(stru
 	struct scsi_device *sdev;
 	int res;
 
-	res = scsi_probe_and_add_lun(shost, channel, id, lun, NULL, &sdev);
+	/*
+	 * Caller already checked if sdev exists, but be paranoid and call
+	 * with rescan of 1.
+	 */
+	res = scsi_probe_and_add_lun(shost, channel, id, lun, NULL, &sdev, 1);
 	if (res != SCSI_SCAN_LUN_PRESENT)
 		sdev = ERR_PTR(-ENODEV);
 	return sdev;
@@ -1112,7 +1143,7 @@ void scsi_rescan_device(struct device *d
  *     sequential scan of LUNs on the target id.
  **/
 static void scsi_scan_target(struct Scsi_Host *shost, unsigned int channel,
-			     unsigned int id)
+			     unsigned int id, unsigned int lun, int rescan)
 {
 	int bflags = 0;
 	int res;
@@ -1124,19 +1155,29 @@ static void scsi_scan_target(struct Scsi
 		 */
 		return;
 
+	if (lun != SCAN_WILD_CARD) {
+		/*
+		 * Scan for a specific host/chan/id/lun.
+		 */
+		scsi_probe_and_add_lun(shost, channel, id, lun, NULL, NULL,
+				       rescan);
+		return;
+	}
+
 	/*
 	 * Scan LUN 0, if there is some response, scan further. Ideally, we
 	 * would not configure LUN 0 until all LUNs are scanned.
 	 */
-	res = scsi_probe_and_add_lun(shost, channel, id, 0, &bflags, &sdev);
+	res = scsi_probe_and_add_lun(shost, channel, id, 0, &bflags, &sdev,
+				     rescan);
 	if (res == SCSI_SCAN_LUN_PRESENT) {
-		if (scsi_report_lun_scan(sdev, bflags) != 0)
+		if (scsi_report_lun_scan(sdev, bflags, rescan) != 0)
 			/*
 			 * The REPORT LUN did not scan the target,
 			 * do a sequential scan.
 			 */
 			scsi_sequential_lun_scan(shost, channel, id, bflags,
-				       	res, sdev->scsi_level);
+				       	res, sdev->scsi_level, rescan);
 	} else if (res == SCSI_SCAN_TARGET_PRESENT) {
 		/*
 		 * There's a target here, but lun 0 is offline so we
@@ -1145,37 +1186,26 @@ static void scsi_scan_target(struct Scsi
 		 * a default scsi level of SCSI_2
 		 */
 		scsi_sequential_lun_scan(shost, channel, id, BLIST_SPARSELUN,
-				SCSI_SCAN_TARGET_PRESENT, SCSI_2);
+				SCSI_SCAN_TARGET_PRESENT, SCSI_2, rescan);
 	}
 }
 
-/**
- * scsi_scan_host - scan the given adapter
- * @shost:	adapter to scan
- *
- * Description:
- *     Iterate and call scsi_scan_target to scan all possible target id's
- *     on all possible channels.
- **/
-void scsi_scan_host(struct Scsi_Host *shost)
+static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
+			      unsigned int id, unsigned int lun, int rescan)
 {
-	uint channel, id, order_id;
+	uint order_id;
 
-	/*
-	 * The sdevscan host, channel, id and lun are filled in as
-	 * needed to scan.
-	 */
-	for (channel = 0; channel <= shost->max_channel; channel++) {
-		/*
-		 * XXX adapter drivers when possible (FCP, iSCSI)
-		 * could modify max_id to match the current max,
-		 * not the absolute max.
-		 *
-		 * XXX add a shost id iterator, so for example,
-		 * the FC ID can be the same as a target id
-		 * without a huge overhead of sparse id's.
-		 */
+	if (id == SCAN_WILD_CARD)
 		for (id = 0; id < shost->max_id; ++id) {
+			/*
+			 * XXX adapter drivers when possible (FCP, iSCSI)
+			 * could modify max_id to match the current max,
+			 * not the absolute max.
+			 *
+			 * XXX add a shost id iterator, so for example,
+			 * the FC ID can be the same as a target id
+			 * without a huge overhead of sparse id's.
+			 */
 			if (shost->reverse_ordering)
 				/*
 				 * Scan from high to low id.
@@ -1183,9 +1213,155 @@ void scsi_scan_host(struct Scsi_Host *sh
 				order_id = shost->max_id - id - 1;
 			else
 				order_id = id;
-			scsi_scan_target(shost, channel, order_id);
+			scsi_scan_target(shost, channel, order_id, lun, rescan);
 		}
+	else
+		scsi_scan_target(shost, channel, id, lun, rescan);
+}
+
+static int scsi_scan_host_selected(struct Scsi_Host *shost,
+				    unsigned int channel, unsigned int id,
+				    unsigned int lun, int rescan)
+{
+	if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) ||
+	    ((id != SCAN_WILD_CARD) && (id > shost->max_id)) ||
+	    ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun)))
+		return -EINVAL;
+
+	if (channel == SCAN_WILD_CARD) 
+		for (channel = 0; channel <= shost->max_channel; channel++)
+			scsi_scan_channel(shost, channel, id, lun, rescan);
+	else
+		scsi_scan_channel(shost, channel, id, lun, rescan);
+	return 0;
+}
+
+/**
+ * scsi_scan_host - scan the given adapter
+ * @shost:	adapter to scan
+ **/
+void scsi_scan_host(struct Scsi_Host *shost)
+{
+	scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD,
+				SCAN_WILD_CARD, 0);
+}
+
+static int check_set(unsigned int *val, char *src, char *wild)
+{
+	char *last;
+
+	if (wild && strncmp(src, wild, 20) == 0) {
+		*val = SCAN_WILD_CARD;
+	} else {
+		/*
+		 * Doesn't check for int overflow
+		 */
+		*val = simple_strtoul(src, &last, 0);
+		if (*last != '\0')
+			return 1;
+	}
+	return 0;
+}
+
+/**
+ * scsi_scan - scan and possibly rescan for a given adapter
+ * @str: string with values of form "host_no chan id lun"
+ *
+ * Description:
+ *     Determine the host_no, channel, id, and lun by parsing @str, and
+ *     then call scsi_scan_host_selected. Except for host_no, values can
+ *     be wild-carded using "-".
+ *
+ * Returns: 0 on success, -error on failure.
+ **/
+int scsi_scan(const char *str)
+{
+	struct Scsi_Host *shost;
+	char s1[15], s2[15], s3[15], s4[15], junk;
+	unsigned int host_no, channel, id, lun;
+	int res;
+
+	res = sscanf(str, "%10s %10s %10s %10s %c", s1, s2, s3, s4, &junk);
+	if (res != 4)
+		return -EINVAL;
+	if (check_set(&host_no, s1, NULL))
+		return -EINVAL;
+	if (check_set(&channel, s2, "-"))
+		return -EINVAL;
+	if (check_set(&id, s3, "-"))
+		return -EINVAL;
+	if (check_set(&lun, s4, "-"))
+		return -EINVAL;
+
+	SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "%s: <%u:%u:%u:%u>\n",
+		__FUNCTION__, host_no, channel, id, lun));
+	/*
+	 * Doesn't check for overflow of host_no
+	 */
+	shost = scsi_host_lookup(host_no);
+	if (!shost)
+		return -ENODEV;
+
+	res = scsi_scan_host_selected(shost, channel, id, lun, 1 /* rescan */);
+	scsi_host_put(shost);
+	return res;
+}
+
+/**
+ * scsi_remove - remove one scsi_device from shost
+ * @str: string with values of form "host_no chan id lun"
+ *
+ * Description:
+ *     Determine the host_no, channel, id, and lun by parsing @str, and
+ *     then call scsi_remove_device. No wild card support.
+ *
+ * Returns: 0 on success, -error on failure.
+ **/
+int scsi_remove(const char *str)
+{
+	struct scsi_device *sdev;
+	struct Scsi_Host *shost;
+	char s1[15], s2[15], s3[15], s4[15], junk;
+	unsigned int host_no, channel, id, lun;
+	int res;
+
+	res = sscanf(str, "%10s %10s %10s %10s %c", s1, s2, s3, s4, &junk);
+	if (res != 4)
+		return -EINVAL;
+	if (check_set(&host_no, s1, NULL))
+		return -EINVAL;
+	if (check_set(&channel, s2, NULL))
+		return -EINVAL;
+	if (check_set(&id, s3, NULL))
+		return -EINVAL;
+	if (check_set(&lun, s4, NULL))
+		return -EINVAL;
+
+	SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "%s: <%u:%u:%u:%u>\n",
+		__FUNCTION__, host_no, channel, id, lun));
+	/*
+	 * Doesn't check for overflow of host_no
+	 */
+	shost = scsi_host_lookup(host_no);
+	if (!shost)
+		return -ENODEV;
+
+	sdev = scsi_find_device(shost, channel, id, lun);
+	if (!sdev) {
+		res = -ENODEV;
+		goto out;
+	}
+
+	if (sdev->access_count) {
+		res = -EBUSY;
+		goto out;
 	}
+
+	res = 0;
+	scsi_remove_device(sdev);
+out:
+	scsi_host_put(shost);
+	return res;
 }
 
 void scsi_forget_host(struct Scsi_Host *shost)
diff -purN -X /home/patman/dontdiff bleed-2.5/drivers/scsi/scsi_sysfs.c scan-del-attr-bl-2.5/drivers/scsi/scsi_sysfs.c
--- bleed-2.5/drivers/scsi/scsi_sysfs.c	Wed Jul  2 18:33:55 2003
+++ scan-del-attr-bl-2.5/drivers/scsi/scsi_sysfs.c	Tue Jul  8 10:54:23 2003
@@ -73,6 +73,27 @@ struct bus_type scsi_bus_type = {
         .match		= scsi_bus_match,
 };
 
+static ssize_t store_scan(struct bus_type *bus, const char *buf, size_t count)
+{
+	int res;
+
+	res = scsi_scan(buf);
+	if (res == 0)
+		res = count;
+	return res;
+};
+static BUS_ATTR(scan, S_IWUSR, NULL, store_scan);
+
+static ssize_t store_delete(struct bus_type *bus, const char *buf, size_t count)
+{
+	int res;
+
+	res = scsi_remove(buf);
+	if (res == 0)
+		res = count;
+	return res;
+};
+static BUS_ATTR(delete, S_IWUSR, NULL, store_delete);
 
 int scsi_sysfs_register(void)
 {
@@ -81,6 +102,12 @@ int scsi_sysfs_register(void)
 	error = bus_register(&scsi_bus_type);
 	if (error)
 		return error;
+	error = bus_create_file(&scsi_bus_type, &bus_attr_scan);
+	if (error)
+		goto bus_unregister;
+	error = bus_create_file(&scsi_bus_type, &bus_attr_delete);
+	if (error)
+		goto bus_unregister;
 	error = class_register(&shost_class);
 	if (error)
 		goto bus_unregister;

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

* examples using sysfs attributes to scan and delete scsi_devices
  2003-07-08 20:40 [PATCH] add sysfs attributes to scan and delete scsi_devices Patrick Mansfield
@ 2003-07-08 20:41 ` Patrick Mansfield
  2003-07-08 20:47 ` [PATCH] add " Christoph Hellwig
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 10+ messages in thread
From: Patrick Mansfield @ 2003-07-08 20:41 UTC (permalink / raw)
  To: linux-scsi, James Bottomley

Some sample usage of the delete and scan attributes. 

The system has one fastt200 (disk array) with 32 LUNs (4:0:0:*),
10 disk drives (4:0:1-10:0).

[root@elm3b79 root]# ls -l /sysfs/bus/scsi
total 0
--w-------    1 root     root            0 Jul  8 13:28 delete
drwxr-xr-x    2 root     root            0 Jul  8 04:04 devices
drwxr-xr-x    5 root     root            0 Jul  8 04:04 drivers
--w-------    1 root     root            0 Jul  8 13:08 scan

[root@elm3b79 root]# ls /sysfs/bus/scsi/devices
0:0:0:0  4:0:0:0   4:0:0:14  4:0:0:2   4:0:0:25  4:0:0:30  4:0:0:8   4:0:4:0
0:0:1:0  4:0:0:1   4:0:0:15  4:0:0:20  4:0:0:26  4:0:0:31  4:0:0:9   4:0:5:0
0:0:2:0  4:0:0:10  4:0:0:16  4:0:0:21  4:0:0:27  4:0:0:4   4:0:1:0   4:0:6:0
0:0:3:0  4:0:0:11  4:0:0:17  4:0:0:22  4:0:0:28  4:0:0:5   4:0:10:0  4:0:7:0
0:0:4:0  4:0:0:12  4:0:0:18  4:0:0:23  4:0:0:29  4:0:0:6   4:0:2:0   4:0:8:0
0:0:5:0  4:0:0:13  4:0:0:19  4:0:0:24  4:0:0:3   4:0:0:7   4:0:3:0   4:0:9:0

# delete a few scsi_devices from the disk array

[root@elm3b79 root]# echo "4 0 0 25" > /root/xx; dd if=/root/xx of=/sysfs/bus/scsi/delete 
0+1 records in
0+1 records out
[root@elm3b79 root]# echo "4 0 0 1" > /root/xx; dd if=/root/xx of=/sysfs/bus/scsi/delete 
0+1 records in
0+1 records out
[root@elm3b79 root]# echo "4 0 0 3" > /root/xx; dd if=/root/xx of=/sysfs/bus/scsi/delete 
0+1 records in
0+1 records out
[root@elm3b79 root]# ls /sysfs/bus/scsi/devices
0:0:0:0  4:0:0:0   4:0:0:15  4:0:0:20  4:0:0:27  4:0:0:5  4:0:10:0  4:0:7:0
0:0:1:0  4:0:0:10  4:0:0:16  4:0:0:21  4:0:0:28  4:0:0:6  4:0:2:0   4:0:8:0
0:0:2:0  4:0:0:11  4:0:0:17  4:0:0:22  4:0:0:29  4:0:0:7  4:0:3:0   4:0:9:0
0:0:3:0  4:0:0:12  4:0:0:18  4:0:0:23  4:0:0:30  4:0:0:8  4:0:4:0
0:0:4:0  4:0:0:13  4:0:0:19  4:0:0:24  4:0:0:31  4:0:0:9  4:0:5:0
0:0:5:0  4:0:0:14  4:0:0:2   4:0:0:26  4:0:0:4   4:0:1:0  4:0:6:0

# Rescan a target, in this particular case a REPORT LUN scan occurs

[root@elm3b79 root]# echo "4 0 0 -" > /root/xx; dd if=/root/xx of=/sysfs/bus/scsi/scan 
0+1 records in
0+1 records out
[root@elm3b79 root]# ls /sysfs/bus/scsi
delete  devices  drivers  scan
[root@elm3b79 root]# ls /sysfs/bus/scsi/devices
0:0:0:0  4:0:0:0   4:0:0:14  4:0:0:2   4:0:0:25  4:0:0:30  4:0:0:8   4:0:4:0
0:0:1:0  4:0:0:1   4:0:0:15  4:0:0:20  4:0:0:26  4:0:0:31  4:0:0:9   4:0:5:0
0:0:2:0  4:0:0:10  4:0:0:16  4:0:0:21  4:0:0:27  4:0:0:4   4:0:1:0   4:0:6:0
0:0:3:0  4:0:0:11  4:0:0:17  4:0:0:22  4:0:0:28  4:0:0:5   4:0:10:0  4:0:7:0
0:0:4:0  4:0:0:12  4:0:0:18  4:0:0:23  4:0:0:29  4:0:0:6   4:0:2:0   4:0:8:0
0:0:5:0  4:0:0:13  4:0:0:19  4:0:0:24  4:0:0:3   4:0:0:7   4:0:3:0   4:0:9:0

# Rescan an entire adapter

[root@elm3b79 root]# echo "4 - - -" > /root/xx; dd if=/root/xx of=/sysfs/bus/scsi/scan 
0+1 records in
0+1 records out

# some failure cases

[root@elm3b79 root]# echo "4 0 0 88" > /root/xx; dd if=/root/xx of=/sysfs/bus/scsi/delete 
dd: writing `/sysfs/bus/scsi/delete': No such device
0+1 records in
0+0 records out
[root@elm3b79 root]# echo "4 0 88" > /root/xx; dd if=/root/xx of=/sysfs/bus/scsi/delete 
dd: writing `/sysfs/bus/scsi/delete': Invalid argument
0+1 records in
0+0 records out

-- Patrick Mansfield

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

* Re: [PATCH] add sysfs attributes to scan and delete scsi_devices
  2003-07-08 20:40 [PATCH] add sysfs attributes to scan and delete scsi_devices Patrick Mansfield
  2003-07-08 20:41 ` examples using " Patrick Mansfield
@ 2003-07-08 20:47 ` Christoph Hellwig
  2003-07-08 22:36   ` Patrick Mansfield
  2003-07-08 20:50 ` James Bottomley
  2003-07-09 20:27 ` [PATCH] take 2 " Patrick Mansfield
  3 siblings, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2003-07-08 20:47 UTC (permalink / raw)
  To: Patrick Mansfield; +Cc: linux-scsi, James Bottomley

On Tue, Jul 08, 2003 at 01:40:16PM -0700, Patrick Mansfield wrote:
> This patch against recent 2.5 bk adds a sysfs attribute to allow scanning
> (or rescanning) and deletion of scsi_devices.
> 
> It also allows scanning of entire hosts, channels, or targets.

Looks good so far but please keep the string parsing in scsi_sysfs.c
instead of scsi_scan.c.  Also doesn't want this some code sharing with
the old procfs code?


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

* Re: [PATCH] add sysfs attributes to scan and delete scsi_devices
  2003-07-08 20:40 [PATCH] add sysfs attributes to scan and delete scsi_devices Patrick Mansfield
  2003-07-08 20:41 ` examples using " Patrick Mansfield
  2003-07-08 20:47 ` [PATCH] add " Christoph Hellwig
@ 2003-07-08 20:50 ` James Bottomley
  2003-07-08 21:13   ` Christoph Hellwig
  2003-07-09 20:27 ` [PATCH] take 2 " Patrick Mansfield
  3 siblings, 1 reply; 10+ messages in thread
From: James Bottomley @ 2003-07-08 20:50 UTC (permalink / raw)
  To: Patrick Mansfield; +Cc: SCSI Mailing List

On Tue, 2003-07-08 at 15:40, Patrick Mansfield wrote:
> This patch against recent 2.5 bk adds a sysfs attribute to allow scanning
> (or rescanning) and deletion of scsi_devices.
> 
> It also allows scanning of entire hosts, channels, or targets.

I'm not convinced we need a bus file for this.  What's the reason we
can't have a per host file instead?

I'm thinking of the hotplug case where you know the sysfs path to the
card just inserted.  Translating that to a hostid will be rather hard.

James



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

* Re: [PATCH] add sysfs attributes to scan and delete scsi_devices
  2003-07-08 20:50 ` James Bottomley
@ 2003-07-08 21:13   ` Christoph Hellwig
  2003-07-08 22:24     ` Patrick Mansfield
  0 siblings, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2003-07-08 21:13 UTC (permalink / raw)
  To: James Bottomley; +Cc: Patrick Mansfield, SCSI Mailing List

On Tue, Jul 08, 2003 at 03:50:15PM -0500, James Bottomley wrote:
> I'm not convinced we need a bus file for this.  What's the reason we
> can't have a per host file instead?
> 
> I'm thinking of the hotplug case where you know the sysfs path to the
> card just inserted.  Translating that to a hostid will be rather hard.

After thinking about this again I tend to agree with you that a per-host
file sounds like the better idea.


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

* Re: [PATCH] add sysfs attributes to scan and delete scsi_devices
  2003-07-08 21:13   ` Christoph Hellwig
@ 2003-07-08 22:24     ` Patrick Mansfield
  2003-07-13 13:43       ` Christoph Hellwig
  0 siblings, 1 reply; 10+ messages in thread
From: Patrick Mansfield @ 2003-07-08 22:24 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: James Bottomley, SCSI Mailing List

On Tue, Jul 08, 2003 at 10:13:51PM +0100, Christoph Hellwig wrote:
> On Tue, Jul 08, 2003 at 03:50:15PM -0500, James Bottomley wrote:
> > I'm not convinced we need a bus file for this.  What's the reason we
> > can't have a per host file instead?
> > 
> > I'm thinking of the hotplug case where you know the sysfs path to the
> > card just inserted.  Translating that to a hostid will be rather hard.
> 
> After thinking about this again I tend to agree with you that a per-host
> file sounds like the better idea.

James/Christoph -

There is not much of a difference either way.

Scanning makes more sense as a host attribute (or as a target attribute,
but we don't have a target device today). Deletion of a scsi_device makes
more sense as a /sysfs/bus/scsi (or even scsi_device) attribute that takes
a bus_id. 

But we should be symmetrical for a user space interface. (And it is easier
to catch sscanf errors using spaces as a separator.)

I'll go ahead and redo it as per-host, and move string parsing into
scsi_sysfs.c.

Thanks for the feedback.

-- Patrick Mansfield

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

* Re: [PATCH] add sysfs attributes to scan and delete scsi_devices
  2003-07-08 20:47 ` [PATCH] add " Christoph Hellwig
@ 2003-07-08 22:36   ` Patrick Mansfield
  0 siblings, 0 replies; 10+ messages in thread
From: Patrick Mansfield @ 2003-07-08 22:36 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-scsi, James Bottomley

On Tue, Jul 08, 2003 at 09:47:27PM +0100, Christoph Hellwig wrote:

> Looks good so far but please keep the string parsing in scsi_sysfs.c
> instead of scsi_scan.c.  Also doesn't want this some code sharing with
> the old procfs code?

I can change procfs to use scsi_scan_host_selected(), it will be externed
for use in scsi_sysfs.c.

But is it worth propagating through the call chain whether a new device
was found (i.e. scsi_add_device returns -ENODEV)?

-- Patrick Mansfield

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

* [PATCH] take 2 add sysfs attributes to scan and delete scsi_devices
  2003-07-08 20:40 [PATCH] add sysfs attributes to scan and delete scsi_devices Patrick Mansfield
                   ` (2 preceding siblings ...)
  2003-07-08 20:50 ` James Bottomley
@ 2003-07-09 20:27 ` Patrick Mansfield
  2003-07-09 20:29   ` and some example usage of the attributes Patrick Mansfield
  3 siblings, 1 reply; 10+ messages in thread
From: Patrick Mansfield @ 2003-07-09 20:27 UTC (permalink / raw)
  To: linux-scsi, James Bottomley

This patch against scsi-misc-2.5 adds a sysfs attribute to allow scanning
(or rescanning) and deletion of scsi_devices.

It also allows scanning of entire hosts, channels, or targets.

Updated per comments received, mainly create the scan and delete
attributes per host.

The scsi_proc.c remove code was not changed, it and this patch still need
changes based on Mike A's patches.

diff -purN -X /home/patman/dontdiff scsi-misc-2.5-pure/drivers/scsi/scsi_priv.h scan-del-attr-sm-2.5/drivers/scsi/scsi_priv.h
--- scsi-misc-2.5-pure/drivers/scsi/scsi_priv.h	Wed Jul  9 09:12:38 2003
+++ scan-del-attr-sm-2.5/drivers/scsi/scsi_priv.h	Wed Jul  9 09:22:42 2003
@@ -42,6 +42,12 @@
 	(((scmd)->sense_buffer[0] & 0x70) == 0x70)
 
 /*
+ * Special value for scanning to specify scanning or rescanning of all
+ * possible channels, (target) ids, or luns on a given shost.
+ */
+#define SCAN_WILD_CARD	~0
+
+/*
  * scsi_target: representation of a scsi target, for now, this is only
  * used for single_lun devices. If no one has active IO to the target,
  * starget_sdev_user is NULL, else it points to the active sdev.
@@ -102,6 +108,8 @@ extern void scsi_exit_procfs(void);
 #endif /* CONFIG_PROC_FS */
 
 /* scsi_scan.c */
+int scsi_scan_host_selected(struct Scsi_Host *, unsigned int, unsigned int,
+			    unsigned int, int);
 extern void scsi_forget_host(struct Scsi_Host *);
 extern void scsi_free_sdev(struct scsi_device *);
 extern void scsi_free_shost(struct Scsi_Host *);
diff -purN -X /home/patman/dontdiff scsi-misc-2.5-pure/drivers/scsi/scsi_proc.c scan-del-attr-sm-2.5/drivers/scsi/scsi_proc.c
--- scsi-misc-2.5-pure/drivers/scsi/scsi_proc.c	Thu Jun 12 02:50:06 2003
+++ scan-del-attr-sm-2.5/drivers/scsi/scsi_proc.c	Wed Jul  9 12:05:37 2003
@@ -174,21 +174,11 @@ static int proc_print_scsidevice(struct 
 static int scsi_add_single_device(uint host, uint channel, uint id, uint lun)
 {
 	struct Scsi_Host *shost;
-	struct scsi_device *sdev;
-	int error = -ENODEV;
-
+	int error;
 	shost = scsi_host_lookup(host);
 	if (!shost)
 		return -ENODEV;
-
-	if (!scsi_find_device(shost, channel, id, lun)) {
-		sdev = scsi_add_device(shost, channel, id, lun);
-		if (IS_ERR(sdev))
-			error = PTR_ERR(sdev);
-		else
-			error = 0;
-	}
-
+	error = scsi_scan_host_selected(shost, channel, id, lun, 1);
 	scsi_host_put(shost);
 	return error;
 }
diff -purN -X /home/patman/dontdiff scsi-misc-2.5-pure/drivers/scsi/scsi_scan.c scan-del-attr-sm-2.5/drivers/scsi/scsi_scan.c
--- scsi-misc-2.5-pure/drivers/scsi/scsi_scan.c	Wed Jul  9 09:12:38 2003
+++ scan-del-attr-sm-2.5/drivers/scsi/scsi_scan.c	Wed Jul  9 09:19:41 2003
@@ -678,13 +678,32 @@ static int scsi_add_lun(struct scsi_devi
  **/
 static int scsi_probe_and_add_lun(struct Scsi_Host *host,
 		uint channel, uint id, uint lun, int *bflagsp,
-		struct scsi_device **sdevp)
+		struct scsi_device **sdevp, int rescan)
 {
 	struct scsi_device *sdev;
 	struct scsi_request *sreq;
 	unsigned char *result;
 	int bflags, res = SCSI_SCAN_NO_RESPONSE;
 
+	/*
+	 * The rescan flag is used as an optimization, the first scan of a
+	 * host adapter calls into here with rescan == 0.
+	 */
+	if (rescan) {
+		sdev = scsi_find_device(host, channel, id, lun);
+		if (sdev) {
+			SCSI_LOG_SCAN_BUS(3, printk(KERN_INFO
+				"scsi scan: device exists on <%d:%d:%d:%d>\n",
+				host->host_no, channel, id, lun));
+			if (sdevp)
+				*sdevp = sdev;
+			if (bflagsp)
+				*bflagsp = scsi_get_device_flags(sdev->vendor,
+								 sdev->model);
+			return SCSI_SCAN_LUN_PRESENT;
+		}
+	}
+
 	sdev = scsi_alloc_sdev(host, channel, id, lun);
 	if (!sdev)
 		goto out;
@@ -759,7 +778,7 @@ static int scsi_probe_and_add_lun(struct
  *     Modifies sdevscan->lun.
  **/
 static void scsi_sequential_lun_scan(struct Scsi_Host *shost, uint channel,
-		uint id, int bflags, int lun0_res, int scsi_level)
+		uint id, int bflags, int lun0_res, int scsi_level, int rescan)
 {
 	unsigned int sparse_lun, lun, max_dev_lun;
 
@@ -828,7 +847,8 @@ static void scsi_sequential_lun_scan(str
 	 */
 	for (lun = 1; lun < max_dev_lun; ++lun)
 		if ((scsi_probe_and_add_lun(shost, channel, id, lun,
-		      NULL, NULL) != SCSI_SCAN_LUN_PRESENT) && !sparse_lun)
+		      NULL, NULL, rescan) != SCSI_SCAN_LUN_PRESENT) &&
+		    !sparse_lun)
 			return;
 }
 
@@ -879,7 +899,8 @@ static int scsilun_to_int(struct scsi_lu
  *     0: scan completed (or no memory, so further scanning is futile)
  *     1: no report lun scan, or not configured
  **/
-static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags)
+static int scsi_report_lun_scan(struct scsi_device *sdev, int bflags,
+				int rescan)
 {
 	char devname[64];
 	unsigned char scsi_cmd[MAX_COMMAND_SIZE];
@@ -1033,7 +1054,7 @@ static int scsi_report_lun_scan(struct s
 			int res;
 
 			res = scsi_probe_and_add_lun(sdev->host, sdev->channel,
-				sdev->id, lun, NULL, NULL);
+				sdev->id, lun, NULL, NULL, rescan);
 			if (res == SCSI_SCAN_NO_RESPONSE) {
 				/*
 				 * Got some results, but now none, abort.
@@ -1059,7 +1080,7 @@ static int scsi_report_lun_scan(struct s
 	return 0;
 }
 #else
-# define scsi_report_lun_scan(sdev, blags)	(1)
+# define scsi_report_lun_scan(sdev, blags, rescan)	(1)
 #endif	/* CONFIG_SCSI_REPORT_LUNS */
 
 struct scsi_device *scsi_add_device(struct Scsi_Host *shost,
@@ -1068,7 +1089,11 @@ struct scsi_device *scsi_add_device(stru
 	struct scsi_device *sdev;
 	int res;
 
-	res = scsi_probe_and_add_lun(shost, channel, id, lun, NULL, &sdev);
+	/*
+	 * Caller already checked if sdev exists, but be paranoid and call
+	 * with rescan of 1.
+	 */
+	res = scsi_probe_and_add_lun(shost, channel, id, lun, NULL, &sdev, 1);
 	if (res != SCSI_SCAN_LUN_PRESENT)
 		sdev = ERR_PTR(-ENODEV);
 	return sdev;
@@ -1111,7 +1136,7 @@ void scsi_rescan_device(struct device *d
  *     sequential scan of LUNs on the target id.
  **/
 static void scsi_scan_target(struct Scsi_Host *shost, unsigned int channel,
-			     unsigned int id)
+			     unsigned int id, unsigned int lun, int rescan)
 {
 	int bflags = 0;
 	int res;
@@ -1123,19 +1148,29 @@ static void scsi_scan_target(struct Scsi
 		 */
 		return;
 
+	if (lun != SCAN_WILD_CARD) {
+		/*
+		 * Scan for a specific host/chan/id/lun.
+		 */
+		scsi_probe_and_add_lun(shost, channel, id, lun, NULL, NULL,
+				       rescan);
+		return;
+	}
+
 	/*
 	 * Scan LUN 0, if there is some response, scan further. Ideally, we
 	 * would not configure LUN 0 until all LUNs are scanned.
 	 */
-	res = scsi_probe_and_add_lun(shost, channel, id, 0, &bflags, &sdev);
+	res = scsi_probe_and_add_lun(shost, channel, id, 0, &bflags, &sdev,
+				     rescan);
 	if (res == SCSI_SCAN_LUN_PRESENT) {
-		if (scsi_report_lun_scan(sdev, bflags) != 0)
+		if (scsi_report_lun_scan(sdev, bflags, rescan) != 0)
 			/*
 			 * The REPORT LUN did not scan the target,
 			 * do a sequential scan.
 			 */
 			scsi_sequential_lun_scan(shost, channel, id, bflags,
-				       	res, sdev->scsi_level);
+				       	res, sdev->scsi_level, rescan);
 	} else if (res == SCSI_SCAN_TARGET_PRESENT) {
 		/*
 		 * There's a target here, but lun 0 is offline so we
@@ -1144,37 +1179,26 @@ static void scsi_scan_target(struct Scsi
 		 * a default scsi level of SCSI_2
 		 */
 		scsi_sequential_lun_scan(shost, channel, id, BLIST_SPARSELUN,
-				SCSI_SCAN_TARGET_PRESENT, SCSI_2);
+				SCSI_SCAN_TARGET_PRESENT, SCSI_2, rescan);
 	}
 }
 
-/**
- * scsi_scan_host - scan the given adapter
- * @shost:	adapter to scan
- *
- * Description:
- *     Iterate and call scsi_scan_target to scan all possible target id's
- *     on all possible channels.
- **/
-void scsi_scan_host(struct Scsi_Host *shost)
+static void scsi_scan_channel(struct Scsi_Host *shost, unsigned int channel,
+			      unsigned int id, unsigned int lun, int rescan)
 {
-	uint channel, id, order_id;
+	uint order_id;
 
-	/*
-	 * The sdevscan host, channel, id and lun are filled in as
-	 * needed to scan.
-	 */
-	for (channel = 0; channel <= shost->max_channel; channel++) {
-		/*
-		 * XXX adapter drivers when possible (FCP, iSCSI)
-		 * could modify max_id to match the current max,
-		 * not the absolute max.
-		 *
-		 * XXX add a shost id iterator, so for example,
-		 * the FC ID can be the same as a target id
-		 * without a huge overhead of sparse id's.
-		 */
+	if (id == SCAN_WILD_CARD)
 		for (id = 0; id < shost->max_id; ++id) {
+			/*
+			 * XXX adapter drivers when possible (FCP, iSCSI)
+			 * could modify max_id to match the current max,
+			 * not the absolute max.
+			 *
+			 * XXX add a shost id iterator, so for example,
+			 * the FC ID can be the same as a target id
+			 * without a huge overhead of sparse id's.
+			 */
 			if (shost->reverse_ordering)
 				/*
 				 * Scan from high to low id.
@@ -1182,9 +1206,36 @@ void scsi_scan_host(struct Scsi_Host *sh
 				order_id = shost->max_id - id - 1;
 			else
 				order_id = id;
-			scsi_scan_target(shost, channel, order_id);
+			scsi_scan_target(shost, channel, order_id, lun, rescan);
 		}
-	}
+	else
+		scsi_scan_target(shost, channel, id, lun, rescan);
+}
+
+int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
+			    unsigned int id, unsigned int lun, int rescan)
+{
+	if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) ||
+	    ((id != SCAN_WILD_CARD) && (id > shost->max_id)) ||
+	    ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun)))
+		return -EINVAL;
+
+	if (channel == SCAN_WILD_CARD) 
+		for (channel = 0; channel <= shost->max_channel; channel++)
+			scsi_scan_channel(shost, channel, id, lun, rescan);
+	else
+		scsi_scan_channel(shost, channel, id, lun, rescan);
+	return 0;
+}
+
+/**
+ * scsi_scan_host - scan the given adapter
+ * @shost:	adapter to scan
+ **/
+void scsi_scan_host(struct Scsi_Host *shost)
+{
+	scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD,
+				SCAN_WILD_CARD, 0);
 }
 
 void scsi_forget_host(struct Scsi_Host *shost)
diff -purN -X /home/patman/dontdiff scsi-misc-2.5-pure/drivers/scsi/scsi_sysfs.c scan-del-attr-sm-2.5/drivers/scsi/scsi_sysfs.c
--- scsi-misc-2.5-pure/drivers/scsi/scsi_sysfs.c	Wed Jul  9 09:12:38 2003
+++ scan-del-attr-sm-2.5/drivers/scsi/scsi_sysfs.c	Wed Jul  9 12:04:45 2003
@@ -15,6 +15,85 @@
 #include "hosts.h"
 
 #include "scsi_priv.h"
+#include "scsi_logging.h"
+
+static int check_set(unsigned int *val, char *src, char *wild)
+{
+	char *last;
+
+	if (wild && strncmp(src, wild, 20) == 0) {
+		*val = SCAN_WILD_CARD;
+	} else {
+		/*
+		 * Doesn't check for int overflow
+		 */
+		*val = simple_strtoul(src, &last, 0);
+		if (*last != '\0')
+			return 1;
+	}
+	return 0;
+}
+
+static int scsi_scan(struct Scsi_Host *shost, const char *str)
+{
+	char s1[15], s2[15], s3[15], junk;
+	unsigned int channel, id, lun;
+	int res;
+
+	res = sscanf(str, "%10s %10s %10s %c", s1, s2, s3, &junk);
+	if (res != 3)
+		return -EINVAL;
+	if (check_set(&channel, s1, "-"))
+		return -EINVAL;
+	if (check_set(&id, s2, "-"))
+		return -EINVAL;
+	if (check_set(&lun, s3, "-"))
+		return -EINVAL;
+
+	SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "%s: <%u:%u:%u:%u>\n",
+		__FUNCTION__, shost->host_no, channel, id, lun));
+	res = scsi_scan_host_selected(shost, channel, id, lun, 1);
+	return res;
+}
+
+static int scsi_remove(struct Scsi_Host *shost, const char *str)
+{
+	struct scsi_device *sdev;
+	char s1[15], s2[15], s3[15], junk;
+	unsigned int channel, id, lun;
+	int res;
+
+	res = sscanf(str, "%10s %10s %10s %c", s1, s2, s3, &junk);
+	if (res != 3)
+		return -EINVAL;
+	if (check_set(&channel, s1, NULL))
+		return -EINVAL;
+	if (check_set(&id, s2, NULL))
+		return -EINVAL;
+	if (check_set(&lun, s3, NULL))
+		return -EINVAL;
+
+	SCSI_LOG_SCAN_BUS(3, printk (KERN_INFO "%s: <%u:%u:%u:%u>\n",
+		__FUNCTION__, shost->host_no, channel, id, lun));
+	sdev = scsi_find_device(shost, channel, id, lun);
+	if (!sdev) {
+		res = -ENODEV;
+		goto out;
+	}
+
+	if (sdev->access_count) {
+		/*
+		 * FIXME andmike patch
+		 */
+		res = -EBUSY;
+		goto out;
+	}
+
+	res = 0;
+	scsi_remove_device(sdev);
+out:
+	return res;
+}
 
 /*
  * shost_show_function: macro to create an attr function that can be used to
@@ -39,6 +118,33 @@ static CLASS_DEVICE_ATTR(field, S_IRUGO,
 /*
  * Create the actual show/store functions and data structures.
  */
+
+static ssize_t store_scan(struct class_device *class_dev, const char *buf,
+			  size_t count)
+{
+	struct Scsi_Host *shost = class_to_shost(class_dev);
+	int res;
+
+	res = scsi_scan(shost, buf);
+	if (res == 0)
+		res = count;
+	return res;
+};
+static CLASS_DEVICE_ATTR(scan, S_IWUSR, NULL, store_scan);
+
+static ssize_t store_delete(struct class_device *class_dev, const char *buf,
+			    size_t count)
+{
+	struct Scsi_Host *shost = class_to_shost(class_dev);
+	int res;
+
+	res = scsi_remove(shost, buf);
+	if (res == 0)
+		res = count;
+	return res;
+};
+static CLASS_DEVICE_ATTR(delete, S_IWUSR, NULL, store_delete);
+
 shost_rd_attr(unique_id, "%u\n");
 shost_rd_attr(host_busy, "%hu\n");
 shost_rd_attr(cmd_per_lun, "%hd\n");
@@ -51,6 +157,8 @@ static struct class_device_attribute *sc
 	&class_device_attr_cmd_per_lun,
 	&class_device_attr_sg_tablesize,
 	&class_device_attr_unchecked_isa_dma,
+	&class_device_attr_scan,
+	&class_device_attr_delete,
 	NULL
 };
 
@@ -73,7 +181,6 @@ struct bus_type scsi_bus_type = {
         .match		= scsi_bus_match,
 };
 
-
 int scsi_sysfs_register(void)
 {
 	int error;

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

* and some example usage of the attributes
  2003-07-09 20:27 ` [PATCH] take 2 " Patrick Mansfield
@ 2003-07-09 20:29   ` Patrick Mansfield
  0 siblings, 0 replies; 10+ messages in thread
From: Patrick Mansfield @ 2003-07-09 20:29 UTC (permalink / raw)
  To: linux-scsi, James Bottomley

Some example uses of the delete and scan attribute.

[root@elm3b79 root]# ls -l /sysfs/class/scsi_host/host2
total 0
-r--r--r--    1 root     root         4096 Jul  9 12:30 cmd_per_lun
--w-------    1 root     root            0 Jul  9 12:34 delete
lrwxrwxrwx    1 root     root           46 Jul  9 12:30 device -> ../../../devices/pci0000:01/0000:01:0c.0/host2
-r--r--r--    1 root     root         4096 Jul  9 12:30 host_busy
--w-------    1 root     root            0 Jul  9 12:36 scan
-r--r--r--    1 root     root         4096 Jul  9 12:30 sg_tablesize
-r--r--r--    1 root     root         4096 Jul  9 12:30 unchecked_isa_dma
-r--r--r--    1 root     root         4096 Jul  9 12:30 unique_id

[root@elm3b79 root]# ls /sysfs/class/scsi_host/host2/device
2:0:0:0   2:0:0:14  2:0:0:2   2:0:0:25  2:0:0:30  2:0:0:8   2:0:4:0  name
2:0:0:1   2:0:0:15  2:0:0:20  2:0:0:26  2:0:0:31  2:0:0:9   2:0:5:0  power
2:0:0:10  2:0:0:16  2:0:0:21  2:0:0:27  2:0:0:4   2:0:1:0   2:0:6:0
2:0:0:11  2:0:0:17  2:0:0:22  2:0:0:28  2:0:0:5   2:0:10:0  2:0:7:0
2:0:0:12  2:0:0:18  2:0:0:23  2:0:0:29  2:0:0:6   2:0:2:0   2:0:8:0
2:0:0:13  2:0:0:19  2:0:0:24  2:0:0:3   2:0:0:7   2:0:3:0   2:0:9:0

# Delete some devices

[root@elm3b79 root]# echo "0 9 0" > /root/xx; dd if=/root/xx of=/sysfs/class/scsi_host/host2/delete 
0+1 records in
0+1 records out
[root@elm3b79 root]# echo "0 0 0" > /root/xx; dd if=/root/xx of=/sysfs/class/scsi_host/host2/delete 
0+1 records in
0+1 records out
[root@elm3b79 root]# echo "0 0 22" > /root/xx; dd if=/root/xx of=/sysfs/class/scsi_host/host2/delete 
0+1 records in
0+1 records out

# Scan a target - for this target REPORT LUN is used

[root@elm3b79 root]# echo "0 0 -" > /root/xx; dd if=/root/xx of=/sysfs/class/scsi_host/host2/scan
0+1 records in
0+1 records out

# Scan the entire host

[root@elm3b79 root]# echo "- - -" > /root/xx; dd if=/root/xx of=/sysfs/class/scsi_host/host2/scan
0+1 records in
0+1 records out

-- Patrick Mansfield

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

* Re: [PATCH] add sysfs attributes to scan and delete scsi_devices
  2003-07-08 22:24     ` Patrick Mansfield
@ 2003-07-13 13:43       ` Christoph Hellwig
  0 siblings, 0 replies; 10+ messages in thread
From: Christoph Hellwig @ 2003-07-13 13:43 UTC (permalink / raw)
  To: Patrick Mansfield; +Cc: James Bottomley, SCSI Mailing List

On Tue, Jul 08, 2003 at 03:24:40PM -0700, Patrick Mansfield wrote:
> Scanning makes more sense as a host attribute (or as a target attribute,
> but we don't have a target device today).

So we should have a scan host attribute for that.

> Deletion of a scsi_device makes
> more sense as a /sysfs/bus/scsi (or even scsi_device) attribute that takes
> a bus_id. 

I don't think it makes sense as a /sysfs/bus/scsi attribute.  Having
it as a scsi_device attribute makes lots of sense, I just wonder whether
the non-symmetric interface would confuse users.  Probably not too much
as scannaing a bus an deleting a device isn't really a symmetric interface
anyway.`


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

end of thread, other threads:[~2003-07-13 13:28 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-07-08 20:40 [PATCH] add sysfs attributes to scan and delete scsi_devices Patrick Mansfield
2003-07-08 20:41 ` examples using " Patrick Mansfield
2003-07-08 20:47 ` [PATCH] add " Christoph Hellwig
2003-07-08 22:36   ` Patrick Mansfield
2003-07-08 20:50 ` James Bottomley
2003-07-08 21:13   ` Christoph Hellwig
2003-07-08 22:24     ` Patrick Mansfield
2003-07-13 13:43       ` Christoph Hellwig
2003-07-09 20:27 ` [PATCH] take 2 " Patrick Mansfield
2003-07-09 20:29   ` and some example usage of the attributes Patrick Mansfield

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