aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/scsi_scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/scsi_scan.c')
-rw-r--r--drivers/scsi/scsi_scan.c203
1 files changed, 197 insertions, 6 deletions
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 94a274645f6f..aa1b1e0e9d22 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,
@@ -805,7 +874,7 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
805 * register it and tell the rest of the kernel 874 * register it and tell the rest of the kernel
806 * about it. 875 * about it.
807 */ 876 */
808 if (scsi_sysfs_add_sdev(sdev) != 0) 877 if (!async && scsi_sysfs_add_sdev(sdev) != 0)
809 return SCSI_SCAN_NO_RESPONSE; 878 return SCSI_SCAN_NO_RESPONSE;
810 879
811 return SCSI_SCAN_LUN_PRESENT; 880 return SCSI_SCAN_LUN_PRESENT;
@@ -974,7 +1043,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
974 goto out_free_result; 1043 goto out_free_result;
975 } 1044 }
976 1045
977 res = scsi_add_lun(sdev, result, &bflags); 1046 res = scsi_add_lun(sdev, result, &bflags, shost->async_scan);
978 if (res == SCSI_SCAN_LUN_PRESENT) { 1047 if (res == SCSI_SCAN_LUN_PRESENT) {
979 if (bflags & BLIST_KEY) { 1048 if (bflags & BLIST_KEY) {
980 sdev->lockable = 0; 1049 sdev->lockable = 0;
@@ -1474,6 +1543,9 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
1474{ 1543{
1475 struct Scsi_Host *shost = dev_to_shost(parent); 1544 struct Scsi_Host *shost = dev_to_shost(parent);
1476 1545
1546 if (!shost->async_scan)
1547 scsi_complete_async_scans();
1548
1477 mutex_lock(&shost->scan_mutex); 1549 mutex_lock(&shost->scan_mutex);
1478 if (scsi_host_scan_allowed(shost)) 1550 if (scsi_host_scan_allowed(shost))
1479 __scsi_scan_target(parent, channel, id, lun, rescan); 1551 __scsi_scan_target(parent, channel, id, lun, rescan);
@@ -1519,6 +1591,9 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
1519 "%s: <%u:%u:%u>\n", 1591 "%s: <%u:%u:%u>\n",
1520 __FUNCTION__, channel, id, lun)); 1592 __FUNCTION__, channel, id, lun));
1521 1593
1594 if (!shost->async_scan)
1595 scsi_complete_async_scans();
1596
1522 if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) || 1597 if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) ||
1523 ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) || 1598 ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) ||
1524 ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun))) 1599 ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun)))
@@ -1539,14 +1614,130 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
1539 return 0; 1614 return 0;
1540} 1615}
1541 1616
1617static void scsi_sysfs_add_devices(struct Scsi_Host *shost)
1618{
1619 struct scsi_device *sdev;
1620 shost_for_each_device(sdev, shost) {
1621 if (scsi_sysfs_add_sdev(sdev) != 0)
1622 scsi_destroy_sdev(sdev);
1623 }
1624}
1625
1626/**
1627 * scsi_prep_async_scan - prepare for an async scan
1628 * @shost: the host which will be scanned
1629 * Returns: a cookie to be passed to scsi_finish_async_scan()
1630 *
1631 * Tells the midlayer this host is going to do an asynchronous scan.
1632 * It reserves the host's position in the scanning list and ensures
1633 * that other asynchronous scans started after this one won't affect the
1634 * ordering of the discovered devices.
1635 */
1636struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)
1637{
1638 struct async_scan_data *data;
1639
1640 if (strncmp(scsi_scan_type, "sync", 4) == 0)
1641 return NULL;
1642
1643 if (shost->async_scan) {
1644 printk("%s called twice for host %d", __FUNCTION__,
1645 shost->host_no);
1646 dump_stack();
1647 return NULL;
1648 }
1649
1650 data = kmalloc(sizeof(*data), GFP_KERNEL);
1651 if (!data)
1652 goto err;
1653 data->shost = scsi_host_get(shost);
1654 if (!data->shost)
1655 goto err;
1656 init_completion(&data->prev_finished);
1657
1658 spin_lock(&async_scan_lock);
1659 shost->async_scan = 1;
1660 if (list_empty(&scanning_hosts))
1661 complete(&data->prev_finished);
1662 list_add_tail(&data->list, &scanning_hosts);
1663 spin_unlock(&async_scan_lock);
1664
1665 return data;
1666
1667 err:
1668 kfree(data);
1669 return NULL;
1670}
1671
1672/**
1673 * scsi_finish_async_scan - asynchronous scan has finished
1674 * @data: cookie returned from earlier call to scsi_prep_async_scan()
1675 *
1676 * All the devices currently attached to this host have been found.
1677 * This function announces all the devices it has found to the rest
1678 * of the system.
1679 */
1680void scsi_finish_async_scan(struct async_scan_data *data)
1681{
1682 struct Scsi_Host *shost;
1683
1684 if (!data)
1685 return;
1686
1687 shost = data->shost;
1688 if (!shost->async_scan) {
1689 printk("%s called twice for host %d", __FUNCTION__,
1690 shost->host_no);
1691 dump_stack();
1692 return;
1693 }
1694
1695 wait_for_completion(&data->prev_finished);
1696
1697 scsi_sysfs_add_devices(shost);
1698
1699 spin_lock(&async_scan_lock);
1700 shost->async_scan = 0;
1701 list_del(&data->list);
1702 if (!list_empty(&scanning_hosts)) {
1703 struct async_scan_data *next = list_entry(scanning_hosts.next,
1704 struct async_scan_data, list);
1705 complete(&next->prev_finished);
1706 }
1707 spin_unlock(&async_scan_lock);
1708
1709 scsi_host_put(shost);
1710 kfree(data);
1711}
1712
1713static int do_scan_async(void *_data)
1714{
1715 struct async_scan_data *data = _data;
1716 scsi_scan_host_selected(data->shost, SCAN_WILD_CARD, SCAN_WILD_CARD,
1717 SCAN_WILD_CARD, 0);
1718
1719 scsi_finish_async_scan(data);
1720 return 0;
1721}
1722
1542/** 1723/**
1543 * scsi_scan_host - scan the given adapter 1724 * scsi_scan_host - scan the given adapter
1544 * @shost: adapter to scan 1725 * @shost: adapter to scan
1545 **/ 1726 **/
1546void scsi_scan_host(struct Scsi_Host *shost) 1727void scsi_scan_host(struct Scsi_Host *shost)
1547{ 1728{
1548 scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD, 1729 struct async_scan_data *data;
1549 SCAN_WILD_CARD, 0); 1730
1731 if (strncmp(scsi_scan_type, "none", 4) == 0)
1732 return;
1733
1734 data = scsi_prep_async_scan(shost);
1735 if (!data) {
1736 scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD,
1737 SCAN_WILD_CARD, 0);
1738 return;
1739 }
1740 kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no);
1550} 1741}
1551EXPORT_SYMBOL(scsi_scan_host); 1742EXPORT_SYMBOL(scsi_scan_host);
1552 1743