All of lore.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 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.