diff options
Diffstat (limited to 'drivers/usb/storage/usb.c')
-rw-r--r-- | drivers/usb/storage/usb.c | 54 |
1 files changed, 41 insertions, 13 deletions
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index e232c7c8990..b8d6031b097 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -47,7 +47,6 @@ | |||
47 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 47 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
48 | */ | 48 | */ |
49 | 49 | ||
50 | #include <linux/config.h> | ||
51 | #include <linux/sched.h> | 50 | #include <linux/sched.h> |
52 | #include <linux/errno.h> | 51 | #include <linux/errno.h> |
53 | #include <linux/suspend.h> | 52 | #include <linux/suspend.h> |
@@ -56,6 +55,7 @@ | |||
56 | #include <linux/slab.h> | 55 | #include <linux/slab.h> |
57 | #include <linux/kthread.h> | 56 | #include <linux/kthread.h> |
58 | #include <linux/mutex.h> | 57 | #include <linux/mutex.h> |
58 | #include <linux/utsrelease.h> | ||
59 | 59 | ||
60 | #include <scsi/scsi.h> | 60 | #include <scsi/scsi.h> |
61 | #include <scsi/scsi_cmnd.h> | 61 | #include <scsi/scsi_cmnd.h> |
@@ -98,6 +98,9 @@ | |||
98 | #ifdef CONFIG_USB_STORAGE_ALAUDA | 98 | #ifdef CONFIG_USB_STORAGE_ALAUDA |
99 | #include "alauda.h" | 99 | #include "alauda.h" |
100 | #endif | 100 | #endif |
101 | #ifdef CONFIG_USB_STORAGE_KARMA | ||
102 | #include "karma.h" | ||
103 | #endif | ||
101 | 104 | ||
102 | /* Some informational data */ | 105 | /* Some informational data */ |
103 | MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); | 106 | MODULE_AUTHOR("Matthew Dharm <mdharm-usb@one-eyed-alien.net>"); |
@@ -374,8 +377,12 @@ static int usb_stor_control_thread(void * __us) | |||
374 | /* lock access to the state */ | 377 | /* lock access to the state */ |
375 | scsi_lock(host); | 378 | scsi_lock(host); |
376 | 379 | ||
380 | /* did the command already complete because of a disconnect? */ | ||
381 | if (!us->srb) | ||
382 | ; /* nothing to do */ | ||
383 | |||
377 | /* indicate that the command is done */ | 384 | /* indicate that the command is done */ |
378 | if (us->srb->result != DID_ABORT << 16) { | 385 | else if (us->srb->result != DID_ABORT << 16) { |
379 | US_DEBUGP("scsi cmd done, result=0x%x\n", | 386 | US_DEBUGP("scsi cmd done, result=0x%x\n", |
380 | us->srb->result); | 387 | us->srb->result); |
381 | us->srb->scsi_done(us->srb); | 388 | us->srb->scsi_done(us->srb); |
@@ -479,7 +486,7 @@ static struct us_unusual_dev *find_unusual(const struct usb_device_id *id) | |||
479 | } | 486 | } |
480 | 487 | ||
481 | /* Get the unusual_devs entries and the string descriptors */ | 488 | /* Get the unusual_devs entries and the string descriptors */ |
482 | static void get_device_info(struct us_data *us, const struct usb_device_id *id) | 489 | static int get_device_info(struct us_data *us, const struct usb_device_id *id) |
483 | { | 490 | { |
484 | struct usb_device *dev = us->pusb_dev; | 491 | struct usb_device *dev = us->pusb_dev; |
485 | struct usb_interface_descriptor *idesc = | 492 | struct usb_interface_descriptor *idesc = |
@@ -496,6 +503,11 @@ static void get_device_info(struct us_data *us, const struct usb_device_id *id) | |||
496 | unusual_dev->useTransport; | 503 | unusual_dev->useTransport; |
497 | us->flags = USB_US_ORIG_FLAGS(id->driver_info); | 504 | us->flags = USB_US_ORIG_FLAGS(id->driver_info); |
498 | 505 | ||
506 | if (us->flags & US_FL_IGNORE_DEVICE) { | ||
507 | printk(KERN_INFO USB_STORAGE "device ignored\n"); | ||
508 | return -ENODEV; | ||
509 | } | ||
510 | |||
499 | /* | 511 | /* |
500 | * This flag is only needed when we're in high-speed, so let's | 512 | * This flag is only needed when we're in high-speed, so let's |
501 | * disable it if we're in full-speed | 513 | * disable it if we're in full-speed |
@@ -525,7 +537,8 @@ static void get_device_info(struct us_data *us, const struct usb_device_id *id) | |||
525 | if (msg >= 0 && !(us->flags & US_FL_NEED_OVERRIDE)) | 537 | if (msg >= 0 && !(us->flags & US_FL_NEED_OVERRIDE)) |
526 | printk(KERN_NOTICE USB_STORAGE "This device " | 538 | printk(KERN_NOTICE USB_STORAGE "This device " |
527 | "(%04x,%04x,%04x S %02x P %02x)" | 539 | "(%04x,%04x,%04x S %02x P %02x)" |
528 | " has %s in unusual_devs.h\n" | 540 | " has %s in unusual_devs.h (kernel" |
541 | " %s)\n" | ||
529 | " Please send a copy of this message to " | 542 | " Please send a copy of this message to " |
530 | "<linux-usb-devel@lists.sourceforge.net>\n", | 543 | "<linux-usb-devel@lists.sourceforge.net>\n", |
531 | le16_to_cpu(ddesc->idVendor), | 544 | le16_to_cpu(ddesc->idVendor), |
@@ -533,8 +546,11 @@ static void get_device_info(struct us_data *us, const struct usb_device_id *id) | |||
533 | le16_to_cpu(ddesc->bcdDevice), | 546 | le16_to_cpu(ddesc->bcdDevice), |
534 | idesc->bInterfaceSubClass, | 547 | idesc->bInterfaceSubClass, |
535 | idesc->bInterfaceProtocol, | 548 | idesc->bInterfaceProtocol, |
536 | msgs[msg]); | 549 | msgs[msg], |
550 | UTS_RELEASE); | ||
537 | } | 551 | } |
552 | |||
553 | return 0; | ||
538 | } | 554 | } |
539 | 555 | ||
540 | /* Get the transport settings */ | 556 | /* Get the transport settings */ |
@@ -633,6 +649,14 @@ static int get_transport(struct us_data *us) | |||
633 | break; | 649 | break; |
634 | #endif | 650 | #endif |
635 | 651 | ||
652 | #ifdef CONFIG_USB_STORAGE_KARMA | ||
653 | case US_PR_KARMA: | ||
654 | us->transport_name = "Rio Karma/Bulk"; | ||
655 | us->transport = rio_karma_transport; | ||
656 | us->transport_reset = usb_stor_Bulk_reset; | ||
657 | break; | ||
658 | #endif | ||
659 | |||
636 | default: | 660 | default: |
637 | return -EIO; | 661 | return -EIO; |
638 | } | 662 | } |
@@ -837,32 +861,34 @@ static void dissociate_dev(struct us_data *us) | |||
837 | * the host */ | 861 | * the host */ |
838 | static void quiesce_and_remove_host(struct us_data *us) | 862 | static void quiesce_and_remove_host(struct us_data *us) |
839 | { | 863 | { |
864 | struct Scsi_Host *host = us_to_host(us); | ||
865 | |||
840 | /* Prevent new USB transfers, stop the current command, and | 866 | /* Prevent new USB transfers, stop the current command, and |
841 | * interrupt a SCSI-scan or device-reset delay */ | 867 | * interrupt a SCSI-scan or device-reset delay */ |
868 | scsi_lock(host); | ||
842 | set_bit(US_FLIDX_DISCONNECTING, &us->flags); | 869 | set_bit(US_FLIDX_DISCONNECTING, &us->flags); |
870 | scsi_unlock(host); | ||
843 | usb_stor_stop_transport(us); | 871 | usb_stor_stop_transport(us); |
844 | wake_up(&us->delay_wait); | 872 | wake_up(&us->delay_wait); |
845 | 873 | ||
846 | /* It doesn't matter if the SCSI-scanning thread is still running. | 874 | /* It doesn't matter if the SCSI-scanning thread is still running. |
847 | * The thread will exit when it sees the DISCONNECTING flag. */ | 875 | * The thread will exit when it sees the DISCONNECTING flag. */ |
848 | 876 | ||
849 | /* Wait for the current command to finish, then remove the host */ | ||
850 | mutex_lock(&us->dev_mutex); | ||
851 | mutex_unlock(&us->dev_mutex); | ||
852 | |||
853 | /* queuecommand won't accept any new commands and the control | 877 | /* queuecommand won't accept any new commands and the control |
854 | * thread won't execute a previously-queued command. If there | 878 | * thread won't execute a previously-queued command. If there |
855 | * is such a command pending, complete it with an error. */ | 879 | * is such a command pending, complete it with an error. */ |
880 | mutex_lock(&us->dev_mutex); | ||
856 | if (us->srb) { | 881 | if (us->srb) { |
857 | us->srb->result = DID_NO_CONNECT << 16; | 882 | us->srb->result = DID_NO_CONNECT << 16; |
858 | scsi_lock(us_to_host(us)); | 883 | scsi_lock(host); |
859 | us->srb->scsi_done(us->srb); | 884 | us->srb->scsi_done(us->srb); |
860 | us->srb = NULL; | 885 | us->srb = NULL; |
861 | scsi_unlock(us_to_host(us)); | 886 | scsi_unlock(host); |
862 | } | 887 | } |
888 | mutex_unlock(&us->dev_mutex); | ||
863 | 889 | ||
864 | /* Now we own no commands so it's safe to remove the SCSI host */ | 890 | /* Now we own no commands so it's safe to remove the SCSI host */ |
865 | scsi_remove_host(us_to_host(us)); | 891 | scsi_remove_host(host); |
866 | } | 892 | } |
867 | 893 | ||
868 | /* Second stage of disconnect processing: deallocate all resources */ | 894 | /* Second stage of disconnect processing: deallocate all resources */ |
@@ -961,7 +987,9 @@ static int storage_probe(struct usb_interface *intf, | |||
961 | * of the match from the usb_device_id table, so we can find the | 987 | * of the match from the usb_device_id table, so we can find the |
962 | * corresponding entry in the private table. | 988 | * corresponding entry in the private table. |
963 | */ | 989 | */ |
964 | get_device_info(us, id); | 990 | result = get_device_info(us, id); |
991 | if (result) | ||
992 | goto BadDevice; | ||
965 | 993 | ||
966 | /* Get the transport, protocol, and pipe settings */ | 994 | /* Get the transport, protocol, and pipe settings */ |
967 | result = get_transport(us); | 995 | result = get_transport(us); |