aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/kernel-parameters.txt5
-rw-r--r--drivers/scsi/Makefile2
-rw-r--r--drivers/scsi/scsi_priv.h3
-rw-r--r--drivers/scsi/scsi_scan.c203
-rw-r--r--drivers/scsi/scsi_wait_scan.c31
-rw-r--r--include/scsi/scsi_device.h30
-rw-r--r--include/scsi/scsi_host.h3
7 files changed, 256 insertions, 21 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index ff571f9298e0..5a92ac085969 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1410,6 +1410,11 @@ and is between 256 and 4096 characters. It is defined in the file
1410 1410
1411 scsi_logging= [SCSI] 1411 scsi_logging= [SCSI]
1412 1412
1413 scsi_mod.scan= [SCSI] sync (default) scans SCSI busses as they are
1414 discovered. async scans them in kernel threads,
1415 allowing boot to proceed. none ignores them, expecting
1416 user space to do the scan.
1417
1413 selinux [SELINUX] Disable or enable SELinux at boot time. 1418 selinux [SELINUX] Disable or enable SELinux at boot time.
1414 Format: { "0" | "1" } 1419 Format: { "0" | "1" }
1415 See security/selinux/Kconfig help text. 1420 See security/selinux/Kconfig help text.
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile
index bcca39c3bcbf..a0a77fde3708 100644
--- a/drivers/scsi/Makefile
+++ b/drivers/scsi/Makefile
@@ -141,6 +141,8 @@ obj-$(CONFIG_CHR_DEV_SCH) += ch.o
141# This goes last, so that "real" scsi devices probe earlier 141# This goes last, so that "real" scsi devices probe earlier
142obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o 142obj-$(CONFIG_SCSI_DEBUG) += scsi_debug.o
143 143
144obj-$(CONFIG_SCSI) += scsi_wait_scan.o
145
144scsi_mod-y += scsi.o hosts.o scsi_ioctl.o constants.o \ 146scsi_mod-y += scsi.o hosts.o scsi_ioctl.o constants.o \
145 scsicam.o scsi_error.o scsi_lib.o \ 147 scsicam.o scsi_error.o scsi_lib.o \
146 scsi_scan.o scsi_sysfs.o \ 148 scsi_scan.o scsi_sysfs.o \
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
index 5d023d44e5e7..f458c2f686d2 100644
--- a/drivers/scsi/scsi_priv.h
+++ b/drivers/scsi/scsi_priv.h
@@ -39,6 +39,9 @@ static inline void scsi_log_completion(struct scsi_cmnd *cmd, int disposition)
39 { }; 39 { };
40#endif 40#endif
41 41
42/* scsi_scan.c */
43int scsi_complete_async_scans(void);
44
42/* scsi_devinfo.c */ 45/* scsi_devinfo.c */
43extern int scsi_get_device_flags(struct scsi_device *sdev, 46extern int scsi_get_device_flags(struct scsi_device *sdev,
44 const unsigned char *vendor, 47 const unsigned char *vendor,
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index fd9e281c3bfe..148e24cc3222 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -29,7 +29,9 @@
29#include <linux/moduleparam.h> 29#include <linux/moduleparam.h>
30#include <linux/init.h> 30#include <linux/init.h>
31#include <linux/blkdev.h> 31#include <linux/blkdev.h>
32#include <asm/semaphore.h> 32#include <linux/delay.h>
33#include <linux/kthread.h>
34#include <linux/spinlock.h>
33 35
34#include <scsi/scsi.h> 36#include <scsi/scsi.h>
35#include <scsi/scsi_cmnd.h> 37#include <scsi/scsi_cmnd.h>
@@ -87,6 +89,11 @@ module_param_named(max_luns, max_scsi_luns, int, S_IRUGO|S_IWUSR);
87MODULE_PARM_DESC(max_luns, 89MODULE_PARM_DESC(max_luns,
88 "last scsi LUN (should be between 1 and 2^32-1)"); 90 "last scsi LUN (should be between 1 and 2^32-1)");
89 91
92static char scsi_scan_type[6] = "sync";
93
94module_param_string(scan, scsi_scan_type, sizeof(scsi_scan_type), S_IRUGO);
95MODULE_PARM_DESC(scan, "sync, async or none");
96
90/* 97/*
91 * max_scsi_report_luns: the maximum number of LUNS that will be 98 * max_scsi_report_luns: the maximum number of LUNS that will be
92 * returned from the REPORT LUNS command. 8 times this value must 99 * returned from the REPORT LUNS command. 8 times this value must
@@ -108,6 +115,68 @@ MODULE_PARM_DESC(inq_timeout,
108 "Timeout (in seconds) waiting for devices to answer INQUIRY." 115 "Timeout (in seconds) waiting for devices to answer INQUIRY."
109 " Default is 5. Some non-compliant devices need more."); 116 " Default is 5. Some non-compliant devices need more.");
110 117
118static DEFINE_SPINLOCK(async_scan_lock);
119static LIST_HEAD(scanning_hosts);
120
121struct async_scan_data {
122 struct list_head list;
123 struct Scsi_Host *shost;
124 struct completion prev_finished;
125};
126
127/**
128 * scsi_complete_async_scans - Wait for asynchronous scans to complete
129 *
130 * Asynchronous scans add themselves to the scanning_hosts list. Once
131 * that list is empty, we know that the scans are complete. Rather than
132 * waking up periodically to check the state of the list, we pretend to be
133 * a scanning task by adding ourselves at the end of the list and going to
134 * sleep. When the task before us wakes us up, we take ourselves off the
135 * list and return.
136 */
137int scsi_complete_async_scans(void)
138{
139 struct async_scan_data *data;
140
141 do {
142 if (list_empty(&scanning_hosts))
143 return 0;
144 /* If we can't get memory immediately, that's OK. Just
145 * sleep a little. Even if we never get memory, the async
146 * scans will finish eventually.
147 */
148 data = kmalloc(sizeof(*data), GFP_KERNEL);
149 if (!data)
150 msleep(1);
151 } while (!data);
152
153 data->shost = NULL;
154 init_completion(&data->prev_finished);
155
156 spin_lock(&async_scan_lock);
157 /* Check that there's still somebody else on the list */
158 if (list_empty(&scanning_hosts))
159 goto done;
160 list_add_tail(&data->list, &scanning_hosts);
161 spin_unlock(&async_scan_lock);
162
163 printk(KERN_INFO "scsi: waiting for bus probes to complete ...\n");
164 wait_for_completion(&data->prev_finished);
165
166 spin_lock(&async_scan_lock);
167 list_del(&data->list);
168 done:
169 spin_unlock(&async_scan_lock);
170
171 kfree(data);
172 return 0;
173}
174
175#ifdef MODULE
176/* Only exported for the benefit of scsi_wait_scan */
177EXPORT_SYMBOL_GPL(scsi_complete_async_scans);
178#endif
179
111/** 180/**
112 * scsi_unlock_floptical - unlock device via a special MODE SENSE command 181 * scsi_unlock_floptical - unlock device via a special MODE SENSE command
113 * @sdev: scsi device to send command to 182 * @sdev: scsi device to send command to
@@ -619,7 +688,7 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result,
619 * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized 688 * SCSI_SCAN_LUN_PRESENT: a new scsi_device was allocated and initialized
620 **/ 689 **/
621static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, 690static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
622 int *bflags) 691 int *bflags, int async)
623{ 692{
624 /* 693 /*
625 * XXX do not save the inquiry, since it can change underneath us, 694 * XXX do not save the inquiry, since it can change underneath us,
@@ -795,7 +864,7 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
795 * register it and tell the rest of the kernel 864 * register it and tell the rest of the kernel
796 * about it. 865 * about it.
797 */ 866 */
798 if (scsi_sysfs_add_sdev(sdev) != 0) 867 if (!async && scsi_sysfs_add_sdev(sdev) != 0)
799 return SCSI_SCAN_NO_RESPONSE; 868 return SCSI_SCAN_NO_RESPONSE;
800 869
801 return SCSI_SCAN_LUN_PRESENT; 870 return SCSI_SCAN_LUN_PRESENT;
@@ -964,7 +1033,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
964 goto out_free_result; 1033 goto out_free_result;
965 } 1034 }
966 1035
967 res = scsi_add_lun(sdev, result, &bflags); 1036 res = scsi_add_lun(sdev, result, &bflags, shost->async_scan);
968 if (res == SCSI_SCAN_LUN_PRESENT) { 1037 if (res == SCSI_SCAN_LUN_PRESENT) {
969 if (bflags & BLIST_KEY) { 1038 if (bflags & BLIST_KEY) {
970 sdev->lockable = 0; 1039 sdev->lockable = 0;
@@ -1464,6 +1533,9 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
1464{ 1533{
1465 struct Scsi_Host *shost = dev_to_shost(parent); 1534 struct Scsi_Host *shost = dev_to_shost(parent);
1466 1535
1536 if (!shost->async_scan)
1537 scsi_complete_async_scans();
1538
1467 mutex_lock(&shost->scan_mutex); 1539 mutex_lock(&shost->scan_mutex);
1468 if (scsi_host_scan_allowed(shost)) 1540 if (scsi_host_scan_allowed(shost))
1469 __scsi_scan_target(parent, channel, id, lun, rescan); 1541 __scsi_scan_target(parent, channel, id, lun, rescan);
@@ -1509,6 +1581,9 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
1509 "%s: <%u:%u:%u>\n", 1581 "%s: <%u:%u:%u>\n",
1510 __FUNCTION__, channel, id, lun)); 1582 __FUNCTION__, channel, id, lun));
1511 1583
1584 if (!shost->async_scan)
1585 scsi_complete_async_scans();
1586
1512 if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) || 1587 if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) ||
1513 ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) || 1588 ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) ||
1514 ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun))) 1589 ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun)))
@@ -1529,14 +1604,130 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
1529 return 0; 1604 return 0;
1530} 1605}
1531 1606
1607static void scsi_sysfs_add_devices(struct Scsi_Host *shost)
1608{
1609 struct scsi_device *sdev;
1610 shost_for_each_device(sdev, shost) {
1611 if (scsi_sysfs_add_sdev(sdev) != 0)
1612 scsi_destroy_sdev(sdev);
1613 }
1614}
1615
1616/**
1617 * scsi_prep_async_scan - prepare for an async scan
1618 * @shost: the host which will be scanned
1619 * Returns: a cookie to be passed to scsi_finish_async_scan()
1620 *
1621 * Tells the midlayer this host is going to do an asynchronous scan.
1622 * It reserves the host's position in the scanning list and ensures
1623 * that other asynchronous scans started after this one won't affect the
1624 * ordering of the discovered devices.
1625 */
1626struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)
1627{
1628 struct async_scan_data *data;
1629
1630 if (strncmp(scsi_scan_type, "sync", 4) == 0)
1631 return NULL;
1632
1633 if (shost->async_scan) {
1634 printk("%s called twice for host %d", __FUNCTION__,
1635 shost->host_no);
1636 dump_stack();
1637 return NULL;
1638 }
1639
1640 data = kmalloc(sizeof(*data), GFP_KERNEL);
1641 if (!data)
1642 goto err;
1643 data->shost = scsi_host_get(shost);
1644 if (!data->shost)
1645 goto err;
1646 init_completion(&data->prev_finished);
1647
1648 spin_lock(&async_scan_lock);
1649 shost->async_scan = 1;
1650 if (list_empty(&scanning_hosts))
1651 complete(&data->prev_finished);
1652 list_add_tail(&data->list, &scanning_hosts);
1653 spin_unlock(&async_scan_lock);
1654
1655 return data;
1656
1657 err:
1658 kfree(data);
1659 return NULL;
1660}
1661
1662/**
1663 * scsi_finish_async_scan - asynchronous scan has finished
1664 * @data: cookie returned from earlier call to scsi_prep_async_scan()
1665 *
1666 * All the devices currently attached to this host have been found.
1667 * This function announces all the devices it has found to the rest
1668 * of the system.
1669 */
1670void scsi_finish_async_scan(struct async_scan_data *data)
1671{
1672 struct Scsi_Host *shost;
1673
1674 if (!data)
1675 return;
1676
1677 shost = data->shost;
1678 if (!shost->async_scan) {
1679 printk("%s called twice for host %d", __FUNCTION__,
1680 shost->host_no);
1681 dump_stack();
1682 return;
1683 }
1684
1685 wait_for_completion(&data->prev_finished);
1686
1687 scsi_sysfs_add_devices(shost);
1688
1689 spin_lock(&async_scan_lock);
1690 shost->async_scan = 0;
1691 list_del(&data->list);
1692 if (!list_empty(&scanning_hosts)) {
1693 struct async_scan_data *next = list_entry(scanning_hosts.next,
1694 struct async_scan_data, list);
1695 complete(&next->prev_finished);
1696 }
1697 spin_unlock(&async_scan_lock);
1698
1699 scsi_host_put(shost);
1700 kfree(data);
1701}
1702
1703static int do_scan_async(void *_data)
1704{
1705 struct async_scan_data *data = _data;
1706 scsi_scan_host_selected(data->shost, SCAN_WILD_CARD, SCAN_WILD_CARD,
1707 SCAN_WILD_CARD, 0);
1708
1709 scsi_finish_async_scan(data);
1710 return 0;
1711}
1712
1532/** 1713/**
1533 * scsi_scan_host - scan the given adapter 1714 * scsi_scan_host - scan the given adapter
1534 * @shost: adapter to scan 1715 * @shost: adapter to scan
1535 **/ 1716 **/
1536void scsi_scan_host(struct Scsi_Host *shost) 1717void scsi_scan_host(struct Scsi_Host *shost)
1537{ 1718{
1538 scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD, 1719 struct async_scan_data *data;
1539 SCAN_WILD_CARD, 0); 1720
1721 if (strncmp(scsi_scan_type, "none", 4) == 0)
1722 return;
1723
1724 data = scsi_prep_async_scan(shost);
1725 if (!data) {
1726 scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD,
1727 SCAN_WILD_CARD, 0);
1728 return;
1729 }
1730 kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no);
1540} 1731}
1541EXPORT_SYMBOL(scsi_scan_host); 1732EXPORT_SYMBOL(scsi_scan_host);
1542 1733
diff --git a/drivers/scsi/scsi_wait_scan.c b/drivers/scsi/scsi_wait_scan.c
new file mode 100644
index 000000000000..8a636103083d
--- /dev/null
+++ b/drivers/scsi/scsi_wait_scan.c
@@ -0,0 +1,31 @@
1/*
2 * scsi_wait_scan.c
3 *
4 * Copyright (C) 2006 James Bottomley <James.Bottomley@SteelEye.com>
5 *
6 * This is a simple module to wait until all the async scans are
7 * complete. The idea is to use it in initrd/initramfs scripts. You
8 * modprobe it after all the modprobes of the root SCSI drivers and it
9 * will wait until they have all finished scanning their busses before
10 * allowing the boot to proceed
11 */
12
13#include <linux/module.h>
14#include "scsi_priv.h"
15
16static int __init wait_scan_init(void)
17{
18 scsi_complete_async_scans();
19 return 0;
20}
21
22static void __exit wait_scan_exit(void)
23{
24}
25
26MODULE_DESCRIPTION("SCSI wait for scans");
27MODULE_AUTHOR("James Bottomley");
28MODULE_LICENSE("GPL");
29
30late_initcall(wait_scan_init);
31module_exit(wait_scan_exit);
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index b401c82036be..ebf31b16dc49 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -223,13 +223,13 @@ extern struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *,
223 struct scsi_device *); 223 struct scsi_device *);
224 224
225/** 225/**
226 * shost_for_each_device - iterate over all devices of a host 226 * shost_for_each_device - iterate over all devices of a host
227 * @sdev: iterator 227 * @sdev: the &struct scsi_device to use as a cursor
228 * @host: host whiches devices we want to iterate over 228 * @shost: the &struct scsi_host to iterate over
229 * 229 *
230 * This traverses over each devices of @shost. The devices have 230 * Iterator that returns each device attached to @shost. This loop
231 * a reference that must be released by scsi_host_put when breaking 231 * takes a reference on each device and releases it at the end. If
232 * out of the loop. 232 * you break out of the loop, you must call scsi_device_put(sdev).
233 */ 233 */
234#define shost_for_each_device(sdev, shost) \ 234#define shost_for_each_device(sdev, shost) \
235 for ((sdev) = __scsi_iterate_devices((shost), NULL); \ 235 for ((sdev) = __scsi_iterate_devices((shost), NULL); \
@@ -237,17 +237,17 @@ extern struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *,
237 (sdev) = __scsi_iterate_devices((shost), (sdev))) 237 (sdev) = __scsi_iterate_devices((shost), (sdev)))
238 238
239/** 239/**
240 * __shost_for_each_device - iterate over all devices of a host (UNLOCKED) 240 * __shost_for_each_device - iterate over all devices of a host (UNLOCKED)
241 * @sdev: iterator 241 * @sdev: the &struct scsi_device to use as a cursor
242 * @host: host whiches devices we want to iterate over 242 * @shost: the &struct scsi_host to iterate over
243 * 243 *
244 * This traverses over each devices of @shost. It does _not_ take a 244 * Iterator that returns each device attached to @shost. It does _not_
245 * reference on the scsi_device, thus it the whole loop must be protected 245 * take a reference on the scsi_device, so the whole loop must be
246 * by shost->host_lock. 246 * protected by shost->host_lock.
247 * 247 *
248 * Note: The only reason why drivers would want to use this is because 248 * Note: The only reason to use this is because you need to access the
249 * they're need to access the device list in irq context. Otherwise you 249 * device list in interrupt context. Otherwise you really want to use
250 * really want to use shost_for_each_device instead. 250 * shost_for_each_device instead.
251 */ 251 */
252#define __shost_for_each_device(sdev, shost) \ 252#define __shost_for_each_device(sdev, shost) \
253 list_for_each_entry((sdev), &((shost)->__devices), siblings) 253 list_for_each_entry((sdev), &((shost)->__devices), siblings)
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 39c6f8cc20c3..ba5b3eb6b43f 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -552,6 +552,9 @@ struct Scsi_Host {
552 /* task mgmt function in progress */ 552 /* task mgmt function in progress */
553 unsigned tmf_in_progress:1; 553 unsigned tmf_in_progress:1;
554 554
555 /* Asynchronous scan in progress */
556 unsigned async_scan:1;
557
555 /* 558 /*
556 * Optional work queue to be utilized by the transport 559 * Optional work queue to be utilized by the transport
557 */ 560 */