Loading Documentation/ABI/testing/sysfs-bus-usb +11 −0 Original line number Diff line number Diff line Loading @@ -182,3 +182,14 @@ Description: USB2 hardware LPM is enabled for the device. Developer can write y/Y/1 or n/N/0 to the file to enable/disable the feature. What: /sys/bus/usb/devices/.../removable Date: February 2012 Contact: Matthew Garrett <mjg@redhat.com> Description: Some information about whether a given USB device is physically fixed to the platform can be inferred from a combination of hub decriptor bits and platform-specific data such as ACPI. This file will read either "removable" or "fixed" if the information is available, and "unknown" otherwise. No newline at end of file drivers/scsi/scsi_scan.c +4 −0 Original line number Diff line number Diff line Loading @@ -1295,6 +1295,7 @@ EXPORT_SYMBOL(int_to_scsilun); * LUNs even if it's older than SCSI-3. * If BLIST_NOREPORTLUN is set, return 1 always. * If BLIST_NOLUN is set, return 0 always. * If starget->no_report_luns is set, return 1 always. * * Return: * 0: scan completed (or no memory, so further scanning is futile) Loading @@ -1321,6 +1322,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, * Only support SCSI-3 and up devices if BLIST_NOREPORTLUN is not set. * Also allow SCSI-2 if BLIST_REPORTLUN2 is set and host adapter does * support more than 8 LUNs. * Don't attempt if the target doesn't support REPORT LUNS. */ if (bflags & BLIST_NOREPORTLUN) return 1; Loading @@ -1332,6 +1334,8 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, return 1; if (bflags & BLIST_NOLUN) return 0; if (starget->no_report_luns) return 1; if (!(sdev = scsi_device_lookup_by_target(starget, 0))) { sdev = scsi_alloc_sdev(starget, 0, NULL); Loading drivers/scsi/sd.c +1 −1 Original line number Diff line number Diff line Loading @@ -2349,7 +2349,7 @@ static int sd_try_extended_inquiry(struct scsi_device *sdp) * some USB ones crash on receiving them, and the pages * we currently ask for are for SPC-3 and beyond */ if (sdp->scsi_level > SCSI_SPC_2) if (sdp->scsi_level > SCSI_SPC_2 && !sdp->skip_vpd_pages) return 1; return 0; } Loading drivers/usb/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -76,6 +76,7 @@ config USB_ARCH_HAS_EHCI default y if MICROBLAZE default y if SPARC_LEON default y if ARCH_MMP default y if MACH_LOONGSON1 default PCI # some non-PCI HCDs implement xHCI Loading drivers/usb/class/cdc-wdm.c +61 −58 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ #define DRIVER_AUTHOR "Oliver Neukum" #define DRIVER_DESC "USB Abstract Control Model driver for USB WCM Device Management" #define HUAWEI_VENDOR_ID 0x12D1 static const struct usb_device_id wdm_ids[] = { { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS | Loading @@ -38,6 +40,20 @@ static const struct usb_device_id wdm_ids[] = { .bInterfaceClass = USB_CLASS_COMM, .bInterfaceSubClass = USB_CDC_SUBCLASS_DMM }, { /* * Huawei E392, E398 and possibly other Qualcomm based modems * embed the Qualcomm QMI protocol inside CDC on CDC ECM like * control interfaces. Userspace access to this is required * to configure the accompanying data interface */ .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, .idVendor = HUAWEI_VENDOR_ID, .bInterfaceClass = USB_CLASS_VENDOR_SPEC, .bInterfaceSubClass = 1, .bInterfaceProtocol = 9, /* NOTE: CDC ECM control interface! */ }, { } }; Loading @@ -54,6 +70,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); #define WDM_POLL_RUNNING 6 #define WDM_RESPONDING 7 #define WDM_SUSPENDING 8 #define WDM_RESETTING 9 #define WDM_MAX 16 Loading Loading @@ -82,7 +99,6 @@ struct wdm_device { u16 bufsize; u16 wMaxCommand; u16 wMaxPacketSize; u16 bMaxPacketSize0; __le16 inum; int reslength; int length; Loading Loading @@ -162,11 +178,9 @@ static void wdm_int_callback(struct urb *urb) int rv = 0; int status = urb->status; struct wdm_device *desc; struct usb_ctrlrequest *req; struct usb_cdc_notification *dr; desc = urb->context; req = desc->irq; dr = (struct usb_cdc_notification *)desc->sbuf; if (status) { Loading Loading @@ -213,24 +227,6 @@ static void wdm_int_callback(struct urb *urb) goto exit; } req->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE); req->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE; req->wValue = 0; req->wIndex = desc->inum; req->wLength = cpu_to_le16(desc->wMaxCommand); usb_fill_control_urb( desc->response, interface_to_usbdev(desc->intf), /* using common endpoint 0 */ usb_rcvctrlpipe(interface_to_usbdev(desc->intf), 0), (unsigned char *)req, desc->inbuf, desc->wMaxCommand, wdm_in_callback, desc ); desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; spin_lock(&desc->iuspin); clear_bit(WDM_READ, &desc->flags); set_bit(WDM_RESPONDING, &desc->flags); Loading Loading @@ -279,14 +275,8 @@ static void free_urbs(struct wdm_device *desc) static void cleanup(struct wdm_device *desc) { usb_free_coherent(interface_to_usbdev(desc->intf), desc->wMaxPacketSize, desc->sbuf, desc->validity->transfer_dma); usb_free_coherent(interface_to_usbdev(desc->intf), desc->bMaxPacketSize0, desc->inbuf, desc->response->transfer_dma); kfree(desc->sbuf); kfree(desc->inbuf); kfree(desc->orq); kfree(desc->irq); kfree(desc->ubuf); Loading Loading @@ -351,6 +341,10 @@ static ssize_t wdm_write else if (test_bit(WDM_IN_USE, &desc->flags)) r = -EAGAIN; if (test_bit(WDM_RESETTING, &desc->flags)) r = -EIO; if (r < 0) { kfree(buf); goto out; Loading Loading @@ -430,6 +424,10 @@ static ssize_t wdm_read rv = -ENODEV; goto err; } if (test_bit(WDM_RESETTING, &desc->flags)) { rv = -EIO; goto err; } usb_mark_last_busy(interface_to_usbdev(desc->intf)); if (rv < 0) { rv = -ERESTARTSYS; Loading Loading @@ -631,7 +629,6 @@ static void wdm_rxwork(struct work_struct *work) static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) { int rv = -EINVAL; struct usb_device *udev = interface_to_usbdev(intf); struct wdm_device *desc; struct usb_host_interface *iface; struct usb_endpoint_descriptor *ep; Loading Loading @@ -692,7 +689,6 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) goto err; desc->wMaxPacketSize = usb_endpoint_maxp(ep); desc->bMaxPacketSize0 = udev->descriptor.bMaxPacketSize0; desc->orq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); if (!desc->orq) Loading @@ -717,19 +713,13 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) if (!desc->ubuf) goto err; desc->sbuf = usb_alloc_coherent(interface_to_usbdev(intf), desc->wMaxPacketSize, GFP_KERNEL, &desc->validity->transfer_dma); desc->sbuf = kmalloc(desc->wMaxPacketSize, GFP_KERNEL); if (!desc->sbuf) goto err; desc->inbuf = usb_alloc_coherent(interface_to_usbdev(intf), desc->wMaxCommand, GFP_KERNEL, &desc->response->transfer_dma); desc->inbuf = kmalloc(desc->wMaxCommand, GFP_KERNEL); if (!desc->inbuf) goto err2; goto err; usb_fill_int_urb( desc->validity, Loading @@ -741,30 +731,39 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) desc, ep->bInterval ); desc->validity->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; desc->irq->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE); desc->irq->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE; desc->irq->wValue = 0; desc->irq->wIndex = desc->inum; desc->irq->wLength = cpu_to_le16(desc->wMaxCommand); usb_fill_control_urb( desc->response, interface_to_usbdev(intf), /* using common endpoint 0 */ usb_rcvctrlpipe(interface_to_usbdev(desc->intf), 0), (unsigned char *)desc->irq, desc->inbuf, desc->wMaxCommand, wdm_in_callback, desc ); usb_set_intfdata(intf, desc); rv = usb_register_dev(intf, &wdm_class); if (rv < 0) goto err3; goto err2; else dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n", intf->minor - WDM_MINOR_BASE); dev_info(&intf->dev, "%s: USB WDM device\n", dev_name(intf->usb_dev)); out: return rv; err3: usb_set_intfdata(intf, NULL); usb_free_coherent(interface_to_usbdev(desc->intf), desc->bMaxPacketSize0, desc->inbuf, desc->response->transfer_dma); err2: usb_free_coherent(interface_to_usbdev(desc->intf), desc->wMaxPacketSize, desc->sbuf, desc->validity->transfer_dma); usb_set_intfdata(intf, NULL); err: free_urbs(desc); kfree(desc->inbuf); kfree(desc->sbuf); kfree(desc->ubuf); kfree(desc->orq); kfree(desc->irq); Loading Loading @@ -869,10 +868,6 @@ static int wdm_pre_reset(struct usb_interface *intf) { struct wdm_device *desc = usb_get_intfdata(intf); mutex_lock(&desc->rlock); mutex_lock(&desc->wlock); kill_urbs(desc); /* * we notify everybody using poll of * an exceptional situation Loading @@ -880,9 +875,16 @@ static int wdm_pre_reset(struct usb_interface *intf) * message from the device is lost */ spin_lock_irq(&desc->iuspin); set_bit(WDM_RESETTING, &desc->flags); /* inform read/write */ set_bit(WDM_READ, &desc->flags); /* unblock read */ clear_bit(WDM_IN_USE, &desc->flags); /* unblock write */ desc->rerr = -EINTR; spin_unlock_irq(&desc->iuspin); wake_up_all(&desc->wait); mutex_lock(&desc->rlock); mutex_lock(&desc->wlock); kill_urbs(desc); cancel_work_sync(&desc->rxwork); return 0; } Loading @@ -891,6 +893,7 @@ static int wdm_post_reset(struct usb_interface *intf) struct wdm_device *desc = usb_get_intfdata(intf); int rv; clear_bit(WDM_RESETTING, &desc->flags); rv = recover_from_urb_loss(desc); mutex_unlock(&desc->wlock); mutex_unlock(&desc->rlock); Loading Loading
Documentation/ABI/testing/sysfs-bus-usb +11 −0 Original line number Diff line number Diff line Loading @@ -182,3 +182,14 @@ Description: USB2 hardware LPM is enabled for the device. Developer can write y/Y/1 or n/N/0 to the file to enable/disable the feature. What: /sys/bus/usb/devices/.../removable Date: February 2012 Contact: Matthew Garrett <mjg@redhat.com> Description: Some information about whether a given USB device is physically fixed to the platform can be inferred from a combination of hub decriptor bits and platform-specific data such as ACPI. This file will read either "removable" or "fixed" if the information is available, and "unknown" otherwise. No newline at end of file
drivers/scsi/scsi_scan.c +4 −0 Original line number Diff line number Diff line Loading @@ -1295,6 +1295,7 @@ EXPORT_SYMBOL(int_to_scsilun); * LUNs even if it's older than SCSI-3. * If BLIST_NOREPORTLUN is set, return 1 always. * If BLIST_NOLUN is set, return 0 always. * If starget->no_report_luns is set, return 1 always. * * Return: * 0: scan completed (or no memory, so further scanning is futile) Loading @@ -1321,6 +1322,7 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, * Only support SCSI-3 and up devices if BLIST_NOREPORTLUN is not set. * Also allow SCSI-2 if BLIST_REPORTLUN2 is set and host adapter does * support more than 8 LUNs. * Don't attempt if the target doesn't support REPORT LUNS. */ if (bflags & BLIST_NOREPORTLUN) return 1; Loading @@ -1332,6 +1334,8 @@ static int scsi_report_lun_scan(struct scsi_target *starget, int bflags, return 1; if (bflags & BLIST_NOLUN) return 0; if (starget->no_report_luns) return 1; if (!(sdev = scsi_device_lookup_by_target(starget, 0))) { sdev = scsi_alloc_sdev(starget, 0, NULL); Loading
drivers/scsi/sd.c +1 −1 Original line number Diff line number Diff line Loading @@ -2349,7 +2349,7 @@ static int sd_try_extended_inquiry(struct scsi_device *sdp) * some USB ones crash on receiving them, and the pages * we currently ask for are for SPC-3 and beyond */ if (sdp->scsi_level > SCSI_SPC_2) if (sdp->scsi_level > SCSI_SPC_2 && !sdp->skip_vpd_pages) return 1; return 0; } Loading
drivers/usb/Kconfig +1 −0 Original line number Diff line number Diff line Loading @@ -76,6 +76,7 @@ config USB_ARCH_HAS_EHCI default y if MICROBLAZE default y if SPARC_LEON default y if ARCH_MMP default y if MACH_LOONGSON1 default PCI # some non-PCI HCDs implement xHCI Loading
drivers/usb/class/cdc-wdm.c +61 −58 Original line number Diff line number Diff line Loading @@ -31,6 +31,8 @@ #define DRIVER_AUTHOR "Oliver Neukum" #define DRIVER_DESC "USB Abstract Control Model driver for USB WCM Device Management" #define HUAWEI_VENDOR_ID 0x12D1 static const struct usb_device_id wdm_ids[] = { { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS | Loading @@ -38,6 +40,20 @@ static const struct usb_device_id wdm_ids[] = { .bInterfaceClass = USB_CLASS_COMM, .bInterfaceSubClass = USB_CDC_SUBCLASS_DMM }, { /* * Huawei E392, E398 and possibly other Qualcomm based modems * embed the Qualcomm QMI protocol inside CDC on CDC ECM like * control interfaces. Userspace access to this is required * to configure the accompanying data interface */ .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, .idVendor = HUAWEI_VENDOR_ID, .bInterfaceClass = USB_CLASS_VENDOR_SPEC, .bInterfaceSubClass = 1, .bInterfaceProtocol = 9, /* NOTE: CDC ECM control interface! */ }, { } }; Loading @@ -54,6 +70,7 @@ MODULE_DEVICE_TABLE (usb, wdm_ids); #define WDM_POLL_RUNNING 6 #define WDM_RESPONDING 7 #define WDM_SUSPENDING 8 #define WDM_RESETTING 9 #define WDM_MAX 16 Loading Loading @@ -82,7 +99,6 @@ struct wdm_device { u16 bufsize; u16 wMaxCommand; u16 wMaxPacketSize; u16 bMaxPacketSize0; __le16 inum; int reslength; int length; Loading Loading @@ -162,11 +178,9 @@ static void wdm_int_callback(struct urb *urb) int rv = 0; int status = urb->status; struct wdm_device *desc; struct usb_ctrlrequest *req; struct usb_cdc_notification *dr; desc = urb->context; req = desc->irq; dr = (struct usb_cdc_notification *)desc->sbuf; if (status) { Loading Loading @@ -213,24 +227,6 @@ static void wdm_int_callback(struct urb *urb) goto exit; } req->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE); req->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE; req->wValue = 0; req->wIndex = desc->inum; req->wLength = cpu_to_le16(desc->wMaxCommand); usb_fill_control_urb( desc->response, interface_to_usbdev(desc->intf), /* using common endpoint 0 */ usb_rcvctrlpipe(interface_to_usbdev(desc->intf), 0), (unsigned char *)req, desc->inbuf, desc->wMaxCommand, wdm_in_callback, desc ); desc->response->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; spin_lock(&desc->iuspin); clear_bit(WDM_READ, &desc->flags); set_bit(WDM_RESPONDING, &desc->flags); Loading Loading @@ -279,14 +275,8 @@ static void free_urbs(struct wdm_device *desc) static void cleanup(struct wdm_device *desc) { usb_free_coherent(interface_to_usbdev(desc->intf), desc->wMaxPacketSize, desc->sbuf, desc->validity->transfer_dma); usb_free_coherent(interface_to_usbdev(desc->intf), desc->bMaxPacketSize0, desc->inbuf, desc->response->transfer_dma); kfree(desc->sbuf); kfree(desc->inbuf); kfree(desc->orq); kfree(desc->irq); kfree(desc->ubuf); Loading Loading @@ -351,6 +341,10 @@ static ssize_t wdm_write else if (test_bit(WDM_IN_USE, &desc->flags)) r = -EAGAIN; if (test_bit(WDM_RESETTING, &desc->flags)) r = -EIO; if (r < 0) { kfree(buf); goto out; Loading Loading @@ -430,6 +424,10 @@ static ssize_t wdm_read rv = -ENODEV; goto err; } if (test_bit(WDM_RESETTING, &desc->flags)) { rv = -EIO; goto err; } usb_mark_last_busy(interface_to_usbdev(desc->intf)); if (rv < 0) { rv = -ERESTARTSYS; Loading Loading @@ -631,7 +629,6 @@ static void wdm_rxwork(struct work_struct *work) static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) { int rv = -EINVAL; struct usb_device *udev = interface_to_usbdev(intf); struct wdm_device *desc; struct usb_host_interface *iface; struct usb_endpoint_descriptor *ep; Loading Loading @@ -692,7 +689,6 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) goto err; desc->wMaxPacketSize = usb_endpoint_maxp(ep); desc->bMaxPacketSize0 = udev->descriptor.bMaxPacketSize0; desc->orq = kmalloc(sizeof(struct usb_ctrlrequest), GFP_KERNEL); if (!desc->orq) Loading @@ -717,19 +713,13 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) if (!desc->ubuf) goto err; desc->sbuf = usb_alloc_coherent(interface_to_usbdev(intf), desc->wMaxPacketSize, GFP_KERNEL, &desc->validity->transfer_dma); desc->sbuf = kmalloc(desc->wMaxPacketSize, GFP_KERNEL); if (!desc->sbuf) goto err; desc->inbuf = usb_alloc_coherent(interface_to_usbdev(intf), desc->wMaxCommand, GFP_KERNEL, &desc->response->transfer_dma); desc->inbuf = kmalloc(desc->wMaxCommand, GFP_KERNEL); if (!desc->inbuf) goto err2; goto err; usb_fill_int_urb( desc->validity, Loading @@ -741,30 +731,39 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id) desc, ep->bInterval ); desc->validity->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; desc->irq->bRequestType = (USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE); desc->irq->bRequest = USB_CDC_GET_ENCAPSULATED_RESPONSE; desc->irq->wValue = 0; desc->irq->wIndex = desc->inum; desc->irq->wLength = cpu_to_le16(desc->wMaxCommand); usb_fill_control_urb( desc->response, interface_to_usbdev(intf), /* using common endpoint 0 */ usb_rcvctrlpipe(interface_to_usbdev(desc->intf), 0), (unsigned char *)desc->irq, desc->inbuf, desc->wMaxCommand, wdm_in_callback, desc ); usb_set_intfdata(intf, desc); rv = usb_register_dev(intf, &wdm_class); if (rv < 0) goto err3; goto err2; else dev_info(&intf->dev, "cdc-wdm%d: USB WDM device\n", intf->minor - WDM_MINOR_BASE); dev_info(&intf->dev, "%s: USB WDM device\n", dev_name(intf->usb_dev)); out: return rv; err3: usb_set_intfdata(intf, NULL); usb_free_coherent(interface_to_usbdev(desc->intf), desc->bMaxPacketSize0, desc->inbuf, desc->response->transfer_dma); err2: usb_free_coherent(interface_to_usbdev(desc->intf), desc->wMaxPacketSize, desc->sbuf, desc->validity->transfer_dma); usb_set_intfdata(intf, NULL); err: free_urbs(desc); kfree(desc->inbuf); kfree(desc->sbuf); kfree(desc->ubuf); kfree(desc->orq); kfree(desc->irq); Loading Loading @@ -869,10 +868,6 @@ static int wdm_pre_reset(struct usb_interface *intf) { struct wdm_device *desc = usb_get_intfdata(intf); mutex_lock(&desc->rlock); mutex_lock(&desc->wlock); kill_urbs(desc); /* * we notify everybody using poll of * an exceptional situation Loading @@ -880,9 +875,16 @@ static int wdm_pre_reset(struct usb_interface *intf) * message from the device is lost */ spin_lock_irq(&desc->iuspin); set_bit(WDM_RESETTING, &desc->flags); /* inform read/write */ set_bit(WDM_READ, &desc->flags); /* unblock read */ clear_bit(WDM_IN_USE, &desc->flags); /* unblock write */ desc->rerr = -EINTR; spin_unlock_irq(&desc->iuspin); wake_up_all(&desc->wait); mutex_lock(&desc->rlock); mutex_lock(&desc->wlock); kill_urbs(desc); cancel_work_sync(&desc->rxwork); return 0; } Loading @@ -891,6 +893,7 @@ static int wdm_post_reset(struct usb_interface *intf) struct wdm_device *desc = usb_get_intfdata(intf); int rv; clear_bit(WDM_RESETTING, &desc->flags); rv = recover_from_urb_loss(desc); mutex_unlock(&desc->wlock); mutex_unlock(&desc->rlock); Loading