aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/ata/libata-core.c96
-rw-r--r--drivers/scsi/scsi_scan.c3
-rw-r--r--drivers/scsi/sd.c109
3 files changed, 121 insertions, 87 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index fecca4223f8e..f178a450ec08 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -56,6 +56,7 @@
56#include <linux/workqueue.h> 56#include <linux/workqueue.h>
57#include <linux/scatterlist.h> 57#include <linux/scatterlist.h>
58#include <linux/io.h> 58#include <linux/io.h>
59#include <linux/async.h>
59#include <scsi/scsi.h> 60#include <scsi/scsi.h>
60#include <scsi/scsi_cmnd.h> 61#include <scsi/scsi_cmnd.h>
61#include <scsi/scsi_host.h> 62#include <scsi/scsi_host.h>
@@ -5909,6 +5910,54 @@ void ata_host_init(struct ata_host *host, struct device *dev,
5909 host->ops = ops; 5910 host->ops = ops;
5910} 5911}
5911 5912
5913
5914static void async_port_probe(void *data, async_cookie_t cookie)
5915{
5916 int rc;
5917 struct ata_port *ap = data;
5918 /* probe */
5919 if (ap->ops->error_handler) {
5920 struct ata_eh_info *ehi = &ap->link.eh_info;
5921 unsigned long flags;
5922
5923 ata_port_probe(ap);
5924
5925 /* kick EH for boot probing */
5926 spin_lock_irqsave(ap->lock, flags);
5927
5928 ehi->probe_mask |= ATA_ALL_DEVICES;
5929 ehi->action |= ATA_EH_RESET | ATA_EH_LPM;
5930 ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
5931
5932 ap->pflags &= ~ATA_PFLAG_INITIALIZING;
5933 ap->pflags |= ATA_PFLAG_LOADING;
5934 ata_port_schedule_eh(ap);
5935
5936 spin_unlock_irqrestore(ap->lock, flags);
5937
5938 /* wait for EH to finish */
5939 ata_port_wait_eh(ap);
5940 } else {
5941 DPRINTK("ata%u: bus probe begin\n", ap->print_id);
5942 rc = ata_bus_probe(ap);
5943 DPRINTK("ata%u: bus probe end\n", ap->print_id);
5944
5945 if (rc) {
5946 /* FIXME: do something useful here?
5947 * Current libata behavior will
5948 * tear down everything when
5949 * the module is removed
5950 * or the h/w is unplugged.
5951 */
5952 }
5953 }
5954
5955 /* in order to keep device order, we need to synchronize at this point */
5956 async_synchronize_cookie(cookie);
5957
5958 ata_scsi_scan_host(ap, 1);
5959
5960}
5912/** 5961/**
5913 * ata_host_register - register initialized ATA host 5962 * ata_host_register - register initialized ATA host
5914 * @host: ATA host to register 5963 * @host: ATA host to register
@@ -5988,52 +6037,9 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
5988 DPRINTK("probe begin\n"); 6037 DPRINTK("probe begin\n");
5989 for (i = 0; i < host->n_ports; i++) { 6038 for (i = 0; i < host->n_ports; i++) {
5990 struct ata_port *ap = host->ports[i]; 6039 struct ata_port *ap = host->ports[i];
5991 6040 async_schedule(async_port_probe, ap);
5992 /* probe */
5993 if (ap->ops->error_handler) {
5994 struct ata_eh_info *ehi = &ap->link.eh_info;
5995 unsigned long flags;
5996
5997 ata_port_probe(ap);
5998
5999 /* kick EH for boot probing */
6000 spin_lock_irqsave(ap->lock, flags);
6001
6002 ehi->probe_mask |= ATA_ALL_DEVICES;
6003 ehi->action |= ATA_EH_RESET | ATA_EH_LPM;
6004 ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
6005
6006 ap->pflags &= ~ATA_PFLAG_INITIALIZING;
6007 ap->pflags |= ATA_PFLAG_LOADING;
6008 ata_port_schedule_eh(ap);
6009
6010 spin_unlock_irqrestore(ap->lock, flags);
6011
6012 /* wait for EH to finish */
6013 ata_port_wait_eh(ap);
6014 } else {
6015 DPRINTK("ata%u: bus probe begin\n", ap->print_id);
6016 rc = ata_bus_probe(ap);
6017 DPRINTK("ata%u: bus probe end\n", ap->print_id);
6018
6019 if (rc) {
6020 /* FIXME: do something useful here?
6021 * Current libata behavior will
6022 * tear down everything when
6023 * the module is removed
6024 * or the h/w is unplugged.
6025 */
6026 }
6027 }
6028 }
6029
6030 /* probes are done, now scan each port's disk(s) */
6031 DPRINTK("host probe begin\n");
6032 for (i = 0; i < host->n_ports; i++) {
6033 struct ata_port *ap = host->ports[i];
6034
6035 ata_scsi_scan_host(ap, 1);
6036 } 6041 }
6042 DPRINTK("probe end\n");
6037 6043
6038 return 0; 6044 return 0;
6039} 6045}
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 18486b51668d..17914a346f71 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -32,6 +32,7 @@
32#include <linux/delay.h> 32#include <linux/delay.h>
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 36
36#include <scsi/scsi.h> 37#include <scsi/scsi.h>
37#include <scsi/scsi_cmnd.h> 38#include <scsi/scsi_cmnd.h>
@@ -179,6 +180,8 @@ int scsi_complete_async_scans(void)
179 spin_unlock(&async_scan_lock); 180 spin_unlock(&async_scan_lock);
180 181
181 kfree(data); 182 kfree(data);
183 /* Synchronize async operations globally */
184 async_synchronize_full();
182 return 0; 185 return 0;
183} 186}
184 187
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 62b28d58e65e..e035c1114010 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -48,6 +48,7 @@
48#include <linux/delay.h> 48#include <linux/delay.h>
49#include <linux/mutex.h> 49#include <linux/mutex.h>
50#include <linux/string_helpers.h> 50#include <linux/string_helpers.h>
51#include <linux/async.h>
51#include <asm/uaccess.h> 52#include <asm/uaccess.h>
52 53
53#include <scsi/scsi.h> 54#include <scsi/scsi.h>
@@ -1802,6 +1803,71 @@ static int sd_format_disk_name(char *prefix, int index, char *buf, int buflen)
1802 return 0; 1803 return 0;
1803} 1804}
1804 1805
1806/*
1807 * The asynchronous part of sd_probe
1808 */
1809static void sd_probe_async(void *data, async_cookie_t cookie)
1810{
1811 struct scsi_disk *sdkp = data;
1812 struct scsi_device *sdp;
1813 struct gendisk *gd;
1814 u32 index;
1815 struct device *dev;
1816
1817 sdp = sdkp->device;
1818 gd = sdkp->disk;
1819 index = sdkp->index;
1820 dev = &sdp->sdev_gendev;
1821
1822 if (!sdp->request_queue->rq_timeout) {
1823 if (sdp->type != TYPE_MOD)
1824 blk_queue_rq_timeout(sdp->request_queue, SD_TIMEOUT);
1825 else
1826 blk_queue_rq_timeout(sdp->request_queue,
1827 SD_MOD_TIMEOUT);
1828 }
1829
1830 device_initialize(&sdkp->dev);
1831 sdkp->dev.parent = &sdp->sdev_gendev;
1832 sdkp->dev.class = &sd_disk_class;
1833 strncpy(sdkp->dev.bus_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE);
1834
1835 if (device_add(&sdkp->dev))
1836 goto out_free_index;
1837
1838 get_device(&sdp->sdev_gendev);
1839
1840 if (index < SD_MAX_DISKS) {
1841 gd->major = sd_major((index & 0xf0) >> 4);
1842 gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
1843 gd->minors = SD_MINORS;
1844 }
1845 gd->fops = &sd_fops;
1846 gd->private_data = &sdkp->driver;
1847 gd->queue = sdkp->device->request_queue;
1848
1849 sd_revalidate_disk(gd);
1850
1851 blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
1852
1853 gd->driverfs_dev = &sdp->sdev_gendev;
1854 gd->flags = GENHD_FL_EXT_DEVT | GENHD_FL_DRIVERFS;
1855 if (sdp->removable)
1856 gd->flags |= GENHD_FL_REMOVABLE;
1857
1858 dev_set_drvdata(dev, sdkp);
1859 add_disk(gd);
1860 sd_dif_config_host(sdkp);
1861
1862 sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
1863 sdp->removable ? "removable " : "");
1864
1865 return;
1866
1867 out_free_index:
1868 ida_remove(&sd_index_ida, index);
1869}
1870
1805/** 1871/**
1806 * sd_probe - called during driver initialization and whenever a 1872 * sd_probe - called during driver initialization and whenever a
1807 * new scsi device is attached to the system. It is called once 1873 * new scsi device is attached to the system. It is called once
@@ -1865,48 +1931,7 @@ static int sd_probe(struct device *dev)
1865 sdkp->openers = 0; 1931 sdkp->openers = 0;
1866 sdkp->previous_state = 1; 1932 sdkp->previous_state = 1;
1867 1933
1868 if (!sdp->request_queue->rq_timeout) { 1934 async_schedule(sd_probe_async, sdkp);
1869 if (sdp->type != TYPE_MOD)
1870 blk_queue_rq_timeout(sdp->request_queue, SD_TIMEOUT);
1871 else
1872 blk_queue_rq_timeout(sdp->request_queue,
1873 SD_MOD_TIMEOUT);
1874 }
1875
1876 device_initialize(&sdkp->dev);
1877 sdkp->dev.parent = &sdp->sdev_gendev;
1878 sdkp->dev.class = &sd_disk_class;
1879 strncpy(sdkp->dev.bus_id, sdp->sdev_gendev.bus_id, BUS_ID_SIZE);
1880
1881 if (device_add(&sdkp->dev))
1882 goto out_free_index;
1883
1884 get_device(&sdp->sdev_gendev);
1885
1886 if (index < SD_MAX_DISKS) {
1887 gd->major = sd_major((index & 0xf0) >> 4);
1888 gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
1889 gd->minors = SD_MINORS;
1890 }
1891 gd->fops = &sd_fops;
1892 gd->private_data = &sdkp->driver;
1893 gd->queue = sdkp->device->request_queue;
1894
1895 sd_revalidate_disk(gd);
1896
1897 blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
1898
1899 gd->driverfs_dev = &sdp->sdev_gendev;
1900 gd->flags = GENHD_FL_EXT_DEVT | GENHD_FL_DRIVERFS;
1901 if (sdp->removable)
1902 gd->flags |= GENHD_FL_REMOVABLE;
1903
1904 dev_set_drvdata(dev, sdkp);
1905 add_disk(gd);
1906 sd_dif_config_host(sdkp);
1907
1908 sd_printk(KERN_NOTICE, sdkp, "Attached SCSI %sdisk\n",
1909 sdp->removable ? "removable " : "");
1910 1935
1911 return 0; 1936 return 0;
1912 1937