diff options
Diffstat (limited to 'drivers/usb/storage')
-rw-r--r-- | drivers/usb/storage/alauda.c | 15 | ||||
-rw-r--r-- | drivers/usb/storage/cypress_atacb.c | 15 | ||||
-rw-r--r-- | drivers/usb/storage/datafab.c | 15 | ||||
-rw-r--r-- | drivers/usb/storage/ene_ub6250.c | 25 | ||||
-rw-r--r-- | drivers/usb/storage/freecom.c | 15 | ||||
-rw-r--r-- | drivers/usb/storage/isd200.c | 17 | ||||
-rw-r--r-- | drivers/usb/storage/jumpshot.c | 15 | ||||
-rw-r--r-- | drivers/usb/storage/karma.c | 15 | ||||
-rw-r--r-- | drivers/usb/storage/onetouch.c | 15 | ||||
-rw-r--r-- | drivers/usb/storage/realtek_cr.c | 29 | ||||
-rw-r--r-- | drivers/usb/storage/sddr09.c | 15 | ||||
-rw-r--r-- | drivers/usb/storage/sddr55.c | 15 | ||||
-rw-r--r-- | drivers/usb/storage/shuttle_usbat.c | 15 | ||||
-rw-r--r-- | drivers/usb/storage/uas.c | 13 | ||||
-rw-r--r-- | drivers/usb/storage/unusual_devs.h | 9 | ||||
-rw-r--r-- | drivers/usb/storage/usb.c | 90 | ||||
-rw-r--r-- | drivers/usb/storage/usb.h | 7 |
17 files changed, 83 insertions, 257 deletions
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c index 42d0eaed4a0..51af2fee2ef 100644 --- a/drivers/usb/storage/alauda.c +++ b/drivers/usb/storage/alauda.c @@ -139,7 +139,7 @@ static int init_alauda(struct us_data *us); { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id alauda_usb_ids[] = { +static struct usb_device_id alauda_usb_ids[] = { # include "unusual_alauda.h" { } /* Terminating entry */ }; @@ -1278,15 +1278,4 @@ static struct usb_driver alauda_driver = { .soft_unbind = 1, }; -static int __init alauda_init(void) -{ - return usb_register(&alauda_driver); -} - -static void __exit alauda_exit(void) -{ - usb_deregister(&alauda_driver); -} - -module_init(alauda_init); -module_exit(alauda_exit); +module_usb_driver(alauda_driver); diff --git a/drivers/usb/storage/cypress_atacb.c b/drivers/usb/storage/cypress_atacb.c index c8447182118..387cbd47acc 100644 --- a/drivers/usb/storage/cypress_atacb.c +++ b/drivers/usb/storage/cypress_atacb.c @@ -43,7 +43,7 @@ MODULE_LICENSE("GPL"); { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id cypress_usb_ids[] = { +static struct usb_device_id cypress_usb_ids[] = { # include "unusual_cypress.h" { } /* Terminating entry */ }; @@ -274,15 +274,4 @@ static struct usb_driver cypress_driver = { .soft_unbind = 1, }; -static int __init cypress_init(void) -{ - return usb_register(&cypress_driver); -} - -static void __exit cypress_exit(void) -{ - usb_deregister(&cypress_driver); -} - -module_init(cypress_init); -module_exit(cypress_exit); +module_usb_driver(cypress_driver); diff --git a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c index ded836b02d7..15d41f2b3d6 100644 --- a/drivers/usb/storage/datafab.c +++ b/drivers/usb/storage/datafab.c @@ -88,7 +88,7 @@ static int datafab_determine_lun(struct us_data *us, { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id datafab_usb_ids[] = { +static struct usb_device_id datafab_usb_ids[] = { # include "unusual_datafab.h" { } /* Terminating entry */ }; @@ -753,15 +753,4 @@ static struct usb_driver datafab_driver = { .soft_unbind = 1, }; -static int __init datafab_init(void) -{ - return usb_register(&datafab_driver); -} - -static void __exit datafab_exit(void) -{ - usb_deregister(&datafab_driver); -} - -module_init(datafab_init); -module_exit(datafab_exit); +module_usb_driver(datafab_driver); diff --git a/drivers/usb/storage/ene_ub6250.c b/drivers/usb/storage/ene_ub6250.c index 9fbe742343c..a6ade4071a9 100644 --- a/drivers/usb/storage/ene_ub6250.c +++ b/drivers/usb/storage/ene_ub6250.c @@ -42,7 +42,7 @@ MODULE_LICENSE("GPL"); { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id ene_ub6250_usb_ids[] = { +static struct usb_device_id ene_ub6250_usb_ids[] = { # include "unusual_ene_ub6250.h" { } /* Terminating entry */ }; @@ -607,8 +607,8 @@ static int sd_scsi_mode_sense(struct us_data *us, struct scsi_cmnd *srb) static int sd_scsi_read_capacity(struct us_data *us, struct scsi_cmnd *srb) { - u32 bl_num; - u16 bl_len; + u32 bl_num; + u32 bl_len; unsigned int offset = 0; unsigned char buf[8]; struct scatterlist *sg = NULL; @@ -622,7 +622,7 @@ static int sd_scsi_read_capacity(struct us_data *us, struct scsi_cmnd *srb) else bl_num = (info->HC_C_SIZE + 1) * 1024 - 1; } else { - bl_len = 1<<(info->SD_READ_BL_LEN); + bl_len = 1 << (info->SD_READ_BL_LEN); bl_num = info->SD_Block_Mult * (info->SD_C_SIZE + 1) * (1 << (info->SD_C_SIZE_MULT + 2)) - 1; } @@ -777,7 +777,7 @@ static int ms_lib_free_logicalmap(struct us_data *us) return 0; } -int ms_lib_alloc_logicalmap(struct us_data *us) +static int ms_lib_alloc_logicalmap(struct us_data *us) { u32 i; struct ene_ub6250_info *info = (struct ene_ub6250_info *) us->extra; @@ -2248,7 +2248,7 @@ static int sd_scsi_irp(struct us_data *us, struct scsi_cmnd *srb) /* * ms_scsi_irp() */ -int ms_scsi_irp(struct us_data *us, struct scsi_cmnd *srb) +static int ms_scsi_irp(struct us_data *us, struct scsi_cmnd *srb) { int result; struct ene_ub6250_info *info = (struct ene_ub6250_info *)us->extra; @@ -2409,15 +2409,4 @@ static struct usb_driver ene_ub6250_driver = { .soft_unbind = 1, }; -static int __init ene_ub6250_init(void) -{ - return usb_register(&ene_ub6250_driver); -} - -static void __exit ene_ub6250_exit(void) -{ - usb_deregister(&ene_ub6250_driver); -} - -module_init(ene_ub6250_init); -module_exit(ene_ub6250_exit); +module_usb_driver(ene_ub6250_driver); diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c index 6542ca40d50..fa161574847 100644 --- a/drivers/usb/storage/freecom.c +++ b/drivers/usb/storage/freecom.c @@ -119,7 +119,7 @@ static int init_freecom(struct us_data *us); { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id freecom_usb_ids[] = { +static struct usb_device_id freecom_usb_ids[] = { # include "unusual_freecom.h" { } /* Terminating entry */ }; @@ -555,15 +555,4 @@ static struct usb_driver freecom_driver = { .soft_unbind = 1, }; -static int __init freecom_init(void) -{ - return usb_register(&freecom_driver); -} - -static void __exit freecom_exit(void) -{ - usb_deregister(&freecom_driver); -} - -module_init(freecom_init); -module_exit(freecom_exit); +module_usb_driver(freecom_driver); diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index ffc4193e950..bd550270083 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c @@ -61,7 +61,7 @@ #include "scsiglue.h" MODULE_DESCRIPTION("Driver for In-System Design, Inc. ISD200 ASIC"); -MODULE_AUTHOR("Björn Stenberg <bjorn@haxx.se>"); +MODULE_AUTHOR("Björn Stenberg <bjorn@haxx.se>"); MODULE_LICENSE("GPL"); static int isd200_Initialization(struct us_data *us); @@ -76,7 +76,7 @@ static int isd200_Initialization(struct us_data *us); { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id isd200_usb_ids[] = { +static struct usb_device_id isd200_usb_ids[] = { # include "unusual_isd200.h" { } /* Terminating entry */ }; @@ -1568,15 +1568,4 @@ static struct usb_driver isd200_driver = { .soft_unbind = 1, }; -static int __init isd200_init(void) -{ - return usb_register(&isd200_driver); -} - -static void __exit isd200_exit(void) -{ - usb_deregister(&isd200_driver); -} - -module_init(isd200_init); -module_exit(isd200_exit); +module_usb_driver(isd200_driver); diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c index 6168596c5ac..a19211b5c26 100644 --- a/drivers/usb/storage/jumpshot.c +++ b/drivers/usb/storage/jumpshot.c @@ -71,7 +71,7 @@ MODULE_LICENSE("GPL"); { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id jumpshot_usb_ids[] = { +static struct usb_device_id jumpshot_usb_ids[] = { # include "unusual_jumpshot.h" { } /* Terminating entry */ }; @@ -679,15 +679,4 @@ static struct usb_driver jumpshot_driver = { .soft_unbind = 1, }; -static int __init jumpshot_init(void) -{ - return usb_register(&jumpshot_driver); -} - -static void __exit jumpshot_exit(void) -{ - usb_deregister(&jumpshot_driver); -} - -module_init(jumpshot_init); -module_exit(jumpshot_exit); +module_usb_driver(jumpshot_driver); diff --git a/drivers/usb/storage/karma.c b/drivers/usb/storage/karma.c index ba1b7890688..e720f8ebdf9 100644 --- a/drivers/usb/storage/karma.c +++ b/drivers/usb/storage/karma.c @@ -59,7 +59,7 @@ static int rio_karma_init(struct us_data *us); { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id karma_usb_ids[] = { +static struct usb_device_id karma_usb_ids[] = { # include "unusual_karma.h" { } /* Terminating entry */ }; @@ -232,15 +232,4 @@ static struct usb_driver karma_driver = { .soft_unbind = 1, }; -static int __init karma_init(void) -{ - return usb_register(&karma_driver); -} - -static void __exit karma_exit(void) -{ - usb_deregister(&karma_driver); -} - -module_init(karma_init); -module_exit(karma_exit); +module_usb_driver(karma_driver); diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index 1943be5a291..d75155c3820 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c @@ -69,7 +69,7 @@ struct usb_onetouch { { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id onetouch_usb_ids[] = { +static struct usb_device_id onetouch_usb_ids[] = { # include "unusual_onetouch.h" { } /* Terminating entry */ }; @@ -314,15 +314,4 @@ static struct usb_driver onetouch_driver = { .soft_unbind = 1, }; -static int __init onetouch_init(void) -{ - return usb_register(&onetouch_driver); -} - -static void __exit onetouch_exit(void) -{ - usb_deregister(&onetouch_driver); -} - -module_init(onetouch_init); -module_exit(onetouch_exit); +module_usb_driver(onetouch_driver); diff --git a/drivers/usb/storage/realtek_cr.c b/drivers/usb/storage/realtek_cr.c index 0ce5f79197e..d32f72061c0 100644 --- a/drivers/usb/storage/realtek_cr.c +++ b/drivers/usb/storage/realtek_cr.c @@ -398,10 +398,9 @@ static int rts51x_write_mem(struct us_data *us, u16 addr, u8 *data, u16 len) u8 cmnd[12] = { 0 }; u8 *buf; - buf = kmalloc(len, GFP_NOIO); + buf = kmemdup(data, len, GFP_NOIO); if (buf == NULL) return USB_STOR_TRANSPORT_ERROR; - memcpy(buf, data, len); US_DEBUGP("%s, addr = 0x%x, len = %d\n", __func__, addr, len); @@ -507,15 +506,14 @@ static int enable_oscillator(struct us_data *us) static int __do_config_autodelink(struct us_data *us, u8 *data, u16 len) { int retval; - u16 addr = 0xFE47; u8 cmnd[12] = {0}; - US_DEBUGP("%s, addr = 0x%x, len = %d\n", __FUNCTION__, addr, len); + US_DEBUGP("%s, addr = 0xfe47, len = %d\n", __FUNCTION__, len); cmnd[0] = 0xF0; cmnd[1] = 0x0E; - cmnd[2] = (u8)(addr >> 8); - cmnd[3] = (u8)addr; + cmnd[2] = 0xfe; + cmnd[3] = 0x47; cmnd[4] = (u8)(len >> 8); cmnd[5] = (u8)len; @@ -791,7 +789,7 @@ static void rts51x_suspend_timer_fn(unsigned long data) rts51x_set_stat(chip, RTS51X_STAT_SS); /* ignore mass storage interface's children */ pm_suspend_ignore_children(&us->pusb_intf->dev, true); - usb_autopm_put_interface(us->pusb_intf); + usb_autopm_put_interface_async(us->pusb_intf); US_DEBUGP("%s: RTS51X_STAT_SS 01," "intf->pm_usage_cnt:%d, power.usage:%d\n", __func__, @@ -818,7 +816,7 @@ static inline int working_scsi(struct scsi_cmnd *srb) return 1; } -void rts51x_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) +static void rts51x_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) { struct rts51x_chip *chip = (struct rts51x_chip *)(us->extra); static int card_first_show = 1; @@ -977,7 +975,7 @@ static void realtek_cr_destructor(void *extra) } #ifdef CONFIG_PM -int realtek_cr_suspend(struct usb_interface *iface, pm_message_t message) +static int realtek_cr_suspend(struct usb_interface *iface, pm_message_t message) { struct us_data *us = usb_get_intfdata(iface); @@ -1104,15 +1102,4 @@ static struct usb_driver realtek_cr_driver = { .supports_autosuspend = 1, }; -static int __init realtek_cr_init(void) -{ - return usb_register(&realtek_cr_driver); -} - -static void __exit realtek_cr_exit(void) -{ - usb_deregister(&realtek_cr_driver); -} - -module_init(realtek_cr_init); -module_exit(realtek_cr_exit); +module_usb_driver(realtek_cr_driver); diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index bcb9a709d34..425df7df2e5 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c @@ -71,7 +71,7 @@ static int usb_stor_sddr09_init(struct us_data *us); { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id sddr09_usb_ids[] = { +static struct usb_device_id sddr09_usb_ids[] = { # include "unusual_sddr09.h" { } /* Terminating entry */ }; @@ -1789,15 +1789,4 @@ static struct usb_driver sddr09_driver = { .soft_unbind = 1, }; -static int __init sddr09_init(void) -{ - return usb_register(&sddr09_driver); -} - -static void __exit sddr09_exit(void) -{ - usb_deregister(&sddr09_driver); -} - -module_init(sddr09_init); -module_exit(sddr09_exit); +module_usb_driver(sddr09_driver); diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c index 44dfed7754e..e4ca5fcb7cc 100644 --- a/drivers/usb/storage/sddr55.c +++ b/drivers/usb/storage/sddr55.c @@ -48,7 +48,7 @@ MODULE_LICENSE("GPL"); { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id sddr55_usb_ids[] = { +static struct usb_device_id sddr55_usb_ids[] = { # include "unusual_sddr55.h" { } /* Terminating entry */ }; @@ -1008,15 +1008,4 @@ static struct usb_driver sddr55_driver = { .soft_unbind = 1, }; -static int __init sddr55_init(void) -{ - return usb_register(&sddr55_driver); -} - -static void __exit sddr55_exit(void) -{ - usb_deregister(&sddr55_driver); -} - -module_init(sddr55_init); -module_exit(sddr55_exit); +module_usb_driver(sddr55_driver); diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index 0b00091d2ae..1369d259061 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c @@ -170,7 +170,7 @@ static int init_usbat_flash(struct us_data *us); { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } -struct usb_device_id usbat_usb_ids[] = { +static struct usb_device_id usbat_usb_ids[] = { # include "unusual_usbat.h" { } /* Terminating entry */ }; @@ -1865,15 +1865,4 @@ static struct usb_driver usbat_driver = { .soft_unbind = 1, }; -static int __init usbat_init(void) -{ - return usb_register(&usbat_driver); -} - -static void __exit usbat_exit(void) -{ - usb_deregister(&usbat_driver); -} - -module_init(usbat_init); -module_exit(usbat_exit); +module_usb_driver(usbat_driver); diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 1d10d5b8204..a33ead5dce2 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -760,18 +760,7 @@ static struct usb_driver uas_driver = { .id_table = uas_usb_ids, }; -static int uas_init(void) -{ - return usb_register(&uas_driver); -} - -static void uas_exit(void) -{ - usb_deregister(&uas_driver); -} - -module_init(uas_init); -module_exit(uas_exit); +module_usb_driver(uas_driver); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Matthew Wilcox and Sarah Sharp"); diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 3041a974faf..856ad92c40d 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -1854,6 +1854,13 @@ UNUSUAL_DEV( 0x1370, 0x6828, 0x0110, 0x0110, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_IGNORE_RESIDUE ), +/* Reported by Qinglin Ye <yestyle@gmail.com> */ +UNUSUAL_DEV( 0x13fe, 0x3600, 0x0100, 0x0100, + "Kingston", + "DT 101 G2", + USB_SC_DEVICE, USB_PR_DEVICE, NULL, + US_FL_BULK_IGNORE_TAG ), + /* Reported by Francesco Foresti <frafore@tiscali.it> */ UNUSUAL_DEV( 0x14cd, 0x6600, 0x0201, 0x0201, "Super Top", @@ -1907,7 +1914,7 @@ UNUSUAL_DEV( 0x1b1c, 0x1ab5, 0x0200, 0x0200, USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_INITIAL_READ10 ), -/* Patch by Richard Schütz <r.schtz@t-online.de> +/* Patch by Richard Schütz <r.schtz@t-online.de> * This external hard drive enclosure uses a JMicron chip which * needs the US_FL_IGNORE_RESIDUE flag to work properly. */ UNUSUAL_DEV( 0x1e68, 0x001b, 0x0000, 0x0000, diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index c325e69415a..db51ba16dc0 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -788,15 +788,19 @@ static void quiesce_and_remove_host(struct us_data *us) struct Scsi_Host *host = us_to_host(us); /* If the device is really gone, cut short reset delays */ - if (us->pusb_dev->state == USB_STATE_NOTATTACHED) + if (us->pusb_dev->state == USB_STATE_NOTATTACHED) { set_bit(US_FLIDX_DISCONNECTING, &us->dflags); + wake_up(&us->delay_wait); + } - /* Prevent SCSI-scanning (if it hasn't started yet) - * and wait for the SCSI-scanning thread to stop. + /* Prevent SCSI scanning (if it hasn't started yet) + * or wait for the SCSI-scanning routine to stop. */ - set_bit(US_FLIDX_DONT_SCAN, &us->dflags); - wake_up(&us->delay_wait); - wait_for_completion(&us->scanning_done); + cancel_delayed_work_sync(&us->scan_dwork); + + /* Balance autopm calls if scanning was cancelled */ + if (test_bit(US_FLIDX_SCAN_PENDING, &us->dflags)) + usb_autopm_put_interface_no_suspend(us->pusb_intf); /* Removing the host will perform an orderly shutdown: caches * synchronized, disks spun down, etc. @@ -823,52 +827,28 @@ static void release_everything(struct us_data *us) scsi_host_put(us_to_host(us)); } -/* Thread to carry out delayed SCSI-device scanning */ -static int usb_stor_scan_thread(void * __us) +/* Delayed-work routine to carry out SCSI-device scanning */ +static void usb_stor_scan_dwork(struct work_struct *work) { - struct us_data *us = (struct us_data *)__us; + struct us_data *us = container_of(work, struct us_data, + scan_dwork.work); struct device *dev = &us->pusb_intf->dev; - dev_dbg(dev, "device found\n"); + dev_dbg(dev, "starting scan\n"); - set_freezable_with_signal(); - /* - * Wait for the timeout to expire or for a disconnect - * - * We can't freeze in this thread or we risk causing khubd to - * fail to freeze, but we can't be non-freezable either. Nor can - * khubd freeze while waiting for scanning to complete as it may - * hold the device lock, causing a hang when suspending devices. - * So we request a fake signal when freezing and use - * interruptible sleep to kick us out of our wait early when - * freezing happens. - */ - if (delay_use > 0) { - dev_dbg(dev, "waiting for device to settle " - "before scanning\n"); - wait_event_interruptible_timeout(us->delay_wait, - test_bit(US_FLIDX_DONT_SCAN, &us->dflags), - delay_use * HZ); + /* For bulk-only devices, determine the max LUN value */ + if (us->protocol == USB_PR_BULK && !(us->fflags & US_FL_SINGLE_LUN)) { + mutex_lock(&us->dev_mutex); + us->max_lun = usb_stor_Bulk_max_lun(us); + mutex_unlock(&us->dev_mutex); } + scsi_scan_host(us_to_host(us)); + dev_dbg(dev, "scan complete\n"); - /* If the device is still connected, perform the scanning */ - if (!test_bit(US_FLIDX_DONT_SCAN, &us->dflags)) { - - /* For bulk-only devices, determine the max LUN value */ - if (us->protocol == USB_PR_BULK && - !(us->fflags & US_FL_SINGLE_LUN)) { - mutex_lock(&us->dev_mutex); - us->max_lun = usb_stor_Bulk_max_lun(us); - mutex_unlock(&us->dev_mutex); - } - scsi_scan_host(us_to_host(us)); - dev_dbg(dev, "scan complete\n"); - - /* Should we unbind if no devices were detected? */ - } + /* Should we unbind if no devices were detected? */ usb_autopm_put_interface(us->pusb_intf); - complete_and_exit(&us->scanning_done, 0); + clear_bit(US_FLIDX_SCAN_PENDING, &us->dflags); } static unsigned int usb_stor_sg_tablesize(struct usb_interface *intf) @@ -915,7 +895,7 @@ int usb_stor_probe1(struct us_data **pus, init_completion(&us->cmnd_ready); init_completion(&(us->notify)); init_waitqueue_head(&us->delay_wait); - init_completion(&us->scanning_done); + INIT_DELAYED_WORK(&us->scan_dwork, usb_stor_scan_dwork); /* Associate the us_data structure with the USB device */ result = associate_dev(us, intf); @@ -946,7 +926,6 @@ EXPORT_SYMBOL_GPL(usb_stor_probe1); /* Second part of general USB mass-storage probing */ int usb_stor_probe2(struct us_data *us) { - struct task_struct *th; int result; struct device *dev = &us->pusb_intf->dev; @@ -987,20 +966,14 @@ int usb_stor_probe2(struct us_data *us) goto BadDevice; } - /* Start up the thread for delayed SCSI-device scanning */ - th = kthread_create(usb_stor_scan_thread, us, "usb-stor-scan"); - if (IS_ERR(th)) { - dev_warn(dev, - "Unable to start the device-scanning thread\n"); - complete(&us->scanning_done); - quiesce_and_remove_host(us); - result = PTR_ERR(th); - goto BadDevice; - } - + /* Submit the delayed_work for SCSI-device scanning */ usb_autopm_get_interface_no_resume(us->pusb_intf); - wake_up_process(th); + set_bit(US_FLIDX_SCAN_PENDING, &us->dflags); + if (delay_use > 0) + dev_dbg(dev, "waiting for device to settle before scanning\n"); + queue_delayed_work(system_freezable_wq, &us->scan_dwork, + delay_use * HZ); return 0; /* We come here if there are any problems */ @@ -1073,6 +1046,7 @@ static struct usb_driver usb_storage_driver = { .id_table = usb_storage_usb_ids, .supports_autosuspend = 1, .soft_unbind = 1, + .no_dynamic_id = 1, }; static int __init usb_stor_init(void) diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 7b0f2113632..75f70f04f37 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h @@ -47,6 +47,7 @@ #include <linux/blkdev.h> #include <linux/completion.h> #include <linux/mutex.h> +#include <linux/workqueue.h> #include <scsi/scsi_host.h> struct us_data; @@ -72,7 +73,7 @@ struct us_unusual_dev { #define US_FLIDX_DISCONNECTING 3 /* disconnect in progress */ #define US_FLIDX_RESETTING 4 /* device reset in progress */ #define US_FLIDX_TIMED_OUT 5 /* SCSI midlayer timed out */ -#define US_FLIDX_DONT_SCAN 6 /* don't scan (disconnect) */ +#define US_FLIDX_SCAN_PENDING 6 /* scanning not yet done */ #define US_FLIDX_REDO_READ10 7 /* redo READ(10) command */ #define US_FLIDX_READ10_WORKED 8 /* previous READ(10) succeeded */ @@ -147,8 +148,8 @@ struct us_data { /* mutual exclusion and synchronization structures */ struct completion cmnd_ready; /* to sleep thread on */ struct completion notify; /* thread begin/end */ - wait_queue_head_t delay_wait; /* wait during scan, reset */ - struct completion scanning_done; /* wait for scan thread */ + wait_queue_head_t delay_wait; /* wait during reset */ + struct delayed_work scan_dwork; /* for async scanning */ /* subdriver information */ void *extra; /* Any extra data */ |