X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fusb%2Fstorage%2Fusb.c;fp=drivers%2Fusb%2Fstorage%2Fusb.c;h=dbcf23980ff13f3f305857b78f297c1838940d69;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=8d7bdcb5924d402f891cbf1a07c2584400a28cb3;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 8d7bdcb59..dbcf23980 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -47,6 +47,7 @@ * 675 Mass Ave, Cambridge, MA 02139, USA. */ +#include #include #include #include @@ -54,8 +55,6 @@ #include #include #include -#include -#include #include #include @@ -189,7 +188,7 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message) struct us_data *us = usb_get_intfdata(iface); /* Wait until no command is running */ - mutex_lock(&us->dev_mutex); + down(&us->dev_semaphore); US_DEBUGP("%s\n", __FUNCTION__); if (us->suspend_resume_hook) @@ -199,7 +198,7 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message) /* When runtime PM is working, we'll set a flag to indicate * whether we should autoresume when a SCSI request arrives. */ - mutex_unlock(&us->dev_mutex); + up(&us->dev_semaphore); return 0; } @@ -207,50 +206,19 @@ static int storage_resume(struct usb_interface *iface) { struct us_data *us = usb_get_intfdata(iface); - mutex_lock(&us->dev_mutex); + down(&us->dev_semaphore); US_DEBUGP("%s\n", __FUNCTION__); if (us->suspend_resume_hook) (us->suspend_resume_hook)(us, US_RESUME); iface->dev.power.power_state.event = PM_EVENT_ON; - mutex_unlock(&us->dev_mutex); + up(&us->dev_semaphore); return 0; } #endif /* CONFIG_PM */ -/* - * The next two routines get called just before and just after - * a USB port reset, whether from this driver or a different one. - */ - -static void storage_pre_reset(struct usb_interface *iface) -{ - struct us_data *us = usb_get_intfdata(iface); - - US_DEBUGP("%s\n", __FUNCTION__); - - /* Make sure no command runs during the reset */ - mutex_lock(&us->dev_mutex); -} - -static void storage_post_reset(struct usb_interface *iface) -{ - struct us_data *us = usb_get_intfdata(iface); - - US_DEBUGP("%s\n", __FUNCTION__); - - /* Report the reset to the SCSI core */ - scsi_lock(us_to_host(us)); - usb_stor_report_bus_reset(us); - scsi_unlock(us_to_host(us)); - - /* FIXME: Notify the subdrivers that they need to reinitialize - * the device */ - mutex_unlock(&us->dev_mutex); -} - /* * fill_inquiry_response takes an unsigned char array (which must * be at least 36 characters) and populates the vendor name, @@ -308,12 +276,12 @@ static int usb_stor_control_thread(void * __us) US_DEBUGP("*** thread awakened.\n"); /* lock the device pointers */ - mutex_lock(&(us->dev_mutex)); + down(&(us->dev_semaphore)); /* if the device has disconnected, we are free to exit */ if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { US_DEBUGP("-- exiting\n"); - mutex_unlock(&us->dev_mutex); + up(&(us->dev_semaphore)); break; } @@ -374,12 +342,8 @@ static int usb_stor_control_thread(void * __us) /* lock access to the state */ scsi_lock(host); - /* did the command already complete because of a disconnect? */ - if (!us->srb) - ; /* nothing to do */ - /* indicate that the command is done */ - else if (us->srb->result != DID_ABORT << 16) { + if (us->srb->result != DID_ABORT << 16) { US_DEBUGP("scsi cmd done, result=0x%x\n", us->srb->result); us->srb->scsi_done(us->srb); @@ -406,7 +370,7 @@ SkipForAbort: scsi_unlock(host); /* unlock the device pointers */ - mutex_unlock(&us->dev_mutex); + up(&(us->dev_semaphore)); } /* for (;;) */ scsi_host_put(host); @@ -483,7 +447,7 @@ static struct us_unusual_dev *find_unusual(const struct usb_device_id *id) } /* Get the unusual_devs entries and the string descriptors */ -static int get_device_info(struct us_data *us, const struct usb_device_id *id) +static void get_device_info(struct us_data *us, const struct usb_device_id *id) { struct usb_device *dev = us->pusb_dev; struct usb_interface_descriptor *idesc = @@ -500,11 +464,6 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id) unusual_dev->useTransport; us->flags = USB_US_ORIG_FLAGS(id->driver_info); - if (us->flags & US_FL_IGNORE_DEVICE) { - printk(KERN_INFO USB_STORAGE "device ignored\n"); - return -ENODEV; - } - /* * This flag is only needed when we're in high-speed, so let's * disable it if we're in full-speed @@ -534,8 +493,7 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id) if (msg >= 0 && !(us->flags & US_FL_NEED_OVERRIDE)) printk(KERN_NOTICE USB_STORAGE "This device " "(%04x,%04x,%04x S %02x P %02x)" - " has %s in unusual_devs.h (kernel" - " %s)\n" + " has %s in unusual_devs.h\n" " Please send a copy of this message to " "\n", le16_to_cpu(ddesc->idVendor), @@ -543,11 +501,8 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id) le16_to_cpu(ddesc->bcdDevice), idesc->bInterfaceSubClass, idesc->bInterfaceProtocol, - msgs[msg], - UTS_RELEASE); + msgs[msg]); } - - return 0; } /* Get the transport settings */ @@ -637,15 +592,6 @@ static int get_transport(struct us_data *us) break; #endif -#ifdef CONFIG_USB_STORAGE_ALAUDA - case US_PR_ALAUDA: - us->transport_name = "Alauda Control/Bulk"; - us->transport = alauda_transport; - us->transport_reset = usb_stor_Bulk_reset; - us->max_lun = 1; - break; -#endif - default: return -EIO; } @@ -701,6 +647,15 @@ static int get_protocol(struct us_data *us) break; #endif +#ifdef CONFIG_USB_STORAGE_ALAUDA + case US_PR_ALAUDA: + us->transport_name = "Alauda Control/Bulk"; + us->transport = alauda_transport; + us->transport_reset = usb_stor_Bulk_reset; + us->max_lun = 1; + break; +#endif + default: return -EIO; } @@ -850,34 +805,32 @@ static void dissociate_dev(struct us_data *us) * the host */ static void quiesce_and_remove_host(struct us_data *us) { - struct Scsi_Host *host = us_to_host(us); - /* Prevent new USB transfers, stop the current command, and * interrupt a SCSI-scan or device-reset delay */ - scsi_lock(host); set_bit(US_FLIDX_DISCONNECTING, &us->flags); - scsi_unlock(host); usb_stor_stop_transport(us); wake_up(&us->delay_wait); /* It doesn't matter if the SCSI-scanning thread is still running. * The thread will exit when it sees the DISCONNECTING flag. */ + /* Wait for the current command to finish, then remove the host */ + down(&us->dev_semaphore); + up(&us->dev_semaphore); + /* queuecommand won't accept any new commands and the control * thread won't execute a previously-queued command. If there * is such a command pending, complete it with an error. */ - mutex_lock(&us->dev_mutex); if (us->srb) { us->srb->result = DID_NO_CONNECT << 16; - scsi_lock(host); + scsi_lock(us_to_host(us)); us->srb->scsi_done(us->srb); us->srb = NULL; - scsi_unlock(host); + scsi_unlock(us_to_host(us)); } - mutex_unlock(&us->dev_mutex); /* Now we own no commands so it's safe to remove the SCSI host */ - scsi_remove_host(host); + scsi_remove_host(us_to_host(us)); } /* Second stage of disconnect processing: deallocate all resources */ @@ -917,9 +870,9 @@ retry: /* For bulk-only devices, determine the max LUN value */ if (us->protocol == US_PR_BULK && !(us->flags & US_FL_SINGLE_LUN)) { - mutex_lock(&us->dev_mutex); + down(&us->dev_semaphore); us->max_lun = usb_stor_Bulk_max_lun(us); - mutex_unlock(&us->dev_mutex); + up(&us->dev_semaphore); } scsi_scan_host(us_to_host(us)); printk(KERN_DEBUG "usb-storage: device scan complete\n"); @@ -959,7 +912,7 @@ static int storage_probe(struct usb_interface *intf, us = host_to_us(host); memset(us, 0, sizeof(struct us_data)); - mutex_init(&(us->dev_mutex)); + init_MUTEX(&(us->dev_semaphore)); init_MUTEX_LOCKED(&(us->sema)); init_completion(&(us->notify)); init_waitqueue_head(&us->delay_wait); @@ -976,9 +929,7 @@ static int storage_probe(struct usb_interface *intf, * of the match from the usb_device_id table, so we can find the * corresponding entry in the private table. */ - result = get_device_info(us, id); - if (result) - goto BadDevice; + get_device_info(us, id); /* Get the transport, protocol, and pipe settings */ result = get_transport(us); @@ -1050,8 +1001,6 @@ static struct usb_driver usb_storage_driver = { .suspend = storage_suspend, .resume = storage_resume, #endif - .pre_reset = storage_pre_reset, - .post_reset = storage_post_reset, .id_table = storage_usb_ids, };