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.c97
1 files changed, 50 insertions, 47 deletions
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index c44783801402..087821fac8fe 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -33,6 +33,7 @@
33#include <linux/kthread.h> 33#include <linux/kthread.h>
34#include <linux/spinlock.h> 34#include <linux/spinlock.h>
35#include <linux/async.h> 35#include <linux/async.h>
36#include <linux/slab.h>
36 37
37#include <scsi/scsi.h> 38#include <scsi/scsi.h>
38#include <scsi/scsi_cmnd.h> 39#include <scsi/scsi_cmnd.h>
@@ -251,6 +252,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
251 sdev->model = scsi_null_device_strs; 252 sdev->model = scsi_null_device_strs;
252 sdev->rev = scsi_null_device_strs; 253 sdev->rev = scsi_null_device_strs;
253 sdev->host = shost; 254 sdev->host = shost;
255 sdev->queue_ramp_up_period = SCSI_DEFAULT_RAMP_UP_PERIOD;
254 sdev->id = starget->id; 256 sdev->id = starget->id;
255 sdev->lun = lun; 257 sdev->lun = lun;
256 sdev->channel = starget->channel; 258 sdev->channel = starget->channel;
@@ -317,6 +319,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,
317out_device_destroy: 319out_device_destroy:
318 scsi_device_set_state(sdev, SDEV_DEL); 320 scsi_device_set_state(sdev, SDEV_DEL);
319 transport_destroy_device(&sdev->sdev_gendev); 321 transport_destroy_device(&sdev->sdev_gendev);
322 put_device(&sdev->sdev_dev);
320 put_device(&sdev->sdev_gendev); 323 put_device(&sdev->sdev_gendev);
321out: 324out:
322 if (display_failure_msg) 325 if (display_failure_msg)
@@ -414,9 +417,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
414 starget->reap_ref = 1; 417 starget->reap_ref = 1;
415 dev->parent = get_device(parent); 418 dev->parent = get_device(parent);
416 dev_set_name(dev, "target%d:%d:%d", shost->host_no, channel, id); 419 dev_set_name(dev, "target%d:%d:%d", shost->host_no, channel, id);
417#ifndef CONFIG_SYSFS_DEPRECATED
418 dev->bus = &scsi_bus_type; 420 dev->bus = &scsi_bus_type;
419#endif
420 dev->type = &scsi_target_type; 421 dev->type = &scsi_target_type;
421 starget->id = id; 422 starget->id = id;
422 starget->channel = channel; 423 starget->channel = channel;
@@ -456,8 +457,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
456 found_target->reap_ref++; 457 found_target->reap_ref++;
457 spin_unlock_irqrestore(shost->host_lock, flags); 458 spin_unlock_irqrestore(shost->host_lock, flags);
458 if (found_target->state != STARGET_DEL) { 459 if (found_target->state != STARGET_DEL) {
459 put_device(parent); 460 put_device(dev);
460 kfree(starget);
461 return found_target; 461 return found_target;
462 } 462 }
463 /* Unfortunately, we found a dying target; need to 463 /* Unfortunately, we found a dying target; need to
@@ -490,19 +490,20 @@ void scsi_target_reap(struct scsi_target *starget)
490 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); 490 struct Scsi_Host *shost = dev_to_shost(starget->dev.parent);
491 unsigned long flags; 491 unsigned long flags;
492 enum scsi_target_state state; 492 enum scsi_target_state state;
493 int empty; 493 int empty = 0;
494 494
495 spin_lock_irqsave(shost->host_lock, flags); 495 spin_lock_irqsave(shost->host_lock, flags);
496 state = starget->state; 496 state = starget->state;
497 empty = --starget->reap_ref == 0 && 497 if (--starget->reap_ref == 0 && list_empty(&starget->devices)) {
498 list_empty(&starget->devices) ? 1 : 0; 498 empty = 1;
499 starget->state = STARGET_DEL;
500 }
499 spin_unlock_irqrestore(shost->host_lock, flags); 501 spin_unlock_irqrestore(shost->host_lock, flags);
500 502
501 if (!empty) 503 if (!empty)
502 return; 504 return;
503 505
504 BUG_ON(state == STARGET_DEL); 506 BUG_ON(state == STARGET_DEL);
505 starget->state = STARGET_DEL;
506 if (state == STARGET_CREATED) 507 if (state == STARGET_CREATED)
507 scsi_target_destroy(starget); 508 scsi_target_destroy(starget);
508 else 509 else
@@ -877,7 +878,7 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
877 * broken RA4x00 Compaq Disk Array 878 * broken RA4x00 Compaq Disk Array
878 */ 879 */
879 if (*bflags & BLIST_MAX_512) 880 if (*bflags & BLIST_MAX_512)
880 blk_queue_max_sectors(sdev->request_queue, 512); 881 blk_queue_max_hw_sectors(sdev->request_queue, 512);
881 882
882 /* 883 /*
883 * Some devices may not want to have a start command automatically 884 * Some devices may not want to have a start command automatically
@@ -940,6 +941,8 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
940 } 941 }
941 } 942 }
942 943
944 sdev->max_queue_depth = sdev->queue_depth;
945
943 /* 946 /*
944 * Ok, the device is now all set up, we can 947 * Ok, the device is now all set up, we can
945 * register it and tell the rest of the kernel 948 * register it and tell the rest of the kernel
@@ -951,15 +954,6 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result,
951 return SCSI_SCAN_LUN_PRESENT; 954 return SCSI_SCAN_LUN_PRESENT;
952} 955}
953 956
954static inline void scsi_destroy_sdev(struct scsi_device *sdev)
955{
956 scsi_device_set_state(sdev, SDEV_DEL);
957 if (sdev->host->hostt->slave_destroy)
958 sdev->host->hostt->slave_destroy(sdev);
959 transport_destroy_device(&sdev->sdev_gendev);
960 put_device(&sdev->sdev_gendev);
961}
962
963#ifdef CONFIG_SCSI_LOGGING 957#ifdef CONFIG_SCSI_LOGGING
964/** 958/**
965 * scsi_inq_str - print INQUIRY data from min to max index, strip trailing whitespace 959 * scsi_inq_str - print INQUIRY data from min to max index, strip trailing whitespace
@@ -1137,7 +1131,7 @@ static int scsi_probe_and_add_lun(struct scsi_target *starget,
1137 } 1131 }
1138 } 1132 }
1139 } else 1133 } else
1140 scsi_destroy_sdev(sdev); 1134 __scsi_remove_device(sdev);
1141 out: 1135 out:
1142 return res; 1136 return res;
1143} 1137}
@@ -1225,7 +1219,7 @@ static void scsi_sequential_lun_scan(struct scsi_target *starget,
1225} 1219}
1226 1220
1227/** 1221/**
1228 * scsilun_to_int: convert a scsi_lun to an int 1222 * scsilun_to_int - convert a scsi_lun to an int
1229 * @scsilun: struct scsi_lun to be converted. 1223 * @scsilun: struct scsi_lun to be converted.
1230 * 1224 *
1231 * Description: 1225 * Description:
@@ -1257,7 +1251,7 @@ int scsilun_to_int(struct scsi_lun *scsilun)
1257EXPORT_SYMBOL(scsilun_to_int); 1251EXPORT_SYMBOL(scsilun_to_int);
1258 1252
1259/** 1253/**
1260 * int_to_scsilun: reverts an int into a scsi_lun 1254 * int_to_scsilun - reverts an int into a scsi_lun
1261 * @lun: integer to be reverted 1255 * @lun: integer to be reverted
1262 * @scsilun: struct scsi_lun to be set. 1256 * @scsilun: struct scsi_lun to be set.
1263 * 1257 *
@@ -1344,8 +1338,10 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
1344 sdev = scsi_alloc_sdev(starget, 0, NULL); 1338 sdev = scsi_alloc_sdev(starget, 0, NULL);
1345 if (!sdev) 1339 if (!sdev)
1346 return 0; 1340 return 0;
1347 if (scsi_device_get(sdev)) 1341 if (scsi_device_get(sdev)) {
1342 __scsi_remove_device(sdev);
1348 return 0; 1343 return 0;
1344 }
1349 } 1345 }
1350 1346
1351 sprintf(devname, "host %d channel %d id %d", 1347 sprintf(devname, "host %d channel %d id %d",
@@ -1498,7 +1494,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags,
1498 /* 1494 /*
1499 * the sdev we used didn't appear in the report luns scan 1495 * the sdev we used didn't appear in the report luns scan
1500 */ 1496 */
1501 scsi_destroy_sdev(sdev); 1497 __scsi_remove_device(sdev);
1502 return ret; 1498 return ret;
1503} 1499}
1504 1500
@@ -1515,14 +1511,18 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel,
1515 starget = scsi_alloc_target(parent, channel, id); 1511 starget = scsi_alloc_target(parent, channel, id);
1516 if (!starget) 1512 if (!starget)
1517 return ERR_PTR(-ENOMEM); 1513 return ERR_PTR(-ENOMEM);
1514 scsi_autopm_get_target(starget);
1518 1515
1519 mutex_lock(&shost->scan_mutex); 1516 mutex_lock(&shost->scan_mutex);
1520 if (!shost->async_scan) 1517 if (!shost->async_scan)
1521 scsi_complete_async_scans(); 1518 scsi_complete_async_scans();
1522 1519
1523 if (scsi_host_scan_allowed(shost)) 1520 if (scsi_host_scan_allowed(shost) && scsi_autopm_get_host(shost) == 0) {
1524 scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata); 1521 scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata);
1522 scsi_autopm_put_host(shost);
1523 }
1525 mutex_unlock(&shost->scan_mutex); 1524 mutex_unlock(&shost->scan_mutex);
1525 scsi_autopm_put_target(starget);
1526 scsi_target_reap(starget); 1526 scsi_target_reap(starget);
1527 put_device(&starget->dev); 1527 put_device(&starget->dev);
1528 1528
@@ -1576,6 +1576,7 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel,
1576 starget = scsi_alloc_target(parent, channel, id); 1576 starget = scsi_alloc_target(parent, channel, id);
1577 if (!starget) 1577 if (!starget)
1578 return; 1578 return;
1579 scsi_autopm_get_target(starget);
1579 1580
1580 if (lun != SCAN_WILD_CARD) { 1581 if (lun != SCAN_WILD_CARD) {
1581 /* 1582 /*
@@ -1601,6 +1602,7 @@ static void __scsi_scan_target(struct device *parent, unsigned int channel,
1601 } 1602 }
1602 1603
1603 out_reap: 1604 out_reap:
1605 scsi_autopm_put_target(starget);
1604 /* now determine if the target has any children at all 1606 /* now determine if the target has any children at all
1605 * and if not, nuke it */ 1607 * and if not, nuke it */
1606 scsi_target_reap(starget); 1608 scsi_target_reap(starget);
@@ -1635,8 +1637,10 @@ void scsi_scan_target(struct device *parent, unsigned int channel,
1635 if (!shost->async_scan) 1637 if (!shost->async_scan)
1636 scsi_complete_async_scans(); 1638 scsi_complete_async_scans();
1637 1639
1638 if (scsi_host_scan_allowed(shost)) 1640 if (scsi_host_scan_allowed(shost) && scsi_autopm_get_host(shost) == 0) {
1639 __scsi_scan_target(parent, channel, id, lun, rescan); 1641 __scsi_scan_target(parent, channel, id, lun, rescan);
1642 scsi_autopm_put_host(shost);
1643 }
1640 mutex_unlock(&shost->scan_mutex); 1644 mutex_unlock(&shost->scan_mutex);
1641} 1645}
1642EXPORT_SYMBOL(scsi_scan_target); 1646EXPORT_SYMBOL(scsi_scan_target);
@@ -1688,7 +1692,7 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
1688 if (!shost->async_scan) 1692 if (!shost->async_scan)
1689 scsi_complete_async_scans(); 1693 scsi_complete_async_scans();
1690 1694
1691 if (scsi_host_scan_allowed(shost)) { 1695 if (scsi_host_scan_allowed(shost) && scsi_autopm_get_host(shost) == 0) {
1692 if (channel == SCAN_WILD_CARD) 1696 if (channel == SCAN_WILD_CARD)
1693 for (channel = 0; channel <= shost->max_channel; 1697 for (channel = 0; channel <= shost->max_channel;
1694 channel++) 1698 channel++)
@@ -1696,6 +1700,7 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel,
1696 rescan); 1700 rescan);
1697 else 1701 else
1698 scsi_scan_channel(shost, channel, id, lun, rescan); 1702 scsi_scan_channel(shost, channel, id, lun, rescan);
1703 scsi_autopm_put_host(shost);
1699 } 1704 }
1700 mutex_unlock(&shost->scan_mutex); 1705 mutex_unlock(&shost->scan_mutex);
1701 1706
@@ -1708,7 +1713,7 @@ static void scsi_sysfs_add_devices(struct Scsi_Host *shost)
1708 shost_for_each_device(sdev, shost) { 1713 shost_for_each_device(sdev, shost) {
1709 if (!scsi_host_scan_allowed(shost) || 1714 if (!scsi_host_scan_allowed(shost) ||
1710 scsi_sysfs_add_sdev(sdev) != 0) 1715 scsi_sysfs_add_sdev(sdev) != 0)
1711 scsi_destroy_sdev(sdev); 1716 __scsi_remove_device(sdev);
1712 } 1717 }
1713} 1718}
1714 1719
@@ -1833,8 +1838,11 @@ static void do_scsi_scan_host(struct Scsi_Host *shost)
1833static int do_scan_async(void *_data) 1838static int do_scan_async(void *_data)
1834{ 1839{
1835 struct async_scan_data *data = _data; 1840 struct async_scan_data *data = _data;
1836 do_scsi_scan_host(data->shost); 1841 struct Scsi_Host *shost = data->shost;
1842
1843 do_scsi_scan_host(shost);
1837 scsi_finish_async_scan(data); 1844 scsi_finish_async_scan(data);
1845 scsi_autopm_put_host(shost);
1838 return 0; 1846 return 0;
1839} 1847}
1840 1848
@@ -1849,16 +1857,20 @@ void scsi_scan_host(struct Scsi_Host *shost)
1849 1857
1850 if (strncmp(scsi_scan_type, "none", 4) == 0) 1858 if (strncmp(scsi_scan_type, "none", 4) == 0)
1851 return; 1859 return;
1860 if (scsi_autopm_get_host(shost) < 0)
1861 return;
1852 1862
1853 data = scsi_prep_async_scan(shost); 1863 data = scsi_prep_async_scan(shost);
1854 if (!data) { 1864 if (!data) {
1855 do_scsi_scan_host(shost); 1865 do_scsi_scan_host(shost);
1866 scsi_autopm_put_host(shost);
1856 return; 1867 return;
1857 } 1868 }
1858 1869
1859 p = kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no); 1870 p = kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no);
1860 if (IS_ERR(p)) 1871 if (IS_ERR(p))
1861 do_scan_async(data); 1872 do_scan_async(data);
1873 /* scsi_autopm_put_host(shost) is called in do_scan_async() */
1862} 1874}
1863EXPORT_SYMBOL(scsi_scan_host); 1875EXPORT_SYMBOL(scsi_scan_host);
1864 1876
@@ -1879,12 +1891,9 @@ void scsi_forget_host(struct Scsi_Host *shost)
1879 spin_unlock_irqrestore(shost->host_lock, flags); 1891 spin_unlock_irqrestore(shost->host_lock, flags);
1880} 1892}
1881 1893
1882/* 1894/**
1883 * Function: scsi_get_host_dev() 1895 * scsi_get_host_dev - Create a scsi_device that points to the host adapter itself
1884 * 1896 * @shost: Host that needs a scsi_device
1885 * Purpose: Create a scsi_device that points to the host adapter itself.
1886 *
1887 * Arguments: SHpnt - Host that needs a scsi_device
1888 * 1897 *
1889 * Lock status: None assumed. 1898 * Lock status: None assumed.
1890 * 1899 *
@@ -1897,7 +1906,7 @@ void scsi_forget_host(struct Scsi_Host *shost)
1897 * 1906 *
1898 * Note - this device is not accessible from any high-level 1907 * Note - this device is not accessible from any high-level
1899 * drivers (including generics), which is probably not 1908 * drivers (including generics), which is probably not
1900 * optimal. We can add hooks later to attach 1909 * optimal. We can add hooks later to attach.
1901 */ 1910 */
1902struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost) 1911struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
1903{ 1912{
@@ -1912,10 +1921,9 @@ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
1912 goto out; 1921 goto out;
1913 1922
1914 sdev = scsi_alloc_sdev(starget, 0, NULL); 1923 sdev = scsi_alloc_sdev(starget, 0, NULL);
1915 if (sdev) { 1924 if (sdev)
1916 sdev->sdev_gendev.parent = get_device(&starget->dev);
1917 sdev->borken = 0; 1925 sdev->borken = 0;
1918 } else 1926 else
1919 scsi_target_reap(starget); 1927 scsi_target_reap(starget);
1920 put_device(&starget->dev); 1928 put_device(&starget->dev);
1921 out: 1929 out:
@@ -1924,24 +1932,19 @@ struct scsi_device *scsi_get_host_dev(struct Scsi_Host *shost)
1924} 1932}
1925EXPORT_SYMBOL(scsi_get_host_dev); 1933EXPORT_SYMBOL(scsi_get_host_dev);
1926 1934
1927/* 1935/**
1928 * Function: scsi_free_host_dev() 1936 * scsi_free_host_dev - Free a scsi_device that points to the host adapter itself
1929 * 1937 * @sdev: Host device to be freed
1930 * Purpose: Free a scsi_device that points to the host adapter itself.
1931 *
1932 * Arguments: SHpnt - Host that needs a scsi_device
1933 * 1938 *
1934 * Lock status: None assumed. 1939 * Lock status: None assumed.
1935 * 1940 *
1936 * Returns: Nothing 1941 * Returns: Nothing
1937 *
1938 * Notes:
1939 */ 1942 */
1940void scsi_free_host_dev(struct scsi_device *sdev) 1943void scsi_free_host_dev(struct scsi_device *sdev)
1941{ 1944{
1942 BUG_ON(sdev->id != sdev->host->this_id); 1945 BUG_ON(sdev->id != sdev->host->this_id);
1943 1946
1944 scsi_destroy_sdev(sdev); 1947 __scsi_remove_device(sdev);
1945} 1948}
1946EXPORT_SYMBOL(scsi_free_host_dev); 1949EXPORT_SYMBOL(scsi_free_host_dev);
1947 1950