aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/scsi_scan.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index a86e62f4b3ba..309b2246d2d3 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -121,6 +121,7 @@ MODULE_PARM_DESC(inq_timeout,
121 "Timeout (in seconds) waiting for devices to answer INQUIRY." 121 "Timeout (in seconds) waiting for devices to answer INQUIRY."
122 " Default is 5. Some non-compliant devices need more."); 122 " Default is 5. Some non-compliant devices need more.");
123 123
124/* This lock protects only this list */
124static DEFINE_SPINLOCK(async_scan_lock); 125static DEFINE_SPINLOCK(async_scan_lock);
125static LIST_HEAD(scanning_hosts); 126static LIST_HEAD(scanning_hosts);
126 127
@@ -1466,14 +1467,14 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
1466 if (strncmp(scsi_scan_type, "none", 4) == 0) 1467 if (strncmp(scsi_scan_type, "none", 4) == 0)
1467 return ERR_PTR(-ENODEV); 1468 return ERR_PTR(-ENODEV);
1468 1469
1469 if (!shost->async_scan)
1470 scsi_complete_async_scans();
1471
1472 starget = scsi_alloc_target(parent, channel, id); 1470 starget = scsi_alloc_target(parent, channel, id);
1473 if (!starget) 1471 if (!starget)
1474 return ERR_PTR(-ENOMEM); 1472 return ERR_PTR(-ENOMEM);
1475 1473
1476 mutex_lock(&shost->scan_mutex); 1474 mutex_lock(&shost->scan_mutex);
1475 if (!shost->async_scan)
1476 scsi_complete_async_scans();
1477
1477 if (scsi_host_scan_allowed(shost)) 1478 if (scsi_host_scan_allowed(shost))
1478 scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata); 1479 scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata);
1479 mutex_unlock(&shost->scan_mutex); 1480 mutex_unlock(&shost->scan_mutex);
@@ -1586,10 +1587,10 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
1586 if (strncmp(scsi_scan_type, "none", 4) == 0) 1587 if (strncmp(scsi_scan_type, "none", 4) == 0)
1587 return; 1588 return;
1588 1589
1590 mutex_lock(&shost->scan_mutex);
1589 if (!shost->async_scan) 1591 if (!shost->async_scan)
1590 scsi_complete_async_scans(); 1592 scsi_complete_async_scans();
1591 1593
1592 mutex_lock(&shost->scan_mutex);
1593 if (scsi_host_scan_allowed(shost)) 1594 if (scsi_host_scan_allowed(shost))
1594 __scsi_scan_target(parent, channel, id, lun, rescan); 1595 __scsi_scan_target(parent, channel, id, lun, rescan);
1595 mutex_unlock(&shost->scan_mutex); 1596 mutex_unlock(&shost->scan_mutex);
@@ -1634,15 +1635,15 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
1634 "%s: <%u:%u:%u>\n", 1635 "%s: <%u:%u:%u>\n",
1635 __FUNCTION__, channel, id, lun)); 1636 __FUNCTION__, channel, id, lun));
1636 1637
1637 if (!shost->async_scan)
1638 scsi_complete_async_scans();
1639
1640 if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) || 1638 if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) ||
1641 ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) || 1639 ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) ||
1642 ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun))) 1640 ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun)))
1643 return -EINVAL; 1641 return -EINVAL;
1644 1642
1645 mutex_lock(&shost->scan_mutex); 1643 mutex_lock(&shost->scan_mutex);
1644 if (!shost->async_scan)
1645 scsi_complete_async_scans();
1646
1646 if (scsi_host_scan_allowed(shost)) { 1647 if (scsi_host_scan_allowed(shost)) {
1647 if (channel == SCAN_WILD_CARD) 1648 if (channel == SCAN_WILD_CARD)
1648 for (channel = 0; channel <= shost->max_channel; 1649 for (channel = 0; channel <= shost->max_channel;
@@ -1661,7 +1662,8 @@ static void scsi_sysfs_add_devices(struct Scsi_Host *shost)
1661{ 1662{
1662 struct scsi_device *sdev; 1663 struct scsi_device *sdev;
1663 shost_for_each_device(sdev, shost) { 1664 shost_for_each_device(sdev, shost) {
1664 if (scsi_sysfs_add_sdev(sdev) != 0) 1665 if (!scsi_host_scan_allowed(shost) ||
1666 scsi_sysfs_add_sdev(sdev) != 0)
1665 scsi_destroy_sdev(sdev); 1667 scsi_destroy_sdev(sdev);
1666 } 1668 }
1667} 1669}
@@ -1679,6 +1681,7 @@ static void scsi_sysfs_add_devices(struct Scsi_Host *shost)
1679static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost) 1681static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)
1680{ 1682{
1681 struct async_scan_data *data; 1683 struct async_scan_data *data;
1684 unsigned long flags;
1682 1685
1683 if (strncmp(scsi_scan_type, "sync", 4) == 0) 1686 if (strncmp(scsi_scan_type, "sync", 4) == 0)
1684 return NULL; 1687 return NULL;
@@ -1698,8 +1701,13 @@ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)
1698 goto err; 1701 goto err;
1699 init_completion(&data->prev_finished); 1702 init_completion(&data->prev_finished);
1700 1703
1701 spin_lock(&async_scan_lock); 1704 mutex_lock(&shost->scan_mutex);
1705 spin_lock_irqsave(shost->host_lock, flags);
1702 shost->async_scan = 1; 1706 shost->async_scan = 1;
1707 spin_unlock_irqrestore(shost->host_lock, flags);
1708 mutex_unlock(&shost->scan_mutex);
1709
1710 spin_lock(&async_scan_lock);
1703 if (list_empty(&scanning_hosts)) 1711 if (list_empty(&scanning_hosts))
1704 complete(&data->prev_finished); 1712 complete(&data->prev_finished);
1705 list_add_tail(&data->list, &scanning_hosts); 1713 list_add_tail(&data->list, &scanning_hosts);
@@ -1723,11 +1731,15 @@ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost)
1723static void scsi_finish_async_scan(struct async_scan_data *data) 1731static void scsi_finish_async_scan(struct async_scan_data *data)
1724{ 1732{
1725 struct Scsi_Host *shost; 1733 struct Scsi_Host *shost;
1734 unsigned long flags;
1726 1735
1727 if (!data) 1736 if (!data)
1728 return; 1737 return;
1729 1738
1730 shost = data->shost; 1739 shost = data->shost;
1740
1741 mutex_lock(&shost->scan_mutex);
1742
1731 if (!shost->async_scan) { 1743 if (!shost->async_scan) {
1732 printk("%s called twice for host %d", __FUNCTION__, 1744 printk("%s called twice for host %d", __FUNCTION__,
1733 shost->host_no); 1745 shost->host_no);
@@ -1739,8 +1751,13 @@ static void scsi_finish_async_scan(struct async_scan_data *data)
1739 1751
1740 scsi_sysfs_add_devices(shost); 1752 scsi_sysfs_add_devices(shost);
1741 1753
1742 spin_lock(&async_scan_lock); 1754 spin_lock_irqsave(shost->host_lock, flags);
1743 shost->async_scan = 0; 1755 shost->async_scan = 0;
1756 spin_unlock_irqrestore(shost->host_lock, flags);
1757
1758 mutex_unlock(&shost->scan_mutex);
1759
1760 spin_lock(&async_scan_lock);
1744 list_del(&data->list); 1761 list_del(&data->list);
1745 if (!list_empty(&scanning_hosts)) { 1762 if (!list_empty(&scanning_hosts)) {
1746 struct async_scan_data *next = list_entry(scanning_hosts.next, 1763 struct async_scan_data *next = list_entry(scanning_hosts.next,