diff options
Diffstat (limited to 'drivers/usb')
149 files changed, 5050 insertions, 3669 deletions
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 83babb0a1df7..c6c816b7ecb5 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
| @@ -47,6 +47,7 @@ config USB_ARCH_HAS_OHCI | |||
| 47 | default y if CPU_SUBTYPE_SH7720 | 47 | default y if CPU_SUBTYPE_SH7720 |
| 48 | default y if CPU_SUBTYPE_SH7721 | 48 | default y if CPU_SUBTYPE_SH7721 |
| 49 | default y if CPU_SUBTYPE_SH7763 | 49 | default y if CPU_SUBTYPE_SH7763 |
| 50 | default y if CPU_SUBTYPE_SH7786 | ||
| 50 | # more: | 51 | # more: |
| 51 | default PCI | 52 | default PCI |
| 52 | 53 | ||
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index b2ceb4aff233..89299a5ce168 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile | |||
| @@ -19,6 +19,7 @@ obj-$(CONFIG_USB_SL811_HCD) += host/ | |||
| 19 | obj-$(CONFIG_USB_U132_HCD) += host/ | 19 | obj-$(CONFIG_USB_U132_HCD) += host/ |
| 20 | obj-$(CONFIG_USB_R8A66597_HCD) += host/ | 20 | obj-$(CONFIG_USB_R8A66597_HCD) += host/ |
| 21 | obj-$(CONFIG_USB_HWA_HCD) += host/ | 21 | obj-$(CONFIG_USB_HWA_HCD) += host/ |
| 22 | obj-$(CONFIG_USB_ISP1760_HCD) += host/ | ||
| 22 | 23 | ||
| 23 | obj-$(CONFIG_USB_C67X00_HCD) += c67x00/ | 24 | obj-$(CONFIG_USB_C67X00_HCD) += c67x00/ |
| 24 | 25 | ||
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 3f3ee1351930..d2747a49b974 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c | |||
| @@ -880,16 +880,19 @@ static int usblp_wwait(struct usblp *usblp, int nonblock) | |||
| 880 | if (rc <= 0) | 880 | if (rc <= 0) |
| 881 | break; | 881 | break; |
| 882 | 882 | ||
| 883 | if (usblp->flags & LP_ABORT) { | 883 | if (schedule_timeout(msecs_to_jiffies(1500)) == 0) { |
| 884 | if (schedule_timeout(msecs_to_jiffies(5000)) == 0) { | 884 | if (usblp->flags & LP_ABORT) { |
| 885 | err = usblp_check_status(usblp, err); | 885 | err = usblp_check_status(usblp, err); |
| 886 | if (err == 1) { /* Paper out */ | 886 | if (err == 1) { /* Paper out */ |
| 887 | rc = -ENOSPC; | 887 | rc = -ENOSPC; |
| 888 | break; | 888 | break; |
| 889 | } | 889 | } |
| 890 | } else { | ||
| 891 | /* Prod the printer, Gentoo#251237. */ | ||
| 892 | mutex_lock(&usblp->mut); | ||
| 893 | usblp_read_status(usblp, usblp->statusbuf); | ||
| 894 | mutex_unlock(&usblp->mut); | ||
| 890 | } | 895 | } |
| 891 | } else { | ||
| 892 | schedule(); | ||
| 893 | } | 896 | } |
| 894 | } | 897 | } |
| 895 | set_current_state(TASK_RUNNING); | 898 | set_current_state(TASK_RUNNING); |
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index 6ec38175a817..73c108d117b4 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c | |||
| @@ -187,7 +187,7 @@ static char *usb_dump_endpoint_descriptor(int speed, char *start, char *end, | |||
| 187 | } | 187 | } |
| 188 | 188 | ||
| 189 | /* this isn't checking for illegal values */ | 189 | /* this isn't checking for illegal values */ |
| 190 | switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | 190 | switch (usb_endpoint_type(desc)) { |
| 191 | case USB_ENDPOINT_XFER_CONTROL: | 191 | case USB_ENDPOINT_XFER_CONTROL: |
| 192 | type = "Ctrl"; | 192 | type = "Ctrl"; |
| 193 | if (speed == USB_SPEED_HIGH) /* uframes per NAK */ | 193 | if (speed == USB_SPEED_HIGH) /* uframes per NAK */ |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 6585f527e381..df3c539f652a 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
| @@ -104,7 +104,7 @@ MODULE_PARM_DESC(usbfs_snoop, "true to log all usbfs traffic"); | |||
| 104 | 104 | ||
| 105 | #define MAX_USBFS_BUFFER_SIZE 16384 | 105 | #define MAX_USBFS_BUFFER_SIZE 16384 |
| 106 | 106 | ||
| 107 | static inline int connected(struct dev_state *ps) | 107 | static int connected(struct dev_state *ps) |
| 108 | { | 108 | { |
| 109 | return (!list_empty(&ps->list) && | 109 | return (!list_empty(&ps->list) && |
| 110 | ps->dev->state != USB_STATE_NOTATTACHED); | 110 | ps->dev->state != USB_STATE_NOTATTACHED); |
| @@ -248,7 +248,7 @@ static void free_async(struct async *as) | |||
| 248 | kfree(as); | 248 | kfree(as); |
| 249 | } | 249 | } |
| 250 | 250 | ||
| 251 | static inline void async_newpending(struct async *as) | 251 | static void async_newpending(struct async *as) |
| 252 | { | 252 | { |
| 253 | struct dev_state *ps = as->ps; | 253 | struct dev_state *ps = as->ps; |
| 254 | unsigned long flags; | 254 | unsigned long flags; |
| @@ -258,7 +258,7 @@ static inline void async_newpending(struct async *as) | |||
| 258 | spin_unlock_irqrestore(&ps->lock, flags); | 258 | spin_unlock_irqrestore(&ps->lock, flags); |
| 259 | } | 259 | } |
| 260 | 260 | ||
| 261 | static inline void async_removepending(struct async *as) | 261 | static void async_removepending(struct async *as) |
| 262 | { | 262 | { |
| 263 | struct dev_state *ps = as->ps; | 263 | struct dev_state *ps = as->ps; |
| 264 | unsigned long flags; | 264 | unsigned long flags; |
| @@ -268,7 +268,7 @@ static inline void async_removepending(struct async *as) | |||
| 268 | spin_unlock_irqrestore(&ps->lock, flags); | 268 | spin_unlock_irqrestore(&ps->lock, flags); |
| 269 | } | 269 | } |
| 270 | 270 | ||
| 271 | static inline struct async *async_getcompleted(struct dev_state *ps) | 271 | static struct async *async_getcompleted(struct dev_state *ps) |
| 272 | { | 272 | { |
| 273 | unsigned long flags; | 273 | unsigned long flags; |
| 274 | struct async *as = NULL; | 274 | struct async *as = NULL; |
| @@ -283,7 +283,7 @@ static inline struct async *async_getcompleted(struct dev_state *ps) | |||
| 283 | return as; | 283 | return as; |
| 284 | } | 284 | } |
| 285 | 285 | ||
| 286 | static inline struct async *async_getpending(struct dev_state *ps, | 286 | static struct async *async_getpending(struct dev_state *ps, |
| 287 | void __user *userurb) | 287 | void __user *userurb) |
| 288 | { | 288 | { |
| 289 | unsigned long flags; | 289 | unsigned long flags; |
| @@ -302,7 +302,7 @@ static inline struct async *async_getpending(struct dev_state *ps, | |||
| 302 | 302 | ||
| 303 | static void snoop_urb(struct urb *urb, void __user *userurb) | 303 | static void snoop_urb(struct urb *urb, void __user *userurb) |
| 304 | { | 304 | { |
| 305 | int j; | 305 | unsigned j; |
| 306 | unsigned char *data = urb->transfer_buffer; | 306 | unsigned char *data = urb->transfer_buffer; |
| 307 | 307 | ||
| 308 | if (!usbfs_snoop) | 308 | if (!usbfs_snoop) |
| @@ -311,9 +311,9 @@ static void snoop_urb(struct urb *urb, void __user *userurb) | |||
| 311 | dev_info(&urb->dev->dev, "direction=%s\n", | 311 | dev_info(&urb->dev->dev, "direction=%s\n", |
| 312 | usb_urb_dir_in(urb) ? "IN" : "OUT"); | 312 | usb_urb_dir_in(urb) ? "IN" : "OUT"); |
| 313 | dev_info(&urb->dev->dev, "userurb=%p\n", userurb); | 313 | dev_info(&urb->dev->dev, "userurb=%p\n", userurb); |
| 314 | dev_info(&urb->dev->dev, "transfer_buffer_length=%d\n", | 314 | dev_info(&urb->dev->dev, "transfer_buffer_length=%u\n", |
| 315 | urb->transfer_buffer_length); | 315 | urb->transfer_buffer_length); |
| 316 | dev_info(&urb->dev->dev, "actual_length=%d\n", urb->actual_length); | 316 | dev_info(&urb->dev->dev, "actual_length=%u\n", urb->actual_length); |
| 317 | dev_info(&urb->dev->dev, "data: "); | 317 | dev_info(&urb->dev->dev, "data: "); |
| 318 | for (j = 0; j < urb->transfer_buffer_length; ++j) | 318 | for (j = 0; j < urb->transfer_buffer_length; ++j) |
| 319 | printk("%02x ", data[j]); | 319 | printk("%02x ", data[j]); |
| @@ -376,7 +376,7 @@ static void destroy_async_on_interface(struct dev_state *ps, | |||
| 376 | destroy_async(ps, &hitlist); | 376 | destroy_async(ps, &hitlist); |
| 377 | } | 377 | } |
| 378 | 378 | ||
| 379 | static inline void destroy_all_async(struct dev_state *ps) | 379 | static void destroy_all_async(struct dev_state *ps) |
| 380 | { | 380 | { |
| 381 | destroy_async(ps, &ps->async_pending); | 381 | destroy_async(ps, &ps->async_pending); |
| 382 | } | 382 | } |
| @@ -525,7 +525,8 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, | |||
| 525 | { | 525 | { |
| 526 | int ret = 0; | 526 | int ret = 0; |
| 527 | 527 | ||
| 528 | if (ps->dev->state != USB_STATE_ADDRESS | 528 | if (ps->dev->state != USB_STATE_UNAUTHENTICATED |
| 529 | && ps->dev->state != USB_STATE_ADDRESS | ||
| 529 | && ps->dev->state != USB_STATE_CONFIGURED) | 530 | && ps->dev->state != USB_STATE_CONFIGURED) |
| 530 | return -EHOSTUNREACH; | 531 | return -EHOSTUNREACH; |
| 531 | if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype)) | 532 | if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype)) |
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c index e1710f260b4f..40dee2ac0133 100644 --- a/drivers/usb/core/endpoint.c +++ b/drivers/usb/core/endpoint.c | |||
| @@ -66,7 +66,7 @@ static ssize_t show_ep_type(struct device *dev, struct device_attribute *attr, | |||
| 66 | struct ep_device *ep = to_ep_device(dev); | 66 | struct ep_device *ep = to_ep_device(dev); |
| 67 | char *type = "unknown"; | 67 | char *type = "unknown"; |
| 68 | 68 | ||
| 69 | switch (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | 69 | switch (usb_endpoint_type(ep->desc)) { |
| 70 | case USB_ENDPOINT_XFER_CONTROL: | 70 | case USB_ENDPOINT_XFER_CONTROL: |
| 71 | type = "Control"; | 71 | type = "Control"; |
| 72 | break; | 72 | break; |
| @@ -94,7 +94,7 @@ static ssize_t show_ep_interval(struct device *dev, | |||
| 94 | 94 | ||
| 95 | in = (ep->desc->bEndpointAddress & USB_DIR_IN); | 95 | in = (ep->desc->bEndpointAddress & USB_DIR_IN); |
| 96 | 96 | ||
| 97 | switch (ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | 97 | switch (usb_endpoint_type(ep->desc)) { |
| 98 | case USB_ENDPOINT_XFER_CONTROL: | 98 | case USB_ENDPOINT_XFER_CONTROL: |
| 99 | if (ep->udev->speed == USB_SPEED_HIGH) /* uframes per NAK */ | 99 | if (ep->udev->speed == USB_SPEED_HIGH) /* uframes per NAK */ |
| 100 | interval = ep->desc->bInterval; | 100 | interval = ep->desc->bInterval; |
| @@ -131,10 +131,9 @@ static ssize_t show_ep_direction(struct device *dev, | |||
| 131 | struct ep_device *ep = to_ep_device(dev); | 131 | struct ep_device *ep = to_ep_device(dev); |
| 132 | char *direction; | 132 | char *direction; |
| 133 | 133 | ||
| 134 | if ((ep->desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == | 134 | if (usb_endpoint_xfer_control(ep->desc)) |
| 135 | USB_ENDPOINT_XFER_CONTROL) | ||
| 136 | direction = "both"; | 135 | direction = "both"; |
| 137 | else if (ep->desc->bEndpointAddress & USB_DIR_IN) | 136 | else if (usb_endpoint_dir_in(ep->desc)) |
| 138 | direction = "in"; | 137 | direction = "in"; |
| 139 | else | 138 | else |
| 140 | direction = "out"; | 139 | direction = "out"; |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 3c711db55d86..81fa8506825d 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
| @@ -279,9 +279,9 @@ static const u8 hs_rh_config_descriptor [] = { | |||
| 279 | * helper routine for returning string descriptors in UTF-16LE | 279 | * helper routine for returning string descriptors in UTF-16LE |
| 280 | * input can actually be ISO-8859-1; ASCII is its 7-bit subset | 280 | * input can actually be ISO-8859-1; ASCII is its 7-bit subset |
| 281 | */ | 281 | */ |
| 282 | static int ascii2utf (char *s, u8 *utf, int utfmax) | 282 | static unsigned ascii2utf(char *s, u8 *utf, int utfmax) |
| 283 | { | 283 | { |
| 284 | int retval; | 284 | unsigned retval; |
| 285 | 285 | ||
| 286 | for (retval = 0; *s && utfmax > 1; utfmax -= 2, retval += 2) { | 286 | for (retval = 0; *s && utfmax > 1; utfmax -= 2, retval += 2) { |
| 287 | *utf++ = *s++; | 287 | *utf++ = *s++; |
| @@ -304,19 +304,15 @@ static int ascii2utf (char *s, u8 *utf, int utfmax) | |||
| 304 | * Produces either a manufacturer, product or serial number string for the | 304 | * Produces either a manufacturer, product or serial number string for the |
| 305 | * virtual root hub device. | 305 | * virtual root hub device. |
| 306 | */ | 306 | */ |
| 307 | static int rh_string ( | 307 | static unsigned rh_string(int id, struct usb_hcd *hcd, u8 *data, unsigned len) |
| 308 | int id, | 308 | { |
| 309 | struct usb_hcd *hcd, | ||
| 310 | u8 *data, | ||
| 311 | int len | ||
| 312 | ) { | ||
| 313 | char buf [100]; | 309 | char buf [100]; |
| 314 | 310 | ||
| 315 | // language ids | 311 | // language ids |
| 316 | if (id == 0) { | 312 | if (id == 0) { |
| 317 | buf[0] = 4; buf[1] = 3; /* 4 bytes string data */ | 313 | buf[0] = 4; buf[1] = 3; /* 4 bytes string data */ |
| 318 | buf[2] = 0x09; buf[3] = 0x04; /* MSFT-speak for "en-us" */ | 314 | buf[2] = 0x09; buf[3] = 0x04; /* MSFT-speak for "en-us" */ |
| 319 | len = min (len, 4); | 315 | len = min_t(unsigned, len, 4); |
| 320 | memcpy (data, buf, len); | 316 | memcpy (data, buf, len); |
| 321 | return len; | 317 | return len; |
| 322 | 318 | ||
| @@ -332,10 +328,7 @@ static int rh_string ( | |||
| 332 | } else if (id == 3) { | 328 | } else if (id == 3) { |
| 333 | snprintf (buf, sizeof buf, "%s %s %s", init_utsname()->sysname, | 329 | snprintf (buf, sizeof buf, "%s %s %s", init_utsname()->sysname, |
| 334 | init_utsname()->release, hcd->driver->description); | 330 | init_utsname()->release, hcd->driver->description); |
| 335 | 331 | } | |
| 336 | // unsupported IDs --> "protocol stall" | ||
| 337 | } else | ||
| 338 | return -EPIPE; | ||
| 339 | 332 | ||
| 340 | switch (len) { /* All cases fall through */ | 333 | switch (len) { /* All cases fall through */ |
| 341 | default: | 334 | default: |
| @@ -360,9 +353,8 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) | |||
| 360 | u8 tbuf [sizeof (struct usb_hub_descriptor)] | 353 | u8 tbuf [sizeof (struct usb_hub_descriptor)] |
| 361 | __attribute__((aligned(4))); | 354 | __attribute__((aligned(4))); |
| 362 | const u8 *bufp = tbuf; | 355 | const u8 *bufp = tbuf; |
| 363 | int len = 0; | 356 | unsigned len = 0; |
| 364 | int status; | 357 | int status; |
| 365 | int n; | ||
| 366 | u8 patch_wakeup = 0; | 358 | u8 patch_wakeup = 0; |
| 367 | u8 patch_protocol = 0; | 359 | u8 patch_protocol = 0; |
| 368 | 360 | ||
| @@ -456,10 +448,11 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) | |||
| 456 | patch_wakeup = 1; | 448 | patch_wakeup = 1; |
| 457 | break; | 449 | break; |
| 458 | case USB_DT_STRING << 8: | 450 | case USB_DT_STRING << 8: |
| 459 | n = rh_string (wValue & 0xff, hcd, ubuf, wLength); | 451 | if ((wValue & 0xff) < 4) |
| 460 | if (n < 0) | 452 | urb->actual_length = rh_string(wValue & 0xff, |
| 453 | hcd, ubuf, wLength); | ||
| 454 | else /* unsupported IDs --> "protocol stall" */ | ||
| 461 | goto error; | 455 | goto error; |
| 462 | urb->actual_length = n; | ||
| 463 | break; | 456 | break; |
| 464 | default: | 457 | default: |
| 465 | goto error; | 458 | goto error; |
| @@ -629,7 +622,7 @@ static int rh_queue_status (struct usb_hcd *hcd, struct urb *urb) | |||
| 629 | { | 622 | { |
| 630 | int retval; | 623 | int retval; |
| 631 | unsigned long flags; | 624 | unsigned long flags; |
| 632 | int len = 1 + (urb->dev->maxchild / 8); | 625 | unsigned len = 1 + (urb->dev->maxchild / 8); |
| 633 | 626 | ||
| 634 | spin_lock_irqsave (&hcd_root_hub_lock, flags); | 627 | spin_lock_irqsave (&hcd_root_hub_lock, flags); |
| 635 | if (hcd->status_urb || urb->transfer_buffer_length < len) { | 628 | if (hcd->status_urb || urb->transfer_buffer_length < len) { |
| @@ -901,7 +894,7 @@ static int register_root_hub(struct usb_hcd *hcd) | |||
| 901 | 894 | ||
| 902 | mutex_lock(&usb_bus_list_lock); | 895 | mutex_lock(&usb_bus_list_lock); |
| 903 | 896 | ||
| 904 | usb_dev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64); | 897 | usb_dev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); |
| 905 | retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE); | 898 | retval = usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE); |
| 906 | if (retval != sizeof usb_dev->descriptor) { | 899 | if (retval != sizeof usb_dev->descriptor) { |
| 907 | mutex_unlock(&usb_bus_list_lock); | 900 | mutex_unlock(&usb_bus_list_lock); |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index cd50d86029e7..be86ae3f4088 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
| @@ -392,7 +392,7 @@ static void hub_irq(struct urb *urb) | |||
| 392 | { | 392 | { |
| 393 | struct usb_hub *hub = urb->context; | 393 | struct usb_hub *hub = urb->context; |
| 394 | int status = urb->status; | 394 | int status = urb->status; |
| 395 | int i; | 395 | unsigned i; |
| 396 | unsigned long bits; | 396 | unsigned long bits; |
| 397 | 397 | ||
| 398 | switch (status) { | 398 | switch (status) { |
| @@ -1305,6 +1305,7 @@ void usb_set_device_state(struct usb_device *udev, | |||
| 1305 | recursively_mark_NOTATTACHED(udev); | 1305 | recursively_mark_NOTATTACHED(udev); |
| 1306 | spin_unlock_irqrestore(&device_state_lock, flags); | 1306 | spin_unlock_irqrestore(&device_state_lock, flags); |
| 1307 | } | 1307 | } |
| 1308 | EXPORT_SYMBOL_GPL(usb_set_device_state); | ||
| 1308 | 1309 | ||
| 1309 | /* | 1310 | /* |
| 1310 | * WUSB devices are simple: they have no hubs behind, so the mapping | 1311 | * WUSB devices are simple: they have no hubs behind, so the mapping |
| @@ -2471,20 +2472,20 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
| 2471 | */ | 2472 | */ |
| 2472 | switch (udev->speed) { | 2473 | switch (udev->speed) { |
| 2473 | case USB_SPEED_VARIABLE: /* fixed at 512 */ | 2474 | case USB_SPEED_VARIABLE: /* fixed at 512 */ |
| 2474 | udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(512); | 2475 | udev->ep0.desc.wMaxPacketSize = cpu_to_le16(512); |
| 2475 | break; | 2476 | break; |
| 2476 | case USB_SPEED_HIGH: /* fixed at 64 */ | 2477 | case USB_SPEED_HIGH: /* fixed at 64 */ |
| 2477 | udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64); | 2478 | udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); |
| 2478 | break; | 2479 | break; |
| 2479 | case USB_SPEED_FULL: /* 8, 16, 32, or 64 */ | 2480 | case USB_SPEED_FULL: /* 8, 16, 32, or 64 */ |
| 2480 | /* to determine the ep0 maxpacket size, try to read | 2481 | /* to determine the ep0 maxpacket size, try to read |
| 2481 | * the device descriptor to get bMaxPacketSize0 and | 2482 | * the device descriptor to get bMaxPacketSize0 and |
| 2482 | * then correct our initial guess. | 2483 | * then correct our initial guess. |
| 2483 | */ | 2484 | */ |
| 2484 | udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(64); | 2485 | udev->ep0.desc.wMaxPacketSize = cpu_to_le16(64); |
| 2485 | break; | 2486 | break; |
| 2486 | case USB_SPEED_LOW: /* fixed at 8 */ | 2487 | case USB_SPEED_LOW: /* fixed at 8 */ |
| 2487 | udev->ep0.desc.wMaxPacketSize = __constant_cpu_to_le16(8); | 2488 | udev->ep0.desc.wMaxPacketSize = cpu_to_le16(8); |
| 2488 | break; | 2489 | break; |
| 2489 | default: | 2490 | default: |
| 2490 | goto fail; | 2491 | goto fail; |
| @@ -3392,10 +3393,10 @@ static int usb_reset_and_verify_device(struct usb_device *udev) | |||
| 3392 | udev->descriptor = descriptor; /* for disconnect() calls */ | 3393 | udev->descriptor = descriptor; /* for disconnect() calls */ |
| 3393 | goto re_enumerate; | 3394 | goto re_enumerate; |
| 3394 | } | 3395 | } |
| 3395 | 3396 | ||
| 3397 | /* Restore the device's previous configuration */ | ||
| 3396 | if (!udev->actconfig) | 3398 | if (!udev->actconfig) |
| 3397 | goto done; | 3399 | goto done; |
| 3398 | |||
| 3399 | ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | 3400 | ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), |
| 3400 | USB_REQ_SET_CONFIGURATION, 0, | 3401 | USB_REQ_SET_CONFIGURATION, 0, |
| 3401 | udev->actconfig->desc.bConfigurationValue, 0, | 3402 | udev->actconfig->desc.bConfigurationValue, 0, |
| @@ -3408,16 +3409,25 @@ static int usb_reset_and_verify_device(struct usb_device *udev) | |||
| 3408 | } | 3409 | } |
| 3409 | usb_set_device_state(udev, USB_STATE_CONFIGURED); | 3410 | usb_set_device_state(udev, USB_STATE_CONFIGURED); |
| 3410 | 3411 | ||
| 3412 | /* Put interfaces back into the same altsettings as before. | ||
| 3413 | * Don't bother to send the Set-Interface request for interfaces | ||
| 3414 | * that were already in altsetting 0; besides being unnecessary, | ||
| 3415 | * many devices can't handle it. Instead just reset the host-side | ||
| 3416 | * endpoint state. | ||
| 3417 | */ | ||
| 3411 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { | 3418 | for (i = 0; i < udev->actconfig->desc.bNumInterfaces; i++) { |
| 3412 | struct usb_interface *intf = udev->actconfig->interface[i]; | 3419 | struct usb_interface *intf = udev->actconfig->interface[i]; |
| 3413 | struct usb_interface_descriptor *desc; | 3420 | struct usb_interface_descriptor *desc; |
| 3414 | 3421 | ||
| 3415 | /* set_interface resets host side toggle even | ||
| 3416 | * for altsetting zero. the interface may have no driver. | ||
| 3417 | */ | ||
| 3418 | desc = &intf->cur_altsetting->desc; | 3422 | desc = &intf->cur_altsetting->desc; |
| 3419 | ret = usb_set_interface(udev, desc->bInterfaceNumber, | 3423 | if (desc->bAlternateSetting == 0) { |
| 3420 | desc->bAlternateSetting); | 3424 | usb_disable_interface(udev, intf, true); |
| 3425 | usb_enable_interface(udev, intf, true); | ||
| 3426 | ret = 0; | ||
| 3427 | } else { | ||
| 3428 | ret = usb_set_interface(udev, desc->bInterfaceNumber, | ||
| 3429 | desc->bAlternateSetting); | ||
| 3430 | } | ||
| 3421 | if (ret < 0) { | 3431 | if (ret < 0) { |
| 3422 | dev_err(&udev->dev, "failed to restore interface %d " | 3432 | dev_err(&udev->dev, "failed to restore interface %d " |
| 3423 | "altsetting %d (error=%d)\n", | 3433 | "altsetting %d (error=%d)\n", |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 49e7f56e0d7f..30a0690f3683 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
| @@ -59,7 +59,7 @@ static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) | |||
| 59 | retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status); | 59 | retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status); |
| 60 | 60 | ||
| 61 | dev_dbg(&urb->dev->dev, | 61 | dev_dbg(&urb->dev->dev, |
| 62 | "%s timed out on ep%d%s len=%d/%d\n", | 62 | "%s timed out on ep%d%s len=%u/%u\n", |
| 63 | current->comm, | 63 | current->comm, |
| 64 | usb_endpoint_num(&urb->ep->desc), | 64 | usb_endpoint_num(&urb->ep->desc), |
| 65 | usb_urb_dir_in(urb) ? "in" : "out", | 65 | usb_urb_dir_in(urb) ? "in" : "out", |
| @@ -804,18 +804,16 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) | |||
| 804 | dev_err(&dev->dev, | 804 | dev_err(&dev->dev, |
| 805 | "string descriptor 0 read error: %d\n", | 805 | "string descriptor 0 read error: %d\n", |
| 806 | err); | 806 | err); |
| 807 | goto errout; | ||
| 808 | } else if (err < 4) { | 807 | } else if (err < 4) { |
| 809 | dev_err(&dev->dev, "string descriptor 0 too short\n"); | 808 | dev_err(&dev->dev, "string descriptor 0 too short\n"); |
| 810 | err = -EINVAL; | ||
| 811 | goto errout; | ||
| 812 | } else { | 809 | } else { |
| 813 | dev->have_langid = 1; | ||
| 814 | dev->string_langid = tbuf[2] | (tbuf[3] << 8); | 810 | dev->string_langid = tbuf[2] | (tbuf[3] << 8); |
| 815 | /* always use the first langid listed */ | 811 | /* always use the first langid listed */ |
| 816 | dev_dbg(&dev->dev, "default language 0x%04x\n", | 812 | dev_dbg(&dev->dev, "default language 0x%04x\n", |
| 817 | dev->string_langid); | 813 | dev->string_langid); |
| 818 | } | 814 | } |
| 815 | |||
| 816 | dev->have_langid = 1; | ||
| 819 | } | 817 | } |
| 820 | 818 | ||
| 821 | err = usb_string_sub(dev, dev->string_langid, index, tbuf); | 819 | err = usb_string_sub(dev, dev->string_langid, index, tbuf); |
| @@ -1719,7 +1717,8 @@ free_interfaces: | |||
| 1719 | } | 1717 | } |
| 1720 | kfree(new_interfaces); | 1718 | kfree(new_interfaces); |
| 1721 | 1719 | ||
| 1722 | if (cp->string == NULL) | 1720 | if (cp->string == NULL && |
| 1721 | !(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS)) | ||
| 1723 | cp->string = usb_cache_string(dev, cp->desc.iConfiguration); | 1722 | cp->string = usb_cache_string(dev, cp->desc.iConfiguration); |
| 1724 | 1723 | ||
| 1725 | /* Now that all the interfaces are set up, register them | 1724 | /* Now that all the interfaces are set up, register them |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index c070b34b669d..ab93918d9207 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
| @@ -54,6 +54,10 @@ static const struct usb_device_id usb_quirk_list[] = { | |||
| 54 | { USB_DEVICE(0x0638, 0x0a13), .driver_info = | 54 | { USB_DEVICE(0x0638, 0x0a13), .driver_info = |
| 55 | USB_QUIRK_STRING_FETCH_255 }, | 55 | USB_QUIRK_STRING_FETCH_255 }, |
| 56 | 56 | ||
| 57 | /* Saitek Cyborg Gold Joystick */ | ||
| 58 | { USB_DEVICE(0x06a3, 0x0006), .driver_info = | ||
| 59 | USB_QUIRK_CONFIG_INTF_STRINGS }, | ||
| 60 | |||
| 57 | /* M-Systems Flash Disk Pioneers */ | 61 | /* M-Systems Flash Disk Pioneers */ |
| 58 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, | 62 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, |
| 59 | 63 | ||
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 4cc2456ef3be..c66789197927 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
| 14 | #include <linux/string.h> | 14 | #include <linux/string.h> |
| 15 | #include <linux/usb.h> | 15 | #include <linux/usb.h> |
| 16 | #include <linux/usb/quirks.h> | ||
| 16 | #include "usb.h" | 17 | #include "usb.h" |
| 17 | 18 | ||
| 18 | /* Active configuration fields */ | 19 | /* Active configuration fields */ |
| @@ -813,7 +814,8 @@ int usb_create_sysfs_intf_files(struct usb_interface *intf) | |||
| 813 | if (intf->sysfs_files_created || intf->unregistering) | 814 | if (intf->sysfs_files_created || intf->unregistering) |
| 814 | return 0; | 815 | return 0; |
| 815 | 816 | ||
| 816 | if (alt->string == NULL) | 817 | if (alt->string == NULL && |
| 818 | !(udev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS)) | ||
| 817 | alt->string = usb_cache_string(udev, alt->desc.iInterface); | 819 | alt->string = usb_cache_string(udev, alt->desc.iInterface); |
| 818 | if (alt->string) | 820 | if (alt->string) |
| 819 | retval = device_create_file(&intf->dev, &dev_attr_interface); | 821 | retval = device_create_file(&intf->dev, &dev_attr_interface); |
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 58bc5e3c2560..3376055f36e7 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c | |||
| @@ -295,7 +295,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
| 295 | if (!urb || urb->hcpriv || !urb->complete) | 295 | if (!urb || urb->hcpriv || !urb->complete) |
| 296 | return -EINVAL; | 296 | return -EINVAL; |
| 297 | dev = urb->dev; | 297 | dev = urb->dev; |
| 298 | if ((!dev) || (dev->state < USB_STATE_DEFAULT)) | 298 | if ((!dev) || (dev->state < USB_STATE_UNAUTHENTICATED)) |
| 299 | return -ENODEV; | 299 | return -ENODEV; |
| 300 | 300 | ||
| 301 | /* For now, get the endpoint from the pipe. Eventually drivers | 301 | /* For now, get the endpoint from the pipe. Eventually drivers |
| @@ -370,7 +370,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
| 370 | } | 370 | } |
| 371 | 371 | ||
| 372 | /* the I/O buffer must be mapped/unmapped, except when length=0 */ | 372 | /* the I/O buffer must be mapped/unmapped, except when length=0 */ |
| 373 | if (urb->transfer_buffer_length < 0) | 373 | if (urb->transfer_buffer_length > INT_MAX) |
| 374 | return -EMSGSIZE; | 374 | return -EMSGSIZE; |
| 375 | 375 | ||
| 376 | #ifdef DEBUG | 376 | #ifdef DEBUG |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index e55fef52a5dc..770b3eaa9184 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
| @@ -254,6 +254,7 @@ config USB_PXA25X_SMALL | |||
| 254 | config USB_GADGET_PXA27X | 254 | config USB_GADGET_PXA27X |
| 255 | boolean "PXA 27x" | 255 | boolean "PXA 27x" |
| 256 | depends on ARCH_PXA && PXA27x | 256 | depends on ARCH_PXA && PXA27x |
| 257 | select USB_OTG_UTILS | ||
| 257 | help | 258 | help |
| 258 | Intel's PXA 27x series XScale ARM v5TE processors include | 259 | Intel's PXA 27x series XScale ARM v5TE processors include |
| 259 | an integrated full speed USB 1.1 device controller. | 260 | an integrated full speed USB 1.1 device controller. |
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c index abf8192f89e8..826f3adde5d8 100644 --- a/drivers/usb/gadget/amd5536udc.c +++ b/drivers/usb/gadget/amd5536udc.c | |||
| @@ -551,7 +551,7 @@ udc_alloc_request(struct usb_ep *usbep, gfp_t gfp) | |||
| 551 | dma_desc->status = AMD_ADDBITS(dma_desc->status, | 551 | dma_desc->status = AMD_ADDBITS(dma_desc->status, |
| 552 | UDC_DMA_STP_STS_BS_HOST_BUSY, | 552 | UDC_DMA_STP_STS_BS_HOST_BUSY, |
| 553 | UDC_DMA_STP_STS_BS); | 553 | UDC_DMA_STP_STS_BS); |
| 554 | dma_desc->bufptr = __constant_cpu_to_le32(DMA_DONT_USE); | 554 | dma_desc->bufptr = cpu_to_le32(DMA_DONT_USE); |
| 555 | req->td_data = dma_desc; | 555 | req->td_data = dma_desc; |
| 556 | req->td_data_last = NULL; | 556 | req->td_data_last = NULL; |
| 557 | req->chain_len = 1; | 557 | req->chain_len = 1; |
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c index 65b03e3445a1..c22fab164113 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c | |||
| @@ -1017,7 +1017,7 @@ static struct usb_endpoint_descriptor usba_ep0_desc = { | |||
| 1017 | .bDescriptorType = USB_DT_ENDPOINT, | 1017 | .bDescriptorType = USB_DT_ENDPOINT, |
| 1018 | .bEndpointAddress = 0, | 1018 | .bEndpointAddress = 0, |
| 1019 | .bmAttributes = USB_ENDPOINT_XFER_CONTROL, | 1019 | .bmAttributes = USB_ENDPOINT_XFER_CONTROL, |
| 1020 | .wMaxPacketSize = __constant_cpu_to_le16(64), | 1020 | .wMaxPacketSize = cpu_to_le16(64), |
| 1021 | /* FIXME: I have no idea what to put here */ | 1021 | /* FIXME: I have no idea what to put here */ |
| 1022 | .bInterval = 1, | 1022 | .bInterval = 1, |
| 1023 | }; | 1023 | }; |
| @@ -1207,21 +1207,21 @@ static int do_test_mode(struct usba_udc *udc) | |||
| 1207 | /* Avoid overly long expressions */ | 1207 | /* Avoid overly long expressions */ |
| 1208 | static inline bool feature_is_dev_remote_wakeup(struct usb_ctrlrequest *crq) | 1208 | static inline bool feature_is_dev_remote_wakeup(struct usb_ctrlrequest *crq) |
| 1209 | { | 1209 | { |
| 1210 | if (crq->wValue == __constant_cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP)) | 1210 | if (crq->wValue == cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP)) |
| 1211 | return true; | 1211 | return true; |
| 1212 | return false; | 1212 | return false; |
| 1213 | } | 1213 | } |
| 1214 | 1214 | ||
| 1215 | static inline bool feature_is_dev_test_mode(struct usb_ctrlrequest *crq) | 1215 | static inline bool feature_is_dev_test_mode(struct usb_ctrlrequest *crq) |
| 1216 | { | 1216 | { |
| 1217 | if (crq->wValue == __constant_cpu_to_le16(USB_DEVICE_TEST_MODE)) | 1217 | if (crq->wValue == cpu_to_le16(USB_DEVICE_TEST_MODE)) |
| 1218 | return true; | 1218 | return true; |
| 1219 | return false; | 1219 | return false; |
| 1220 | } | 1220 | } |
| 1221 | 1221 | ||
| 1222 | static inline bool feature_is_ep_halt(struct usb_ctrlrequest *crq) | 1222 | static inline bool feature_is_ep_halt(struct usb_ctrlrequest *crq) |
| 1223 | { | 1223 | { |
| 1224 | if (crq->wValue == __constant_cpu_to_le16(USB_ENDPOINT_HALT)) | 1224 | if (crq->wValue == cpu_to_le16(USB_ENDPOINT_HALT)) |
| 1225 | return true; | 1225 | return true; |
| 1226 | return false; | 1226 | return false; |
| 1227 | } | 1227 | } |
| @@ -1239,7 +1239,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep, | |||
| 1239 | status = cpu_to_le16(udc->devstatus); | 1239 | status = cpu_to_le16(udc->devstatus); |
| 1240 | } else if (crq->bRequestType | 1240 | } else if (crq->bRequestType |
| 1241 | == (USB_DIR_IN | USB_RECIP_INTERFACE)) { | 1241 | == (USB_DIR_IN | USB_RECIP_INTERFACE)) { |
| 1242 | status = __constant_cpu_to_le16(0); | 1242 | status = cpu_to_le16(0); |
| 1243 | } else if (crq->bRequestType | 1243 | } else if (crq->bRequestType |
| 1244 | == (USB_DIR_IN | USB_RECIP_ENDPOINT)) { | 1244 | == (USB_DIR_IN | USB_RECIP_ENDPOINT)) { |
| 1245 | struct usba_ep *target; | 1245 | struct usba_ep *target; |
| @@ -1250,12 +1250,12 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep, | |||
| 1250 | 1250 | ||
| 1251 | status = 0; | 1251 | status = 0; |
| 1252 | if (is_stalled(udc, target)) | 1252 | if (is_stalled(udc, target)) |
| 1253 | status |= __constant_cpu_to_le16(1); | 1253 | status |= cpu_to_le16(1); |
| 1254 | } else | 1254 | } else |
| 1255 | goto delegate; | 1255 | goto delegate; |
| 1256 | 1256 | ||
| 1257 | /* Write directly to the FIFO. No queueing is done. */ | 1257 | /* Write directly to the FIFO. No queueing is done. */ |
| 1258 | if (crq->wLength != __constant_cpu_to_le16(sizeof(status))) | 1258 | if (crq->wLength != cpu_to_le16(sizeof(status))) |
| 1259 | goto stall; | 1259 | goto stall; |
| 1260 | ep->state = DATA_STAGE_IN; | 1260 | ep->state = DATA_STAGE_IN; |
| 1261 | __raw_writew(status, ep->fifo); | 1261 | __raw_writew(status, ep->fifo); |
| @@ -1274,7 +1274,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep, | |||
| 1274 | } else if (crq->bRequestType == USB_RECIP_ENDPOINT) { | 1274 | } else if (crq->bRequestType == USB_RECIP_ENDPOINT) { |
| 1275 | struct usba_ep *target; | 1275 | struct usba_ep *target; |
| 1276 | 1276 | ||
| 1277 | if (crq->wLength != __constant_cpu_to_le16(0) | 1277 | if (crq->wLength != cpu_to_le16(0) |
| 1278 | || !feature_is_ep_halt(crq)) | 1278 | || !feature_is_ep_halt(crq)) |
| 1279 | goto stall; | 1279 | goto stall; |
| 1280 | target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex)); | 1280 | target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex)); |
| @@ -1308,7 +1308,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep, | |||
| 1308 | } else if (crq->bRequestType == USB_RECIP_ENDPOINT) { | 1308 | } else if (crq->bRequestType == USB_RECIP_ENDPOINT) { |
| 1309 | struct usba_ep *target; | 1309 | struct usba_ep *target; |
| 1310 | 1310 | ||
| 1311 | if (crq->wLength != __constant_cpu_to_le16(0) | 1311 | if (crq->wLength != cpu_to_le16(0) |
| 1312 | || !feature_is_ep_halt(crq)) | 1312 | || !feature_is_ep_halt(crq)) |
| 1313 | goto stall; | 1313 | goto stall; |
| 1314 | 1314 | ||
| @@ -1514,7 +1514,7 @@ restart: | |||
| 1514 | */ | 1514 | */ |
| 1515 | ep->state = DATA_STAGE_IN; | 1515 | ep->state = DATA_STAGE_IN; |
| 1516 | } else { | 1516 | } else { |
| 1517 | if (crq.crq.wLength != __constant_cpu_to_le16(0)) | 1517 | if (crq.crq.wLength != cpu_to_le16(0)) |
| 1518 | ep->state = DATA_STAGE_OUT; | 1518 | ep->state = DATA_STAGE_OUT; |
| 1519 | else | 1519 | else |
| 1520 | ep->state = STATUS_STAGE_IN; | 1520 | ep->state = STATUS_STAGE_IN; |
diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c index 5495b171cf29..928137d3dbdc 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/cdc2.c | |||
| @@ -66,7 +66,7 @@ static struct usb_device_descriptor device_desc = { | |||
| 66 | .bLength = sizeof device_desc, | 66 | .bLength = sizeof device_desc, |
| 67 | .bDescriptorType = USB_DT_DEVICE, | 67 | .bDescriptorType = USB_DT_DEVICE, |
| 68 | 68 | ||
| 69 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 69 | .bcdUSB = cpu_to_le16(0x0200), |
| 70 | 70 | ||
| 71 | .bDeviceClass = USB_CLASS_COMM, | 71 | .bDeviceClass = USB_CLASS_COMM, |
| 72 | .bDeviceSubClass = 0, | 72 | .bDeviceSubClass = 0, |
| @@ -74,8 +74,8 @@ static struct usb_device_descriptor device_desc = { | |||
| 74 | /* .bMaxPacketSize0 = f(hardware) */ | 74 | /* .bMaxPacketSize0 = f(hardware) */ |
| 75 | 75 | ||
| 76 | /* Vendor and product id can be overridden by module parameters. */ | 76 | /* Vendor and product id can be overridden by module parameters. */ |
| 77 | .idVendor = __constant_cpu_to_le16(CDC_VENDOR_NUM), | 77 | .idVendor = cpu_to_le16(CDC_VENDOR_NUM), |
| 78 | .idProduct = __constant_cpu_to_le16(CDC_PRODUCT_NUM), | 78 | .idProduct = cpu_to_le16(CDC_PRODUCT_NUM), |
| 79 | /* .bcdDevice = f(hardware) */ | 79 | /* .bcdDevice = f(hardware) */ |
| 80 | /* .iManufacturer = DYNAMIC */ | 80 | /* .iManufacturer = DYNAMIC */ |
| 81 | /* .iProduct = DYNAMIC */ | 81 | /* .iProduct = DYNAMIC */ |
| @@ -193,7 +193,7 @@ static int __init cdc_bind(struct usb_composite_dev *cdev) | |||
| 193 | gadget->name, | 193 | gadget->name, |
| 194 | cdc_config_driver.label); | 194 | cdc_config_driver.label); |
| 195 | device_desc.bcdDevice = | 195 | device_desc.bcdDevice = |
| 196 | __constant_cpu_to_le16(0x0300 | 0x0099); | 196 | cpu_to_le16(0x0300 | 0x0099); |
| 197 | } | 197 | } |
| 198 | 198 | ||
| 199 | 199 | ||
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index bebf911c7e5f..22c65960c429 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c | |||
| @@ -56,7 +56,6 @@ | |||
| 56 | #include <linux/dma-mapping.h> | 56 | #include <linux/dma-mapping.h> |
| 57 | #include <linux/init.h> | 57 | #include <linux/init.h> |
| 58 | #include <linux/interrupt.h> | 58 | #include <linux/interrupt.h> |
| 59 | #include <linux/interrupt.h> | ||
| 60 | #include <linux/io.h> | 59 | #include <linux/io.h> |
| 61 | #include <linux/irq.h> | 60 | #include <linux/irq.h> |
| 62 | #include <linux/kernel.h> | 61 | #include <linux/kernel.h> |
| @@ -2626,7 +2625,7 @@ static int udc_probe(struct device *dev, void __iomem *regs, const char *name) | |||
| 2626 | INIT_LIST_HEAD(&udc->gadget.ep_list); | 2625 | INIT_LIST_HEAD(&udc->gadget.ep_list); |
| 2627 | udc->gadget.ep0 = NULL; | 2626 | udc->gadget.ep0 = NULL; |
| 2628 | 2627 | ||
| 2629 | strcpy(udc->gadget.dev.bus_id, "gadget"); | 2628 | dev_set_name(&udc->gadget.dev, "gadget"); |
| 2630 | udc->gadget.dev.dma_mask = dev->dma_mask; | 2629 | udc->gadget.dev.dma_mask = dev->dma_mask; |
| 2631 | udc->gadget.dev.parent = dev; | 2630 | udc->gadget.dev.parent = dev; |
| 2632 | udc->gadget.dev.release = udc_release; | 2631 | udc->gadget.dev.release = udc_release; |
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index 5d11c291f1ad..59e85234fa0a 100644 --- a/drivers/usb/gadget/composite.c +++ b/drivers/usb/gadget/composite.c | |||
| @@ -149,16 +149,17 @@ done: | |||
| 149 | int usb_function_deactivate(struct usb_function *function) | 149 | int usb_function_deactivate(struct usb_function *function) |
| 150 | { | 150 | { |
| 151 | struct usb_composite_dev *cdev = function->config->cdev; | 151 | struct usb_composite_dev *cdev = function->config->cdev; |
| 152 | unsigned long flags; | ||
| 152 | int status = 0; | 153 | int status = 0; |
| 153 | 154 | ||
| 154 | spin_lock(&cdev->lock); | 155 | spin_lock_irqsave(&cdev->lock, flags); |
| 155 | 156 | ||
| 156 | if (cdev->deactivations == 0) | 157 | if (cdev->deactivations == 0) |
| 157 | status = usb_gadget_disconnect(cdev->gadget); | 158 | status = usb_gadget_disconnect(cdev->gadget); |
| 158 | if (status == 0) | 159 | if (status == 0) |
| 159 | cdev->deactivations++; | 160 | cdev->deactivations++; |
| 160 | 161 | ||
| 161 | spin_unlock(&cdev->lock); | 162 | spin_unlock_irqrestore(&cdev->lock, flags); |
| 162 | return status; | 163 | return status; |
| 163 | } | 164 | } |
| 164 | 165 | ||
| @@ -1013,7 +1014,7 @@ composite_suspend(struct usb_gadget *gadget) | |||
| 1013 | struct usb_composite_dev *cdev = get_gadget_data(gadget); | 1014 | struct usb_composite_dev *cdev = get_gadget_data(gadget); |
| 1014 | struct usb_function *f; | 1015 | struct usb_function *f; |
| 1015 | 1016 | ||
| 1016 | /* REVISIT: should we have config and device level | 1017 | /* REVISIT: should we have config level |
| 1017 | * suspend/resume callbacks? | 1018 | * suspend/resume callbacks? |
| 1018 | */ | 1019 | */ |
| 1019 | DBG(cdev, "suspend\n"); | 1020 | DBG(cdev, "suspend\n"); |
| @@ -1023,6 +1024,8 @@ composite_suspend(struct usb_gadget *gadget) | |||
| 1023 | f->suspend(f); | 1024 | f->suspend(f); |
| 1024 | } | 1025 | } |
| 1025 | } | 1026 | } |
| 1027 | if (composite->suspend) | ||
| 1028 | composite->suspend(cdev); | ||
| 1026 | } | 1029 | } |
| 1027 | 1030 | ||
| 1028 | static void | 1031 | static void |
| @@ -1031,10 +1034,12 @@ composite_resume(struct usb_gadget *gadget) | |||
| 1031 | struct usb_composite_dev *cdev = get_gadget_data(gadget); | 1034 | struct usb_composite_dev *cdev = get_gadget_data(gadget); |
| 1032 | struct usb_function *f; | 1035 | struct usb_function *f; |
| 1033 | 1036 | ||
| 1034 | /* REVISIT: should we have config and device level | 1037 | /* REVISIT: should we have config level |
| 1035 | * suspend/resume callbacks? | 1038 | * suspend/resume callbacks? |
| 1036 | */ | 1039 | */ |
| 1037 | DBG(cdev, "resume\n"); | 1040 | DBG(cdev, "resume\n"); |
| 1041 | if (composite->resume) | ||
| 1042 | composite->resume(cdev); | ||
| 1038 | if (cdev->config) { | 1043 | if (cdev->config) { |
| 1039 | list_for_each_entry(f, &cdev->config->functions, list) { | 1044 | list_for_each_entry(f, &cdev->config->functions, list) { |
| 1040 | if (f->resume) | 1045 | if (f->resume) |
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 9064696636ac..a56b24d305f8 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
| @@ -1437,7 +1437,7 @@ restart: | |||
| 1437 | } | 1437 | } |
| 1438 | if (urb->transfer_buffer_length > 1) | 1438 | if (urb->transfer_buffer_length > 1) |
| 1439 | buf [1] = 0; | 1439 | buf [1] = 0; |
| 1440 | urb->actual_length = min (2, | 1440 | urb->actual_length = min_t(u32, 2, |
| 1441 | urb->transfer_buffer_length); | 1441 | urb->transfer_buffer_length); |
| 1442 | value = 0; | 1442 | value = 0; |
| 1443 | status = 0; | 1443 | status = 0; |
| @@ -1626,7 +1626,7 @@ static int dummy_hub_control ( | |||
| 1626 | hub_descriptor ((struct usb_hub_descriptor *) buf); | 1626 | hub_descriptor ((struct usb_hub_descriptor *) buf); |
| 1627 | break; | 1627 | break; |
| 1628 | case GetHubStatus: | 1628 | case GetHubStatus: |
| 1629 | *(__le32 *) buf = __constant_cpu_to_le32 (0); | 1629 | *(__le32 *) buf = cpu_to_le32 (0); |
| 1630 | break; | 1630 | break; |
| 1631 | case GetPortStatus: | 1631 | case GetPortStatus: |
| 1632 | if (wIndex != 1) | 1632 | if (wIndex != 1) |
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index a36b1175b18d..cd0914ec898e 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c | |||
| @@ -148,7 +148,7 @@ ep_matches ( | |||
| 148 | return 0; | 148 | return 0; |
| 149 | 149 | ||
| 150 | /* BOTH: "high bandwidth" works only at high speed */ | 150 | /* BOTH: "high bandwidth" works only at high speed */ |
| 151 | if ((desc->wMaxPacketSize & __constant_cpu_to_le16(3<<11))) { | 151 | if ((desc->wMaxPacketSize & cpu_to_le16(3<<11))) { |
| 152 | if (!gadget->is_dualspeed) | 152 | if (!gadget->is_dualspeed) |
| 153 | return 0; | 153 | return 0; |
| 154 | /* configure your hardware with enough buffering!! */ | 154 | /* configure your hardware with enough buffering!! */ |
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 37252d0012a7..d006dc652e02 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c | |||
| @@ -156,7 +156,7 @@ static struct usb_device_descriptor device_desc = { | |||
| 156 | .bLength = sizeof device_desc, | 156 | .bLength = sizeof device_desc, |
| 157 | .bDescriptorType = USB_DT_DEVICE, | 157 | .bDescriptorType = USB_DT_DEVICE, |
| 158 | 158 | ||
| 159 | .bcdUSB = __constant_cpu_to_le16 (0x0200), | 159 | .bcdUSB = cpu_to_le16 (0x0200), |
| 160 | 160 | ||
| 161 | .bDeviceClass = USB_CLASS_COMM, | 161 | .bDeviceClass = USB_CLASS_COMM, |
| 162 | .bDeviceSubClass = 0, | 162 | .bDeviceSubClass = 0, |
| @@ -167,8 +167,8 @@ static struct usb_device_descriptor device_desc = { | |||
| 167 | * we support. (As does bNumConfigurations.) These values can | 167 | * we support. (As does bNumConfigurations.) These values can |
| 168 | * also be overridden by module parameters. | 168 | * also be overridden by module parameters. |
| 169 | */ | 169 | */ |
| 170 | .idVendor = __constant_cpu_to_le16 (CDC_VENDOR_NUM), | 170 | .idVendor = cpu_to_le16 (CDC_VENDOR_NUM), |
| 171 | .idProduct = __constant_cpu_to_le16 (CDC_PRODUCT_NUM), | 171 | .idProduct = cpu_to_le16 (CDC_PRODUCT_NUM), |
| 172 | /* .bcdDevice = f(hardware) */ | 172 | /* .bcdDevice = f(hardware) */ |
| 173 | /* .iManufacturer = DYNAMIC */ | 173 | /* .iManufacturer = DYNAMIC */ |
| 174 | /* .iProduct = DYNAMIC */ | 174 | /* .iProduct = DYNAMIC */ |
| @@ -318,7 +318,7 @@ static int __init eth_bind(struct usb_composite_dev *cdev) | |||
| 318 | gadget->name, | 318 | gadget->name, |
| 319 | eth_config_driver.label); | 319 | eth_config_driver.label); |
| 320 | device_desc.bcdDevice = | 320 | device_desc.bcdDevice = |
| 321 | __constant_cpu_to_le16(0x0300 | 0x0099); | 321 | cpu_to_le16(0x0300 | 0x0099); |
| 322 | } | 322 | } |
| 323 | 323 | ||
| 324 | 324 | ||
diff --git a/drivers/usb/gadget/f_acm.c b/drivers/usb/gadget/f_acm.c index c1d34df0b157..7953948bfe4a 100644 --- a/drivers/usb/gadget/f_acm.c +++ b/drivers/usb/gadget/f_acm.c | |||
| @@ -125,7 +125,7 @@ static struct usb_cdc_header_desc acm_header_desc __initdata = { | |||
| 125 | .bLength = sizeof(acm_header_desc), | 125 | .bLength = sizeof(acm_header_desc), |
| 126 | .bDescriptorType = USB_DT_CS_INTERFACE, | 126 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 127 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, | 127 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, |
| 128 | .bcdCDC = __constant_cpu_to_le16(0x0110), | 128 | .bcdCDC = cpu_to_le16(0x0110), |
| 129 | }; | 129 | }; |
| 130 | 130 | ||
| 131 | static struct usb_cdc_call_mgmt_descriptor | 131 | static struct usb_cdc_call_mgmt_descriptor |
| @@ -159,7 +159,7 @@ static struct usb_endpoint_descriptor acm_fs_notify_desc __initdata = { | |||
| 159 | .bDescriptorType = USB_DT_ENDPOINT, | 159 | .bDescriptorType = USB_DT_ENDPOINT, |
| 160 | .bEndpointAddress = USB_DIR_IN, | 160 | .bEndpointAddress = USB_DIR_IN, |
| 161 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 161 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
| 162 | .wMaxPacketSize = __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET), | 162 | .wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET), |
| 163 | .bInterval = 1 << GS_LOG2_NOTIFY_INTERVAL, | 163 | .bInterval = 1 << GS_LOG2_NOTIFY_INTERVAL, |
| 164 | }; | 164 | }; |
| 165 | 165 | ||
| @@ -197,7 +197,7 @@ static struct usb_endpoint_descriptor acm_hs_notify_desc __initdata = { | |||
| 197 | .bDescriptorType = USB_DT_ENDPOINT, | 197 | .bDescriptorType = USB_DT_ENDPOINT, |
| 198 | .bEndpointAddress = USB_DIR_IN, | 198 | .bEndpointAddress = USB_DIR_IN, |
| 199 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 199 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
| 200 | .wMaxPacketSize = __constant_cpu_to_le16(GS_NOTIFY_MAXPACKET), | 200 | .wMaxPacketSize = cpu_to_le16(GS_NOTIFY_MAXPACKET), |
| 201 | .bInterval = GS_LOG2_NOTIFY_INTERVAL+4, | 201 | .bInterval = GS_LOG2_NOTIFY_INTERVAL+4, |
| 202 | }; | 202 | }; |
| 203 | 203 | ||
| @@ -205,14 +205,14 @@ static struct usb_endpoint_descriptor acm_hs_in_desc __initdata = { | |||
| 205 | .bLength = USB_DT_ENDPOINT_SIZE, | 205 | .bLength = USB_DT_ENDPOINT_SIZE, |
| 206 | .bDescriptorType = USB_DT_ENDPOINT, | 206 | .bDescriptorType = USB_DT_ENDPOINT, |
| 207 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 207 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 208 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 208 | .wMaxPacketSize = cpu_to_le16(512), |
| 209 | }; | 209 | }; |
| 210 | 210 | ||
| 211 | static struct usb_endpoint_descriptor acm_hs_out_desc __initdata = { | 211 | static struct usb_endpoint_descriptor acm_hs_out_desc __initdata = { |
| 212 | .bLength = USB_DT_ENDPOINT_SIZE, | 212 | .bLength = USB_DT_ENDPOINT_SIZE, |
| 213 | .bDescriptorType = USB_DT_ENDPOINT, | 213 | .bDescriptorType = USB_DT_ENDPOINT, |
| 214 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 214 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 215 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 215 | .wMaxPacketSize = cpu_to_le16(512), |
| 216 | }; | 216 | }; |
| 217 | 217 | ||
| 218 | static struct usb_descriptor_header *acm_hs_function[] __initdata = { | 218 | static struct usb_descriptor_header *acm_hs_function[] __initdata = { |
diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c index 4ae579948e54..ecf5bdd0ae06 100644 --- a/drivers/usb/gadget/f_ecm.c +++ b/drivers/usb/gadget/f_ecm.c | |||
| @@ -130,7 +130,7 @@ static struct usb_cdc_header_desc ecm_header_desc __initdata = { | |||
| 130 | .bDescriptorType = USB_DT_CS_INTERFACE, | 130 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 131 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, | 131 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, |
| 132 | 132 | ||
| 133 | .bcdCDC = __constant_cpu_to_le16(0x0110), | 133 | .bcdCDC = cpu_to_le16(0x0110), |
| 134 | }; | 134 | }; |
| 135 | 135 | ||
| 136 | static struct usb_cdc_union_desc ecm_union_desc __initdata = { | 136 | static struct usb_cdc_union_desc ecm_union_desc __initdata = { |
| @@ -148,9 +148,9 @@ static struct usb_cdc_ether_desc ecm_desc __initdata = { | |||
| 148 | 148 | ||
| 149 | /* this descriptor actually adds value, surprise! */ | 149 | /* this descriptor actually adds value, surprise! */ |
| 150 | /* .iMACAddress = DYNAMIC */ | 150 | /* .iMACAddress = DYNAMIC */ |
| 151 | .bmEthernetStatistics = __constant_cpu_to_le32(0), /* no statistics */ | 151 | .bmEthernetStatistics = cpu_to_le32(0), /* no statistics */ |
| 152 | .wMaxSegmentSize = __constant_cpu_to_le16(ETH_FRAME_LEN), | 152 | .wMaxSegmentSize = cpu_to_le16(ETH_FRAME_LEN), |
| 153 | .wNumberMCFilters = __constant_cpu_to_le16(0), | 153 | .wNumberMCFilters = cpu_to_le16(0), |
| 154 | .bNumberPowerFilters = 0, | 154 | .bNumberPowerFilters = 0, |
| 155 | }; | 155 | }; |
| 156 | 156 | ||
| @@ -192,7 +192,7 @@ static struct usb_endpoint_descriptor fs_ecm_notify_desc __initdata = { | |||
| 192 | 192 | ||
| 193 | .bEndpointAddress = USB_DIR_IN, | 193 | .bEndpointAddress = USB_DIR_IN, |
| 194 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 194 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
| 195 | .wMaxPacketSize = __constant_cpu_to_le16(ECM_STATUS_BYTECOUNT), | 195 | .wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT), |
| 196 | .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC, | 196 | .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC, |
| 197 | }; | 197 | }; |
| 198 | 198 | ||
| @@ -236,7 +236,7 @@ static struct usb_endpoint_descriptor hs_ecm_notify_desc __initdata = { | |||
| 236 | 236 | ||
| 237 | .bEndpointAddress = USB_DIR_IN, | 237 | .bEndpointAddress = USB_DIR_IN, |
| 238 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 238 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
| 239 | .wMaxPacketSize = __constant_cpu_to_le16(ECM_STATUS_BYTECOUNT), | 239 | .wMaxPacketSize = cpu_to_le16(ECM_STATUS_BYTECOUNT), |
| 240 | .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, | 240 | .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, |
| 241 | }; | 241 | }; |
| 242 | static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = { | 242 | static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = { |
| @@ -245,7 +245,7 @@ static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = { | |||
| 245 | 245 | ||
| 246 | .bEndpointAddress = USB_DIR_IN, | 246 | .bEndpointAddress = USB_DIR_IN, |
| 247 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 247 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 248 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 248 | .wMaxPacketSize = cpu_to_le16(512), |
| 249 | }; | 249 | }; |
| 250 | 250 | ||
| 251 | static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = { | 251 | static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = { |
| @@ -254,7 +254,7 @@ static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = { | |||
| 254 | 254 | ||
| 255 | .bEndpointAddress = USB_DIR_OUT, | 255 | .bEndpointAddress = USB_DIR_OUT, |
| 256 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 256 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 257 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 257 | .wMaxPacketSize = cpu_to_le16(512), |
| 258 | }; | 258 | }; |
| 259 | 259 | ||
| 260 | static struct usb_descriptor_header *ecm_hs_function[] __initdata = { | 260 | static struct usb_descriptor_header *ecm_hs_function[] __initdata = { |
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c index 8affe1dfc2c1..eb6ddfc20857 100644 --- a/drivers/usb/gadget/f_loopback.c +++ b/drivers/usb/gadget/f_loopback.c | |||
| @@ -100,7 +100,7 @@ static struct usb_endpoint_descriptor hs_loop_source_desc = { | |||
| 100 | .bDescriptorType = USB_DT_ENDPOINT, | 100 | .bDescriptorType = USB_DT_ENDPOINT, |
| 101 | 101 | ||
| 102 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 102 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 103 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 103 | .wMaxPacketSize = cpu_to_le16(512), |
| 104 | }; | 104 | }; |
| 105 | 105 | ||
| 106 | static struct usb_endpoint_descriptor hs_loop_sink_desc = { | 106 | static struct usb_endpoint_descriptor hs_loop_sink_desc = { |
| @@ -108,7 +108,7 @@ static struct usb_endpoint_descriptor hs_loop_sink_desc = { | |||
| 108 | .bDescriptorType = USB_DT_ENDPOINT, | 108 | .bDescriptorType = USB_DT_ENDPOINT, |
| 109 | 109 | ||
| 110 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 110 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 111 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 111 | .wMaxPacketSize = cpu_to_le16(512), |
| 112 | }; | 112 | }; |
| 113 | 113 | ||
| 114 | static struct usb_descriptor_header *hs_loopback_descs[] = { | 114 | static struct usb_descriptor_header *hs_loopback_descs[] = { |
| @@ -359,7 +359,7 @@ static struct usb_configuration loopback_driver = { | |||
| 359 | * loopback_add - add a loopback testing configuration to a device | 359 | * loopback_add - add a loopback testing configuration to a device |
| 360 | * @cdev: the device to support the loopback configuration | 360 | * @cdev: the device to support the loopback configuration |
| 361 | */ | 361 | */ |
| 362 | int __init loopback_add(struct usb_composite_dev *cdev) | 362 | int __init loopback_add(struct usb_composite_dev *cdev, bool autoresume) |
| 363 | { | 363 | { |
| 364 | int id; | 364 | int id; |
| 365 | 365 | ||
| @@ -372,6 +372,10 @@ int __init loopback_add(struct usb_composite_dev *cdev) | |||
| 372 | loopback_intf.iInterface = id; | 372 | loopback_intf.iInterface = id; |
| 373 | loopback_driver.iConfiguration = id; | 373 | loopback_driver.iConfiguration = id; |
| 374 | 374 | ||
| 375 | /* support autoresume for remote wakeup testing */ | ||
| 376 | if (autoresume) | ||
| 377 | sourcesink_driver.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | ||
| 378 | |||
| 375 | /* support OTG systems */ | 379 | /* support OTG systems */ |
| 376 | if (gadget_is_otg(cdev->gadget)) { | 380 | if (gadget_is_otg(cdev->gadget)) { |
| 377 | loopback_driver.descriptors = otg_desc; | 381 | loopback_driver.descriptors = otg_desc; |
diff --git a/drivers/usb/gadget/f_obex.c b/drivers/usb/gadget/f_obex.c index 38aa896cc5db..46d6266f30ec 100644 --- a/drivers/usb/gadget/f_obex.c +++ b/drivers/usb/gadget/f_obex.c | |||
| @@ -123,7 +123,7 @@ static struct usb_cdc_header_desc obex_cdc_header_desc __initdata = { | |||
| 123 | .bLength = sizeof(obex_cdc_header_desc), | 123 | .bLength = sizeof(obex_cdc_header_desc), |
| 124 | .bDescriptorType = USB_DT_CS_INTERFACE, | 124 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 125 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, | 125 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, |
| 126 | .bcdCDC = __constant_cpu_to_le16(0x0120), | 126 | .bcdCDC = cpu_to_le16(0x0120), |
| 127 | }; | 127 | }; |
| 128 | 128 | ||
| 129 | static struct usb_cdc_union_desc obex_cdc_union_desc __initdata = { | 129 | static struct usb_cdc_union_desc obex_cdc_union_desc __initdata = { |
| @@ -138,7 +138,7 @@ static struct usb_cdc_obex_desc obex_desc __initdata = { | |||
| 138 | .bLength = sizeof(obex_desc), | 138 | .bLength = sizeof(obex_desc), |
| 139 | .bDescriptorType = USB_DT_CS_INTERFACE, | 139 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 140 | .bDescriptorSubType = USB_CDC_OBEX_TYPE, | 140 | .bDescriptorSubType = USB_CDC_OBEX_TYPE, |
| 141 | .bcdVersion = __constant_cpu_to_le16(0x0100), | 141 | .bcdVersion = cpu_to_le16(0x0100), |
| 142 | }; | 142 | }; |
| 143 | 143 | ||
| 144 | /* High-Speed Support */ | 144 | /* High-Speed Support */ |
| @@ -149,7 +149,7 @@ static struct usb_endpoint_descriptor obex_hs_ep_out_desc __initdata = { | |||
| 149 | 149 | ||
| 150 | .bEndpointAddress = USB_DIR_OUT, | 150 | .bEndpointAddress = USB_DIR_OUT, |
| 151 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 151 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 152 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 152 | .wMaxPacketSize = cpu_to_le16(512), |
| 153 | }; | 153 | }; |
| 154 | 154 | ||
| 155 | static struct usb_endpoint_descriptor obex_hs_ep_in_desc __initdata = { | 155 | static struct usb_endpoint_descriptor obex_hs_ep_in_desc __initdata = { |
| @@ -158,7 +158,7 @@ static struct usb_endpoint_descriptor obex_hs_ep_in_desc __initdata = { | |||
| 158 | 158 | ||
| 159 | .bEndpointAddress = USB_DIR_IN, | 159 | .bEndpointAddress = USB_DIR_IN, |
| 160 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 160 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 161 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 161 | .wMaxPacketSize = cpu_to_le16(512), |
| 162 | }; | 162 | }; |
| 163 | 163 | ||
| 164 | static struct usb_descriptor_header *hs_function[] __initdata = { | 164 | static struct usb_descriptor_header *hs_function[] __initdata = { |
diff --git a/drivers/usb/gadget/f_phonet.c b/drivers/usb/gadget/f_phonet.c index c0916c7b217e..c1abeb89b413 100644 --- a/drivers/usb/gadget/f_phonet.c +++ b/drivers/usb/gadget/f_phonet.c | |||
| @@ -79,7 +79,7 @@ pn_header_desc = { | |||
| 79 | .bLength = sizeof pn_header_desc, | 79 | .bLength = sizeof pn_header_desc, |
| 80 | .bDescriptorType = USB_DT_CS_INTERFACE, | 80 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 81 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, | 81 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, |
| 82 | .bcdCDC = __constant_cpu_to_le16(0x0110), | 82 | .bcdCDC = cpu_to_le16(0x0110), |
| 83 | }; | 83 | }; |
| 84 | 84 | ||
| 85 | static const struct usb_cdc_header_desc | 85 | static const struct usb_cdc_header_desc |
| @@ -87,7 +87,7 @@ pn_phonet_desc = { | |||
| 87 | .bLength = sizeof pn_phonet_desc, | 87 | .bLength = sizeof pn_phonet_desc, |
| 88 | .bDescriptorType = USB_DT_CS_INTERFACE, | 88 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 89 | .bDescriptorSubType = USB_CDC_PHONET_TYPE, | 89 | .bDescriptorSubType = USB_CDC_PHONET_TYPE, |
| 90 | .bcdCDC = __constant_cpu_to_le16(0x1505), /* ??? */ | 90 | .bcdCDC = cpu_to_le16(0x1505), /* ??? */ |
| 91 | }; | 91 | }; |
| 92 | 92 | ||
| 93 | static struct usb_cdc_union_desc | 93 | static struct usb_cdc_union_desc |
| @@ -138,7 +138,7 @@ pn_hs_sink_desc = { | |||
| 138 | 138 | ||
| 139 | .bEndpointAddress = USB_DIR_OUT, | 139 | .bEndpointAddress = USB_DIR_OUT, |
| 140 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 140 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 141 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 141 | .wMaxPacketSize = cpu_to_le16(512), |
| 142 | }; | 142 | }; |
| 143 | 143 | ||
| 144 | static struct usb_endpoint_descriptor | 144 | static struct usb_endpoint_descriptor |
| @@ -157,7 +157,7 @@ pn_hs_source_desc = { | |||
| 157 | 157 | ||
| 158 | .bEndpointAddress = USB_DIR_IN, | 158 | .bEndpointAddress = USB_DIR_IN, |
| 159 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 159 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 160 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 160 | .wMaxPacketSize = cpu_to_le16(512), |
| 161 | }; | 161 | }; |
| 162 | 162 | ||
| 163 | static struct usb_descriptor_header *fs_pn_function[] = { | 163 | static struct usb_descriptor_header *fs_pn_function[] = { |
diff --git a/drivers/usb/gadget/f_rndis.c b/drivers/usb/gadget/f_rndis.c index 3a8bb53fc473..3279a4726042 100644 --- a/drivers/usb/gadget/f_rndis.c +++ b/drivers/usb/gadget/f_rndis.c | |||
| @@ -137,7 +137,7 @@ static struct usb_cdc_header_desc header_desc __initdata = { | |||
| 137 | .bDescriptorType = USB_DT_CS_INTERFACE, | 137 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 138 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, | 138 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, |
| 139 | 139 | ||
| 140 | .bcdCDC = __constant_cpu_to_le16(0x0110), | 140 | .bcdCDC = cpu_to_le16(0x0110), |
| 141 | }; | 141 | }; |
| 142 | 142 | ||
| 143 | static struct usb_cdc_call_mgmt_descriptor call_mgmt_descriptor __initdata = { | 143 | static struct usb_cdc_call_mgmt_descriptor call_mgmt_descriptor __initdata = { |
| @@ -187,7 +187,7 @@ static struct usb_endpoint_descriptor fs_notify_desc __initdata = { | |||
| 187 | 187 | ||
| 188 | .bEndpointAddress = USB_DIR_IN, | 188 | .bEndpointAddress = USB_DIR_IN, |
| 189 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 189 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
| 190 | .wMaxPacketSize = __constant_cpu_to_le16(STATUS_BYTECOUNT), | 190 | .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), |
| 191 | .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC, | 191 | .bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC, |
| 192 | }; | 192 | }; |
| 193 | 193 | ||
| @@ -230,7 +230,7 @@ static struct usb_endpoint_descriptor hs_notify_desc __initdata = { | |||
| 230 | 230 | ||
| 231 | .bEndpointAddress = USB_DIR_IN, | 231 | .bEndpointAddress = USB_DIR_IN, |
| 232 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 232 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
| 233 | .wMaxPacketSize = __constant_cpu_to_le16(STATUS_BYTECOUNT), | 233 | .wMaxPacketSize = cpu_to_le16(STATUS_BYTECOUNT), |
| 234 | .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, | 234 | .bInterval = LOG2_STATUS_INTERVAL_MSEC + 4, |
| 235 | }; | 235 | }; |
| 236 | static struct usb_endpoint_descriptor hs_in_desc __initdata = { | 236 | static struct usb_endpoint_descriptor hs_in_desc __initdata = { |
| @@ -239,7 +239,7 @@ static struct usb_endpoint_descriptor hs_in_desc __initdata = { | |||
| 239 | 239 | ||
| 240 | .bEndpointAddress = USB_DIR_IN, | 240 | .bEndpointAddress = USB_DIR_IN, |
| 241 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 241 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 242 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 242 | .wMaxPacketSize = cpu_to_le16(512), |
| 243 | }; | 243 | }; |
| 244 | 244 | ||
| 245 | static struct usb_endpoint_descriptor hs_out_desc __initdata = { | 245 | static struct usb_endpoint_descriptor hs_out_desc __initdata = { |
| @@ -248,7 +248,7 @@ static struct usb_endpoint_descriptor hs_out_desc __initdata = { | |||
| 248 | 248 | ||
| 249 | .bEndpointAddress = USB_DIR_OUT, | 249 | .bEndpointAddress = USB_DIR_OUT, |
| 250 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 250 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 251 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 251 | .wMaxPacketSize = cpu_to_le16(512), |
| 252 | }; | 252 | }; |
| 253 | 253 | ||
| 254 | static struct usb_descriptor_header *eth_hs_function[] __initdata = { | 254 | static struct usb_descriptor_header *eth_hs_function[] __initdata = { |
| @@ -437,7 +437,7 @@ invalid: | |||
| 437 | DBG(cdev, "rndis req%02x.%02x v%04x i%04x l%d\n", | 437 | DBG(cdev, "rndis req%02x.%02x v%04x i%04x l%d\n", |
| 438 | ctrl->bRequestType, ctrl->bRequest, | 438 | ctrl->bRequestType, ctrl->bRequest, |
| 439 | w_value, w_index, w_length); | 439 | w_value, w_index, w_length); |
| 440 | req->zero = 0; | 440 | req->zero = (value < w_length); |
| 441 | req->length = value; | 441 | req->length = value; |
| 442 | value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); | 442 | value = usb_ep_queue(cdev->gadget->ep0, req, GFP_ATOMIC); |
| 443 | if (value < 0) | 443 | if (value < 0) |
diff --git a/drivers/usb/gadget/f_serial.c b/drivers/usb/gadget/f_serial.c index fe5674db344b..db0aa93606ef 100644 --- a/drivers/usb/gadget/f_serial.c +++ b/drivers/usb/gadget/f_serial.c | |||
| @@ -89,14 +89,14 @@ static struct usb_endpoint_descriptor gser_hs_in_desc __initdata = { | |||
| 89 | .bLength = USB_DT_ENDPOINT_SIZE, | 89 | .bLength = USB_DT_ENDPOINT_SIZE, |
| 90 | .bDescriptorType = USB_DT_ENDPOINT, | 90 | .bDescriptorType = USB_DT_ENDPOINT, |
| 91 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 91 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 92 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 92 | .wMaxPacketSize = cpu_to_le16(512), |
| 93 | }; | 93 | }; |
| 94 | 94 | ||
| 95 | static struct usb_endpoint_descriptor gser_hs_out_desc __initdata = { | 95 | static struct usb_endpoint_descriptor gser_hs_out_desc __initdata = { |
| 96 | .bLength = USB_DT_ENDPOINT_SIZE, | 96 | .bLength = USB_DT_ENDPOINT_SIZE, |
| 97 | .bDescriptorType = USB_DT_ENDPOINT, | 97 | .bDescriptorType = USB_DT_ENDPOINT, |
| 98 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 98 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 99 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 99 | .wMaxPacketSize = cpu_to_le16(512), |
| 100 | }; | 100 | }; |
| 101 | 101 | ||
| 102 | static struct usb_descriptor_header *gser_hs_function[] __initdata = { | 102 | static struct usb_descriptor_header *gser_hs_function[] __initdata = { |
diff --git a/drivers/usb/gadget/f_sourcesink.c b/drivers/usb/gadget/f_sourcesink.c index dc84d26d2835..bffe91d525f9 100644 --- a/drivers/usb/gadget/f_sourcesink.c +++ b/drivers/usb/gadget/f_sourcesink.c | |||
| @@ -59,7 +59,6 @@ struct f_sourcesink { | |||
| 59 | 59 | ||
| 60 | struct usb_ep *in_ep; | 60 | struct usb_ep *in_ep; |
| 61 | struct usb_ep *out_ep; | 61 | struct usb_ep *out_ep; |
| 62 | struct timer_list resume; | ||
| 63 | }; | 62 | }; |
| 64 | 63 | ||
| 65 | static inline struct f_sourcesink *func_to_ss(struct usb_function *f) | 64 | static inline struct f_sourcesink *func_to_ss(struct usb_function *f) |
| @@ -67,10 +66,6 @@ static inline struct f_sourcesink *func_to_ss(struct usb_function *f) | |||
| 67 | return container_of(f, struct f_sourcesink, function); | 66 | return container_of(f, struct f_sourcesink, function); |
| 68 | } | 67 | } |
| 69 | 68 | ||
| 70 | static unsigned autoresume; | ||
| 71 | module_param(autoresume, uint, 0); | ||
| 72 | MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup"); | ||
| 73 | |||
| 74 | static unsigned pattern; | 69 | static unsigned pattern; |
| 75 | module_param(pattern, uint, 0); | 70 | module_param(pattern, uint, 0); |
| 76 | MODULE_PARM_DESC(pattern, "0 = all zeroes, 1 = mod63 "); | 71 | MODULE_PARM_DESC(pattern, "0 = all zeroes, 1 = mod63 "); |
| @@ -118,7 +113,7 @@ static struct usb_endpoint_descriptor hs_source_desc = { | |||
| 118 | .bDescriptorType = USB_DT_ENDPOINT, | 113 | .bDescriptorType = USB_DT_ENDPOINT, |
| 119 | 114 | ||
| 120 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 115 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 121 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 116 | .wMaxPacketSize = cpu_to_le16(512), |
| 122 | }; | 117 | }; |
| 123 | 118 | ||
| 124 | static struct usb_endpoint_descriptor hs_sink_desc = { | 119 | static struct usb_endpoint_descriptor hs_sink_desc = { |
| @@ -126,7 +121,7 @@ static struct usb_endpoint_descriptor hs_sink_desc = { | |||
| 126 | .bDescriptorType = USB_DT_ENDPOINT, | 121 | .bDescriptorType = USB_DT_ENDPOINT, |
| 127 | 122 | ||
| 128 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 123 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 129 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 124 | .wMaxPacketSize = cpu_to_le16(512), |
| 130 | }; | 125 | }; |
| 131 | 126 | ||
| 132 | static struct usb_descriptor_header *hs_source_sink_descs[] = { | 127 | static struct usb_descriptor_header *hs_source_sink_descs[] = { |
| @@ -155,21 +150,6 @@ static struct usb_gadget_strings *sourcesink_strings[] = { | |||
| 155 | 150 | ||
| 156 | /*-------------------------------------------------------------------------*/ | 151 | /*-------------------------------------------------------------------------*/ |
| 157 | 152 | ||
| 158 | static void sourcesink_autoresume(unsigned long _c) | ||
| 159 | { | ||
| 160 | struct usb_composite_dev *cdev = (void *)_c; | ||
| 161 | struct usb_gadget *g = cdev->gadget; | ||
| 162 | |||
| 163 | /* Normally the host would be woken up for something | ||
| 164 | * more significant than just a timer firing; likely | ||
| 165 | * because of some direct user request. | ||
| 166 | */ | ||
| 167 | if (g->speed != USB_SPEED_UNKNOWN) { | ||
| 168 | int status = usb_gadget_wakeup(g); | ||
| 169 | DBG(cdev, "%s --> %d\n", __func__, status); | ||
| 170 | } | ||
| 171 | } | ||
| 172 | |||
| 173 | static int __init | 153 | static int __init |
| 174 | sourcesink_bind(struct usb_configuration *c, struct usb_function *f) | 154 | sourcesink_bind(struct usb_configuration *c, struct usb_function *f) |
| 175 | { | 155 | { |
| @@ -198,9 +178,6 @@ autoconf_fail: | |||
| 198 | goto autoconf_fail; | 178 | goto autoconf_fail; |
| 199 | ss->out_ep->driver_data = cdev; /* claim */ | 179 | ss->out_ep->driver_data = cdev; /* claim */ |
| 200 | 180 | ||
| 201 | setup_timer(&ss->resume, sourcesink_autoresume, | ||
| 202 | (unsigned long) c->cdev); | ||
| 203 | |||
| 204 | /* support high speed hardware */ | 181 | /* support high speed hardware */ |
| 205 | if (gadget_is_dualspeed(c->cdev->gadget)) { | 182 | if (gadget_is_dualspeed(c->cdev->gadget)) { |
| 206 | hs_source_desc.bEndpointAddress = | 183 | hs_source_desc.bEndpointAddress = |
| @@ -359,7 +336,6 @@ static void disable_source_sink(struct f_sourcesink *ss) | |||
| 359 | 336 | ||
| 360 | cdev = ss->function.config->cdev; | 337 | cdev = ss->function.config->cdev; |
| 361 | disable_endpoints(cdev, ss->in_ep, ss->out_ep); | 338 | disable_endpoints(cdev, ss->in_ep, ss->out_ep); |
| 362 | del_timer(&ss->resume); | ||
| 363 | VDBG(cdev, "%s disabled\n", ss->function.name); | 339 | VDBG(cdev, "%s disabled\n", ss->function.name); |
| 364 | } | 340 | } |
| 365 | 341 | ||
| @@ -426,30 +402,6 @@ static void sourcesink_disable(struct usb_function *f) | |||
| 426 | disable_source_sink(ss); | 402 | disable_source_sink(ss); |
| 427 | } | 403 | } |
| 428 | 404 | ||
| 429 | static void sourcesink_suspend(struct usb_function *f) | ||
| 430 | { | ||
| 431 | struct f_sourcesink *ss = func_to_ss(f); | ||
| 432 | struct usb_composite_dev *cdev = f->config->cdev; | ||
| 433 | |||
| 434 | if (cdev->gadget->speed == USB_SPEED_UNKNOWN) | ||
| 435 | return; | ||
| 436 | |||
| 437 | if (autoresume) { | ||
| 438 | mod_timer(&ss->resume, jiffies + (HZ * autoresume)); | ||
| 439 | DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume); | ||
| 440 | } else | ||
| 441 | DBG(cdev, "%s\n", __func__); | ||
| 442 | } | ||
| 443 | |||
| 444 | static void sourcesink_resume(struct usb_function *f) | ||
| 445 | { | ||
| 446 | struct f_sourcesink *ss = func_to_ss(f); | ||
| 447 | struct usb_composite_dev *cdev = f->config->cdev; | ||
| 448 | |||
| 449 | DBG(cdev, "%s\n", __func__); | ||
| 450 | del_timer(&ss->resume); | ||
| 451 | } | ||
| 452 | |||
| 453 | /*-------------------------------------------------------------------------*/ | 405 | /*-------------------------------------------------------------------------*/ |
| 454 | 406 | ||
| 455 | static int __init sourcesink_bind_config(struct usb_configuration *c) | 407 | static int __init sourcesink_bind_config(struct usb_configuration *c) |
| @@ -467,8 +419,6 @@ static int __init sourcesink_bind_config(struct usb_configuration *c) | |||
| 467 | ss->function.unbind = sourcesink_unbind; | 419 | ss->function.unbind = sourcesink_unbind; |
| 468 | ss->function.set_alt = sourcesink_set_alt; | 420 | ss->function.set_alt = sourcesink_set_alt; |
| 469 | ss->function.disable = sourcesink_disable; | 421 | ss->function.disable = sourcesink_disable; |
| 470 | ss->function.suspend = sourcesink_suspend; | ||
| 471 | ss->function.resume = sourcesink_resume; | ||
| 472 | 422 | ||
| 473 | status = usb_add_function(c, &ss->function); | 423 | status = usb_add_function(c, &ss->function); |
| 474 | if (status) | 424 | if (status) |
| @@ -559,7 +509,7 @@ static struct usb_configuration sourcesink_driver = { | |||
| 559 | * sourcesink_add - add a source/sink testing configuration to a device | 509 | * sourcesink_add - add a source/sink testing configuration to a device |
| 560 | * @cdev: the device to support the configuration | 510 | * @cdev: the device to support the configuration |
| 561 | */ | 511 | */ |
| 562 | int __init sourcesink_add(struct usb_composite_dev *cdev) | 512 | int __init sourcesink_add(struct usb_composite_dev *cdev, bool autoresume) |
| 563 | { | 513 | { |
| 564 | int id; | 514 | int id; |
| 565 | 515 | ||
diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c index fe1832875771..a9c98fdb626d 100644 --- a/drivers/usb/gadget/f_subset.c +++ b/drivers/usb/gadget/f_subset.c | |||
| @@ -108,7 +108,7 @@ static struct usb_cdc_header_desc mdlm_header_desc __initdata = { | |||
| 108 | .bDescriptorType = USB_DT_CS_INTERFACE, | 108 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 109 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, | 109 | .bDescriptorSubType = USB_CDC_HEADER_TYPE, |
| 110 | 110 | ||
| 111 | .bcdCDC = __constant_cpu_to_le16(0x0110), | 111 | .bcdCDC = cpu_to_le16(0x0110), |
| 112 | }; | 112 | }; |
| 113 | 113 | ||
| 114 | static struct usb_cdc_mdlm_desc mdlm_desc __initdata = { | 114 | static struct usb_cdc_mdlm_desc mdlm_desc __initdata = { |
| @@ -116,7 +116,7 @@ static struct usb_cdc_mdlm_desc mdlm_desc __initdata = { | |||
| 116 | .bDescriptorType = USB_DT_CS_INTERFACE, | 116 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 117 | .bDescriptorSubType = USB_CDC_MDLM_TYPE, | 117 | .bDescriptorSubType = USB_CDC_MDLM_TYPE, |
| 118 | 118 | ||
| 119 | .bcdVersion = __constant_cpu_to_le16(0x0100), | 119 | .bcdVersion = cpu_to_le16(0x0100), |
| 120 | .bGUID = { | 120 | .bGUID = { |
| 121 | 0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6, | 121 | 0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6, |
| 122 | 0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f, | 122 | 0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f, |
| @@ -144,9 +144,9 @@ static struct usb_cdc_ether_desc ether_desc __initdata = { | |||
| 144 | 144 | ||
| 145 | /* this descriptor actually adds value, surprise! */ | 145 | /* this descriptor actually adds value, surprise! */ |
| 146 | /* .iMACAddress = DYNAMIC */ | 146 | /* .iMACAddress = DYNAMIC */ |
| 147 | .bmEthernetStatistics = __constant_cpu_to_le32(0), /* no statistics */ | 147 | .bmEthernetStatistics = cpu_to_le32(0), /* no statistics */ |
| 148 | .wMaxSegmentSize = __constant_cpu_to_le16(ETH_FRAME_LEN), | 148 | .wMaxSegmentSize = cpu_to_le16(ETH_FRAME_LEN), |
| 149 | .wNumberMCFilters = __constant_cpu_to_le16(0), | 149 | .wNumberMCFilters = cpu_to_le16(0), |
| 150 | .bNumberPowerFilters = 0, | 150 | .bNumberPowerFilters = 0, |
| 151 | }; | 151 | }; |
| 152 | 152 | ||
| @@ -186,7 +186,7 @@ static struct usb_endpoint_descriptor hs_subset_in_desc __initdata = { | |||
| 186 | .bDescriptorType = USB_DT_ENDPOINT, | 186 | .bDescriptorType = USB_DT_ENDPOINT, |
| 187 | 187 | ||
| 188 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 188 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 189 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 189 | .wMaxPacketSize = cpu_to_le16(512), |
| 190 | }; | 190 | }; |
| 191 | 191 | ||
| 192 | static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = { | 192 | static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = { |
| @@ -194,7 +194,7 @@ static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = { | |||
| 194 | .bDescriptorType = USB_DT_ENDPOINT, | 194 | .bDescriptorType = USB_DT_ENDPOINT, |
| 195 | 195 | ||
| 196 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 196 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 197 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 197 | .wMaxPacketSize = cpu_to_le16(512), |
| 198 | }; | 198 | }; |
| 199 | 199 | ||
| 200 | static struct usb_descriptor_header *hs_eth_function[] __initdata = { | 200 | static struct usb_descriptor_header *hs_eth_function[] __initdata = { |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 1ab9dac7e12d..5c030b080d4c 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
| @@ -847,13 +847,13 @@ device_desc = { | |||
| 847 | .bLength = sizeof device_desc, | 847 | .bLength = sizeof device_desc, |
| 848 | .bDescriptorType = USB_DT_DEVICE, | 848 | .bDescriptorType = USB_DT_DEVICE, |
| 849 | 849 | ||
| 850 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 850 | .bcdUSB = cpu_to_le16(0x0200), |
| 851 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | 851 | .bDeviceClass = USB_CLASS_PER_INTERFACE, |
| 852 | 852 | ||
| 853 | /* The next three values can be overridden by module parameters */ | 853 | /* The next three values can be overridden by module parameters */ |
| 854 | .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_ID), | 854 | .idVendor = cpu_to_le16(DRIVER_VENDOR_ID), |
| 855 | .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_ID), | 855 | .idProduct = cpu_to_le16(DRIVER_PRODUCT_ID), |
| 856 | .bcdDevice = __constant_cpu_to_le16(0xffff), | 856 | .bcdDevice = cpu_to_le16(0xffff), |
| 857 | 857 | ||
| 858 | .iManufacturer = STRING_MANUFACTURER, | 858 | .iManufacturer = STRING_MANUFACTURER, |
| 859 | .iProduct = STRING_PRODUCT, | 859 | .iProduct = STRING_PRODUCT, |
| @@ -926,7 +926,7 @@ fs_intr_in_desc = { | |||
| 926 | 926 | ||
| 927 | .bEndpointAddress = USB_DIR_IN, | 927 | .bEndpointAddress = USB_DIR_IN, |
| 928 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 928 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
| 929 | .wMaxPacketSize = __constant_cpu_to_le16(2), | 929 | .wMaxPacketSize = cpu_to_le16(2), |
| 930 | .bInterval = 32, // frames -> 32 ms | 930 | .bInterval = 32, // frames -> 32 ms |
| 931 | }; | 931 | }; |
| 932 | 932 | ||
| @@ -954,7 +954,7 @@ dev_qualifier = { | |||
| 954 | .bLength = sizeof dev_qualifier, | 954 | .bLength = sizeof dev_qualifier, |
| 955 | .bDescriptorType = USB_DT_DEVICE_QUALIFIER, | 955 | .bDescriptorType = USB_DT_DEVICE_QUALIFIER, |
| 956 | 956 | ||
| 957 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 957 | .bcdUSB = cpu_to_le16(0x0200), |
| 958 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | 958 | .bDeviceClass = USB_CLASS_PER_INTERFACE, |
| 959 | 959 | ||
| 960 | .bNumConfigurations = 1, | 960 | .bNumConfigurations = 1, |
| @@ -967,7 +967,7 @@ hs_bulk_in_desc = { | |||
| 967 | 967 | ||
| 968 | /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */ | 968 | /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */ |
| 969 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 969 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 970 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 970 | .wMaxPacketSize = cpu_to_le16(512), |
| 971 | }; | 971 | }; |
| 972 | 972 | ||
| 973 | static struct usb_endpoint_descriptor | 973 | static struct usb_endpoint_descriptor |
| @@ -977,7 +977,7 @@ hs_bulk_out_desc = { | |||
| 977 | 977 | ||
| 978 | /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */ | 978 | /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */ |
| 979 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 979 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 980 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 980 | .wMaxPacketSize = cpu_to_le16(512), |
| 981 | .bInterval = 1, // NAK every 1 uframe | 981 | .bInterval = 1, // NAK every 1 uframe |
| 982 | }; | 982 | }; |
| 983 | 983 | ||
| @@ -988,7 +988,7 @@ hs_intr_in_desc = { | |||
| 988 | 988 | ||
| 989 | /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */ | 989 | /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */ |
| 990 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 990 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
| 991 | .wMaxPacketSize = __constant_cpu_to_le16(2), | 991 | .wMaxPacketSize = cpu_to_le16(2), |
| 992 | .bInterval = 9, // 2**(9-1) = 256 uframes -> 32 ms | 992 | .bInterval = 9, // 2**(9-1) = 256 uframes -> 32 ms |
| 993 | }; | 993 | }; |
| 994 | 994 | ||
| @@ -1711,7 +1711,9 @@ static int do_write(struct fsg_dev *fsg) | |||
| 1711 | curlun->sense_data = SS_WRITE_PROTECTED; | 1711 | curlun->sense_data = SS_WRITE_PROTECTED; |
| 1712 | return -EINVAL; | 1712 | return -EINVAL; |
| 1713 | } | 1713 | } |
| 1714 | spin_lock(&curlun->filp->f_lock); | ||
| 1714 | curlun->filp->f_flags &= ~O_SYNC; // Default is not to wait | 1715 | curlun->filp->f_flags &= ~O_SYNC; // Default is not to wait |
| 1716 | spin_unlock(&curlun->filp->f_lock); | ||
| 1715 | 1717 | ||
| 1716 | /* Get the starting Logical Block Address and check that it's | 1718 | /* Get the starting Logical Block Address and check that it's |
| 1717 | * not too big */ | 1719 | * not too big */ |
| @@ -1728,8 +1730,11 @@ static int do_write(struct fsg_dev *fsg) | |||
| 1728 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; | 1730 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; |
| 1729 | return -EINVAL; | 1731 | return -EINVAL; |
| 1730 | } | 1732 | } |
| 1731 | if (fsg->cmnd[1] & 0x08) // FUA | 1733 | if (fsg->cmnd[1] & 0x08) { // FUA |
| 1734 | spin_lock(&curlun->filp->f_lock); | ||
| 1732 | curlun->filp->f_flags |= O_SYNC; | 1735 | curlun->filp->f_flags |= O_SYNC; |
| 1736 | spin_unlock(&curlun->filp->f_lock); | ||
| 1737 | } | ||
| 1733 | } | 1738 | } |
| 1734 | if (lba >= curlun->num_sectors) { | 1739 | if (lba >= curlun->num_sectors) { |
| 1735 | curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 1740 | curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
| @@ -2646,7 +2651,7 @@ static int send_status(struct fsg_dev *fsg) | |||
| 2646 | struct bulk_cs_wrap *csw = bh->buf; | 2651 | struct bulk_cs_wrap *csw = bh->buf; |
| 2647 | 2652 | ||
| 2648 | /* Store and send the Bulk-only CSW */ | 2653 | /* Store and send the Bulk-only CSW */ |
| 2649 | csw->Signature = __constant_cpu_to_le32(USB_BULK_CS_SIG); | 2654 | csw->Signature = cpu_to_le32(USB_BULK_CS_SIG); |
| 2650 | csw->Tag = fsg->tag; | 2655 | csw->Tag = fsg->tag; |
| 2651 | csw->Residue = cpu_to_le32(fsg->residue); | 2656 | csw->Residue = cpu_to_le32(fsg->residue); |
| 2652 | csw->Status = status; | 2657 | csw->Status = status; |
| @@ -3089,7 +3094,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
| 3089 | 3094 | ||
| 3090 | /* Is the CBW valid? */ | 3095 | /* Is the CBW valid? */ |
| 3091 | if (req->actual != USB_BULK_CB_WRAP_LEN || | 3096 | if (req->actual != USB_BULK_CB_WRAP_LEN || |
| 3092 | cbw->Signature != __constant_cpu_to_le32( | 3097 | cbw->Signature != cpu_to_le32( |
| 3093 | USB_BULK_CB_SIG)) { | 3098 | USB_BULK_CB_SIG)) { |
| 3094 | DBG(fsg, "invalid CBW: len %u sig 0x%x\n", | 3099 | DBG(fsg, "invalid CBW: len %u sig 0x%x\n", |
| 3095 | req->actual, | 3100 | req->actual, |
diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index d8d9a52a44b3..9d7b95d4e3d2 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c | |||
| @@ -1802,7 +1802,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
| 1802 | 1802 | ||
| 1803 | out: | 1803 | out: |
| 1804 | if (retval) | 1804 | if (retval) |
| 1805 | printk("gadget driver register failed %d\n", retval); | 1805 | printk(KERN_WARNING "gadget driver register failed %d\n", |
| 1806 | retval); | ||
| 1806 | return retval; | 1807 | return retval; |
| 1807 | } | 1808 | } |
| 1808 | EXPORT_SYMBOL(usb_gadget_register_driver); | 1809 | EXPORT_SYMBOL(usb_gadget_register_driver); |
| @@ -1847,7 +1848,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
| 1847 | udc_controller->gadget.dev.driver = NULL; | 1848 | udc_controller->gadget.dev.driver = NULL; |
| 1848 | udc_controller->driver = NULL; | 1849 | udc_controller->driver = NULL; |
| 1849 | 1850 | ||
| 1850 | printk("unregistered gadget driver '%s'\n", driver->driver.name); | 1851 | printk(KERN_WARNING "unregistered gadget driver '%s'\n", |
| 1852 | driver->driver.name); | ||
| 1851 | return 0; | 1853 | return 0; |
| 1852 | } | 1854 | } |
| 1853 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | 1855 | EXPORT_SYMBOL(usb_gadget_unregister_driver); |
| @@ -2455,7 +2457,7 @@ module_init(udc_init); | |||
| 2455 | static void __exit udc_exit(void) | 2457 | static void __exit udc_exit(void) |
| 2456 | { | 2458 | { |
| 2457 | platform_driver_unregister(&udc_driver); | 2459 | platform_driver_unregister(&udc_driver); |
| 2458 | printk("%s unregistered\n", driver_desc); | 2460 | printk(KERN_WARNING "%s unregistered\n", driver_desc); |
| 2459 | } | 2461 | } |
| 2460 | 2462 | ||
| 2461 | module_exit(udc_exit); | 2463 | module_exit(udc_exit); |
diff --git a/drivers/usb/gadget/g_zero.h b/drivers/usb/gadget/g_zero.h index dd2f16ad5a88..e84b3c47ed3c 100644 --- a/drivers/usb/gadget/g_zero.h +++ b/drivers/usb/gadget/g_zero.h | |||
| @@ -19,7 +19,7 @@ void disable_endpoints(struct usb_composite_dev *cdev, | |||
| 19 | struct usb_ep *in, struct usb_ep *out); | 19 | struct usb_ep *in, struct usb_ep *out); |
| 20 | 20 | ||
| 21 | /* configuration-specific linkup */ | 21 | /* configuration-specific linkup */ |
| 22 | int sourcesink_add(struct usb_composite_dev *cdev); | 22 | int sourcesink_add(struct usb_composite_dev *cdev, bool autoresume); |
| 23 | int loopback_add(struct usb_composite_dev *cdev); | 23 | int loopback_add(struct usb_composite_dev *cdev, bool autoresume); |
| 24 | 24 | ||
| 25 | #endif /* __G_ZERO_H */ | 25 | #endif /* __G_ZERO_H */ |
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 60d3f9e9b51f..b9312dc6e041 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c | |||
| @@ -199,10 +199,10 @@ DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(1); | |||
| 199 | static struct usb_device_descriptor device_desc = { | 199 | static struct usb_device_descriptor device_desc = { |
| 200 | .bLength = USB_DT_DEVICE_SIZE, | 200 | .bLength = USB_DT_DEVICE_SIZE, |
| 201 | .bDescriptorType = USB_DT_DEVICE, | 201 | .bDescriptorType = USB_DT_DEVICE, |
| 202 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 202 | .bcdUSB = cpu_to_le16(0x0200), |
| 203 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | 203 | .bDeviceClass = USB_CLASS_PER_INTERFACE, |
| 204 | .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_NUM), | 204 | .idVendor = cpu_to_le16(DRIVER_VENDOR_NUM), |
| 205 | .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_NUM), | 205 | .idProduct = cpu_to_le16(DRIVER_PRODUCT_NUM), |
| 206 | .iManufacturer = STRING_MANUFACTURER, | 206 | .iManufacturer = STRING_MANUFACTURER, |
| 207 | .iProduct = STRING_PRODUCT, | 207 | .iProduct = STRING_PRODUCT, |
| 208 | .bNumConfigurations = 1, | 208 | .bNumConfigurations = 1, |
| @@ -241,8 +241,8 @@ static const struct usb_ac_header_descriptor_1 ac_header_desc = { | |||
| 241 | .bLength = USB_DT_AC_HEADER_SIZE(1), | 241 | .bLength = USB_DT_AC_HEADER_SIZE(1), |
| 242 | .bDescriptorType = USB_DT_CS_INTERFACE, | 242 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 243 | .bDescriptorSubtype = USB_MS_HEADER, | 243 | .bDescriptorSubtype = USB_MS_HEADER, |
| 244 | .bcdADC = __constant_cpu_to_le16(0x0100), | 244 | .bcdADC = cpu_to_le16(0x0100), |
| 245 | .wTotalLength = __constant_cpu_to_le16(USB_DT_AC_HEADER_SIZE(1)), | 245 | .wTotalLength = cpu_to_le16(USB_DT_AC_HEADER_SIZE(1)), |
| 246 | .bInCollection = 1, | 246 | .bInCollection = 1, |
| 247 | .baInterfaceNr = { | 247 | .baInterfaceNr = { |
| 248 | [0] = GMIDI_MS_INTERFACE, | 248 | [0] = GMIDI_MS_INTERFACE, |
| @@ -265,8 +265,8 @@ static const struct usb_ms_header_descriptor ms_header_desc = { | |||
| 265 | .bLength = USB_DT_MS_HEADER_SIZE, | 265 | .bLength = USB_DT_MS_HEADER_SIZE, |
| 266 | .bDescriptorType = USB_DT_CS_INTERFACE, | 266 | .bDescriptorType = USB_DT_CS_INTERFACE, |
| 267 | .bDescriptorSubtype = USB_MS_HEADER, | 267 | .bDescriptorSubtype = USB_MS_HEADER, |
| 268 | .bcdMSC = __constant_cpu_to_le16(0x0100), | 268 | .bcdMSC = cpu_to_le16(0x0100), |
| 269 | .wTotalLength = __constant_cpu_to_le16(USB_DT_MS_HEADER_SIZE | 269 | .wTotalLength = cpu_to_le16(USB_DT_MS_HEADER_SIZE |
| 270 | + 2*USB_DT_MIDI_IN_SIZE | 270 | + 2*USB_DT_MIDI_IN_SIZE |
| 271 | + 2*USB_DT_MIDI_OUT_SIZE(1)), | 271 | + 2*USB_DT_MIDI_OUT_SIZE(1)), |
| 272 | }; | 272 | }; |
| @@ -1099,10 +1099,9 @@ static int gmidi_register_card(struct gmidi_device *dev) | |||
| 1099 | .dev_free = gmidi_snd_free, | 1099 | .dev_free = gmidi_snd_free, |
| 1100 | }; | 1100 | }; |
| 1101 | 1101 | ||
| 1102 | card = snd_card_new(index, id, THIS_MODULE, 0); | 1102 | err = snd_card_create(index, id, THIS_MODULE, 0, &card); |
| 1103 | if (!card) { | 1103 | if (err < 0) { |
| 1104 | ERROR(dev, "snd_card_new failed\n"); | 1104 | ERROR(dev, "snd_card_create failed\n"); |
| 1105 | err = -ENOMEM; | ||
| 1106 | goto fail; | 1105 | goto fail; |
| 1107 | } | 1106 | } |
| 1108 | dev->card = card; | 1107 | dev->card = card; |
| @@ -1227,7 +1226,7 @@ autoconf_fail: | |||
| 1227 | */ | 1226 | */ |
| 1228 | pr_warning("%s: controller '%s' not recognized\n", | 1227 | pr_warning("%s: controller '%s' not recognized\n", |
| 1229 | shortname, gadget->name); | 1228 | shortname, gadget->name); |
| 1230 | device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); | 1229 | device_desc.bcdDevice = cpu_to_le16(0x9999); |
| 1231 | } | 1230 | } |
| 1232 | 1231 | ||
| 1233 | 1232 | ||
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 63419c4d503c..de010c939dbb 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
| @@ -1472,7 +1472,7 @@ static void ep0_setup(struct goku_udc *dev) | |||
| 1472 | /* active endpoint */ | 1472 | /* active endpoint */ |
| 1473 | if (tmp > 3 || (!dev->ep[tmp].desc && tmp != 0)) | 1473 | if (tmp > 3 || (!dev->ep[tmp].desc && tmp != 0)) |
| 1474 | goto stall; | 1474 | goto stall; |
| 1475 | if (ctrl.wIndex & __constant_cpu_to_le16( | 1475 | if (ctrl.wIndex & cpu_to_le16( |
| 1476 | USB_DIR_IN)) { | 1476 | USB_DIR_IN)) { |
| 1477 | if (!dev->ep[tmp].is_in) | 1477 | if (!dev->ep[tmp].is_in) |
| 1478 | goto stall; | 1478 | goto stall; |
| @@ -1480,7 +1480,7 @@ static void ep0_setup(struct goku_udc *dev) | |||
| 1480 | if (dev->ep[tmp].is_in) | 1480 | if (dev->ep[tmp].is_in) |
| 1481 | goto stall; | 1481 | goto stall; |
| 1482 | } | 1482 | } |
| 1483 | if (ctrl.wValue != __constant_cpu_to_le16( | 1483 | if (ctrl.wValue != cpu_to_le16( |
| 1484 | USB_ENDPOINT_HALT)) | 1484 | USB_ENDPOINT_HALT)) |
| 1485 | goto stall; | 1485 | goto stall; |
| 1486 | if (tmp) | 1486 | if (tmp) |
| @@ -1493,7 +1493,7 @@ succeed: | |||
| 1493 | return; | 1493 | return; |
| 1494 | case USB_RECIP_DEVICE: | 1494 | case USB_RECIP_DEVICE: |
| 1495 | /* device remote wakeup: always clear */ | 1495 | /* device remote wakeup: always clear */ |
| 1496 | if (ctrl.wValue != __constant_cpu_to_le16(1)) | 1496 | if (ctrl.wValue != cpu_to_le16(1)) |
| 1497 | goto stall; | 1497 | goto stall; |
| 1498 | VDBG(dev, "clear dev remote wakeup\n"); | 1498 | VDBG(dev, "clear dev remote wakeup\n"); |
| 1499 | goto succeed; | 1499 | goto succeed; |
| @@ -1519,7 +1519,7 @@ succeed: | |||
| 1519 | dev->req_config = (ctrl.bRequest == USB_REQ_SET_CONFIGURATION | 1519 | dev->req_config = (ctrl.bRequest == USB_REQ_SET_CONFIGURATION |
| 1520 | && ctrl.bRequestType == USB_RECIP_DEVICE); | 1520 | && ctrl.bRequestType == USB_RECIP_DEVICE); |
| 1521 | if (unlikely(dev->req_config)) | 1521 | if (unlikely(dev->req_config)) |
| 1522 | dev->configured = (ctrl.wValue != __constant_cpu_to_le16(0)); | 1522 | dev->configured = (ctrl.wValue != cpu_to_le16(0)); |
| 1523 | 1523 | ||
| 1524 | /* delegate everything to the gadget driver. | 1524 | /* delegate everything to the gadget driver. |
| 1525 | * it may respond after this irq handler returns. | 1525 | * it may respond after this irq handler returns. |
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c index 77c5d0a8a06e..168658b4b4e2 100644 --- a/drivers/usb/gadget/imx_udc.c +++ b/drivers/usb/gadget/imx_udc.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * driver/usb/gadget/imx_udc.c | 2 | * driver/usb/gadget/imx_udc.c |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2005 Mike Lee(eemike@gmail.com) | 4 | * Copyright (C) 2005 Mike Lee <eemike@gmail.com> |
| 5 | * Copyright (C) 2008 Darius Augulis <augulis.darius@gmail.com> | 5 | * Copyright (C) 2008 Darius Augulis <augulis.darius@gmail.com> |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
| @@ -28,6 +28,7 @@ | |||
| 28 | #include <linux/dma-mapping.h> | 28 | #include <linux/dma-mapping.h> |
| 29 | #include <linux/clk.h> | 29 | #include <linux/clk.h> |
| 30 | #include <linux/delay.h> | 30 | #include <linux/delay.h> |
| 31 | #include <linux/timer.h> | ||
| 31 | 32 | ||
| 32 | #include <linux/usb/ch9.h> | 33 | #include <linux/usb/ch9.h> |
| 33 | #include <linux/usb/gadget.h> | 34 | #include <linux/usb/gadget.h> |
| @@ -51,7 +52,8 @@ void ep0_chg_stat(const char *label, struct imx_udc_struct *imx_usb, | |||
| 51 | void imx_udc_enable(struct imx_udc_struct *imx_usb) | 52 | void imx_udc_enable(struct imx_udc_struct *imx_usb) |
| 52 | { | 53 | { |
| 53 | int temp = __raw_readl(imx_usb->base + USB_CTRL); | 54 | int temp = __raw_readl(imx_usb->base + USB_CTRL); |
| 54 | __raw_writel(temp | CTRL_FE_ENA | CTRL_AFE_ENA, imx_usb->base + USB_CTRL); | 55 | __raw_writel(temp | CTRL_FE_ENA | CTRL_AFE_ENA, |
| 56 | imx_usb->base + USB_CTRL); | ||
| 55 | imx_usb->gadget.speed = USB_SPEED_FULL; | 57 | imx_usb->gadget.speed = USB_SPEED_FULL; |
| 56 | } | 58 | } |
| 57 | 59 | ||
| @@ -126,7 +128,8 @@ void imx_udc_config(struct imx_udc_struct *imx_usb) | |||
| 126 | for (j = 0; j < 5; j++) { | 128 | for (j = 0; j < 5; j++) { |
| 127 | __raw_writeb(ep_conf[j], | 129 | __raw_writeb(ep_conf[j], |
| 128 | imx_usb->base + USB_DDAT); | 130 | imx_usb->base + USB_DDAT); |
| 129 | do {} while (__raw_readl(imx_usb->base + USB_DADR) | 131 | do {} while (__raw_readl(imx_usb->base |
| 132 | + USB_DADR) | ||
| 130 | & DADR_BSY); | 133 | & DADR_BSY); |
| 131 | } | 134 | } |
| 132 | } | 135 | } |
| @@ -183,7 +186,8 @@ void imx_udc_init_ep(struct imx_udc_struct *imx_usb) | |||
| 183 | temp = (EP_DIR(imx_ep) << 7) | (max << 5) | 186 | temp = (EP_DIR(imx_ep) << 7) | (max << 5) |
| 184 | | (imx_ep->bmAttributes << 3); | 187 | | (imx_ep->bmAttributes << 3); |
| 185 | __raw_writel(temp, imx_usb->base + USB_EP_STAT(i)); | 188 | __raw_writel(temp, imx_usb->base + USB_EP_STAT(i)); |
| 186 | __raw_writel(temp | EPSTAT_FLUSH, imx_usb->base + USB_EP_STAT(i)); | 189 | __raw_writel(temp | EPSTAT_FLUSH, |
| 190 | imx_usb->base + USB_EP_STAT(i)); | ||
| 187 | D_INI(imx_usb->dev, "<%s> ep%d_stat %08x\n", __func__, i, | 191 | D_INI(imx_usb->dev, "<%s> ep%d_stat %08x\n", __func__, i, |
| 188 | __raw_readl(imx_usb->base + USB_EP_STAT(i))); | 192 | __raw_readl(imx_usb->base + USB_EP_STAT(i))); |
| 189 | } | 193 | } |
| @@ -278,15 +282,18 @@ void imx_ep_stall(struct imx_ep_struct *imx_ep) | |||
| 278 | struct imx_udc_struct *imx_usb = imx_ep->imx_usb; | 282 | struct imx_udc_struct *imx_usb = imx_ep->imx_usb; |
| 279 | int temp, i; | 283 | int temp, i; |
| 280 | 284 | ||
| 281 | D_ERR(imx_usb->dev, "<%s> Forced stall on %s\n", __func__, imx_ep->ep.name); | 285 | D_ERR(imx_usb->dev, |
| 286 | "<%s> Forced stall on %s\n", __func__, imx_ep->ep.name); | ||
| 282 | 287 | ||
| 283 | imx_flush(imx_ep); | 288 | imx_flush(imx_ep); |
| 284 | 289 | ||
| 285 | /* Special care for ep0 */ | 290 | /* Special care for ep0 */ |
| 286 | if (EP_NO(imx_ep)) { | 291 | if (!EP_NO(imx_ep)) { |
| 287 | temp = __raw_readl(imx_usb->base + USB_CTRL); | 292 | temp = __raw_readl(imx_usb->base + USB_CTRL); |
| 288 | __raw_writel(temp | CTRL_CMDOVER | CTRL_CMDERROR, imx_usb->base + USB_CTRL); | 293 | __raw_writel(temp | CTRL_CMDOVER | CTRL_CMDERROR, |
| 289 | do { } while (__raw_readl(imx_usb->base + USB_CTRL) & CTRL_CMDOVER); | 294 | imx_usb->base + USB_CTRL); |
| 295 | do { } while (__raw_readl(imx_usb->base + USB_CTRL) | ||
| 296 | & CTRL_CMDOVER); | ||
| 290 | temp = __raw_readl(imx_usb->base + USB_CTRL); | 297 | temp = __raw_readl(imx_usb->base + USB_CTRL); |
| 291 | __raw_writel(temp & ~CTRL_CMDERROR, imx_usb->base + USB_CTRL); | 298 | __raw_writel(temp & ~CTRL_CMDERROR, imx_usb->base + USB_CTRL); |
| 292 | } | 299 | } |
| @@ -296,12 +303,13 @@ void imx_ep_stall(struct imx_ep_struct *imx_ep) | |||
| 296 | imx_usb->base + USB_EP_STAT(EP_NO(imx_ep))); | 303 | imx_usb->base + USB_EP_STAT(EP_NO(imx_ep))); |
| 297 | 304 | ||
| 298 | for (i = 0; i < 100; i ++) { | 305 | for (i = 0; i < 100; i ++) { |
| 299 | temp = __raw_readl(imx_usb->base + USB_EP_STAT(EP_NO(imx_ep))); | 306 | temp = __raw_readl(imx_usb->base |
| 307 | + USB_EP_STAT(EP_NO(imx_ep))); | ||
| 300 | if (!(temp & EPSTAT_STALL)) | 308 | if (!(temp & EPSTAT_STALL)) |
| 301 | break; | 309 | break; |
| 302 | udelay(20); | 310 | udelay(20); |
| 303 | } | 311 | } |
| 304 | if (i == 50) | 312 | if (i == 100) |
| 305 | D_ERR(imx_usb->dev, "<%s> Non finished stall on %s\n", | 313 | D_ERR(imx_usb->dev, "<%s> Non finished stall on %s\n", |
| 306 | __func__, imx_ep->ep.name); | 314 | __func__, imx_ep->ep.name); |
| 307 | } | 315 | } |
| @@ -325,7 +333,8 @@ static int imx_udc_wakeup(struct usb_gadget *_gadget) | |||
| 325 | ******************************************************************************* | 333 | ******************************************************************************* |
| 326 | */ | 334 | */ |
| 327 | 335 | ||
| 328 | static void ep_add_request(struct imx_ep_struct *imx_ep, struct imx_request *req) | 336 | static void ep_add_request(struct imx_ep_struct *imx_ep, |
| 337 | struct imx_request *req) | ||
| 329 | { | 338 | { |
| 330 | if (unlikely(!req)) | 339 | if (unlikely(!req)) |
| 331 | return; | 340 | return; |
| @@ -334,7 +343,8 @@ static void ep_add_request(struct imx_ep_struct *imx_ep, struct imx_request *req | |||
| 334 | list_add_tail(&req->queue, &imx_ep->queue); | 343 | list_add_tail(&req->queue, &imx_ep->queue); |
| 335 | } | 344 | } |
| 336 | 345 | ||
| 337 | static void ep_del_request(struct imx_ep_struct *imx_ep, struct imx_request *req) | 346 | static void ep_del_request(struct imx_ep_struct *imx_ep, |
| 347 | struct imx_request *req) | ||
| 338 | { | 348 | { |
| 339 | if (unlikely(!req)) | 349 | if (unlikely(!req)) |
| 340 | return; | 350 | return; |
| @@ -343,7 +353,8 @@ static void ep_del_request(struct imx_ep_struct *imx_ep, struct imx_request *req | |||
| 343 | req->in_use = 0; | 353 | req->in_use = 0; |
| 344 | } | 354 | } |
| 345 | 355 | ||
| 346 | static void done(struct imx_ep_struct *imx_ep, struct imx_request *req, int status) | 356 | static void done(struct imx_ep_struct *imx_ep, |
| 357 | struct imx_request *req, int status) | ||
| 347 | { | 358 | { |
| 348 | ep_del_request(imx_ep, req); | 359 | ep_del_request(imx_ep, req); |
| 349 | 360 | ||
| @@ -494,7 +505,8 @@ static int write_fifo(struct imx_ep_struct *imx_ep, struct imx_request *req) | |||
| 494 | __func__, imx_ep->ep.name, req, | 505 | __func__, imx_ep->ep.name, req, |
| 495 | completed ? "completed" : "not completed"); | 506 | completed ? "completed" : "not completed"); |
| 496 | if (!EP_NO(imx_ep)) | 507 | if (!EP_NO(imx_ep)) |
| 497 | ep0_chg_stat(__func__, imx_ep->imx_usb, EP0_IDLE); | 508 | ep0_chg_stat(__func__, |
| 509 | imx_ep->imx_usb, EP0_IDLE); | ||
| 498 | } | 510 | } |
| 499 | } | 511 | } |
| 500 | 512 | ||
| @@ -539,10 +551,9 @@ static int handle_ep0(struct imx_ep_struct *imx_ep) | |||
| 539 | struct imx_request *req = NULL; | 551 | struct imx_request *req = NULL; |
| 540 | int ret = 0; | 552 | int ret = 0; |
| 541 | 553 | ||
| 542 | if (!list_empty(&imx_ep->queue)) | 554 | if (!list_empty(&imx_ep->queue)) { |
| 543 | req = list_entry(imx_ep->queue.next, struct imx_request, queue); | 555 | req = list_entry(imx_ep->queue.next, struct imx_request, queue); |
| 544 | 556 | ||
| 545 | if (req) { | ||
| 546 | switch (imx_ep->imx_usb->ep0state) { | 557 | switch (imx_ep->imx_usb->ep0state) { |
| 547 | 558 | ||
| 548 | case EP0_IN_DATA_PHASE: /* GET_DESCRIPTOR */ | 559 | case EP0_IN_DATA_PHASE: /* GET_DESCRIPTOR */ |
| @@ -561,6 +572,10 @@ static int handle_ep0(struct imx_ep_struct *imx_ep) | |||
| 561 | } | 572 | } |
| 562 | } | 573 | } |
| 563 | 574 | ||
| 575 | else | ||
| 576 | D_ERR(imx_ep->imx_usb->dev, "<%s> no request on %s\n", | ||
| 577 | __func__, imx_ep->ep.name); | ||
| 578 | |||
| 564 | return ret; | 579 | return ret; |
| 565 | } | 580 | } |
| 566 | 581 | ||
| @@ -583,7 +598,8 @@ static void handle_ep0_devreq(struct imx_udc_struct *imx_usb) | |||
| 583 | "<%s> no setup packet received\n", __func__); | 598 | "<%s> no setup packet received\n", __func__); |
| 584 | goto stall; | 599 | goto stall; |
| 585 | } | 600 | } |
| 586 | u.word[i] = __raw_readl(imx_usb->base + USB_EP_FDAT(EP_NO(imx_ep))); | 601 | u.word[i] = __raw_readl(imx_usb->base |
| 602 | + USB_EP_FDAT(EP_NO(imx_ep))); | ||
| 587 | } | 603 | } |
| 588 | 604 | ||
| 589 | temp = imx_ep_empty(imx_ep); | 605 | temp = imx_ep_empty(imx_ep); |
| @@ -759,7 +775,7 @@ static int imx_ep_queue | |||
| 759 | */ | 775 | */ |
| 760 | if (imx_usb->set_config && !EP_NO(imx_ep)) { | 776 | if (imx_usb->set_config && !EP_NO(imx_ep)) { |
| 761 | imx_usb->set_config = 0; | 777 | imx_usb->set_config = 0; |
| 762 | D_EPX(imx_usb->dev, | 778 | D_ERR(imx_usb->dev, |
| 763 | "<%s> gadget reply set config\n", __func__); | 779 | "<%s> gadget reply set config\n", __func__); |
| 764 | return 0; | 780 | return 0; |
| 765 | } | 781 | } |
| @@ -779,28 +795,29 @@ static int imx_ep_queue | |||
| 779 | return -ESHUTDOWN; | 795 | return -ESHUTDOWN; |
| 780 | } | 796 | } |
| 781 | 797 | ||
| 782 | local_irq_save(flags); | ||
| 783 | |||
| 784 | /* Debug */ | 798 | /* Debug */ |
| 785 | D_REQ(imx_usb->dev, "<%s> ep%d %s request for [%d] bytes\n", | 799 | D_REQ(imx_usb->dev, "<%s> ep%d %s request for [%d] bytes\n", |
| 786 | __func__, EP_NO(imx_ep), | 800 | __func__, EP_NO(imx_ep), |
| 787 | ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state == EP0_IN_DATA_PHASE) | 801 | ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state |
| 788 | || (EP_NO(imx_ep) && EP_DIR(imx_ep))) ? "IN" : "OUT", usb_req->length); | 802 | == EP0_IN_DATA_PHASE) |
| 803 | || (EP_NO(imx_ep) && EP_DIR(imx_ep))) | ||
| 804 | ? "IN" : "OUT", usb_req->length); | ||
| 789 | dump_req(__func__, imx_ep, usb_req); | 805 | dump_req(__func__, imx_ep, usb_req); |
| 790 | 806 | ||
| 791 | if (imx_ep->stopped) { | 807 | if (imx_ep->stopped) { |
| 792 | usb_req->status = -ESHUTDOWN; | 808 | usb_req->status = -ESHUTDOWN; |
| 793 | ret = -ESHUTDOWN; | 809 | return -ESHUTDOWN; |
| 794 | goto out; | ||
| 795 | } | 810 | } |
| 796 | 811 | ||
| 797 | if (req->in_use) { | 812 | if (req->in_use) { |
| 798 | D_ERR(imx_usb->dev, | 813 | D_ERR(imx_usb->dev, |
| 799 | "<%s> refusing to queue req %p (already queued)\n", | 814 | "<%s> refusing to queue req %p (already queued)\n", |
| 800 | __func__, req); | 815 | __func__, req); |
| 801 | goto out; | 816 | return 0; |
| 802 | } | 817 | } |
| 803 | 818 | ||
| 819 | local_irq_save(flags); | ||
| 820 | |||
| 804 | usb_req->status = -EINPROGRESS; | 821 | usb_req->status = -EINPROGRESS; |
| 805 | usb_req->actual = 0; | 822 | usb_req->actual = 0; |
| 806 | 823 | ||
| @@ -810,7 +827,7 @@ static int imx_ep_queue | |||
| 810 | ret = handle_ep0(imx_ep); | 827 | ret = handle_ep0(imx_ep); |
| 811 | else | 828 | else |
| 812 | ret = handle_ep(imx_ep); | 829 | ret = handle_ep(imx_ep); |
| 813 | out: | 830 | |
| 814 | local_irq_restore(flags); | 831 | local_irq_restore(flags); |
| 815 | return ret; | 832 | return ret; |
| 816 | } | 833 | } |
| @@ -997,71 +1014,32 @@ static void udc_stop_activity(struct imx_udc_struct *imx_usb, | |||
| 997 | ******************************************************************************* | 1014 | ******************************************************************************* |
| 998 | */ | 1015 | */ |
| 999 | 1016 | ||
| 1000 | static irqreturn_t imx_udc_irq(int irq, void *dev) | 1017 | /* |
| 1018 | * Called when timer expires. | ||
| 1019 | * Timer is started when CFG_CHG is received. | ||
| 1020 | */ | ||
| 1021 | static void handle_config(unsigned long data) | ||
| 1001 | { | 1022 | { |
| 1002 | struct imx_udc_struct *imx_usb = dev; | 1023 | struct imx_udc_struct *imx_usb = (void *)data; |
| 1003 | struct usb_ctrlrequest u; | 1024 | struct usb_ctrlrequest u; |
| 1004 | int temp, cfg, intf, alt; | 1025 | int temp, cfg, intf, alt; |
| 1005 | int intr = __raw_readl(imx_usb->base + USB_INTR); | ||
| 1006 | 1026 | ||
| 1007 | if (intr & (INTR_WAKEUP | INTR_SUSPEND | INTR_RESUME | INTR_RESET_START | 1027 | local_irq_disable(); |
| 1008 | | INTR_RESET_STOP | INTR_CFG_CHG)) { | ||
| 1009 | dump_intr(__func__, intr, imx_usb->dev); | ||
| 1010 | dump_usb_stat(__func__, imx_usb); | ||
| 1011 | } | ||
| 1012 | 1028 | ||
| 1013 | if (!imx_usb->driver) { | 1029 | temp = __raw_readl(imx_usb->base + USB_STAT); |
| 1014 | /*imx_udc_disable(imx_usb);*/ | 1030 | cfg = (temp & STAT_CFG) >> 5; |
| 1015 | goto end_irq; | 1031 | intf = (temp & STAT_INTF) >> 3; |
| 1016 | } | 1032 | alt = temp & STAT_ALTSET; |
| 1017 | 1033 | ||
| 1018 | if (intr & INTR_WAKEUP) { | 1034 | D_REQ(imx_usb->dev, |
| 1019 | if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN | 1035 | "<%s> orig config C=%d, I=%d, A=%d / " |
| 1020 | && imx_usb->driver && imx_usb->driver->resume) | 1036 | "req config C=%d, I=%d, A=%d\n", |
| 1021 | imx_usb->driver->resume(&imx_usb->gadget); | 1037 | __func__, imx_usb->cfg, imx_usb->intf, imx_usb->alt, |
| 1022 | imx_usb->set_config = 0; | 1038 | cfg, intf, alt); |
| 1023 | imx_usb->gadget.speed = USB_SPEED_FULL; | ||
| 1024 | } | ||
| 1025 | |||
| 1026 | if (intr & INTR_SUSPEND) { | ||
| 1027 | if (imx_usb->gadget.speed != USB_SPEED_UNKNOWN | ||
| 1028 | && imx_usb->driver && imx_usb->driver->suspend) | ||
| 1029 | imx_usb->driver->suspend(&imx_usb->gadget); | ||
| 1030 | imx_usb->set_config = 0; | ||
| 1031 | imx_usb->gadget.speed = USB_SPEED_UNKNOWN; | ||
| 1032 | } | ||
| 1033 | |||
| 1034 | if (intr & INTR_RESET_START) { | ||
| 1035 | __raw_writel(intr, imx_usb->base + USB_INTR); | ||
| 1036 | udc_stop_activity(imx_usb, imx_usb->driver); | ||
| 1037 | imx_usb->set_config = 0; | ||
| 1038 | imx_usb->gadget.speed = USB_SPEED_UNKNOWN; | ||
| 1039 | } | ||
| 1040 | 1039 | ||
| 1041 | if (intr & INTR_RESET_STOP) | 1040 | if (cfg == 1 || cfg == 2) { |
| 1042 | imx_usb->gadget.speed = USB_SPEED_FULL; | ||
| 1043 | 1041 | ||
| 1044 | if (intr & INTR_CFG_CHG) { | ||
| 1045 | __raw_writel(INTR_CFG_CHG, imx_usb->base + USB_INTR); | ||
| 1046 | temp = __raw_readl(imx_usb->base + USB_STAT); | ||
| 1047 | cfg = (temp & STAT_CFG) >> 5; | ||
| 1048 | intf = (temp & STAT_INTF) >> 3; | ||
| 1049 | alt = temp & STAT_ALTSET; | ||
| 1050 | |||
| 1051 | D_REQ(imx_usb->dev, | ||
| 1052 | "<%s> orig config C=%d, I=%d, A=%d / " | ||
| 1053 | "req config C=%d, I=%d, A=%d\n", | ||
| 1054 | __func__, imx_usb->cfg, imx_usb->intf, imx_usb->alt, | ||
| 1055 | cfg, intf, alt); | ||
| 1056 | |||
| 1057 | if (cfg != 1 && cfg != 2) | ||
| 1058 | goto end_irq; | ||
| 1059 | |||
| 1060 | imx_usb->set_config = 0; | ||
| 1061 | |||
| 1062 | /* Config setup */ | ||
| 1063 | if (imx_usb->cfg != cfg) { | 1042 | if (imx_usb->cfg != cfg) { |
| 1064 | D_REQ(imx_usb->dev, "<%s> Change config start\n",__func__); | ||
| 1065 | u.bRequest = USB_REQ_SET_CONFIGURATION; | 1043 | u.bRequest = USB_REQ_SET_CONFIGURATION; |
| 1066 | u.bRequestType = USB_DIR_OUT | | 1044 | u.bRequestType = USB_DIR_OUT | |
| 1067 | USB_TYPE_STANDARD | | 1045 | USB_TYPE_STANDARD | |
| @@ -1070,14 +1048,10 @@ static irqreturn_t imx_udc_irq(int irq, void *dev) | |||
| 1070 | u.wIndex = 0; | 1048 | u.wIndex = 0; |
| 1071 | u.wLength = 0; | 1049 | u.wLength = 0; |
| 1072 | imx_usb->cfg = cfg; | 1050 | imx_usb->cfg = cfg; |
| 1073 | imx_usb->set_config = 1; | ||
| 1074 | imx_usb->driver->setup(&imx_usb->gadget, &u); | 1051 | imx_usb->driver->setup(&imx_usb->gadget, &u); |
| 1075 | imx_usb->set_config = 0; | ||
| 1076 | D_REQ(imx_usb->dev, "<%s> Change config done\n",__func__); | ||
| 1077 | 1052 | ||
| 1078 | } | 1053 | } |
| 1079 | if (imx_usb->intf != intf || imx_usb->alt != alt) { | 1054 | if (imx_usb->intf != intf || imx_usb->alt != alt) { |
| 1080 | D_REQ(imx_usb->dev, "<%s> Change interface start\n",__func__); | ||
| 1081 | u.bRequest = USB_REQ_SET_INTERFACE; | 1055 | u.bRequest = USB_REQ_SET_INTERFACE; |
| 1082 | u.bRequestType = USB_DIR_OUT | | 1056 | u.bRequestType = USB_DIR_OUT | |
| 1083 | USB_TYPE_STANDARD | | 1057 | USB_TYPE_STANDARD | |
| @@ -1087,20 +1061,92 @@ static irqreturn_t imx_udc_irq(int irq, void *dev) | |||
| 1087 | u.wLength = 0; | 1061 | u.wLength = 0; |
| 1088 | imx_usb->intf = intf; | 1062 | imx_usb->intf = intf; |
| 1089 | imx_usb->alt = alt; | 1063 | imx_usb->alt = alt; |
| 1090 | imx_usb->set_config = 1; | ||
| 1091 | imx_usb->driver->setup(&imx_usb->gadget, &u); | 1064 | imx_usb->driver->setup(&imx_usb->gadget, &u); |
| 1092 | imx_usb->set_config = 0; | ||
| 1093 | D_REQ(imx_usb->dev, "<%s> Change interface done\n",__func__); | ||
| 1094 | } | 1065 | } |
| 1095 | } | 1066 | } |
| 1096 | 1067 | ||
| 1068 | imx_usb->set_config = 0; | ||
| 1069 | |||
| 1070 | local_irq_enable(); | ||
| 1071 | } | ||
| 1072 | |||
| 1073 | static irqreturn_t imx_udc_irq(int irq, void *dev) | ||
| 1074 | { | ||
| 1075 | struct imx_udc_struct *imx_usb = dev; | ||
| 1076 | int intr = __raw_readl(imx_usb->base + USB_INTR); | ||
| 1077 | int temp; | ||
| 1078 | |||
| 1079 | if (intr & (INTR_WAKEUP | INTR_SUSPEND | INTR_RESUME | INTR_RESET_START | ||
| 1080 | | INTR_RESET_STOP | INTR_CFG_CHG)) { | ||
| 1081 | dump_intr(__func__, intr, imx_usb->dev); | ||
| 1082 | dump_usb_stat(__func__, imx_usb); | ||
| 1083 | } | ||
| 1084 | |||
| 1085 | if (!imx_usb->driver) | ||
| 1086 | goto end_irq; | ||
| 1087 | |||
| 1097 | if (intr & INTR_SOF) { | 1088 | if (intr & INTR_SOF) { |
| 1089 | /* Copy from Freescale BSP. | ||
| 1090 | We must enable SOF intr and set CMDOVER. | ||
| 1091 | Datasheet don't specifiy this action, but it | ||
| 1092 | is done in Freescale BSP, so just copy it. | ||
| 1093 | */ | ||
| 1098 | if (imx_usb->ep0state == EP0_IDLE) { | 1094 | if (imx_usb->ep0state == EP0_IDLE) { |
| 1099 | temp = __raw_readl(imx_usb->base + USB_CTRL); | 1095 | temp = __raw_readl(imx_usb->base + USB_CTRL); |
| 1100 | __raw_writel(temp | CTRL_CMDOVER, imx_usb->base + USB_CTRL); | 1096 | __raw_writel(temp | CTRL_CMDOVER, |
| 1097 | imx_usb->base + USB_CTRL); | ||
| 1101 | } | 1098 | } |
| 1102 | } | 1099 | } |
| 1103 | 1100 | ||
| 1101 | if (intr & INTR_CFG_CHG) { | ||
| 1102 | /* A workaround of serious IMX UDC bug. | ||
| 1103 | Handling of CFG_CHG should be delayed for some time, because | ||
| 1104 | IMX does not NACK the host when CFG_CHG interrupt is pending. | ||
| 1105 | There is no time to handle current CFG_CHG | ||
| 1106 | if next CFG_CHG or SETUP packed is send immediately. | ||
| 1107 | We have to clear CFG_CHG, start the timer and | ||
| 1108 | NACK the host by setting CTRL_CMDOVER | ||
| 1109 | if it sends any SETUP packet. | ||
| 1110 | When timer expires, handler is called to handle configuration | ||
| 1111 | changes. While CFG_CHG is not handled (set_config=1), | ||
| 1112 | we must NACK the host to every SETUP packed. | ||
| 1113 | This delay prevents from going out of sync with host. | ||
| 1114 | */ | ||
| 1115 | __raw_writel(INTR_CFG_CHG, imx_usb->base + USB_INTR); | ||
| 1116 | imx_usb->set_config = 1; | ||
| 1117 | mod_timer(&imx_usb->timer, jiffies + 5); | ||
| 1118 | goto end_irq; | ||
| 1119 | } | ||
| 1120 | |||
| 1121 | if (intr & INTR_WAKEUP) { | ||
| 1122 | if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN | ||
| 1123 | && imx_usb->driver && imx_usb->driver->resume) | ||
| 1124 | imx_usb->driver->resume(&imx_usb->gadget); | ||
| 1125 | imx_usb->set_config = 0; | ||
| 1126 | del_timer(&imx_usb->timer); | ||
| 1127 | imx_usb->gadget.speed = USB_SPEED_FULL; | ||
| 1128 | } | ||
| 1129 | |||
| 1130 | if (intr & INTR_SUSPEND) { | ||
| 1131 | if (imx_usb->gadget.speed != USB_SPEED_UNKNOWN | ||
| 1132 | && imx_usb->driver && imx_usb->driver->suspend) | ||
| 1133 | imx_usb->driver->suspend(&imx_usb->gadget); | ||
| 1134 | imx_usb->set_config = 0; | ||
| 1135 | del_timer(&imx_usb->timer); | ||
| 1136 | imx_usb->gadget.speed = USB_SPEED_UNKNOWN; | ||
| 1137 | } | ||
| 1138 | |||
| 1139 | if (intr & INTR_RESET_START) { | ||
| 1140 | __raw_writel(intr, imx_usb->base + USB_INTR); | ||
| 1141 | udc_stop_activity(imx_usb, imx_usb->driver); | ||
| 1142 | imx_usb->set_config = 0; | ||
| 1143 | del_timer(&imx_usb->timer); | ||
| 1144 | imx_usb->gadget.speed = USB_SPEED_UNKNOWN; | ||
| 1145 | } | ||
| 1146 | |||
| 1147 | if (intr & INTR_RESET_STOP) | ||
| 1148 | imx_usb->gadget.speed = USB_SPEED_FULL; | ||
| 1149 | |||
| 1104 | end_irq: | 1150 | end_irq: |
| 1105 | __raw_writel(intr, imx_usb->base + USB_INTR); | 1151 | __raw_writel(intr, imx_usb->base + USB_INTR); |
| 1106 | return IRQ_HANDLED; | 1152 | return IRQ_HANDLED; |
| @@ -1109,6 +1155,7 @@ end_irq: | |||
| 1109 | static irqreturn_t imx_udc_ctrl_irq(int irq, void *dev) | 1155 | static irqreturn_t imx_udc_ctrl_irq(int irq, void *dev) |
| 1110 | { | 1156 | { |
| 1111 | struct imx_udc_struct *imx_usb = dev; | 1157 | struct imx_udc_struct *imx_usb = dev; |
| 1158 | struct imx_ep_struct *imx_ep = &imx_usb->imx_ep[0]; | ||
| 1112 | int intr = __raw_readl(imx_usb->base + USB_EP_INTR(0)); | 1159 | int intr = __raw_readl(imx_usb->base + USB_EP_INTR(0)); |
| 1113 | 1160 | ||
| 1114 | dump_ep_intr(__func__, 0, intr, imx_usb->dev); | 1161 | dump_ep_intr(__func__, 0, intr, imx_usb->dev); |
| @@ -1118,16 +1165,15 @@ static irqreturn_t imx_udc_ctrl_irq(int irq, void *dev) | |||
| 1118 | return IRQ_HANDLED; | 1165 | return IRQ_HANDLED; |
| 1119 | } | 1166 | } |
| 1120 | 1167 | ||
| 1121 | /* DEVREQ IRQ has highest priority */ | 1168 | /* DEVREQ has highest priority */ |
| 1122 | if (intr & (EPINTR_DEVREQ | EPINTR_MDEVREQ)) | 1169 | if (intr & (EPINTR_DEVREQ | EPINTR_MDEVREQ)) |
| 1123 | handle_ep0_devreq(imx_usb); | 1170 | handle_ep0_devreq(imx_usb); |
| 1124 | /* Seem i.MX is missing EOF interrupt sometimes. | 1171 | /* Seem i.MX is missing EOF interrupt sometimes. |
| 1125 | * Therefore we monitor both EOF and FIFO_EMPTY interrups | 1172 | * Therefore we don't monitor EOF. |
| 1126 | * when transmiting, and both EOF and FIFO_FULL when | 1173 | * We call handle_ep0() only if a request is queued for ep0. |
| 1127 | * receiving data. | ||
| 1128 | */ | 1174 | */ |
| 1129 | else if (intr & (EPINTR_EOF | EPINTR_FIFO_EMPTY | EPINTR_FIFO_FULL)) | 1175 | else if (!list_empty(&imx_ep->queue)) |
| 1130 | handle_ep0(&imx_usb->imx_ep[0]); | 1176 | handle_ep0(imx_ep); |
| 1131 | 1177 | ||
| 1132 | __raw_writel(intr, imx_usb->base + USB_EP_INTR(0)); | 1178 | __raw_writel(intr, imx_usb->base + USB_EP_INTR(0)); |
| 1133 | 1179 | ||
| @@ -1186,8 +1232,8 @@ static struct imx_udc_struct controller = { | |||
| 1186 | .ep0 = &controller.imx_ep[0].ep, | 1232 | .ep0 = &controller.imx_ep[0].ep, |
| 1187 | .name = driver_name, | 1233 | .name = driver_name, |
| 1188 | .dev = { | 1234 | .dev = { |
| 1189 | .bus_id = "gadget", | 1235 | .init_name = "gadget", |
| 1190 | }, | 1236 | }, |
| 1191 | }, | 1237 | }, |
| 1192 | 1238 | ||
| 1193 | .imx_ep[0] = { | 1239 | .imx_ep[0] = { |
| @@ -1318,6 +1364,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
| 1318 | 1364 | ||
| 1319 | udc_stop_activity(imx_usb, driver); | 1365 | udc_stop_activity(imx_usb, driver); |
| 1320 | imx_udc_disable(imx_usb); | 1366 | imx_udc_disable(imx_usb); |
| 1367 | del_timer(&imx_usb->timer); | ||
| 1321 | 1368 | ||
| 1322 | driver->unbind(&imx_usb->gadget); | 1369 | driver->unbind(&imx_usb->gadget); |
| 1323 | imx_usb->gadget.dev.driver = NULL; | 1370 | imx_usb->gadget.dev.driver = NULL; |
| @@ -1435,6 +1482,10 @@ static int __init imx_udc_probe(struct platform_device *pdev) | |||
| 1435 | usb_init_data(imx_usb); | 1482 | usb_init_data(imx_usb); |
| 1436 | imx_udc_init(imx_usb); | 1483 | imx_udc_init(imx_usb); |
| 1437 | 1484 | ||
| 1485 | init_timer(&imx_usb->timer); | ||
| 1486 | imx_usb->timer.function = handle_config; | ||
| 1487 | imx_usb->timer.data = (unsigned long)imx_usb; | ||
| 1488 | |||
| 1438 | return 0; | 1489 | return 0; |
| 1439 | 1490 | ||
| 1440 | fail3: | 1491 | fail3: |
| @@ -1457,6 +1508,7 @@ static int __exit imx_udc_remove(struct platform_device *pdev) | |||
| 1457 | int i; | 1508 | int i; |
| 1458 | 1509 | ||
| 1459 | imx_udc_disable(imx_usb); | 1510 | imx_udc_disable(imx_usb); |
| 1511 | del_timer(&imx_usb->timer); | ||
| 1460 | 1512 | ||
| 1461 | for (i = 0; i < IMX_USB_NB_EP + 1; i++) | 1513 | for (i = 0; i < IMX_USB_NB_EP + 1; i++) |
| 1462 | free_irq(imx_usb->usbd_int[i], imx_usb); | 1514 | free_irq(imx_usb->usbd_int[i], imx_usb); |
diff --git a/drivers/usb/gadget/imx_udc.h b/drivers/usb/gadget/imx_udc.h index 850076937d8d..b48ad59603d1 100644 --- a/drivers/usb/gadget/imx_udc.h +++ b/drivers/usb/gadget/imx_udc.h | |||
| @@ -23,7 +23,8 @@ | |||
| 23 | /* Helper macros */ | 23 | /* Helper macros */ |
| 24 | #define EP_NO(ep) ((ep->bEndpointAddress) & ~USB_DIR_IN) /* IN:1, OUT:0 */ | 24 | #define EP_NO(ep) ((ep->bEndpointAddress) & ~USB_DIR_IN) /* IN:1, OUT:0 */ |
| 25 | #define EP_DIR(ep) ((ep->bEndpointAddress) & USB_DIR_IN ? 1 : 0) | 25 | #define EP_DIR(ep) ((ep->bEndpointAddress) & USB_DIR_IN ? 1 : 0) |
| 26 | #define irq_to_ep(irq) (((irq) >= USBD_INT0) || ((irq) <= USBD_INT6) ? ((irq) - USBD_INT0) : (USBD_INT6)) /*should not happen*/ | 26 | #define irq_to_ep(irq) (((irq) >= USBD_INT0) || ((irq) <= USBD_INT6) \ |
| 27 | ? ((irq) - USBD_INT0) : (USBD_INT6)) /*should not happen*/ | ||
| 27 | #define ep_to_irq(ep) (EP_NO((ep)) + USBD_INT0) | 28 | #define ep_to_irq(ep) (EP_NO((ep)) + USBD_INT0) |
| 28 | #define IMX_USB_NB_EP 6 | 29 | #define IMX_USB_NB_EP 6 |
| 29 | 30 | ||
| @@ -58,6 +59,7 @@ struct imx_udc_struct { | |||
| 58 | struct device *dev; | 59 | struct device *dev; |
| 59 | struct imx_ep_struct imx_ep[IMX_USB_NB_EP]; | 60 | struct imx_ep_struct imx_ep[IMX_USB_NB_EP]; |
| 60 | struct clk *clk; | 61 | struct clk *clk; |
| 62 | struct timer_list timer; | ||
| 61 | enum ep0_state ep0state; | 63 | enum ep0_state ep0state; |
| 62 | struct resource *res; | 64 | struct resource *res; |
| 63 | void __iomem *base; | 65 | void __iomem *base; |
| @@ -88,8 +90,8 @@ struct imx_udc_struct { | |||
| 88 | #define USB_EP_FDAT3(x) (0x3F + (x*0x30)) /* USB FIFO data */ | 90 | #define USB_EP_FDAT3(x) (0x3F + (x*0x30)) /* USB FIFO data */ |
| 89 | #define USB_EP_FSTAT(x) (0x40 + (x*0x30)) /* USB FIFO status */ | 91 | #define USB_EP_FSTAT(x) (0x40 + (x*0x30)) /* USB FIFO status */ |
| 90 | #define USB_EP_FCTRL(x) (0x44 + (x*0x30)) /* USB FIFO control */ | 92 | #define USB_EP_FCTRL(x) (0x44 + (x*0x30)) /* USB FIFO control */ |
| 91 | #define USB_EP_LRFP(x) (0x48 + (x*0x30)) /* USB last read frame pointer */ | 93 | #define USB_EP_LRFP(x) (0x48 + (x*0x30)) /* USB last rd f. pointer */ |
| 92 | #define USB_EP_LWFP(x) (0x4C + (x*0x30)) /* USB last write frame pointer */ | 94 | #define USB_EP_LWFP(x) (0x4C + (x*0x30)) /* USB last wr f. pointer */ |
| 93 | #define USB_EP_FALRM(x) (0x50 + (x*0x30)) /* USB FIFO alarm */ | 95 | #define USB_EP_FALRM(x) (0x50 + (x*0x30)) /* USB FIFO alarm */ |
| 94 | #define USB_EP_FRDP(x) (0x54 + (x*0x30)) /* USB FIFO read pointer */ | 96 | #define USB_EP_FRDP(x) (0x54 + (x*0x30)) /* USB FIFO read pointer */ |
| 95 | #define USB_EP_FWRP(x) (0x58 + (x*0x30)) /* USB FIFO write pointer */ | 97 | #define USB_EP_FWRP(x) (0x58 + (x*0x30)) /* USB FIFO write pointer */ |
| @@ -170,7 +172,7 @@ struct imx_udc_struct { | |||
| 170 | /* #define DEBUG_IRQ */ | 172 | /* #define DEBUG_IRQ */ |
| 171 | /* #define DEBUG_EPIRQ */ | 173 | /* #define DEBUG_EPIRQ */ |
| 172 | /* #define DEBUG_DUMP */ | 174 | /* #define DEBUG_DUMP */ |
| 173 | #define DEBUG_ERR | 175 | /* #define DEBUG_ERR */ |
| 174 | 176 | ||
| 175 | #ifdef DEBUG_REQ | 177 | #ifdef DEBUG_REQ |
| 176 | #define D_REQ(dev, args...) dev_dbg(dev, ## args) | 178 | #define D_REQ(dev, args...) dev_dbg(dev, ## args) |
| @@ -228,7 +230,8 @@ struct imx_udc_struct { | |||
| 228 | #endif /* DEBUG_IRQ */ | 230 | #endif /* DEBUG_IRQ */ |
| 229 | 231 | ||
| 230 | #ifdef DEBUG_EPIRQ | 232 | #ifdef DEBUG_EPIRQ |
| 231 | static void dump_ep_intr(const char *label, int nr, int irqreg, struct device *dev) | 233 | static void dump_ep_intr(const char *label, int nr, int irqreg, |
| 234 | struct device *dev) | ||
| 232 | { | 235 | { |
| 233 | dev_dbg(dev, "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, nr, | 236 | dev_dbg(dev, "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, nr, |
| 234 | (irqreg & EPINTR_FIFO_FULL) ? " full" : "", | 237 | (irqreg & EPINTR_FIFO_FULL) ? " full" : "", |
| @@ -246,7 +249,8 @@ struct imx_udc_struct { | |||
| 246 | #endif /* DEBUG_IRQ */ | 249 | #endif /* DEBUG_IRQ */ |
| 247 | 250 | ||
| 248 | #ifdef DEBUG_DUMP | 251 | #ifdef DEBUG_DUMP |
| 249 | static void dump_usb_stat(const char *label, struct imx_udc_struct *imx_usb) | 252 | static void dump_usb_stat(const char *label, |
| 253 | struct imx_udc_struct *imx_usb) | ||
| 250 | { | 254 | { |
| 251 | int temp = __raw_readl(imx_usb->base + USB_STAT); | 255 | int temp = __raw_readl(imx_usb->base + USB_STAT); |
| 252 | 256 | ||
| @@ -259,12 +263,15 @@ struct imx_udc_struct { | |||
| 259 | (temp & STAT_ALTSET)); | 263 | (temp & STAT_ALTSET)); |
| 260 | } | 264 | } |
| 261 | 265 | ||
| 262 | static void dump_ep_stat(const char *label, struct imx_ep_struct *imx_ep) | 266 | static void dump_ep_stat(const char *label, |
| 267 | struct imx_ep_struct *imx_ep) | ||
| 263 | { | 268 | { |
| 264 | int temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_INTR(EP_NO(imx_ep))); | 269 | int temp = __raw_readl(imx_ep->imx_usb->base |
| 270 | + USB_EP_INTR(EP_NO(imx_ep))); | ||
| 265 | 271 | ||
| 266 | dev_dbg(imx_ep->imx_usb->dev, | 272 | dev_dbg(imx_ep->imx_usb->dev, |
| 267 | "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, EP_NO(imx_ep), | 273 | "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", |
| 274 | label, EP_NO(imx_ep), | ||
| 268 | (temp & EPINTR_FIFO_FULL) ? " full" : "", | 275 | (temp & EPINTR_FIFO_FULL) ? " full" : "", |
| 269 | (temp & EPINTR_FIFO_EMPTY) ? " fempty" : "", | 276 | (temp & EPINTR_FIFO_EMPTY) ? " fempty" : "", |
| 270 | (temp & EPINTR_FIFO_ERROR) ? " ferr" : "", | 277 | (temp & EPINTR_FIFO_ERROR) ? " ferr" : "", |
| @@ -275,18 +282,22 @@ struct imx_udc_struct { | |||
| 275 | (temp & EPINTR_DEVREQ) ? " devreq" : "", | 282 | (temp & EPINTR_DEVREQ) ? " devreq" : "", |
| 276 | (temp & EPINTR_EOT) ? " eot" : ""); | 283 | (temp & EPINTR_EOT) ? " eot" : ""); |
| 277 | 284 | ||
| 278 | temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_STAT(EP_NO(imx_ep))); | 285 | temp = __raw_readl(imx_ep->imx_usb->base |
| 286 | + USB_EP_STAT(EP_NO(imx_ep))); | ||
| 279 | 287 | ||
| 280 | dev_dbg(imx_ep->imx_usb->dev, | 288 | dev_dbg(imx_ep->imx_usb->dev, |
| 281 | "<%s> EP%d_STAT=[%s%s bcount=%d]\n", label, EP_NO(imx_ep), | 289 | "<%s> EP%d_STAT=[%s%s bcount=%d]\n", |
| 290 | label, EP_NO(imx_ep), | ||
| 282 | (temp & EPSTAT_SIP) ? " sip" : "", | 291 | (temp & EPSTAT_SIP) ? " sip" : "", |
| 283 | (temp & EPSTAT_STALL) ? " stall" : "", | 292 | (temp & EPSTAT_STALL) ? " stall" : "", |
| 284 | (temp & EPSTAT_BCOUNT) >> 16); | 293 | (temp & EPSTAT_BCOUNT) >> 16); |
| 285 | 294 | ||
| 286 | temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_FSTAT(EP_NO(imx_ep))); | 295 | temp = __raw_readl(imx_ep->imx_usb->base |
| 296 | + USB_EP_FSTAT(EP_NO(imx_ep))); | ||
| 287 | 297 | ||
| 288 | dev_dbg(imx_ep->imx_usb->dev, | 298 | dev_dbg(imx_ep->imx_usb->dev, |
| 289 | "<%s> EP%d_FSTAT=[%s%s%s%s%s%s%s]\n", label, EP_NO(imx_ep), | 299 | "<%s> EP%d_FSTAT=[%s%s%s%s%s%s%s]\n", |
| 300 | label, EP_NO(imx_ep), | ||
| 290 | (temp & FSTAT_ERR) ? " ferr" : "", | 301 | (temp & FSTAT_ERR) ? " ferr" : "", |
| 291 | (temp & FSTAT_UF) ? " funder" : "", | 302 | (temp & FSTAT_UF) ? " funder" : "", |
| 292 | (temp & FSTAT_OF) ? " fover" : "", | 303 | (temp & FSTAT_OF) ? " fover" : "", |
| @@ -296,19 +307,23 @@ struct imx_udc_struct { | |||
| 296 | (temp & FSTAT_EMPTY) ? " fempty" : ""); | 307 | (temp & FSTAT_EMPTY) ? " fempty" : ""); |
| 297 | } | 308 | } |
| 298 | 309 | ||
| 299 | static void dump_req(const char *label, struct imx_ep_struct *imx_ep, struct usb_request *req) | 310 | static void dump_req(const char *label, struct imx_ep_struct *imx_ep, |
| 311 | struct usb_request *req) | ||
| 300 | { | 312 | { |
| 301 | int i; | 313 | int i; |
| 302 | 314 | ||
| 303 | if (!req || !req->buf) { | 315 | if (!req || !req->buf) { |
| 304 | dev_dbg(imx_ep->imx_usb->dev, "<%s> req or req buf is free\n", label); | 316 | dev_dbg(imx_ep->imx_usb->dev, |
| 317 | "<%s> req or req buf is free\n", label); | ||
| 305 | return; | 318 | return; |
| 306 | } | 319 | } |
| 307 | 320 | ||
| 308 | if ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state == EP0_IN_DATA_PHASE) | 321 | if ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state |
| 322 | == EP0_IN_DATA_PHASE) | ||
| 309 | || (EP_NO(imx_ep) && EP_DIR(imx_ep))) { | 323 | || (EP_NO(imx_ep) && EP_DIR(imx_ep))) { |
| 310 | 324 | ||
| 311 | dev_dbg(imx_ep->imx_usb->dev, "<%s> request dump <", label); | 325 | dev_dbg(imx_ep->imx_usb->dev, |
| 326 | "<%s> request dump <", label); | ||
| 312 | for (i = 0; i < req->length; i++) | 327 | for (i = 0; i < req->length; i++) |
| 313 | printk("%02x-", *((u8 *)req->buf + i)); | 328 | printk("%02x-", *((u8 *)req->buf + i)); |
| 314 | printk(">\n"); | 329 | printk(">\n"); |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 317b48fdbf01..d20937f28a19 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
| @@ -1334,7 +1334,7 @@ static void make_qualifier (struct dev_data *dev) | |||
| 1334 | 1334 | ||
| 1335 | qual.bLength = sizeof qual; | 1335 | qual.bLength = sizeof qual; |
| 1336 | qual.bDescriptorType = USB_DT_DEVICE_QUALIFIER; | 1336 | qual.bDescriptorType = USB_DT_DEVICE_QUALIFIER; |
| 1337 | qual.bcdUSB = __constant_cpu_to_le16 (0x0200); | 1337 | qual.bcdUSB = cpu_to_le16 (0x0200); |
| 1338 | 1338 | ||
| 1339 | desc = dev->dev; | 1339 | desc = dev->dev; |
| 1340 | qual.bDeviceClass = desc->bDeviceClass; | 1340 | qual.bDeviceClass = desc->bDeviceClass; |
| @@ -1908,7 +1908,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
| 1908 | || dev->dev->bNumConfigurations != 1) | 1908 | || dev->dev->bNumConfigurations != 1) |
| 1909 | goto fail; | 1909 | goto fail; |
| 1910 | dev->dev->bNumConfigurations = 1; | 1910 | dev->dev->bNumConfigurations = 1; |
| 1911 | dev->dev->bcdUSB = __constant_cpu_to_le16 (0x0200); | 1911 | dev->dev->bcdUSB = cpu_to_le16 (0x0200); |
| 1912 | 1912 | ||
| 1913 | /* triggers gadgetfs_bind(); then we can enumerate. */ | 1913 | /* triggers gadgetfs_bind(); then we can enumerate. */ |
| 1914 | spin_unlock_irq (&dev->lock); | 1914 | spin_unlock_irq (&dev->lock); |
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c index d554b0895603..6cd3d54f5640 100644 --- a/drivers/usb/gadget/lh7a40x_udc.c +++ b/drivers/usb/gadget/lh7a40x_udc.c | |||
| @@ -432,8 +432,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
| 432 | device_add(&dev->gadget.dev); | 432 | device_add(&dev->gadget.dev); |
| 433 | retval = driver->bind(&dev->gadget); | 433 | retval = driver->bind(&dev->gadget); |
| 434 | if (retval) { | 434 | if (retval) { |
| 435 | printk("%s: bind to driver %s --> error %d\n", dev->gadget.name, | 435 | printk(KERN_WARNING "%s: bind to driver %s --> error %d\n", |
| 436 | driver->driver.name, retval); | 436 | dev->gadget.name, driver->driver.name, retval); |
| 437 | device_del(&dev->gadget.dev); | 437 | device_del(&dev->gadget.dev); |
| 438 | 438 | ||
| 439 | dev->driver = 0; | 439 | dev->driver = 0; |
| @@ -445,8 +445,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
| 445 | * for set_configuration as well as eventual disconnect. | 445 | * for set_configuration as well as eventual disconnect. |
| 446 | * NOTE: this shouldn't power up until later. | 446 | * NOTE: this shouldn't power up until later. |
| 447 | */ | 447 | */ |
| 448 | printk("%s: registered gadget driver '%s'\n", dev->gadget.name, | 448 | printk(KERN_WARNING "%s: registered gadget driver '%s'\n", |
| 449 | driver->driver.name); | 449 | dev->gadget.name, driver->driver.name); |
| 450 | 450 | ||
| 451 | udc_enable(dev); | 451 | udc_enable(dev); |
| 452 | 452 | ||
| @@ -581,7 +581,8 @@ static int read_fifo(struct lh7a40x_ep *ep, struct lh7a40x_request *req) | |||
| 581 | * discard the extra data. | 581 | * discard the extra data. |
| 582 | */ | 582 | */ |
| 583 | if (req->req.status != -EOVERFLOW) | 583 | if (req->req.status != -EOVERFLOW) |
| 584 | printk("%s overflow %d\n", ep->ep.name, count); | 584 | printk(KERN_WARNING "%s overflow %d\n", |
| 585 | ep->ep.name, count); | ||
| 585 | req->req.status = -EOVERFLOW; | 586 | req->req.status = -EOVERFLOW; |
| 586 | } else { | 587 | } else { |
| 587 | *buf++ = byte; | 588 | *buf++ = byte; |
| @@ -831,7 +832,8 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr) | |||
| 831 | queue); | 832 | queue); |
| 832 | 833 | ||
| 833 | if (!req) { | 834 | if (!req) { |
| 834 | printk("%s: NULL REQ %d\n", | 835 | printk(KERN_WARNING |
| 836 | "%s: NULL REQ %d\n", | ||
| 835 | __func__, ep_idx); | 837 | __func__, ep_idx); |
| 836 | flush(ep); | 838 | flush(ep); |
| 837 | break; | 839 | break; |
| @@ -844,7 +846,7 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr) | |||
| 844 | 846 | ||
| 845 | } else { | 847 | } else { |
| 846 | /* Throw packet away.. */ | 848 | /* Throw packet away.. */ |
| 847 | printk("%s: No descriptor?!?\n", __func__); | 849 | printk(KERN_WARNING "%s: No descriptor?!?\n", __func__); |
| 848 | flush(ep); | 850 | flush(ep); |
| 849 | } | 851 | } |
| 850 | } | 852 | } |
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 12c6d83b218c..9498be87a724 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
| @@ -142,8 +142,8 @@ static char *type_string (u8 bmAttributes) | |||
| 142 | 142 | ||
| 143 | #include "net2280.h" | 143 | #include "net2280.h" |
| 144 | 144 | ||
| 145 | #define valid_bit __constant_cpu_to_le32 (1 << VALID_BIT) | 145 | #define valid_bit cpu_to_le32 (1 << VALID_BIT) |
| 146 | #define dma_done_ie __constant_cpu_to_le32 (1 << DMA_DONE_INTERRUPT_ENABLE) | 146 | #define dma_done_ie cpu_to_le32 (1 << DMA_DONE_INTERRUPT_ENABLE) |
| 147 | 147 | ||
| 148 | /*-------------------------------------------------------------------------*/ | 148 | /*-------------------------------------------------------------------------*/ |
| 149 | 149 | ||
| @@ -425,7 +425,7 @@ net2280_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags) | |||
| 425 | return NULL; | 425 | return NULL; |
| 426 | } | 426 | } |
| 427 | td->dmacount = 0; /* not VALID */ | 427 | td->dmacount = 0; /* not VALID */ |
| 428 | td->dmaaddr = __constant_cpu_to_le32 (DMA_ADDR_INVALID); | 428 | td->dmaaddr = cpu_to_le32 (DMA_ADDR_INVALID); |
| 429 | td->dmadesc = td->dmaaddr; | 429 | td->dmadesc = td->dmaaddr; |
| 430 | req->td = td; | 430 | req->td = td; |
| 431 | } | 431 | } |
| @@ -775,7 +775,7 @@ static void start_dma (struct net2280_ep *ep, struct net2280_request *req) | |||
| 775 | fill_dma_desc (ep, req, 1); | 775 | fill_dma_desc (ep, req, 1); |
| 776 | 776 | ||
| 777 | if (!use_dma_chaining) | 777 | if (!use_dma_chaining) |
| 778 | req->td->dmacount |= __constant_cpu_to_le32 (1 << END_OF_CHAIN); | 778 | req->td->dmacount |= cpu_to_le32 (1 << END_OF_CHAIN); |
| 779 | 779 | ||
| 780 | start_queue (ep, tmp, req->td_dma); | 780 | start_queue (ep, tmp, req->td_dma); |
| 781 | } | 781 | } |
| @@ -2407,9 +2407,9 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) | |||
| 2407 | 2407 | ||
| 2408 | if (readl (&e->regs->ep_rsp) | 2408 | if (readl (&e->regs->ep_rsp) |
| 2409 | & (1 << SET_ENDPOINT_HALT)) | 2409 | & (1 << SET_ENDPOINT_HALT)) |
| 2410 | status = __constant_cpu_to_le32 (1); | 2410 | status = cpu_to_le32 (1); |
| 2411 | else | 2411 | else |
| 2412 | status = __constant_cpu_to_le32 (0); | 2412 | status = cpu_to_le32 (0); |
| 2413 | 2413 | ||
| 2414 | /* don't bother with a request object! */ | 2414 | /* don't bother with a request object! */ |
| 2415 | writel (0, &dev->epregs [0].ep_irqenb); | 2415 | writel (0, &dev->epregs [0].ep_irqenb); |
| @@ -2667,7 +2667,7 @@ static void handle_stat1_irqs (struct net2280 *dev, u32 stat) | |||
| 2667 | req = list_entry (ep->queue.next, | 2667 | req = list_entry (ep->queue.next, |
| 2668 | struct net2280_request, queue); | 2668 | struct net2280_request, queue); |
| 2669 | dmacount = req->td->dmacount; | 2669 | dmacount = req->td->dmacount; |
| 2670 | dmacount &= __constant_cpu_to_le32 ( | 2670 | dmacount &= cpu_to_le32 ( |
| 2671 | (1 << VALID_BIT) | 2671 | (1 << VALID_BIT) |
| 2672 | | DMA_BYTE_COUNT_MASK); | 2672 | | DMA_BYTE_COUNT_MASK); |
| 2673 | if (dmacount && (dmacount & valid_bit) == 0) | 2673 | if (dmacount && (dmacount & valid_bit) == 0) |
| @@ -2881,7 +2881,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 2881 | goto done; | 2881 | goto done; |
| 2882 | } | 2882 | } |
| 2883 | td->dmacount = 0; /* not VALID */ | 2883 | td->dmacount = 0; /* not VALID */ |
| 2884 | td->dmaaddr = __constant_cpu_to_le32 (DMA_ADDR_INVALID); | 2884 | td->dmaaddr = cpu_to_le32 (DMA_ADDR_INVALID); |
| 2885 | td->dmadesc = td->dmaaddr; | 2885 | td->dmadesc = td->dmaaddr; |
| 2886 | dev->ep [i].dummy = td; | 2886 | dev->ep [i].dummy = td; |
| 2887 | } | 2887 | } |
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 5a3034fdfe47..29500154d00c 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c | |||
| @@ -225,12 +225,12 @@ module_param(qlen, uint, S_IRUGO|S_IWUSR); | |||
| 225 | static struct usb_device_descriptor device_desc = { | 225 | static struct usb_device_descriptor device_desc = { |
| 226 | .bLength = sizeof device_desc, | 226 | .bLength = sizeof device_desc, |
| 227 | .bDescriptorType = USB_DT_DEVICE, | 227 | .bDescriptorType = USB_DT_DEVICE, |
| 228 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 228 | .bcdUSB = cpu_to_le16(0x0200), |
| 229 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | 229 | .bDeviceClass = USB_CLASS_PER_INTERFACE, |
| 230 | .bDeviceSubClass = 0, | 230 | .bDeviceSubClass = 0, |
| 231 | .bDeviceProtocol = 0, | 231 | .bDeviceProtocol = 0, |
| 232 | .idVendor = __constant_cpu_to_le16(PRINTER_VENDOR_NUM), | 232 | .idVendor = cpu_to_le16(PRINTER_VENDOR_NUM), |
| 233 | .idProduct = __constant_cpu_to_le16(PRINTER_PRODUCT_NUM), | 233 | .idProduct = cpu_to_le16(PRINTER_PRODUCT_NUM), |
| 234 | .iManufacturer = STRING_MANUFACTURER, | 234 | .iManufacturer = STRING_MANUFACTURER, |
| 235 | .iProduct = STRING_PRODUCT, | 235 | .iProduct = STRING_PRODUCT, |
| 236 | .iSerialNumber = STRING_SERIALNUM, | 236 | .iSerialNumber = STRING_SERIALNUM, |
| @@ -299,20 +299,20 @@ static struct usb_endpoint_descriptor hs_ep_in_desc = { | |||
| 299 | .bLength = USB_DT_ENDPOINT_SIZE, | 299 | .bLength = USB_DT_ENDPOINT_SIZE, |
| 300 | .bDescriptorType = USB_DT_ENDPOINT, | 300 | .bDescriptorType = USB_DT_ENDPOINT, |
| 301 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 301 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 302 | .wMaxPacketSize = __constant_cpu_to_le16(512) | 302 | .wMaxPacketSize = cpu_to_le16(512) |
| 303 | }; | 303 | }; |
| 304 | 304 | ||
| 305 | static struct usb_endpoint_descriptor hs_ep_out_desc = { | 305 | static struct usb_endpoint_descriptor hs_ep_out_desc = { |
| 306 | .bLength = USB_DT_ENDPOINT_SIZE, | 306 | .bLength = USB_DT_ENDPOINT_SIZE, |
| 307 | .bDescriptorType = USB_DT_ENDPOINT, | 307 | .bDescriptorType = USB_DT_ENDPOINT, |
| 308 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 308 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
| 309 | .wMaxPacketSize = __constant_cpu_to_le16(512) | 309 | .wMaxPacketSize = cpu_to_le16(512) |
| 310 | }; | 310 | }; |
| 311 | 311 | ||
| 312 | static struct usb_qualifier_descriptor dev_qualifier = { | 312 | static struct usb_qualifier_descriptor dev_qualifier = { |
| 313 | .bLength = sizeof dev_qualifier, | 313 | .bLength = sizeof dev_qualifier, |
| 314 | .bDescriptorType = USB_DT_DEVICE_QUALIFIER, | 314 | .bDescriptorType = USB_DT_DEVICE_QUALIFIER, |
| 315 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 315 | .bcdUSB = cpu_to_le16(0x0200), |
| 316 | .bDeviceClass = USB_CLASS_PRINTER, | 316 | .bDeviceClass = USB_CLASS_PRINTER, |
| 317 | .bNumConfigurations = 1 | 317 | .bNumConfigurations = 1 |
| 318 | }; | 318 | }; |
| @@ -1406,16 +1406,16 @@ printer_bind(struct usb_gadget *gadget) | |||
| 1406 | gadget->name); | 1406 | gadget->name); |
| 1407 | /* unrecognized, but safe unless bulk is REALLY quirky */ | 1407 | /* unrecognized, but safe unless bulk is REALLY quirky */ |
| 1408 | device_desc.bcdDevice = | 1408 | device_desc.bcdDevice = |
| 1409 | __constant_cpu_to_le16(0xFFFF); | 1409 | cpu_to_le16(0xFFFF); |
| 1410 | } | 1410 | } |
| 1411 | snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s", | 1411 | snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s", |
| 1412 | init_utsname()->sysname, init_utsname()->release, | 1412 | init_utsname()->sysname, init_utsname()->release, |
| 1413 | gadget->name); | 1413 | gadget->name); |
| 1414 | 1414 | ||
| 1415 | device_desc.idVendor = | 1415 | device_desc.idVendor = |
| 1416 | __constant_cpu_to_le16(PRINTER_VENDOR_NUM); | 1416 | cpu_to_le16(PRINTER_VENDOR_NUM); |
| 1417 | device_desc.idProduct = | 1417 | device_desc.idProduct = |
| 1418 | __constant_cpu_to_le16(PRINTER_PRODUCT_NUM); | 1418 | cpu_to_le16(PRINTER_PRODUCT_NUM); |
| 1419 | 1419 | ||
| 1420 | /* support optional vendor/distro customization */ | 1420 | /* support optional vendor/distro customization */ |
| 1421 | if (idVendor) { | 1421 | if (idVendor) { |
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 990f40f988d4..8cc676ecbb23 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c | |||
| @@ -30,6 +30,7 @@ | |||
| 30 | #include <linux/proc_fs.h> | 30 | #include <linux/proc_fs.h> |
| 31 | #include <linux/clk.h> | 31 | #include <linux/clk.h> |
| 32 | #include <linux/irq.h> | 32 | #include <linux/irq.h> |
| 33 | #include <linux/gpio.h> | ||
| 33 | 34 | ||
| 34 | #include <asm/byteorder.h> | 35 | #include <asm/byteorder.h> |
| 35 | #include <mach/hardware.h> | 36 | #include <mach/hardware.h> |
| @@ -278,7 +279,7 @@ static void pxa_init_debugfs(struct pxa_udc *udc) | |||
| 278 | goto err_queues; | 279 | goto err_queues; |
| 279 | eps = debugfs_create_file("epstate", 0400, root, udc, | 280 | eps = debugfs_create_file("epstate", 0400, root, udc, |
| 280 | &eps_dbg_fops); | 281 | &eps_dbg_fops); |
| 281 | if (!queues) | 282 | if (!eps) |
| 282 | goto err_eps; | 283 | goto err_eps; |
| 283 | 284 | ||
| 284 | udc->debugfs_root = root; | 285 | udc->debugfs_root = root; |
| @@ -747,13 +748,13 @@ static void req_done(struct pxa_ep *ep, struct pxa27x_request *req, int status) | |||
| 747 | } | 748 | } |
| 748 | 749 | ||
| 749 | /** | 750 | /** |
| 750 | * ep_end_out_req - Ends control endpoint in request | 751 | * ep_end_out_req - Ends endpoint OUT request |
| 751 | * @ep: physical endpoint | 752 | * @ep: physical endpoint |
| 752 | * @req: pxa request | 753 | * @req: pxa request |
| 753 | * | 754 | * |
| 754 | * Context: ep->lock held | 755 | * Context: ep->lock held |
| 755 | * | 756 | * |
| 756 | * Ends endpoint in request (completes usb request). | 757 | * Ends endpoint OUT request (completes usb request). |
| 757 | */ | 758 | */ |
| 758 | static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) | 759 | static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) |
| 759 | { | 760 | { |
| @@ -762,13 +763,13 @@ static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) | |||
| 762 | } | 763 | } |
| 763 | 764 | ||
| 764 | /** | 765 | /** |
| 765 | * ep0_end_out_req - Ends control endpoint in request (ends data stage) | 766 | * ep0_end_out_req - Ends control endpoint OUT request (ends data stage) |
| 766 | * @ep: physical endpoint | 767 | * @ep: physical endpoint |
| 767 | * @req: pxa request | 768 | * @req: pxa request |
| 768 | * | 769 | * |
| 769 | * Context: ep->lock held | 770 | * Context: ep->lock held |
| 770 | * | 771 | * |
| 771 | * Ends control endpoint in request (completes usb request), and puts | 772 | * Ends control endpoint OUT request (completes usb request), and puts |
| 772 | * control endpoint into idle state | 773 | * control endpoint into idle state |
| 773 | */ | 774 | */ |
| 774 | static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) | 775 | static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) |
| @@ -779,13 +780,13 @@ static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) | |||
| 779 | } | 780 | } |
| 780 | 781 | ||
| 781 | /** | 782 | /** |
| 782 | * ep_end_in_req - Ends endpoint out request | 783 | * ep_end_in_req - Ends endpoint IN request |
| 783 | * @ep: physical endpoint | 784 | * @ep: physical endpoint |
| 784 | * @req: pxa request | 785 | * @req: pxa request |
| 785 | * | 786 | * |
| 786 | * Context: ep->lock held | 787 | * Context: ep->lock held |
| 787 | * | 788 | * |
| 788 | * Ends endpoint out request (completes usb request). | 789 | * Ends endpoint IN request (completes usb request). |
| 789 | */ | 790 | */ |
| 790 | static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) | 791 | static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) |
| 791 | { | 792 | { |
| @@ -794,20 +795,18 @@ static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) | |||
| 794 | } | 795 | } |
| 795 | 796 | ||
| 796 | /** | 797 | /** |
| 797 | * ep0_end_in_req - Ends control endpoint out request (ends data stage) | 798 | * ep0_end_in_req - Ends control endpoint IN request (ends data stage) |
| 798 | * @ep: physical endpoint | 799 | * @ep: physical endpoint |
| 799 | * @req: pxa request | 800 | * @req: pxa request |
| 800 | * | 801 | * |
| 801 | * Context: ep->lock held | 802 | * Context: ep->lock held |
| 802 | * | 803 | * |
| 803 | * Ends control endpoint out request (completes usb request), and puts | 804 | * Ends control endpoint IN request (completes usb request), and puts |
| 804 | * control endpoint into status state | 805 | * control endpoint into status state |
| 805 | */ | 806 | */ |
| 806 | static void ep0_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) | 807 | static void ep0_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) |
| 807 | { | 808 | { |
| 808 | struct pxa_udc *udc = ep->dev; | 809 | set_ep0state(ep->dev, IN_STATUS_STAGE); |
| 809 | |||
| 810 | set_ep0state(udc, IN_STATUS_STAGE); | ||
| 811 | ep_end_in_req(ep, req); | 810 | ep_end_in_req(ep, req); |
| 812 | } | 811 | } |
| 813 | 812 | ||
| @@ -1167,7 +1166,7 @@ static int pxa_ep_queue(struct usb_ep *_ep, struct usb_request *_req, | |||
| 1167 | ep_end_in_req(ep, req); | 1166 | ep_end_in_req(ep, req); |
| 1168 | } else { | 1167 | } else { |
| 1169 | ep_err(ep, "got a request of %d bytes while" | 1168 | ep_err(ep, "got a request of %d bytes while" |
| 1170 | "in state WATI_ACK_SET_CONF_INTERF\n", | 1169 | "in state WAIT_ACK_SET_CONF_INTERF\n", |
| 1171 | length); | 1170 | length); |
| 1172 | ep_del_request(ep, req); | 1171 | ep_del_request(ep, req); |
| 1173 | rc = -EL2HLT; | 1172 | rc = -EL2HLT; |
| @@ -1213,30 +1212,26 @@ static int pxa_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | |||
| 1213 | struct udc_usb_ep *udc_usb_ep; | 1212 | struct udc_usb_ep *udc_usb_ep; |
| 1214 | struct pxa27x_request *req; | 1213 | struct pxa27x_request *req; |
| 1215 | unsigned long flags; | 1214 | unsigned long flags; |
| 1216 | int rc; | 1215 | int rc = -EINVAL; |
| 1217 | 1216 | ||
| 1218 | if (!_ep) | 1217 | if (!_ep) |
| 1219 | return -EINVAL; | 1218 | return rc; |
| 1220 | udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); | 1219 | udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); |
| 1221 | ep = udc_usb_ep->pxa_ep; | 1220 | ep = udc_usb_ep->pxa_ep; |
| 1222 | if (!ep || is_ep0(ep)) | 1221 | if (!ep || is_ep0(ep)) |
| 1223 | return -EINVAL; | 1222 | return rc; |
| 1224 | 1223 | ||
| 1225 | spin_lock_irqsave(&ep->lock, flags); | 1224 | spin_lock_irqsave(&ep->lock, flags); |
| 1226 | 1225 | ||
| 1227 | /* make sure it's actually queued on this endpoint */ | 1226 | /* make sure it's actually queued on this endpoint */ |
| 1228 | list_for_each_entry(req, &ep->queue, queue) { | 1227 | list_for_each_entry(req, &ep->queue, queue) { |
| 1229 | if (&req->req == _req) | 1228 | if (&req->req == _req) { |
| 1229 | req_done(ep, req, -ECONNRESET); | ||
| 1230 | rc = 0; | ||
| 1230 | break; | 1231 | break; |
| 1232 | } | ||
| 1231 | } | 1233 | } |
| 1232 | 1234 | ||
| 1233 | rc = -EINVAL; | ||
| 1234 | if (&req->req != _req) | ||
| 1235 | goto out; | ||
| 1236 | |||
| 1237 | rc = 0; | ||
| 1238 | req_done(ep, req, -ECONNRESET); | ||
| 1239 | out: | ||
| 1240 | spin_unlock_irqrestore(&ep->lock, flags); | 1235 | spin_unlock_irqrestore(&ep->lock, flags); |
| 1241 | return rc; | 1236 | return rc; |
| 1242 | } | 1237 | } |
| @@ -1471,6 +1466,32 @@ static struct usb_ep_ops pxa_ep_ops = { | |||
| 1471 | .fifo_flush = pxa_ep_fifo_flush, | 1466 | .fifo_flush = pxa_ep_fifo_flush, |
| 1472 | }; | 1467 | }; |
| 1473 | 1468 | ||
| 1469 | /** | ||
| 1470 | * dplus_pullup - Connect or disconnect pullup resistor to D+ pin | ||
| 1471 | * @udc: udc device | ||
| 1472 | * @on: 0 if disconnect pullup resistor, 1 otherwise | ||
| 1473 | * Context: any | ||
| 1474 | * | ||
| 1475 | * Handle D+ pullup resistor, make the device visible to the usb bus, and | ||
| 1476 | * declare it as a full speed usb device | ||
| 1477 | */ | ||
| 1478 | static void dplus_pullup(struct pxa_udc *udc, int on) | ||
| 1479 | { | ||
| 1480 | if (on) { | ||
| 1481 | if (gpio_is_valid(udc->mach->gpio_pullup)) | ||
| 1482 | gpio_set_value(udc->mach->gpio_pullup, | ||
| 1483 | !udc->mach->gpio_pullup_inverted); | ||
| 1484 | if (udc->mach->udc_command) | ||
| 1485 | udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT); | ||
| 1486 | } else { | ||
| 1487 | if (gpio_is_valid(udc->mach->gpio_pullup)) | ||
| 1488 | gpio_set_value(udc->mach->gpio_pullup, | ||
| 1489 | udc->mach->gpio_pullup_inverted); | ||
| 1490 | if (udc->mach->udc_command) | ||
| 1491 | udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); | ||
| 1492 | } | ||
| 1493 | udc->pullup_on = on; | ||
| 1494 | } | ||
| 1474 | 1495 | ||
| 1475 | /** | 1496 | /** |
| 1476 | * pxa_udc_get_frame - Returns usb frame number | 1497 | * pxa_udc_get_frame - Returns usb frame number |
| @@ -1500,21 +1521,145 @@ static int pxa_udc_wakeup(struct usb_gadget *_gadget) | |||
| 1500 | return 0; | 1521 | return 0; |
| 1501 | } | 1522 | } |
| 1502 | 1523 | ||
| 1524 | static void udc_enable(struct pxa_udc *udc); | ||
| 1525 | static void udc_disable(struct pxa_udc *udc); | ||
| 1526 | |||
| 1527 | /** | ||
| 1528 | * should_enable_udc - Tells if UDC should be enabled | ||
| 1529 | * @udc: udc device | ||
| 1530 | * Context: any | ||
| 1531 | * | ||
| 1532 | * The UDC should be enabled if : | ||
| 1533 | |||
| 1534 | * - the pullup resistor is connected | ||
| 1535 | * - and a gadget driver is bound | ||
| 1536 | * - and vbus is sensed (or no vbus sense is available) | ||
| 1537 | * | ||
| 1538 | * Returns 1 if UDC should be enabled, 0 otherwise | ||
| 1539 | */ | ||
| 1540 | static int should_enable_udc(struct pxa_udc *udc) | ||
| 1541 | { | ||
| 1542 | int put_on; | ||
| 1543 | |||
| 1544 | put_on = ((udc->pullup_on) && (udc->driver)); | ||
| 1545 | put_on &= ((udc->vbus_sensed) || (!udc->transceiver)); | ||
| 1546 | return put_on; | ||
| 1547 | } | ||
| 1548 | |||
| 1549 | /** | ||
| 1550 | * should_disable_udc - Tells if UDC should be disabled | ||
| 1551 | * @udc: udc device | ||
| 1552 | * Context: any | ||
| 1553 | * | ||
| 1554 | * The UDC should be disabled if : | ||
| 1555 | * - the pullup resistor is not connected | ||
| 1556 | * - or no gadget driver is bound | ||
| 1557 | * - or no vbus is sensed (when vbus sesing is available) | ||
| 1558 | * | ||
| 1559 | * Returns 1 if UDC should be disabled | ||
| 1560 | */ | ||
| 1561 | static int should_disable_udc(struct pxa_udc *udc) | ||
| 1562 | { | ||
| 1563 | int put_off; | ||
| 1564 | |||
| 1565 | put_off = ((!udc->pullup_on) || (!udc->driver)); | ||
| 1566 | put_off |= ((!udc->vbus_sensed) && (udc->transceiver)); | ||
| 1567 | return put_off; | ||
| 1568 | } | ||
| 1569 | |||
| 1570 | /** | ||
| 1571 | * pxa_udc_pullup - Offer manual D+ pullup control | ||
| 1572 | * @_gadget: usb gadget using the control | ||
| 1573 | * @is_active: 0 if disconnect, else connect D+ pullup resistor | ||
| 1574 | * Context: !in_interrupt() | ||
| 1575 | * | ||
| 1576 | * Returns 0 if OK, -EOPNOTSUPP if udc driver doesn't handle D+ pullup | ||
| 1577 | */ | ||
| 1578 | static int pxa_udc_pullup(struct usb_gadget *_gadget, int is_active) | ||
| 1579 | { | ||
| 1580 | struct pxa_udc *udc = to_gadget_udc(_gadget); | ||
| 1581 | |||
| 1582 | if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command) | ||
| 1583 | return -EOPNOTSUPP; | ||
| 1584 | |||
| 1585 | dplus_pullup(udc, is_active); | ||
| 1586 | |||
| 1587 | if (should_enable_udc(udc)) | ||
| 1588 | udc_enable(udc); | ||
| 1589 | if (should_disable_udc(udc)) | ||
| 1590 | udc_disable(udc); | ||
| 1591 | return 0; | ||
| 1592 | } | ||
| 1593 | |||
| 1594 | static void udc_enable(struct pxa_udc *udc); | ||
| 1595 | static void udc_disable(struct pxa_udc *udc); | ||
| 1596 | |||
| 1597 | /** | ||
| 1598 | * pxa_udc_vbus_session - Called by external transceiver to enable/disable udc | ||
| 1599 | * @_gadget: usb gadget | ||
| 1600 | * @is_active: 0 if should disable the udc, 1 if should enable | ||
| 1601 | * | ||
| 1602 | * Enables the udc, and optionnaly activates D+ pullup resistor. Or disables the | ||
| 1603 | * udc, and deactivates D+ pullup resistor. | ||
| 1604 | * | ||
| 1605 | * Returns 0 | ||
| 1606 | */ | ||
| 1607 | static int pxa_udc_vbus_session(struct usb_gadget *_gadget, int is_active) | ||
| 1608 | { | ||
| 1609 | struct pxa_udc *udc = to_gadget_udc(_gadget); | ||
| 1610 | |||
| 1611 | udc->vbus_sensed = is_active; | ||
| 1612 | if (should_enable_udc(udc)) | ||
| 1613 | udc_enable(udc); | ||
| 1614 | if (should_disable_udc(udc)) | ||
| 1615 | udc_disable(udc); | ||
| 1616 | |||
| 1617 | return 0; | ||
| 1618 | } | ||
| 1619 | |||
| 1620 | /** | ||
| 1621 | * pxa_udc_vbus_draw - Called by gadget driver after SET_CONFIGURATION completed | ||
| 1622 | * @_gadget: usb gadget | ||
| 1623 | * @mA: current drawn | ||
| 1624 | * | ||
| 1625 | * Context: !in_interrupt() | ||
| 1626 | * | ||
| 1627 | * Called after a configuration was chosen by a USB host, to inform how much | ||
| 1628 | * current can be drawn by the device from VBus line. | ||
| 1629 | * | ||
| 1630 | * Returns 0 or -EOPNOTSUPP if no transceiver is handling the udc | ||
| 1631 | */ | ||
| 1632 | static int pxa_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA) | ||
| 1633 | { | ||
| 1634 | struct pxa_udc *udc; | ||
| 1635 | |||
| 1636 | udc = to_gadget_udc(_gadget); | ||
| 1637 | if (udc->transceiver) | ||
| 1638 | return otg_set_power(udc->transceiver, mA); | ||
| 1639 | return -EOPNOTSUPP; | ||
| 1640 | } | ||
| 1641 | |||
| 1503 | static const struct usb_gadget_ops pxa_udc_ops = { | 1642 | static const struct usb_gadget_ops pxa_udc_ops = { |
| 1504 | .get_frame = pxa_udc_get_frame, | 1643 | .get_frame = pxa_udc_get_frame, |
| 1505 | .wakeup = pxa_udc_wakeup, | 1644 | .wakeup = pxa_udc_wakeup, |
| 1506 | /* current versions must always be self-powered */ | 1645 | .pullup = pxa_udc_pullup, |
| 1646 | .vbus_session = pxa_udc_vbus_session, | ||
| 1647 | .vbus_draw = pxa_udc_vbus_draw, | ||
| 1507 | }; | 1648 | }; |
| 1508 | 1649 | ||
| 1509 | /** | 1650 | /** |
| 1510 | * udc_disable - disable udc device controller | 1651 | * udc_disable - disable udc device controller |
| 1511 | * @udc: udc device | 1652 | * @udc: udc device |
| 1653 | * Context: any | ||
| 1512 | * | 1654 | * |
| 1513 | * Disables the udc device : disables clocks, udc interrupts, control endpoint | 1655 | * Disables the udc device : disables clocks, udc interrupts, control endpoint |
| 1514 | * interrupts. | 1656 | * interrupts. |
| 1515 | */ | 1657 | */ |
| 1516 | static void udc_disable(struct pxa_udc *udc) | 1658 | static void udc_disable(struct pxa_udc *udc) |
| 1517 | { | 1659 | { |
| 1660 | if (!udc->enabled) | ||
| 1661 | return; | ||
| 1662 | |||
| 1518 | udc_writel(udc, UDCICR0, 0); | 1663 | udc_writel(udc, UDCICR0, 0); |
| 1519 | udc_writel(udc, UDCICR1, 0); | 1664 | udc_writel(udc, UDCICR1, 0); |
| 1520 | 1665 | ||
| @@ -1523,8 +1668,8 @@ static void udc_disable(struct pxa_udc *udc) | |||
| 1523 | 1668 | ||
| 1524 | ep0_idle(udc); | 1669 | ep0_idle(udc); |
| 1525 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 1670 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
| 1526 | if (udc->mach->udc_command) | 1671 | |
| 1527 | udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); | 1672 | udc->enabled = 0; |
| 1528 | } | 1673 | } |
| 1529 | 1674 | ||
| 1530 | /** | 1675 | /** |
| @@ -1555,10 +1700,9 @@ static __init void udc_init_data(struct pxa_udc *dev) | |||
| 1555 | } | 1700 | } |
| 1556 | 1701 | ||
| 1557 | /* USB endpoints init */ | 1702 | /* USB endpoints init */ |
| 1558 | for (i = 0; i < NR_USB_ENDPOINTS; i++) | 1703 | for (i = 1; i < NR_USB_ENDPOINTS; i++) |
| 1559 | if (i != 0) | 1704 | list_add_tail(&dev->udc_usb_ep[i].usb_ep.ep_list, |
| 1560 | list_add_tail(&dev->udc_usb_ep[i].usb_ep.ep_list, | 1705 | &dev->gadget.ep_list); |
| 1561 | &dev->gadget.ep_list); | ||
| 1562 | } | 1706 | } |
| 1563 | 1707 | ||
| 1564 | /** | 1708 | /** |
| @@ -1570,6 +1714,9 @@ static __init void udc_init_data(struct pxa_udc *dev) | |||
| 1570 | */ | 1714 | */ |
| 1571 | static void udc_enable(struct pxa_udc *udc) | 1715 | static void udc_enable(struct pxa_udc *udc) |
| 1572 | { | 1716 | { |
| 1717 | if (udc->enabled) | ||
| 1718 | return; | ||
| 1719 | |||
| 1573 | udc_writel(udc, UDCICR0, 0); | 1720 | udc_writel(udc, UDCICR0, 0); |
| 1574 | udc_writel(udc, UDCICR1, 0); | 1721 | udc_writel(udc, UDCICR1, 0); |
| 1575 | udc_clear_mask_UDCCR(udc, UDCCR_UDE); | 1722 | udc_clear_mask_UDCCR(udc, UDCCR_UDE); |
| @@ -1598,9 +1745,7 @@ static void udc_enable(struct pxa_udc *udc) | |||
| 1598 | /* enable ep0 irqs */ | 1745 | /* enable ep0 irqs */ |
| 1599 | pio_irq_enable(&udc->pxa_ep[0]); | 1746 | pio_irq_enable(&udc->pxa_ep[0]); |
| 1600 | 1747 | ||
| 1601 | dev_info(udc->dev, "UDC connecting\n"); | 1748 | udc->enabled = 1; |
| 1602 | if (udc->mach->udc_command) | ||
| 1603 | udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT); | ||
| 1604 | } | 1749 | } |
| 1605 | 1750 | ||
| 1606 | /** | 1751 | /** |
| @@ -1612,6 +1757,9 @@ static void udc_enable(struct pxa_udc *udc) | |||
| 1612 | * usb traffic follows until a disconnect is reported. Then a host may connect | 1757 | * usb traffic follows until a disconnect is reported. Then a host may connect |
| 1613 | * again, or the driver might get unbound. | 1758 | * again, or the driver might get unbound. |
| 1614 | * | 1759 | * |
| 1760 | * Note that the udc is not automatically enabled. Check function | ||
| 1761 | * should_enable_udc(). | ||
| 1762 | * | ||
| 1615 | * Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise | 1763 | * Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise |
| 1616 | */ | 1764 | */ |
| 1617 | int usb_gadget_register_driver(struct usb_gadget_driver *driver) | 1765 | int usb_gadget_register_driver(struct usb_gadget_driver *driver) |
| @@ -1630,6 +1778,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
| 1630 | /* first hook up the driver ... */ | 1778 | /* first hook up the driver ... */ |
| 1631 | udc->driver = driver; | 1779 | udc->driver = driver; |
| 1632 | udc->gadget.dev.driver = &driver->driver; | 1780 | udc->gadget.dev.driver = &driver->driver; |
| 1781 | dplus_pullup(udc, 1); | ||
| 1633 | 1782 | ||
| 1634 | retval = device_add(&udc->gadget.dev); | 1783 | retval = device_add(&udc->gadget.dev); |
| 1635 | if (retval) { | 1784 | if (retval) { |
| @@ -1645,9 +1794,21 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
| 1645 | dev_dbg(udc->dev, "registered gadget driver '%s'\n", | 1794 | dev_dbg(udc->dev, "registered gadget driver '%s'\n", |
| 1646 | driver->driver.name); | 1795 | driver->driver.name); |
| 1647 | 1796 | ||
| 1648 | udc_enable(udc); | 1797 | if (udc->transceiver) { |
| 1798 | retval = otg_set_peripheral(udc->transceiver, &udc->gadget); | ||
| 1799 | if (retval) { | ||
| 1800 | dev_err(udc->dev, "can't bind to transceiver\n"); | ||
| 1801 | goto transceiver_fail; | ||
| 1802 | } | ||
| 1803 | } | ||
| 1804 | |||
| 1805 | if (should_enable_udc(udc)) | ||
| 1806 | udc_enable(udc); | ||
| 1649 | return 0; | 1807 | return 0; |
| 1650 | 1808 | ||
| 1809 | transceiver_fail: | ||
| 1810 | if (driver->unbind) | ||
| 1811 | driver->unbind(&udc->gadget); | ||
| 1651 | bind_fail: | 1812 | bind_fail: |
| 1652 | device_del(&udc->gadget.dev); | 1813 | device_del(&udc->gadget.dev); |
| 1653 | add_fail: | 1814 | add_fail: |
| @@ -1699,14 +1860,17 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
| 1699 | 1860 | ||
| 1700 | stop_activity(udc, driver); | 1861 | stop_activity(udc, driver); |
| 1701 | udc_disable(udc); | 1862 | udc_disable(udc); |
| 1863 | dplus_pullup(udc, 0); | ||
| 1702 | 1864 | ||
| 1703 | driver->unbind(&udc->gadget); | 1865 | driver->unbind(&udc->gadget); |
| 1704 | udc->driver = NULL; | 1866 | udc->driver = NULL; |
| 1705 | 1867 | ||
| 1706 | device_del(&udc->gadget.dev); | 1868 | device_del(&udc->gadget.dev); |
| 1707 | |||
| 1708 | dev_info(udc->dev, "unregistered gadget driver '%s'\n", | 1869 | dev_info(udc->dev, "unregistered gadget driver '%s'\n", |
| 1709 | driver->driver.name); | 1870 | driver->driver.name); |
| 1871 | |||
| 1872 | if (udc->transceiver) | ||
| 1873 | return otg_set_peripheral(udc->transceiver, NULL); | ||
| 1710 | return 0; | 1874 | return 0; |
| 1711 | } | 1875 | } |
| 1712 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | 1876 | EXPORT_SYMBOL(usb_gadget_unregister_driver); |
| @@ -1823,14 +1987,14 @@ static void handle_ep0(struct pxa_udc *udc, int fifo_irq, int opc_irq) | |||
| 1823 | struct pxa27x_request *req = NULL; | 1987 | struct pxa27x_request *req = NULL; |
| 1824 | int completed = 0; | 1988 | int completed = 0; |
| 1825 | 1989 | ||
| 1990 | if (!list_empty(&ep->queue)) | ||
| 1991 | req = list_entry(ep->queue.next, struct pxa27x_request, queue); | ||
| 1992 | |||
| 1826 | udccsr0 = udc_ep_readl(ep, UDCCSR); | 1993 | udccsr0 = udc_ep_readl(ep, UDCCSR); |
| 1827 | ep_dbg(ep, "state=%s, req=%p, udccsr0=0x%03x, udcbcr=%d, irq_msk=%x\n", | 1994 | ep_dbg(ep, "state=%s, req=%p, udccsr0=0x%03x, udcbcr=%d, irq_msk=%x\n", |
| 1828 | EP0_STNAME(udc), req, udccsr0, udc_ep_readl(ep, UDCBCR), | 1995 | EP0_STNAME(udc), req, udccsr0, udc_ep_readl(ep, UDCBCR), |
| 1829 | (fifo_irq << 1 | opc_irq)); | 1996 | (fifo_irq << 1 | opc_irq)); |
| 1830 | 1997 | ||
| 1831 | if (!list_empty(&ep->queue)) | ||
| 1832 | req = list_entry(ep->queue.next, struct pxa27x_request, queue); | ||
| 1833 | |||
| 1834 | if (udccsr0 & UDCCSR0_SST) { | 1998 | if (udccsr0 & UDCCSR0_SST) { |
| 1835 | ep_dbg(ep, "clearing stall status\n"); | 1999 | ep_dbg(ep, "clearing stall status\n"); |
| 1836 | nuke(ep, -EPIPE); | 2000 | nuke(ep, -EPIPE); |
| @@ -2212,7 +2376,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev) | |||
| 2212 | { | 2376 | { |
| 2213 | struct resource *regs; | 2377 | struct resource *regs; |
| 2214 | struct pxa_udc *udc = &memory; | 2378 | struct pxa_udc *udc = &memory; |
| 2215 | int retval; | 2379 | int retval = 0, gpio; |
| 2216 | 2380 | ||
| 2217 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2381 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 2218 | if (!regs) | 2382 | if (!regs) |
| @@ -2223,6 +2387,20 @@ static int __init pxa_udc_probe(struct platform_device *pdev) | |||
| 2223 | 2387 | ||
| 2224 | udc->dev = &pdev->dev; | 2388 | udc->dev = &pdev->dev; |
| 2225 | udc->mach = pdev->dev.platform_data; | 2389 | udc->mach = pdev->dev.platform_data; |
| 2390 | udc->transceiver = otg_get_transceiver(); | ||
| 2391 | |||
| 2392 | gpio = udc->mach->gpio_pullup; | ||
| 2393 | if (gpio_is_valid(gpio)) { | ||
| 2394 | retval = gpio_request(gpio, "USB D+ pullup"); | ||
| 2395 | if (retval == 0) | ||
| 2396 | gpio_direction_output(gpio, | ||
| 2397 | udc->mach->gpio_pullup_inverted); | ||
| 2398 | } | ||
| 2399 | if (retval) { | ||
| 2400 | dev_err(&pdev->dev, "Couldn't request gpio %d : %d\n", | ||
| 2401 | gpio, retval); | ||
| 2402 | return retval; | ||
| 2403 | } | ||
| 2226 | 2404 | ||
| 2227 | udc->clk = clk_get(&pdev->dev, NULL); | 2405 | udc->clk = clk_get(&pdev->dev, NULL); |
| 2228 | if (IS_ERR(udc->clk)) { | 2406 | if (IS_ERR(udc->clk)) { |
| @@ -2240,6 +2418,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev) | |||
| 2240 | device_initialize(&udc->gadget.dev); | 2418 | device_initialize(&udc->gadget.dev); |
| 2241 | udc->gadget.dev.parent = &pdev->dev; | 2419 | udc->gadget.dev.parent = &pdev->dev; |
| 2242 | udc->gadget.dev.dma_mask = NULL; | 2420 | udc->gadget.dev.dma_mask = NULL; |
| 2421 | udc->vbus_sensed = 0; | ||
| 2243 | 2422 | ||
| 2244 | the_controller = udc; | 2423 | the_controller = udc; |
| 2245 | platform_set_drvdata(pdev, udc); | 2424 | platform_set_drvdata(pdev, udc); |
| @@ -2273,14 +2452,21 @@ err_clk: | |||
| 2273 | static int __exit pxa_udc_remove(struct platform_device *_dev) | 2452 | static int __exit pxa_udc_remove(struct platform_device *_dev) |
| 2274 | { | 2453 | { |
| 2275 | struct pxa_udc *udc = platform_get_drvdata(_dev); | 2454 | struct pxa_udc *udc = platform_get_drvdata(_dev); |
| 2455 | int gpio = udc->mach->gpio_pullup; | ||
| 2276 | 2456 | ||
| 2277 | usb_gadget_unregister_driver(udc->driver); | 2457 | usb_gadget_unregister_driver(udc->driver); |
| 2278 | free_irq(udc->irq, udc); | 2458 | free_irq(udc->irq, udc); |
| 2279 | pxa_cleanup_debugfs(udc); | 2459 | pxa_cleanup_debugfs(udc); |
| 2460 | if (gpio_is_valid(gpio)) | ||
| 2461 | gpio_free(gpio); | ||
| 2462 | |||
| 2463 | otg_put_transceiver(udc->transceiver); | ||
| 2280 | 2464 | ||
| 2465 | udc->transceiver = NULL; | ||
| 2281 | platform_set_drvdata(_dev, NULL); | 2466 | platform_set_drvdata(_dev, NULL); |
| 2282 | the_controller = NULL; | 2467 | the_controller = NULL; |
| 2283 | clk_put(udc->clk); | 2468 | clk_put(udc->clk); |
| 2469 | iounmap(udc->regs); | ||
| 2284 | 2470 | ||
| 2285 | return 0; | 2471 | return 0; |
| 2286 | } | 2472 | } |
| @@ -2319,6 +2505,8 @@ static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state) | |||
| 2319 | } | 2505 | } |
| 2320 | 2506 | ||
| 2321 | udc_disable(udc); | 2507 | udc_disable(udc); |
| 2508 | udc->pullup_resume = udc->pullup_on; | ||
| 2509 | dplus_pullup(udc, 0); | ||
| 2322 | 2510 | ||
| 2323 | return 0; | 2511 | return 0; |
| 2324 | } | 2512 | } |
| @@ -2346,7 +2534,9 @@ static int pxa_udc_resume(struct platform_device *_dev) | |||
| 2346 | ep->udccsr_value, ep->udccr_value); | 2534 | ep->udccsr_value, ep->udccr_value); |
| 2347 | } | 2535 | } |
| 2348 | 2536 | ||
| 2349 | udc_enable(udc); | 2537 | dplus_pullup(udc, udc->pullup_resume); |
| 2538 | if (should_enable_udc(udc)) | ||
| 2539 | udc_enable(udc); | ||
| 2350 | /* | 2540 | /* |
| 2351 | * We do not handle OTG yet. | 2541 | * We do not handle OTG yet. |
| 2352 | * | 2542 | * |
diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/pxa27x_udc.h index 1d1b7936ee11..db58125331da 100644 --- a/drivers/usb/gadget/pxa27x_udc.h +++ b/drivers/usb/gadget/pxa27x_udc.h | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
| 27 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
| 28 | #include <linux/io.h> | 28 | #include <linux/io.h> |
| 29 | #include <linux/usb/otg.h> | ||
| 29 | 30 | ||
| 30 | /* | 31 | /* |
| 31 | * Register definitions | 32 | * Register definitions |
| @@ -421,10 +422,14 @@ struct udc_stats { | |||
| 421 | * @driver: bound gadget (zero, g_ether, g_file_storage, ...) | 422 | * @driver: bound gadget (zero, g_ether, g_file_storage, ...) |
| 422 | * @dev: device | 423 | * @dev: device |
| 423 | * @mach: machine info, used to activate specific GPIO | 424 | * @mach: machine info, used to activate specific GPIO |
| 425 | * @transceiver: external transceiver to handle vbus sense and D+ pullup | ||
| 424 | * @ep0state: control endpoint state machine state | 426 | * @ep0state: control endpoint state machine state |
| 425 | * @stats: statistics on udc usage | 427 | * @stats: statistics on udc usage |
| 426 | * @udc_usb_ep: array of usb endpoints offered by the gadget | 428 | * @udc_usb_ep: array of usb endpoints offered by the gadget |
| 427 | * @pxa_ep: array of pxa available endpoints | 429 | * @pxa_ep: array of pxa available endpoints |
| 430 | * @enabled: UDC was enabled by a previous udc_enable() | ||
| 431 | * @pullup_on: if pullup resistor connected to D+ pin | ||
| 432 | * @pullup_resume: if pullup resistor should be connected to D+ pin on resume | ||
| 428 | * @config: UDC active configuration | 433 | * @config: UDC active configuration |
| 429 | * @last_interface: UDC interface of the last SET_INTERFACE host request | 434 | * @last_interface: UDC interface of the last SET_INTERFACE host request |
| 430 | * @last_alternate: UDC altsetting of the last SET_INTERFACE host request | 435 | * @last_alternate: UDC altsetting of the last SET_INTERFACE host request |
| @@ -443,6 +448,7 @@ struct pxa_udc { | |||
| 443 | struct usb_gadget_driver *driver; | 448 | struct usb_gadget_driver *driver; |
| 444 | struct device *dev; | 449 | struct device *dev; |
| 445 | struct pxa2xx_udc_mach_info *mach; | 450 | struct pxa2xx_udc_mach_info *mach; |
| 451 | struct otg_transceiver *transceiver; | ||
| 446 | 452 | ||
| 447 | enum ep0_state ep0state; | 453 | enum ep0_state ep0state; |
| 448 | struct udc_stats stats; | 454 | struct udc_stats stats; |
| @@ -450,6 +456,10 @@ struct pxa_udc { | |||
| 450 | struct udc_usb_ep udc_usb_ep[NR_USB_ENDPOINTS]; | 456 | struct udc_usb_ep udc_usb_ep[NR_USB_ENDPOINTS]; |
| 451 | struct pxa_ep pxa_ep[NR_PXA_ENDPOINTS]; | 457 | struct pxa_ep pxa_ep[NR_PXA_ENDPOINTS]; |
| 452 | 458 | ||
| 459 | unsigned enabled:1; | ||
| 460 | unsigned pullup_on:1; | ||
| 461 | unsigned pullup_resume:1; | ||
| 462 | unsigned vbus_sensed:1; | ||
| 453 | unsigned config:2; | 463 | unsigned config:2; |
| 454 | unsigned last_interface:3; | 464 | unsigned last_interface:3; |
| 455 | unsigned last_alternate:3; | 465 | unsigned last_alternate:3; |
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 8c26f5ea2b83..2b4660e08c4d 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c | |||
| @@ -63,7 +63,7 @@ MODULE_PARM_DESC (rndis_debug, "enable debugging"); | |||
| 63 | static rndis_params rndis_per_dev_params [RNDIS_MAX_CONFIGS]; | 63 | static rndis_params rndis_per_dev_params [RNDIS_MAX_CONFIGS]; |
| 64 | 64 | ||
| 65 | /* Driver Version */ | 65 | /* Driver Version */ |
| 66 | static const __le32 rndis_driver_version = __constant_cpu_to_le32 (1); | 66 | static const __le32 rndis_driver_version = cpu_to_le32 (1); |
| 67 | 67 | ||
| 68 | /* Function Prototypes */ | 68 | /* Function Prototypes */ |
| 69 | static rndis_resp_t *rndis_add_response (int configNr, u32 length); | 69 | static rndis_resp_t *rndis_add_response (int configNr, u32 length); |
| @@ -170,7 +170,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
| 170 | int i, count; | 170 | int i, count; |
| 171 | rndis_query_cmplt_type *resp; | 171 | rndis_query_cmplt_type *resp; |
| 172 | struct net_device *net; | 172 | struct net_device *net; |
| 173 | struct net_device_stats *stats; | 173 | const struct net_device_stats *stats; |
| 174 | 174 | ||
| 175 | if (!r) return -ENOMEM; | 175 | if (!r) return -ENOMEM; |
| 176 | resp = (rndis_query_cmplt_type *) r->buf; | 176 | resp = (rndis_query_cmplt_type *) r->buf; |
| @@ -190,13 +190,10 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
| 190 | 190 | ||
| 191 | /* response goes here, right after the header */ | 191 | /* response goes here, right after the header */ |
| 192 | outbuf = (__le32 *) &resp[1]; | 192 | outbuf = (__le32 *) &resp[1]; |
| 193 | resp->InformationBufferOffset = __constant_cpu_to_le32 (16); | 193 | resp->InformationBufferOffset = cpu_to_le32 (16); |
| 194 | 194 | ||
| 195 | net = rndis_per_dev_params[configNr].dev; | 195 | net = rndis_per_dev_params[configNr].dev; |
| 196 | if (net->get_stats) | 196 | stats = dev_get_stats(net); |
| 197 | stats = net->get_stats(net); | ||
| 198 | else | ||
| 199 | stats = NULL; | ||
| 200 | 197 | ||
| 201 | switch (OID) { | 198 | switch (OID) { |
| 202 | 199 | ||
| @@ -221,7 +218,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
| 221 | * reddite ergo quae sunt Caesaris Caesari | 218 | * reddite ergo quae sunt Caesaris Caesari |
| 222 | * et quae sunt Dei Deo! | 219 | * et quae sunt Dei Deo! |
| 223 | */ | 220 | */ |
| 224 | *outbuf = __constant_cpu_to_le32 (0); | 221 | *outbuf = cpu_to_le32 (0); |
| 225 | retval = 0; | 222 | retval = 0; |
| 226 | break; | 223 | break; |
| 227 | 224 | ||
| @@ -256,7 +253,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
| 256 | pr_debug("%s: OID_GEN_LINK_SPEED\n", __func__); | 253 | pr_debug("%s: OID_GEN_LINK_SPEED\n", __func__); |
| 257 | if (rndis_per_dev_params [configNr].media_state | 254 | if (rndis_per_dev_params [configNr].media_state |
| 258 | == NDIS_MEDIA_STATE_DISCONNECTED) | 255 | == NDIS_MEDIA_STATE_DISCONNECTED) |
| 259 | *outbuf = __constant_cpu_to_le32 (0); | 256 | *outbuf = cpu_to_le32 (0); |
| 260 | else | 257 | else |
| 261 | *outbuf = cpu_to_le32 ( | 258 | *outbuf = cpu_to_le32 ( |
| 262 | rndis_per_dev_params [configNr].speed); | 259 | rndis_per_dev_params [configNr].speed); |
| @@ -317,7 +314,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
| 317 | /* mandatory */ | 314 | /* mandatory */ |
| 318 | case OID_GEN_MAXIMUM_TOTAL_SIZE: | 315 | case OID_GEN_MAXIMUM_TOTAL_SIZE: |
| 319 | pr_debug("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__); | 316 | pr_debug("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__); |
| 320 | *outbuf = __constant_cpu_to_le32(RNDIS_MAX_TOTAL_SIZE); | 317 | *outbuf = cpu_to_le32(RNDIS_MAX_TOTAL_SIZE); |
| 321 | retval = 0; | 318 | retval = 0; |
| 322 | break; | 319 | break; |
| 323 | 320 | ||
| @@ -332,7 +329,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
| 332 | 329 | ||
| 333 | case OID_GEN_PHYSICAL_MEDIUM: | 330 | case OID_GEN_PHYSICAL_MEDIUM: |
| 334 | pr_debug("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__); | 331 | pr_debug("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__); |
| 335 | *outbuf = __constant_cpu_to_le32 (0); | 332 | *outbuf = cpu_to_le32 (0); |
| 336 | retval = 0; | 333 | retval = 0; |
| 337 | break; | 334 | break; |
| 338 | 335 | ||
| @@ -342,7 +339,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
| 342 | */ | 339 | */ |
| 343 | case OID_GEN_MAC_OPTIONS: /* from WinME */ | 340 | case OID_GEN_MAC_OPTIONS: /* from WinME */ |
| 344 | pr_debug("%s: OID_GEN_MAC_OPTIONS\n", __func__); | 341 | pr_debug("%s: OID_GEN_MAC_OPTIONS\n", __func__); |
| 345 | *outbuf = __constant_cpu_to_le32( | 342 | *outbuf = cpu_to_le32( |
| 346 | NDIS_MAC_OPTION_RECEIVE_SERIALIZED | 343 | NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
| 347 | | NDIS_MAC_OPTION_FULL_DUPLEX); | 344 | | NDIS_MAC_OPTION_FULL_DUPLEX); |
| 348 | retval = 0; | 345 | retval = 0; |
| @@ -431,7 +428,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
| 431 | case OID_802_3_MULTICAST_LIST: | 428 | case OID_802_3_MULTICAST_LIST: |
| 432 | pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__); | 429 | pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__); |
| 433 | /* Multicast base address only */ | 430 | /* Multicast base address only */ |
| 434 | *outbuf = __constant_cpu_to_le32 (0xE0000000); | 431 | *outbuf = cpu_to_le32 (0xE0000000); |
| 435 | retval = 0; | 432 | retval = 0; |
| 436 | break; | 433 | break; |
| 437 | 434 | ||
| @@ -439,7 +436,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
| 439 | case OID_802_3_MAXIMUM_LIST_SIZE: | 436 | case OID_802_3_MAXIMUM_LIST_SIZE: |
| 440 | pr_debug("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__); | 437 | pr_debug("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__); |
| 441 | /* Multicast base address only */ | 438 | /* Multicast base address only */ |
| 442 | *outbuf = __constant_cpu_to_le32 (1); | 439 | *outbuf = cpu_to_le32 (1); |
| 443 | retval = 0; | 440 | retval = 0; |
| 444 | break; | 441 | break; |
| 445 | 442 | ||
| @@ -461,14 +458,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
| 461 | /* mandatory */ | 458 | /* mandatory */ |
| 462 | case OID_802_3_XMIT_ONE_COLLISION: | 459 | case OID_802_3_XMIT_ONE_COLLISION: |
| 463 | pr_debug("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__); | 460 | pr_debug("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__); |
| 464 | *outbuf = __constant_cpu_to_le32 (0); | 461 | *outbuf = cpu_to_le32 (0); |
| 465 | retval = 0; | 462 | retval = 0; |
| 466 | break; | 463 | break; |
| 467 | 464 | ||
| 468 | /* mandatory */ | 465 | /* mandatory */ |
| 469 | case OID_802_3_XMIT_MORE_COLLISIONS: | 466 | case OID_802_3_XMIT_MORE_COLLISIONS: |
| 470 | pr_debug("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__); | 467 | pr_debug("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__); |
| 471 | *outbuf = __constant_cpu_to_le32 (0); | 468 | *outbuf = cpu_to_le32 (0); |
| 472 | retval = 0; | 469 | retval = 0; |
| 473 | break; | 470 | break; |
| 474 | 471 | ||
| @@ -572,24 +569,24 @@ static int rndis_init_response (int configNr, rndis_init_msg_type *buf) | |||
| 572 | return -ENOMEM; | 569 | return -ENOMEM; |
| 573 | resp = (rndis_init_cmplt_type *) r->buf; | 570 | resp = (rndis_init_cmplt_type *) r->buf; |
| 574 | 571 | ||
| 575 | resp->MessageType = __constant_cpu_to_le32 ( | 572 | resp->MessageType = cpu_to_le32 ( |
| 576 | REMOTE_NDIS_INITIALIZE_CMPLT); | 573 | REMOTE_NDIS_INITIALIZE_CMPLT); |
| 577 | resp->MessageLength = __constant_cpu_to_le32 (52); | 574 | resp->MessageLength = cpu_to_le32 (52); |
| 578 | resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ | 575 | resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ |
| 579 | resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); | 576 | resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS); |
| 580 | resp->MajorVersion = __constant_cpu_to_le32 (RNDIS_MAJOR_VERSION); | 577 | resp->MajorVersion = cpu_to_le32 (RNDIS_MAJOR_VERSION); |
| 581 | resp->MinorVersion = __constant_cpu_to_le32 (RNDIS_MINOR_VERSION); | 578 | resp->MinorVersion = cpu_to_le32 (RNDIS_MINOR_VERSION); |
| 582 | resp->DeviceFlags = __constant_cpu_to_le32 (RNDIS_DF_CONNECTIONLESS); | 579 | resp->DeviceFlags = cpu_to_le32 (RNDIS_DF_CONNECTIONLESS); |
| 583 | resp->Medium = __constant_cpu_to_le32 (RNDIS_MEDIUM_802_3); | 580 | resp->Medium = cpu_to_le32 (RNDIS_MEDIUM_802_3); |
| 584 | resp->MaxPacketsPerTransfer = __constant_cpu_to_le32 (1); | 581 | resp->MaxPacketsPerTransfer = cpu_to_le32 (1); |
| 585 | resp->MaxTransferSize = cpu_to_le32 ( | 582 | resp->MaxTransferSize = cpu_to_le32 ( |
| 586 | params->dev->mtu | 583 | params->dev->mtu |
| 587 | + sizeof (struct ethhdr) | 584 | + sizeof (struct ethhdr) |
| 588 | + sizeof (struct rndis_packet_msg_type) | 585 | + sizeof (struct rndis_packet_msg_type) |
| 589 | + 22); | 586 | + 22); |
| 590 | resp->PacketAlignmentFactor = __constant_cpu_to_le32 (0); | 587 | resp->PacketAlignmentFactor = cpu_to_le32 (0); |
| 591 | resp->AFListOffset = __constant_cpu_to_le32 (0); | 588 | resp->AFListOffset = cpu_to_le32 (0); |
| 592 | resp->AFListSize = __constant_cpu_to_le32 (0); | 589 | resp->AFListSize = cpu_to_le32 (0); |
| 593 | 590 | ||
| 594 | params->resp_avail(params->v); | 591 | params->resp_avail(params->v); |
| 595 | return 0; | 592 | return 0; |
| @@ -617,7 +614,7 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf) | |||
| 617 | return -ENOMEM; | 614 | return -ENOMEM; |
| 618 | resp = (rndis_query_cmplt_type *) r->buf; | 615 | resp = (rndis_query_cmplt_type *) r->buf; |
| 619 | 616 | ||
| 620 | resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT); | 617 | resp->MessageType = cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT); |
| 621 | resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ | 618 | resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ |
| 622 | 619 | ||
| 623 | if (gen_ndis_query_resp (configNr, le32_to_cpu (buf->OID), | 620 | if (gen_ndis_query_resp (configNr, le32_to_cpu (buf->OID), |
| @@ -626,13 +623,13 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf) | |||
| 626 | le32_to_cpu(buf->InformationBufferLength), | 623 | le32_to_cpu(buf->InformationBufferLength), |
| 627 | r)) { | 624 | r)) { |
| 628 | /* OID not supported */ | 625 | /* OID not supported */ |
| 629 | resp->Status = __constant_cpu_to_le32 ( | 626 | resp->Status = cpu_to_le32 ( |
| 630 | RNDIS_STATUS_NOT_SUPPORTED); | 627 | RNDIS_STATUS_NOT_SUPPORTED); |
| 631 | resp->MessageLength = __constant_cpu_to_le32 (sizeof *resp); | 628 | resp->MessageLength = cpu_to_le32 (sizeof *resp); |
| 632 | resp->InformationBufferLength = __constant_cpu_to_le32 (0); | 629 | resp->InformationBufferLength = cpu_to_le32 (0); |
| 633 | resp->InformationBufferOffset = __constant_cpu_to_le32 (0); | 630 | resp->InformationBufferOffset = cpu_to_le32 (0); |
| 634 | } else | 631 | } else |
| 635 | resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); | 632 | resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS); |
| 636 | 633 | ||
| 637 | params->resp_avail(params->v); | 634 | params->resp_avail(params->v); |
| 638 | return 0; | 635 | return 0; |
| @@ -665,14 +662,14 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf) | |||
| 665 | pr_debug("\n"); | 662 | pr_debug("\n"); |
| 666 | #endif | 663 | #endif |
| 667 | 664 | ||
| 668 | resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT); | 665 | resp->MessageType = cpu_to_le32 (REMOTE_NDIS_SET_CMPLT); |
| 669 | resp->MessageLength = __constant_cpu_to_le32 (16); | 666 | resp->MessageLength = cpu_to_le32 (16); |
| 670 | resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ | 667 | resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ |
| 671 | if (gen_ndis_set_resp (configNr, le32_to_cpu (buf->OID), | 668 | if (gen_ndis_set_resp (configNr, le32_to_cpu (buf->OID), |
| 672 | ((u8 *) buf) + 8 + BufOffset, BufLength, r)) | 669 | ((u8 *) buf) + 8 + BufOffset, BufLength, r)) |
| 673 | resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED); | 670 | resp->Status = cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED); |
| 674 | else | 671 | else |
| 675 | resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); | 672 | resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS); |
| 676 | 673 | ||
| 677 | params->resp_avail(params->v); | 674 | params->resp_avail(params->v); |
| 678 | return 0; | 675 | return 0; |
| @@ -689,11 +686,11 @@ static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf) | |||
| 689 | return -ENOMEM; | 686 | return -ENOMEM; |
| 690 | resp = (rndis_reset_cmplt_type *) r->buf; | 687 | resp = (rndis_reset_cmplt_type *) r->buf; |
| 691 | 688 | ||
| 692 | resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT); | 689 | resp->MessageType = cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT); |
| 693 | resp->MessageLength = __constant_cpu_to_le32 (16); | 690 | resp->MessageLength = cpu_to_le32 (16); |
| 694 | resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); | 691 | resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS); |
| 695 | /* resent information */ | 692 | /* resent information */ |
| 696 | resp->AddressingReset = __constant_cpu_to_le32 (1); | 693 | resp->AddressingReset = cpu_to_le32 (1); |
| 697 | 694 | ||
| 698 | params->resp_avail(params->v); | 695 | params->resp_avail(params->v); |
| 699 | return 0; | 696 | return 0; |
| @@ -713,11 +710,11 @@ static int rndis_keepalive_response (int configNr, | |||
| 713 | return -ENOMEM; | 710 | return -ENOMEM; |
| 714 | resp = (rndis_keepalive_cmplt_type *) r->buf; | 711 | resp = (rndis_keepalive_cmplt_type *) r->buf; |
| 715 | 712 | ||
| 716 | resp->MessageType = __constant_cpu_to_le32 ( | 713 | resp->MessageType = cpu_to_le32 ( |
| 717 | REMOTE_NDIS_KEEPALIVE_CMPLT); | 714 | REMOTE_NDIS_KEEPALIVE_CMPLT); |
| 718 | resp->MessageLength = __constant_cpu_to_le32 (16); | 715 | resp->MessageLength = cpu_to_le32 (16); |
| 719 | resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ | 716 | resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ |
| 720 | resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); | 717 | resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS); |
| 721 | 718 | ||
| 722 | params->resp_avail(params->v); | 719 | params->resp_avail(params->v); |
| 723 | return 0; | 720 | return 0; |
| @@ -742,12 +739,12 @@ static int rndis_indicate_status_msg (int configNr, u32 status) | |||
| 742 | return -ENOMEM; | 739 | return -ENOMEM; |
| 743 | resp = (rndis_indicate_status_msg_type *) r->buf; | 740 | resp = (rndis_indicate_status_msg_type *) r->buf; |
| 744 | 741 | ||
| 745 | resp->MessageType = __constant_cpu_to_le32 ( | 742 | resp->MessageType = cpu_to_le32 ( |
| 746 | REMOTE_NDIS_INDICATE_STATUS_MSG); | 743 | REMOTE_NDIS_INDICATE_STATUS_MSG); |
| 747 | resp->MessageLength = __constant_cpu_to_le32 (20); | 744 | resp->MessageLength = cpu_to_le32 (20); |
| 748 | resp->Status = cpu_to_le32 (status); | 745 | resp->Status = cpu_to_le32 (status); |
| 749 | resp->StatusBufferLength = __constant_cpu_to_le32 (0); | 746 | resp->StatusBufferLength = cpu_to_le32 (0); |
| 750 | resp->StatusBufferOffset = __constant_cpu_to_le32 (0); | 747 | resp->StatusBufferOffset = cpu_to_le32 (0); |
| 751 | 748 | ||
| 752 | params->resp_avail(params->v); | 749 | params->resp_avail(params->v); |
| 753 | return 0; | 750 | return 0; |
| @@ -963,9 +960,9 @@ void rndis_add_hdr (struct sk_buff *skb) | |||
| 963 | return; | 960 | return; |
| 964 | header = (void *) skb_push (skb, sizeof *header); | 961 | header = (void *) skb_push (skb, sizeof *header); |
| 965 | memset (header, 0, sizeof *header); | 962 | memset (header, 0, sizeof *header); |
| 966 | header->MessageType = __constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG); | 963 | header->MessageType = cpu_to_le32(REMOTE_NDIS_PACKET_MSG); |
| 967 | header->MessageLength = cpu_to_le32(skb->len); | 964 | header->MessageLength = cpu_to_le32(skb->len); |
| 968 | header->DataOffset = __constant_cpu_to_le32 (36); | 965 | header->DataOffset = cpu_to_le32 (36); |
| 969 | header->DataLength = cpu_to_le32(skb->len - sizeof *header); | 966 | header->DataLength = cpu_to_le32(skb->len - sizeof *header); |
| 970 | } | 967 | } |
| 971 | 968 | ||
| @@ -1029,7 +1026,7 @@ int rndis_rm_hdr(struct sk_buff *skb) | |||
| 1029 | __le32 *tmp = (void *) skb->data; | 1026 | __le32 *tmp = (void *) skb->data; |
| 1030 | 1027 | ||
| 1031 | /* MessageType, MessageLength */ | 1028 | /* MessageType, MessageLength */ |
| 1032 | if (__constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG) | 1029 | if (cpu_to_le32(REMOTE_NDIS_PACKET_MSG) |
| 1033 | != get_unaligned(tmp++)) | 1030 | != get_unaligned(tmp++)) |
| 1034 | return -EINVAL; | 1031 | return -EINVAL; |
| 1035 | tmp++; | 1032 | tmp++; |
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 37879af1c433..f46a60962dab 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
| @@ -87,12 +87,12 @@ static struct usb_gadget_strings *dev_strings[] = { | |||
| 87 | static struct usb_device_descriptor device_desc = { | 87 | static struct usb_device_descriptor device_desc = { |
| 88 | .bLength = USB_DT_DEVICE_SIZE, | 88 | .bLength = USB_DT_DEVICE_SIZE, |
| 89 | .bDescriptorType = USB_DT_DEVICE, | 89 | .bDescriptorType = USB_DT_DEVICE, |
| 90 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 90 | .bcdUSB = cpu_to_le16(0x0200), |
| 91 | /* .bDeviceClass = f(use_acm) */ | 91 | /* .bDeviceClass = f(use_acm) */ |
| 92 | .bDeviceSubClass = 0, | 92 | .bDeviceSubClass = 0, |
| 93 | .bDeviceProtocol = 0, | 93 | .bDeviceProtocol = 0, |
| 94 | /* .bMaxPacketSize0 = f(hardware) */ | 94 | /* .bMaxPacketSize0 = f(hardware) */ |
| 95 | .idVendor = __constant_cpu_to_le16(GS_VENDOR_ID), | 95 | .idVendor = cpu_to_le16(GS_VENDOR_ID), |
| 96 | /* .idProduct = f(use_acm) */ | 96 | /* .idProduct = f(use_acm) */ |
| 97 | /* .bcdDevice = f(hardware) */ | 97 | /* .bcdDevice = f(hardware) */ |
| 98 | /* .iManufacturer = DYNAMIC */ | 98 | /* .iManufacturer = DYNAMIC */ |
| @@ -216,7 +216,7 @@ static int __init gs_bind(struct usb_composite_dev *cdev) | |||
| 216 | pr_warning("gs_bind: controller '%s' not recognized\n", | 216 | pr_warning("gs_bind: controller '%s' not recognized\n", |
| 217 | gadget->name); | 217 | gadget->name); |
| 218 | device_desc.bcdDevice = | 218 | device_desc.bcdDevice = |
| 219 | __constant_cpu_to_le16(GS_VERSION_NUM | 0x0099); | 219 | cpu_to_le16(GS_VERSION_NUM | 0x0099); |
| 220 | } | 220 | } |
| 221 | 221 | ||
| 222 | if (gadget_is_otg(cdev->gadget)) { | 222 | if (gadget_is_otg(cdev->gadget)) { |
| @@ -255,19 +255,19 @@ static int __init init(void) | |||
| 255 | serial_config_driver.bConfigurationValue = 2; | 255 | serial_config_driver.bConfigurationValue = 2; |
| 256 | device_desc.bDeviceClass = USB_CLASS_COMM; | 256 | device_desc.bDeviceClass = USB_CLASS_COMM; |
| 257 | device_desc.idProduct = | 257 | device_desc.idProduct = |
| 258 | __constant_cpu_to_le16(GS_CDC_PRODUCT_ID); | 258 | cpu_to_le16(GS_CDC_PRODUCT_ID); |
| 259 | } else if (use_obex) { | 259 | } else if (use_obex) { |
| 260 | serial_config_driver.label = "CDC OBEX config"; | 260 | serial_config_driver.label = "CDC OBEX config"; |
| 261 | serial_config_driver.bConfigurationValue = 3; | 261 | serial_config_driver.bConfigurationValue = 3; |
| 262 | device_desc.bDeviceClass = USB_CLASS_COMM; | 262 | device_desc.bDeviceClass = USB_CLASS_COMM; |
| 263 | device_desc.idProduct = | 263 | device_desc.idProduct = |
| 264 | __constant_cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID); | 264 | cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID); |
| 265 | } else { | 265 | } else { |
| 266 | serial_config_driver.label = "Generic Serial config"; | 266 | serial_config_driver.label = "Generic Serial config"; |
| 267 | serial_config_driver.bConfigurationValue = 1; | 267 | serial_config_driver.bConfigurationValue = 1; |
| 268 | device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; | 268 | device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; |
| 269 | device_desc.idProduct = | 269 | device_desc.idProduct = |
| 270 | __constant_cpu_to_le16(GS_PRODUCT_ID); | 270 | cpu_to_le16(GS_PRODUCT_ID); |
| 271 | } | 271 | } |
| 272 | strings_dev[STRING_DESCRIPTION_IDX].s = serial_config_driver.label; | 272 | strings_dev[STRING_DESCRIPTION_IDX].s = serial_config_driver.label; |
| 273 | 273 | ||
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index 53d59287f2bc..0a4d99ab40d8 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c | |||
| @@ -1092,7 +1092,7 @@ int __init gserial_setup(struct usb_gadget *g, unsigned count) | |||
| 1092 | gs_tty_driver->init_termios.c_ispeed = 9600; | 1092 | gs_tty_driver->init_termios.c_ispeed = 9600; |
| 1093 | gs_tty_driver->init_termios.c_ospeed = 9600; | 1093 | gs_tty_driver->init_termios.c_ospeed = 9600; |
| 1094 | 1094 | ||
| 1095 | coding.dwDTERate = __constant_cpu_to_le32(9600); | 1095 | coding.dwDTERate = cpu_to_le32(9600); |
| 1096 | coding.bCharFormat = 8; | 1096 | coding.bCharFormat = 8; |
| 1097 | coding.bParityType = USB_CDC_NO_PARITY; | 1097 | coding.bParityType = USB_CDC_NO_PARITY; |
| 1098 | coding.bDataBits = USB_CDC_1_STOP_BITS; | 1098 | coding.bDataBits = USB_CDC_1_STOP_BITS; |
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 361d9659ac48..2d772401b7ad 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c | |||
| @@ -102,22 +102,32 @@ module_param(loopdefault, bool, S_IRUGO|S_IWUSR); | |||
| 102 | #ifndef CONFIG_USB_ZERO_HNPTEST | 102 | #ifndef CONFIG_USB_ZERO_HNPTEST |
| 103 | #define DRIVER_VENDOR_NUM 0x0525 /* NetChip */ | 103 | #define DRIVER_VENDOR_NUM 0x0525 /* NetChip */ |
| 104 | #define DRIVER_PRODUCT_NUM 0xa4a0 /* Linux-USB "Gadget Zero" */ | 104 | #define DRIVER_PRODUCT_NUM 0xa4a0 /* Linux-USB "Gadget Zero" */ |
| 105 | #define DEFAULT_AUTORESUME 0 | ||
| 105 | #else | 106 | #else |
| 106 | #define DRIVER_VENDOR_NUM 0x1a0a /* OTG test device IDs */ | 107 | #define DRIVER_VENDOR_NUM 0x1a0a /* OTG test device IDs */ |
| 107 | #define DRIVER_PRODUCT_NUM 0xbadd | 108 | #define DRIVER_PRODUCT_NUM 0xbadd |
| 109 | #define DEFAULT_AUTORESUME 5 | ||
| 108 | #endif | 110 | #endif |
| 109 | 111 | ||
| 112 | /* If the optional "autoresume" mode is enabled, it provides good | ||
| 113 | * functional coverage for the "USBCV" test harness from USB-IF. | ||
| 114 | * It's always set if OTG mode is enabled. | ||
| 115 | */ | ||
| 116 | unsigned autoresume = DEFAULT_AUTORESUME; | ||
| 117 | module_param(autoresume, uint, S_IRUGO); | ||
| 118 | MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup"); | ||
| 119 | |||
| 110 | /*-------------------------------------------------------------------------*/ | 120 | /*-------------------------------------------------------------------------*/ |
| 111 | 121 | ||
| 112 | static struct usb_device_descriptor device_desc = { | 122 | static struct usb_device_descriptor device_desc = { |
| 113 | .bLength = sizeof device_desc, | 123 | .bLength = sizeof device_desc, |
| 114 | .bDescriptorType = USB_DT_DEVICE, | 124 | .bDescriptorType = USB_DT_DEVICE, |
| 115 | 125 | ||
| 116 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 126 | .bcdUSB = cpu_to_le16(0x0200), |
| 117 | .bDeviceClass = USB_CLASS_VENDOR_SPEC, | 127 | .bDeviceClass = USB_CLASS_VENDOR_SPEC, |
| 118 | 128 | ||
| 119 | .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_NUM), | 129 | .idVendor = cpu_to_le16(DRIVER_VENDOR_NUM), |
| 120 | .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_NUM), | 130 | .idProduct = cpu_to_le16(DRIVER_PRODUCT_NUM), |
| 121 | .bNumConfigurations = 2, | 131 | .bNumConfigurations = 2, |
| 122 | }; | 132 | }; |
| 123 | 133 | ||
| @@ -212,6 +222,47 @@ void disable_endpoints(struct usb_composite_dev *cdev, | |||
| 212 | 222 | ||
| 213 | /*-------------------------------------------------------------------------*/ | 223 | /*-------------------------------------------------------------------------*/ |
| 214 | 224 | ||
| 225 | static struct timer_list autoresume_timer; | ||
| 226 | |||
| 227 | static void zero_autoresume(unsigned long _c) | ||
| 228 | { | ||
| 229 | struct usb_composite_dev *cdev = (void *)_c; | ||
| 230 | struct usb_gadget *g = cdev->gadget; | ||
| 231 | |||
| 232 | /* unconfigured devices can't issue wakeups */ | ||
| 233 | if (!cdev->config) | ||
| 234 | return; | ||
| 235 | |||
| 236 | /* Normally the host would be woken up for something | ||
| 237 | * more significant than just a timer firing; likely | ||
| 238 | * because of some direct user request. | ||
| 239 | */ | ||
| 240 | if (g->speed != USB_SPEED_UNKNOWN) { | ||
| 241 | int status = usb_gadget_wakeup(g); | ||
| 242 | INFO(cdev, "%s --> %d\n", __func__, status); | ||
| 243 | } | ||
| 244 | } | ||
| 245 | |||
| 246 | static void zero_suspend(struct usb_composite_dev *cdev) | ||
| 247 | { | ||
| 248 | if (cdev->gadget->speed == USB_SPEED_UNKNOWN) | ||
| 249 | return; | ||
| 250 | |||
| 251 | if (autoresume) { | ||
| 252 | mod_timer(&autoresume_timer, jiffies + (HZ * autoresume)); | ||
| 253 | DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume); | ||
| 254 | } else | ||
| 255 | DBG(cdev, "%s\n", __func__); | ||
| 256 | } | ||
| 257 | |||
| 258 | static void zero_resume(struct usb_composite_dev *cdev) | ||
| 259 | { | ||
| 260 | DBG(cdev, "%s\n", __func__); | ||
| 261 | del_timer(&autoresume_timer); | ||
| 262 | } | ||
| 263 | |||
| 264 | /*-------------------------------------------------------------------------*/ | ||
| 265 | |||
| 215 | static int __init zero_bind(struct usb_composite_dev *cdev) | 266 | static int __init zero_bind(struct usb_composite_dev *cdev) |
| 216 | { | 267 | { |
| 217 | int gcnum; | 268 | int gcnum; |
| @@ -239,17 +290,19 @@ static int __init zero_bind(struct usb_composite_dev *cdev) | |||
| 239 | strings_dev[STRING_SERIAL_IDX].id = id; | 290 | strings_dev[STRING_SERIAL_IDX].id = id; |
| 240 | device_desc.iSerialNumber = id; | 291 | device_desc.iSerialNumber = id; |
| 241 | 292 | ||
| 293 | setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev); | ||
| 294 | |||
| 242 | /* Register primary, then secondary configuration. Note that | 295 | /* Register primary, then secondary configuration. Note that |
| 243 | * SH3 only allows one config... | 296 | * SH3 only allows one config... |
| 244 | */ | 297 | */ |
| 245 | if (loopdefault) { | 298 | if (loopdefault) { |
| 246 | loopback_add(cdev); | 299 | loopback_add(cdev, autoresume != 0); |
| 247 | if (!gadget_is_sh(gadget)) | 300 | if (!gadget_is_sh(gadget)) |
| 248 | sourcesink_add(cdev); | 301 | sourcesink_add(cdev, autoresume != 0); |
| 249 | } else { | 302 | } else { |
| 250 | sourcesink_add(cdev); | 303 | sourcesink_add(cdev, autoresume != 0); |
| 251 | if (!gadget_is_sh(gadget)) | 304 | if (!gadget_is_sh(gadget)) |
| 252 | loopback_add(cdev); | 305 | loopback_add(cdev, autoresume != 0); |
| 253 | } | 306 | } |
| 254 | 307 | ||
| 255 | gcnum = usb_gadget_controller_number(gadget); | 308 | gcnum = usb_gadget_controller_number(gadget); |
| @@ -265,7 +318,7 @@ static int __init zero_bind(struct usb_composite_dev *cdev) | |||
| 265 | */ | 318 | */ |
| 266 | pr_warning("%s: controller '%s' not recognized\n", | 319 | pr_warning("%s: controller '%s' not recognized\n", |
| 267 | longname, gadget->name); | 320 | longname, gadget->name); |
| 268 | device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); | 321 | device_desc.bcdDevice = cpu_to_le16(0x9999); |
| 269 | } | 322 | } |
| 270 | 323 | ||
| 271 | 324 | ||
| @@ -278,11 +331,20 @@ static int __init zero_bind(struct usb_composite_dev *cdev) | |||
| 278 | return 0; | 331 | return 0; |
| 279 | } | 332 | } |
| 280 | 333 | ||
| 334 | static int zero_unbind(struct usb_composite_dev *cdev) | ||
| 335 | { | ||
| 336 | del_timer_sync(&autoresume_timer); | ||
| 337 | return 0; | ||
| 338 | } | ||
| 339 | |||
| 281 | static struct usb_composite_driver zero_driver = { | 340 | static struct usb_composite_driver zero_driver = { |
| 282 | .name = "zero", | 341 | .name = "zero", |
| 283 | .dev = &device_desc, | 342 | .dev = &device_desc, |
| 284 | .strings = dev_strings, | 343 | .strings = dev_strings, |
| 285 | .bind = zero_bind, | 344 | .bind = zero_bind, |
| 345 | .unbind = zero_unbind, | ||
| 346 | .suspend = zero_suspend, | ||
| 347 | .resume = zero_resume, | ||
| 286 | }; | 348 | }; |
| 287 | 349 | ||
| 288 | MODULE_AUTHOR("David Brownell"); | 350 | MODULE_AUTHOR("David Brownell"); |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 2c63bfb1f8d9..845479f7c707 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
| @@ -24,10 +24,7 @@ config USB_EHCI_HCD | |||
| 24 | The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0 | 24 | The Enhanced Host Controller Interface (EHCI) is standard for USB 2.0 |
| 25 | "high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware. | 25 | "high speed" (480 Mbit/sec, 60 Mbyte/sec) host controller hardware. |
| 26 | If your USB host controller supports USB 2.0, you will likely want to | 26 | If your USB host controller supports USB 2.0, you will likely want to |
| 27 | configure this Host Controller Driver. At the time of this writing, | 27 | configure this Host Controller Driver. |
| 28 | the primary implementation of EHCI is a chip from NEC, widely available | ||
| 29 | in add-on PCI cards, but implementations are in the works from other | ||
| 30 | vendors including Intel and Philips. Motherboard support is appearing. | ||
| 31 | 28 | ||
| 32 | EHCI controllers are packaged with "companion" host controllers (OHCI | 29 | EHCI controllers are packaged with "companion" host controllers (OHCI |
| 33 | or UHCI) to handle USB 1.1 devices connected to root hub ports. Ports | 30 | or UHCI) to handle USB 1.1 devices connected to root hub ports. Ports |
| @@ -123,7 +120,7 @@ config USB_ISP116X_HCD | |||
| 123 | 120 | ||
| 124 | config USB_ISP1760_HCD | 121 | config USB_ISP1760_HCD |
| 125 | tristate "ISP 1760 HCD support" | 122 | tristate "ISP 1760 HCD support" |
| 126 | depends on USB && EXPERIMENTAL && (PCI || PPC_OF) | 123 | depends on USB && EXPERIMENTAL |
| 127 | ---help--- | 124 | ---help--- |
| 128 | The ISP1760 chip is a USB 2.0 host controller. | 125 | The ISP1760 chip is a USB 2.0 host controller. |
| 129 | 126 | ||
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index e551bb38852b..f2618d17710d 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
| @@ -110,6 +110,42 @@ MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications"); | |||
| 110 | 110 | ||
| 111 | /*-------------------------------------------------------------------------*/ | 111 | /*-------------------------------------------------------------------------*/ |
| 112 | 112 | ||
| 113 | static void | ||
| 114 | timer_action(struct ehci_hcd *ehci, enum ehci_timer_action action) | ||
| 115 | { | ||
| 116 | /* Don't override timeouts which shrink or (later) disable | ||
| 117 | * the async ring; just the I/O watchdog. Note that if a | ||
| 118 | * SHRINK were pending, OFF would never be requested. | ||
| 119 | */ | ||
| 120 | if (timer_pending(&ehci->watchdog) | ||
| 121 | && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF)) | ||
| 122 | & ehci->actions)) | ||
| 123 | return; | ||
| 124 | |||
| 125 | if (!test_and_set_bit(action, &ehci->actions)) { | ||
| 126 | unsigned long t; | ||
| 127 | |||
| 128 | switch (action) { | ||
| 129 | case TIMER_IO_WATCHDOG: | ||
| 130 | t = EHCI_IO_JIFFIES; | ||
| 131 | break; | ||
| 132 | case TIMER_ASYNC_OFF: | ||
| 133 | t = EHCI_ASYNC_JIFFIES; | ||
| 134 | break; | ||
| 135 | /* case TIMER_ASYNC_SHRINK: */ | ||
| 136 | default: | ||
| 137 | /* add a jiffie since we synch against the | ||
| 138 | * 8 KHz uframe counter. | ||
| 139 | */ | ||
| 140 | t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1; | ||
| 141 | break; | ||
| 142 | } | ||
| 143 | mod_timer(&ehci->watchdog, t + jiffies); | ||
| 144 | } | ||
| 145 | } | ||
| 146 | |||
| 147 | /*-------------------------------------------------------------------------*/ | ||
| 148 | |||
| 113 | /* | 149 | /* |
| 114 | * handshake - spin reading hc until handshake completes or fails | 150 | * handshake - spin reading hc until handshake completes or fails |
| 115 | * @ptr: address of hc register to be read | 151 | * @ptr: address of hc register to be read |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index ecc9b66c03cd..1976b1b3778c 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
| @@ -333,12 +333,40 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
| 333 | token = hc32_to_cpu(ehci, qtd->hw_token); | 333 | token = hc32_to_cpu(ehci, qtd->hw_token); |
| 334 | 334 | ||
| 335 | /* always clean up qtds the hc de-activated */ | 335 | /* always clean up qtds the hc de-activated */ |
| 336 | retry_xacterr: | ||
| 336 | if ((token & QTD_STS_ACTIVE) == 0) { | 337 | if ((token & QTD_STS_ACTIVE) == 0) { |
| 337 | 338 | ||
| 338 | /* on STALL, error, and short reads this urb must | 339 | /* on STALL, error, and short reads this urb must |
| 339 | * complete and all its qtds must be recycled. | 340 | * complete and all its qtds must be recycled. |
| 340 | */ | 341 | */ |
| 341 | if ((token & QTD_STS_HALT) != 0) { | 342 | if ((token & QTD_STS_HALT) != 0) { |
| 343 | |||
| 344 | /* retry transaction errors until we | ||
| 345 | * reach the software xacterr limit | ||
| 346 | */ | ||
| 347 | if ((token & QTD_STS_XACT) && | ||
| 348 | QTD_CERR(token) == 0 && | ||
| 349 | --qh->xacterrs > 0 && | ||
| 350 | !urb->unlinked) { | ||
| 351 | ehci_dbg(ehci, | ||
| 352 | "detected XactErr len %zu/%zu retry %d\n", | ||
| 353 | qtd->length - QTD_LENGTH(token), qtd->length, | ||
| 354 | QH_XACTERR_MAX - qh->xacterrs); | ||
| 355 | |||
| 356 | /* reset the token in the qtd and the | ||
| 357 | * qh overlay (which still contains | ||
| 358 | * the qtd) so that we pick up from | ||
| 359 | * where we left off | ||
| 360 | */ | ||
| 361 | token &= ~QTD_STS_HALT; | ||
| 362 | token |= QTD_STS_ACTIVE | | ||
| 363 | (EHCI_TUNE_CERR << 10); | ||
| 364 | qtd->hw_token = cpu_to_hc32(ehci, | ||
| 365 | token); | ||
| 366 | wmb(); | ||
| 367 | qh->hw_token = cpu_to_hc32(ehci, token); | ||
| 368 | goto retry_xacterr; | ||
| 369 | } | ||
| 342 | stopped = 1; | 370 | stopped = 1; |
| 343 | 371 | ||
| 344 | /* magic dummy for some short reads; qh won't advance. | 372 | /* magic dummy for some short reads; qh won't advance. |
| @@ -421,6 +449,9 @@ halt: | |||
| 421 | /* remove qtd; it's recycled after possible urb completion */ | 449 | /* remove qtd; it's recycled after possible urb completion */ |
| 422 | list_del (&qtd->qtd_list); | 450 | list_del (&qtd->qtd_list); |
| 423 | last = qtd; | 451 | last = qtd; |
| 452 | |||
| 453 | /* reinit the xacterr counter for the next qtd */ | ||
| 454 | qh->xacterrs = QH_XACTERR_MAX; | ||
| 424 | } | 455 | } |
| 425 | 456 | ||
| 426 | /* last urb's completion might still need calling */ | 457 | /* last urb's completion might still need calling */ |
| @@ -862,6 +893,7 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
| 862 | head->qh_next.qh = qh; | 893 | head->qh_next.qh = qh; |
| 863 | head->hw_next = dma; | 894 | head->hw_next = dma; |
| 864 | 895 | ||
| 896 | qh->xacterrs = QH_XACTERR_MAX; | ||
| 865 | qh->qh_state = QH_STATE_LINKED; | 897 | qh->qh_state = QH_STATE_LINKED; |
| 866 | /* qtd completions reported later by interrupt */ | 898 | /* qtd completions reported later by interrupt */ |
| 867 | } | 899 | } |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 1d0b49e3f192..ada5d2ba297b 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
| @@ -563,7 +563,7 @@ static int qh_unlink_periodic(struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
| 563 | // and this qh is active in the current uframe | 563 | // and this qh is active in the current uframe |
| 564 | // (and overlay token SplitXstate is false?) | 564 | // (and overlay token SplitXstate is false?) |
| 565 | // THEN | 565 | // THEN |
| 566 | // qh->hw_info1 |= __constant_cpu_to_hc32(1 << 7 /* "ignore" */); | 566 | // qh->hw_info1 |= cpu_to_hc32(1 << 7 /* "ignore" */); |
| 567 | 567 | ||
| 568 | /* high bandwidth, or otherwise part of every microframe */ | 568 | /* high bandwidth, or otherwise part of every microframe */ |
| 569 | if ((period = qh->period) == 0) | 569 | if ((period = qh->period) == 0) |
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 262b00c9b334..6cff195e1a36 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
| @@ -190,40 +190,6 @@ timer_action_done (struct ehci_hcd *ehci, enum ehci_timer_action action) | |||
| 190 | clear_bit (action, &ehci->actions); | 190 | clear_bit (action, &ehci->actions); |
| 191 | } | 191 | } |
| 192 | 192 | ||
| 193 | static inline void | ||
| 194 | timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) | ||
| 195 | { | ||
| 196 | /* Don't override timeouts which shrink or (later) disable | ||
| 197 | * the async ring; just the I/O watchdog. Note that if a | ||
| 198 | * SHRINK were pending, OFF would never be requested. | ||
| 199 | */ | ||
| 200 | if (timer_pending(&ehci->watchdog) | ||
| 201 | && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF)) | ||
| 202 | & ehci->actions)) | ||
| 203 | return; | ||
| 204 | |||
| 205 | if (!test_and_set_bit (action, &ehci->actions)) { | ||
| 206 | unsigned long t; | ||
| 207 | |||
| 208 | switch (action) { | ||
| 209 | case TIMER_IO_WATCHDOG: | ||
| 210 | t = EHCI_IO_JIFFIES; | ||
| 211 | break; | ||
| 212 | case TIMER_ASYNC_OFF: | ||
| 213 | t = EHCI_ASYNC_JIFFIES; | ||
| 214 | break; | ||
| 215 | // case TIMER_ASYNC_SHRINK: | ||
| 216 | default: | ||
| 217 | /* add a jiffie since we synch against the | ||
| 218 | * 8 KHz uframe counter. | ||
| 219 | */ | ||
| 220 | t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1; | ||
| 221 | break; | ||
| 222 | } | ||
| 223 | mod_timer(&ehci->watchdog, t + jiffies); | ||
| 224 | } | ||
| 225 | } | ||
| 226 | |||
| 227 | static void free_cached_itd_list(struct ehci_hcd *ehci); | 193 | static void free_cached_itd_list(struct ehci_hcd *ehci); |
| 228 | 194 | ||
| 229 | /*-------------------------------------------------------------------------*/ | 195 | /*-------------------------------------------------------------------------*/ |
| @@ -287,7 +253,7 @@ struct ehci_qtd { | |||
| 287 | 253 | ||
| 288 | /* | 254 | /* |
| 289 | * Now the following defines are not converted using the | 255 | * Now the following defines are not converted using the |
| 290 | * __constant_cpu_to_le32() macro anymore, since we have to support | 256 | * cpu_to_le32() macro anymore, since we have to support |
| 291 | * "dynamic" switching between be and le support, so that the driver | 257 | * "dynamic" switching between be and le support, so that the driver |
| 292 | * can be used on one system with SoC EHCI controller using big-endian | 258 | * can be used on one system with SoC EHCI controller using big-endian |
| 293 | * descriptors as well as a normal little-endian PCI EHCI controller. | 259 | * descriptors as well as a normal little-endian PCI EHCI controller. |
| @@ -376,6 +342,9 @@ struct ehci_qh { | |||
| 376 | #define QH_STATE_UNLINK_WAIT 4 /* LINKED and on reclaim q */ | 342 | #define QH_STATE_UNLINK_WAIT 4 /* LINKED and on reclaim q */ |
| 377 | #define QH_STATE_COMPLETING 5 /* don't touch token.HALT */ | 343 | #define QH_STATE_COMPLETING 5 /* don't touch token.HALT */ |
| 378 | 344 | ||
| 345 | u8 xacterrs; /* XactErr retry counter */ | ||
| 346 | #define QH_XACTERR_MAX 32 /* XactErr retry limit */ | ||
| 347 | |||
| 379 | /* periodic schedule info */ | 348 | /* periodic schedule info */ |
| 380 | u8 usecs; /* intr bandwidth */ | 349 | u8 usecs; /* intr bandwidth */ |
| 381 | u8 gap_uf; /* uframes split/csplit gap */ | 350 | u8 gap_uf; /* uframes split/csplit gap */ |
diff --git a/drivers/usb/host/fhci-dbg.c b/drivers/usb/host/fhci-dbg.c index 34e14edf390b..ea8a4255c5da 100644 --- a/drivers/usb/host/fhci-dbg.c +++ b/drivers/usb/host/fhci-dbg.c | |||
| @@ -108,7 +108,7 @@ void fhci_dfs_create(struct fhci_hcd *fhci) | |||
| 108 | { | 108 | { |
| 109 | struct device *dev = fhci_to_hcd(fhci)->self.controller; | 109 | struct device *dev = fhci_to_hcd(fhci)->self.controller; |
| 110 | 110 | ||
| 111 | fhci->dfs_root = debugfs_create_dir(dev->bus_id, NULL); | 111 | fhci->dfs_root = debugfs_create_dir(dev_name(dev), NULL); |
| 112 | if (!fhci->dfs_root) { | 112 | if (!fhci->dfs_root) { |
| 113 | WARN_ON(1); | 113 | WARN_ON(1); |
| 114 | return; | 114 | return; |
diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index ba622cc8a9ba..0951818ef93b 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c | |||
| @@ -583,7 +583,7 @@ static int __devinit of_fhci_probe(struct of_device *ofdev, | |||
| 583 | if (sprop && strcmp(sprop, "host")) | 583 | if (sprop && strcmp(sprop, "host")) |
| 584 | return -ENODEV; | 584 | return -ENODEV; |
| 585 | 585 | ||
| 586 | hcd = usb_create_hcd(&fhci_driver, dev, dev->bus_id); | 586 | hcd = usb_create_hcd(&fhci_driver, dev, dev_name(dev)); |
| 587 | if (!hcd) { | 587 | if (!hcd) { |
| 588 | dev_err(dev, "could not create hcd\n"); | 588 | dev_err(dev, "could not create hcd\n"); |
| 589 | return -ENOMEM; | 589 | return -ENOMEM; |
| @@ -650,7 +650,7 @@ static int __devinit of_fhci_probe(struct of_device *ofdev, | |||
| 650 | } | 650 | } |
| 651 | } | 651 | } |
| 652 | 652 | ||
| 653 | ret = gpio_request(gpio, dev->bus_id); | 653 | ret = gpio_request(gpio, dev_name(dev)); |
| 654 | if (ret) { | 654 | if (ret) { |
| 655 | dev_err(dev, "failed to request gpio %d", i); | 655 | dev_err(dev, "failed to request gpio %d", i); |
| 656 | goto err_gpios; | 656 | goto err_gpios; |
diff --git a/drivers/usb/host/hwa-hc.c b/drivers/usb/host/hwa-hc.c index 8582236e4cad..cbf30e515f29 100644 --- a/drivers/usb/host/hwa-hc.c +++ b/drivers/usb/host/hwa-hc.c | |||
| @@ -464,8 +464,7 @@ static int __hwahc_dev_set_key(struct wusbhc *wusbhc, u8 port_idx, u32 tkid, | |||
| 464 | port_idx << 8 | iface_no, | 464 | port_idx << 8 | iface_no, |
| 465 | keyd, keyd_len, 1000 /* FIXME: arbitrary */); | 465 | keyd, keyd_len, 1000 /* FIXME: arbitrary */); |
| 466 | 466 | ||
| 467 | memset(keyd, 0, sizeof(*keyd)); /* clear keys etc. */ | 467 | kzfree(keyd); /* clear keys etc. */ |
| 468 | kfree(keyd); | ||
| 469 | return result; | 468 | return result; |
| 470 | } | 469 | } |
| 471 | 470 | ||
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 4dda31b26892..a2b305477afe 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c | |||
| @@ -772,7 +772,7 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd, | |||
| 772 | break; | 772 | break; |
| 773 | case PIPE_INTERRUPT: | 773 | case PIPE_INTERRUPT: |
| 774 | urb->interval = ep->period; | 774 | urb->interval = ep->period; |
| 775 | ep->length = min((int)ep->maxpacket, | 775 | ep->length = min_t(u32, ep->maxpacket, |
| 776 | urb->transfer_buffer_length); | 776 | urb->transfer_buffer_length); |
| 777 | 777 | ||
| 778 | /* urb submitted for already existing endpoint */ | 778 | /* urb submitted for already existing endpoint */ |
diff --git a/drivers/usb/host/isp116x.h b/drivers/usb/host/isp116x.h index aa211bafcff9..12db961acdfb 100644 --- a/drivers/usb/host/isp116x.h +++ b/drivers/usb/host/isp116x.h | |||
| @@ -563,7 +563,7 @@ static void urb_dbg(struct urb *urb, char *msg) | |||
| 563 | */ | 563 | */ |
| 564 | static inline void dump_ptd(struct ptd *ptd) | 564 | static inline void dump_ptd(struct ptd *ptd) |
| 565 | { | 565 | { |
| 566 | printk("td: %x %d%c%d %d,%d,%d %x %x%x%x\n", | 566 | printk(KERN_WARNING "td: %x %d%c%d %d,%d,%d %x %x%x%x\n", |
| 567 | PTD_GET_CC(ptd), PTD_GET_FA(ptd), | 567 | PTD_GET_CC(ptd), PTD_GET_FA(ptd), |
| 568 | PTD_DIR_STR(ptd), PTD_GET_EP(ptd), | 568 | PTD_DIR_STR(ptd), PTD_GET_EP(ptd), |
| 569 | PTD_GET_COUNT(ptd), PTD_GET_LEN(ptd), PTD_GET_MPS(ptd), | 569 | PTD_GET_COUNT(ptd), PTD_GET_LEN(ptd), PTD_GET_MPS(ptd), |
| @@ -576,7 +576,7 @@ static inline void dump_ptd_out_data(struct ptd *ptd, u8 * buf) | |||
| 576 | int k; | 576 | int k; |
| 577 | 577 | ||
| 578 | if (PTD_GET_DIR(ptd) != PTD_DIR_IN && PTD_GET_LEN(ptd)) { | 578 | if (PTD_GET_DIR(ptd) != PTD_DIR_IN && PTD_GET_LEN(ptd)) { |
| 579 | printk("-> "); | 579 | printk(KERN_WARNING "-> "); |
| 580 | for (k = 0; k < PTD_GET_LEN(ptd); ++k) | 580 | for (k = 0; k < PTD_GET_LEN(ptd); ++k) |
| 581 | printk("%02x ", ((u8 *) buf)[k]); | 581 | printk("%02x ", ((u8 *) buf)[k]); |
| 582 | printk("\n"); | 582 | printk("\n"); |
| @@ -588,13 +588,13 @@ static inline void dump_ptd_in_data(struct ptd *ptd, u8 * buf) | |||
| 588 | int k; | 588 | int k; |
| 589 | 589 | ||
| 590 | if (PTD_GET_DIR(ptd) == PTD_DIR_IN && PTD_GET_COUNT(ptd)) { | 590 | if (PTD_GET_DIR(ptd) == PTD_DIR_IN && PTD_GET_COUNT(ptd)) { |
| 591 | printk("<- "); | 591 | printk(KERN_WARNING "<- "); |
| 592 | for (k = 0; k < PTD_GET_COUNT(ptd); ++k) | 592 | for (k = 0; k < PTD_GET_COUNT(ptd); ++k) |
| 593 | printk("%02x ", ((u8 *) buf)[k]); | 593 | printk("%02x ", ((u8 *) buf)[k]); |
| 594 | printk("\n"); | 594 | printk("\n"); |
| 595 | } | 595 | } |
| 596 | if (PTD_GET_LAST(ptd)) | 596 | if (PTD_GET_LAST(ptd)) |
| 597 | printk("-\n"); | 597 | printk(KERN_WARNING "-\n"); |
| 598 | } | 598 | } |
| 599 | 599 | ||
| 600 | #else | 600 | #else |
diff --git a/drivers/usb/host/isp1760-hcd.c b/drivers/usb/host/isp1760-hcd.c index b899f1a59c26..cd07ea3f0c63 100644 --- a/drivers/usb/host/isp1760-hcd.c +++ b/drivers/usb/host/isp1760-hcd.c | |||
| @@ -644,7 +644,7 @@ static void transform_add_int(struct isp1760_hcd *priv, struct isp1760_qh *qh, | |||
| 644 | 644 | ||
| 645 | if (urb->dev->speed != USB_SPEED_HIGH) { | 645 | if (urb->dev->speed != USB_SPEED_HIGH) { |
| 646 | /* split */ | 646 | /* split */ |
| 647 | ptd->dw5 = __constant_cpu_to_le32(0x1c); | 647 | ptd->dw5 = cpu_to_le32(0x1c); |
| 648 | 648 | ||
| 649 | if (qh->period >= 32) | 649 | if (qh->period >= 32) |
| 650 | period = qh->period / 2; | 650 | period = qh->period / 2; |
| @@ -819,6 +819,13 @@ static void enqueue_an_ATL_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, | |||
| 819 | u32 atl_regs, payload; | 819 | u32 atl_regs, payload; |
| 820 | u32 buffstatus; | 820 | u32 buffstatus; |
| 821 | 821 | ||
| 822 | /* | ||
| 823 | * When this function is called from the interrupt handler to enqueue | ||
| 824 | * a follow-up packet, the SKIP register gets written and read back | ||
| 825 | * almost immediately. With ISP1761, this register requires a delay of | ||
| 826 | * 195ns between a write and subsequent read (see section 15.1.1.3). | ||
| 827 | */ | ||
| 828 | ndelay(195); | ||
| 822 | skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG); | 829 | skip_map = isp1760_readl(hcd->regs + HC_ATL_PTD_SKIPMAP_REG); |
| 823 | 830 | ||
| 824 | BUG_ON(!skip_map); | 831 | BUG_ON(!skip_map); |
| @@ -853,6 +860,13 @@ static void enqueue_an_INT_packet(struct usb_hcd *hcd, struct isp1760_qh *qh, | |||
| 853 | u32 int_regs, payload; | 860 | u32 int_regs, payload; |
| 854 | u32 buffstatus; | 861 | u32 buffstatus; |
| 855 | 862 | ||
| 863 | /* | ||
| 864 | * When this function is called from the interrupt handler to enqueue | ||
| 865 | * a follow-up packet, the SKIP register gets written and read back | ||
| 866 | * almost immediately. With ISP1761, this register requires a delay of | ||
| 867 | * 195ns between a write and subsequent read (see section 15.1.1.3). | ||
| 868 | */ | ||
| 869 | ndelay(195); | ||
| 856 | skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG); | 870 | skip_map = isp1760_readl(hcd->regs + HC_INT_PTD_SKIPMAP_REG); |
| 857 | 871 | ||
| 858 | BUG_ON(!skip_map); | 872 | BUG_ON(!skip_map); |
| @@ -1054,7 +1068,7 @@ static void do_atl_int(struct usb_hcd *usb_hcd) | |||
| 1054 | priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs + | 1068 | priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs + |
| 1055 | atl_regs, sizeof(ptd)); | 1069 | atl_regs, sizeof(ptd)); |
| 1056 | 1070 | ||
| 1057 | ptd.dw0 |= __constant_cpu_to_le32(PTD_VALID); | 1071 | ptd.dw0 |= cpu_to_le32(PTD_VALID); |
| 1058 | priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs + | 1072 | priv_write_copy(priv, (u32 *)&ptd, usb_hcd->regs + |
| 1059 | atl_regs, sizeof(ptd)); | 1073 | atl_regs, sizeof(ptd)); |
| 1060 | 1074 | ||
| @@ -2235,9 +2249,10 @@ void deinit_kmem_cache(void) | |||
| 2235 | kmem_cache_destroy(qh_cachep); | 2249 | kmem_cache_destroy(qh_cachep); |
| 2236 | } | 2250 | } |
| 2237 | 2251 | ||
| 2238 | struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq, | 2252 | struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len, |
| 2239 | u64 irqflags, struct device *dev, const char *busname, | 2253 | int irq, unsigned long irqflags, |
| 2240 | unsigned int devflags) | 2254 | struct device *dev, const char *busname, |
| 2255 | unsigned int devflags) | ||
| 2241 | { | 2256 | { |
| 2242 | struct usb_hcd *hcd; | 2257 | struct usb_hcd *hcd; |
| 2243 | struct isp1760_hcd *priv; | 2258 | struct isp1760_hcd *priv; |
diff --git a/drivers/usb/host/isp1760-hcd.h b/drivers/usb/host/isp1760-hcd.h index a9daea587962..462f4943cb1b 100644 --- a/drivers/usb/host/isp1760-hcd.h +++ b/drivers/usb/host/isp1760-hcd.h | |||
| @@ -2,9 +2,10 @@ | |||
| 2 | #define _ISP1760_HCD_H_ | 2 | #define _ISP1760_HCD_H_ |
| 3 | 3 | ||
| 4 | /* exports for if */ | 4 | /* exports for if */ |
| 5 | struct usb_hcd *isp1760_register(u64 res_start, u64 res_len, int irq, | 5 | struct usb_hcd *isp1760_register(phys_addr_t res_start, resource_size_t res_len, |
| 6 | u64 irqflags, struct device *dev, const char *busname, | 6 | int irq, unsigned long irqflags, |
| 7 | unsigned int devflags); | 7 | struct device *dev, const char *busname, |
| 8 | unsigned int devflags); | ||
| 8 | int init_kmem_once(void); | 9 | int init_kmem_once(void); |
| 9 | void deinit_kmem_cache(void); | 10 | void deinit_kmem_cache(void); |
| 10 | 11 | ||
diff --git a/drivers/usb/host/isp1760-if.c b/drivers/usb/host/isp1760-if.c index 4cf7ca428b33..3fa3a1702796 100644 --- a/drivers/usb/host/isp1760-if.c +++ b/drivers/usb/host/isp1760-if.c | |||
| @@ -10,6 +10,7 @@ | |||
| 10 | 10 | ||
| 11 | #include <linux/usb.h> | 11 | #include <linux/usb.h> |
| 12 | #include <linux/io.h> | 12 | #include <linux/io.h> |
| 13 | #include <linux/platform_device.h> | ||
| 13 | 14 | ||
| 14 | #include "../core/hcd.h" | 15 | #include "../core/hcd.h" |
| 15 | #include "isp1760-hcd.h" | 16 | #include "isp1760-hcd.h" |
| @@ -300,39 +301,101 @@ static struct pci_driver isp1761_pci_driver = { | |||
| 300 | }; | 301 | }; |
| 301 | #endif | 302 | #endif |
| 302 | 303 | ||
| 304 | static int __devinit isp1760_plat_probe(struct platform_device *pdev) | ||
| 305 | { | ||
| 306 | int ret = 0; | ||
| 307 | struct usb_hcd *hcd; | ||
| 308 | struct resource *mem_res; | ||
| 309 | struct resource *irq_res; | ||
| 310 | resource_size_t mem_size; | ||
| 311 | unsigned long irqflags = IRQF_SHARED | IRQF_DISABLED; | ||
| 312 | |||
| 313 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 314 | if (!mem_res) { | ||
| 315 | pr_warning("isp1760: Memory resource not available\n"); | ||
| 316 | ret = -ENODEV; | ||
| 317 | goto out; | ||
| 318 | } | ||
| 319 | mem_size = resource_size(mem_res); | ||
| 320 | if (!request_mem_region(mem_res->start, mem_size, "isp1760")) { | ||
| 321 | pr_warning("isp1760: Cannot reserve the memory resource\n"); | ||
| 322 | ret = -EBUSY; | ||
| 323 | goto out; | ||
| 324 | } | ||
| 325 | |||
| 326 | irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | ||
| 327 | if (!irq_res) { | ||
| 328 | pr_warning("isp1760: IRQ resource not available\n"); | ||
| 329 | return -ENODEV; | ||
| 330 | } | ||
| 331 | irqflags |= irq_res->flags & IRQF_TRIGGER_MASK; | ||
| 332 | |||
| 333 | hcd = isp1760_register(mem_res->start, mem_size, irq_res->start, | ||
| 334 | irqflags, &pdev->dev, dev_name(&pdev->dev), 0); | ||
| 335 | if (IS_ERR(hcd)) { | ||
| 336 | pr_warning("isp1760: Failed to register the HCD device\n"); | ||
| 337 | ret = -ENODEV; | ||
| 338 | goto cleanup; | ||
| 339 | } | ||
| 340 | |||
| 341 | pr_info("ISP1760 USB device initialised\n"); | ||
| 342 | return ret; | ||
| 343 | |||
| 344 | cleanup: | ||
| 345 | release_mem_region(mem_res->start, mem_size); | ||
| 346 | out: | ||
| 347 | return ret; | ||
| 348 | } | ||
| 349 | |||
| 350 | static int __devexit isp1760_plat_remove(struct platform_device *pdev) | ||
| 351 | { | ||
| 352 | struct resource *mem_res; | ||
| 353 | resource_size_t mem_size; | ||
| 354 | |||
| 355 | mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
| 356 | mem_size = resource_size(mem_res); | ||
| 357 | release_mem_region(mem_res->start, mem_size); | ||
| 358 | |||
| 359 | return 0; | ||
| 360 | } | ||
| 361 | |||
| 362 | static struct platform_driver isp1760_plat_driver = { | ||
| 363 | .probe = isp1760_plat_probe, | ||
| 364 | .remove = isp1760_plat_remove, | ||
| 365 | .driver = { | ||
| 366 | .name = "isp1760", | ||
| 367 | }, | ||
| 368 | }; | ||
| 369 | |||
| 303 | static int __init isp1760_init(void) | 370 | static int __init isp1760_init(void) |
| 304 | { | 371 | { |
| 305 | int ret; | 372 | int ret, any_ret = -ENODEV; |
| 306 | 373 | ||
| 307 | init_kmem_once(); | 374 | init_kmem_once(); |
| 308 | 375 | ||
| 376 | ret = platform_driver_register(&isp1760_plat_driver); | ||
| 377 | if (!ret) | ||
| 378 | any_ret = 0; | ||
| 309 | #ifdef CONFIG_PPC_OF | 379 | #ifdef CONFIG_PPC_OF |
| 310 | ret = of_register_platform_driver(&isp1760_of_driver); | 380 | ret = of_register_platform_driver(&isp1760_of_driver); |
| 311 | if (ret) { | 381 | if (!ret) |
| 312 | deinit_kmem_cache(); | 382 | any_ret = 0; |
| 313 | return ret; | ||
| 314 | } | ||
| 315 | #endif | 383 | #endif |
| 316 | #ifdef CONFIG_PCI | 384 | #ifdef CONFIG_PCI |
| 317 | ret = pci_register_driver(&isp1761_pci_driver); | 385 | ret = pci_register_driver(&isp1761_pci_driver); |
| 318 | if (ret) | 386 | if (!ret) |
| 319 | goto unreg_of; | 387 | any_ret = 0; |
| 320 | #endif | 388 | #endif |
| 321 | return ret; | ||
| 322 | 389 | ||
| 323 | #ifdef CONFIG_PCI | 390 | if (any_ret) |
| 324 | unreg_of: | 391 | deinit_kmem_cache(); |
| 325 | #endif | 392 | return any_ret; |
| 326 | #ifdef CONFIG_PPC_OF | ||
| 327 | of_unregister_platform_driver(&isp1760_of_driver); | ||
| 328 | #endif | ||
| 329 | deinit_kmem_cache(); | ||
| 330 | return ret; | ||
| 331 | } | 393 | } |
| 332 | module_init(isp1760_init); | 394 | module_init(isp1760_init); |
| 333 | 395 | ||
| 334 | static void __exit isp1760_exit(void) | 396 | static void __exit isp1760_exit(void) |
| 335 | { | 397 | { |
| 398 | platform_driver_unregister(&isp1760_plat_driver); | ||
| 336 | #ifdef CONFIG_PPC_OF | 399 | #ifdef CONFIG_PPC_OF |
| 337 | of_unregister_platform_driver(&isp1760_of_driver); | 400 | of_unregister_platform_driver(&isp1760_of_driver); |
| 338 | #endif | 401 | #endif |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 5cf5f1eca4f4..25db704f3a2a 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
| @@ -997,7 +997,7 @@ MODULE_LICENSE ("GPL"); | |||
| 997 | #define SA1111_DRIVER ohci_hcd_sa1111_driver | 997 | #define SA1111_DRIVER ohci_hcd_sa1111_driver |
| 998 | #endif | 998 | #endif |
| 999 | 999 | ||
| 1000 | #ifdef CONFIG_ARCH_S3C2410 | 1000 | #if defined(CONFIG_ARCH_S3C2410) || defined(CONFIG_ARCH_S3C64XX) |
| 1001 | #include "ohci-s3c2410.c" | 1001 | #include "ohci-s3c2410.c" |
| 1002 | #define PLATFORM_DRIVER ohci_hcd_s3c2410_driver | 1002 | #define PLATFORM_DRIVER ohci_hcd_s3c2410_driver |
| 1003 | #endif | 1003 | #endif |
| @@ -1049,7 +1049,8 @@ MODULE_LICENSE ("GPL"); | |||
| 1049 | 1049 | ||
| 1050 | #if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 1050 | #if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
| 1051 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ | 1051 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ |
| 1052 | defined(CONFIG_CPU_SUBTYPE_SH7763) | 1052 | defined(CONFIG_CPU_SUBTYPE_SH7763) || \ |
| 1053 | defined(CONFIG_CPU_SUBTYPE_SH7786) | ||
| 1053 | #include "ohci-sh.c" | 1054 | #include "ohci-sh.c" |
| 1054 | #define PLATFORM_DRIVER ohci_hcd_sh_driver | 1055 | #define PLATFORM_DRIVER ohci_hcd_sh_driver |
| 1055 | #endif | 1056 | #endif |
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index f46af7a718d4..a68af2dd55ca 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c | |||
| @@ -21,9 +21,7 @@ | |||
| 21 | 21 | ||
| 22 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
| 23 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
| 24 | 24 | #include <plat/usb-control.h> | |
| 25 | #include <mach/hardware.h> | ||
| 26 | #include <mach/usb-control.h> | ||
| 27 | 25 | ||
| 28 | #define valid_port(idx) ((idx) == 1 || (idx) == 2) | 26 | #define valid_port(idx) ((idx) == 1 || (idx) == 2) |
| 29 | 27 | ||
| @@ -372,7 +370,7 @@ static int usb_hcd_s3c2410_probe (const struct hc_driver *driver, | |||
| 372 | 370 | ||
| 373 | usb_clk = clk_get(&dev->dev, "usb-bus-host"); | 371 | usb_clk = clk_get(&dev->dev, "usb-bus-host"); |
| 374 | if (IS_ERR(usb_clk)) { | 372 | if (IS_ERR(usb_clk)) { |
| 375 | dev_err(&dev->dev, "cannot get usb-host clock\n"); | 373 | dev_err(&dev->dev, "cannot get usb-bus-host clock\n"); |
| 376 | retval = -ENOENT; | 374 | retval = -ENOENT; |
| 377 | goto err_clk; | 375 | goto err_clk; |
| 378 | } | 376 | } |
diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index 75548f7c716b..5ac489ee3dab 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c | |||
| @@ -845,14 +845,14 @@ static inline void qh_update(struct oxu_hcd *oxu, | |||
| 845 | is_out = !(qtd->hw_token & cpu_to_le32(1 << 8)); | 845 | is_out = !(qtd->hw_token & cpu_to_le32(1 << 8)); |
| 846 | epnum = (le32_to_cpup(&qh->hw_info1) >> 8) & 0x0f; | 846 | epnum = (le32_to_cpup(&qh->hw_info1) >> 8) & 0x0f; |
| 847 | if (unlikely(!usb_gettoggle(qh->dev, epnum, is_out))) { | 847 | if (unlikely(!usb_gettoggle(qh->dev, epnum, is_out))) { |
| 848 | qh->hw_token &= ~__constant_cpu_to_le32(QTD_TOGGLE); | 848 | qh->hw_token &= ~cpu_to_le32(QTD_TOGGLE); |
| 849 | usb_settoggle(qh->dev, epnum, is_out, 1); | 849 | usb_settoggle(qh->dev, epnum, is_out, 1); |
| 850 | } | 850 | } |
| 851 | } | 851 | } |
| 852 | 852 | ||
| 853 | /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */ | 853 | /* HC must see latest qtd and qh data before we clear ACTIVE+HALT */ |
| 854 | wmb(); | 854 | wmb(); |
| 855 | qh->hw_token &= __constant_cpu_to_le32(QTD_TOGGLE | QTD_STS_PING); | 855 | qh->hw_token &= cpu_to_le32(QTD_TOGGLE | QTD_STS_PING); |
| 856 | } | 856 | } |
| 857 | 857 | ||
| 858 | /* If it weren't for a common silicon quirk (writing the dummy into the qh | 858 | /* If it weren't for a common silicon quirk (writing the dummy into the qh |
| @@ -937,7 +937,7 @@ __acquires(oxu->lock) | |||
| 937 | struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv; | 937 | struct ehci_qh *qh = (struct ehci_qh *) urb->hcpriv; |
| 938 | 938 | ||
| 939 | /* S-mask in a QH means it's an interrupt urb */ | 939 | /* S-mask in a QH means it's an interrupt urb */ |
| 940 | if ((qh->hw_info2 & __constant_cpu_to_le32(QH_SMASK)) != 0) { | 940 | if ((qh->hw_info2 & cpu_to_le32(QH_SMASK)) != 0) { |
| 941 | 941 | ||
| 942 | /* ... update hc-wide periodic stats (for usbfs) */ | 942 | /* ... update hc-wide periodic stats (for usbfs) */ |
| 943 | oxu_to_hcd(oxu)->self.bandwidth_int_reqs--; | 943 | oxu_to_hcd(oxu)->self.bandwidth_int_reqs--; |
| @@ -981,7 +981,7 @@ static void unlink_async(struct oxu_hcd *oxu, struct ehci_qh *qh); | |||
| 981 | static void intr_deschedule(struct oxu_hcd *oxu, struct ehci_qh *qh); | 981 | static void intr_deschedule(struct oxu_hcd *oxu, struct ehci_qh *qh); |
| 982 | static int qh_schedule(struct oxu_hcd *oxu, struct ehci_qh *qh); | 982 | static int qh_schedule(struct oxu_hcd *oxu, struct ehci_qh *qh); |
| 983 | 983 | ||
| 984 | #define HALT_BIT __constant_cpu_to_le32(QTD_STS_HALT) | 984 | #define HALT_BIT cpu_to_le32(QTD_STS_HALT) |
| 985 | 985 | ||
| 986 | /* Process and free completed qtds for a qh, returning URBs to drivers. | 986 | /* Process and free completed qtds for a qh, returning URBs to drivers. |
| 987 | * Chases up to qh->hw_current. Returns number of completions called, | 987 | * Chases up to qh->hw_current. Returns number of completions called, |
| @@ -1160,7 +1160,7 @@ halt: | |||
| 1160 | /* should be rare for periodic transfers, | 1160 | /* should be rare for periodic transfers, |
| 1161 | * except maybe high bandwidth ... | 1161 | * except maybe high bandwidth ... |
| 1162 | */ | 1162 | */ |
| 1163 | if ((__constant_cpu_to_le32(QH_SMASK) | 1163 | if ((cpu_to_le32(QH_SMASK) |
| 1164 | & qh->hw_info2) != 0) { | 1164 | & qh->hw_info2) != 0) { |
| 1165 | intr_deschedule(oxu, qh); | 1165 | intr_deschedule(oxu, qh); |
| 1166 | (void) qh_schedule(oxu, qh); | 1166 | (void) qh_schedule(oxu, qh); |
| @@ -1350,7 +1350,7 @@ static struct list_head *qh_urb_transaction(struct oxu_hcd *oxu, | |||
| 1350 | } | 1350 | } |
| 1351 | 1351 | ||
| 1352 | /* by default, enable interrupt on urb completion */ | 1352 | /* by default, enable interrupt on urb completion */ |
| 1353 | qtd->hw_token |= __constant_cpu_to_le32(QTD_IOC); | 1353 | qtd->hw_token |= cpu_to_le32(QTD_IOC); |
| 1354 | return head; | 1354 | return head; |
| 1355 | 1355 | ||
| 1356 | cleanup: | 1356 | cleanup: |
| @@ -1539,7 +1539,7 @@ static void qh_link_async(struct oxu_hcd *oxu, struct ehci_qh *qh) | |||
| 1539 | /* qtd completions reported later by interrupt */ | 1539 | /* qtd completions reported later by interrupt */ |
| 1540 | } | 1540 | } |
| 1541 | 1541 | ||
| 1542 | #define QH_ADDR_MASK __constant_cpu_to_le32(0x7f) | 1542 | #define QH_ADDR_MASK cpu_to_le32(0x7f) |
| 1543 | 1543 | ||
| 1544 | /* | 1544 | /* |
| 1545 | * For control/bulk/interrupt, return QH with these TDs appended. | 1545 | * For control/bulk/interrupt, return QH with these TDs appended. |
| @@ -2012,7 +2012,7 @@ static void qh_unlink_periodic(struct oxu_hcd *oxu, struct ehci_qh *qh) | |||
| 2012 | * and this qh is active in the current uframe | 2012 | * and this qh is active in the current uframe |
| 2013 | * (and overlay token SplitXstate is false?) | 2013 | * (and overlay token SplitXstate is false?) |
| 2014 | * THEN | 2014 | * THEN |
| 2015 | * qh->hw_info1 |= __constant_cpu_to_le32(1 << 7 "ignore"); | 2015 | * qh->hw_info1 |= cpu_to_le32(1 << 7 "ignore"); |
| 2016 | */ | 2016 | */ |
| 2017 | 2017 | ||
| 2018 | /* high bandwidth, or otherwise part of every microframe */ | 2018 | /* high bandwidth, or otherwise part of every microframe */ |
| @@ -2057,7 +2057,7 @@ static void intr_deschedule(struct oxu_hcd *oxu, struct ehci_qh *qh) | |||
| 2057 | * active high speed queues may need bigger delays... | 2057 | * active high speed queues may need bigger delays... |
| 2058 | */ | 2058 | */ |
| 2059 | if (list_empty(&qh->qtd_list) | 2059 | if (list_empty(&qh->qtd_list) |
| 2060 | || (__constant_cpu_to_le32(QH_CMASK) & qh->hw_info2) != 0) | 2060 | || (cpu_to_le32(QH_CMASK) & qh->hw_info2) != 0) |
| 2061 | wait = 2; | 2061 | wait = 2; |
| 2062 | else | 2062 | else |
| 2063 | wait = 55; /* worst case: 3 * 1024 */ | 2063 | wait = 55; /* worst case: 3 * 1024 */ |
| @@ -2183,10 +2183,10 @@ static int qh_schedule(struct oxu_hcd *oxu, struct ehci_qh *qh) | |||
| 2183 | qh->start = frame; | 2183 | qh->start = frame; |
| 2184 | 2184 | ||
| 2185 | /* reset S-frame and (maybe) C-frame masks */ | 2185 | /* reset S-frame and (maybe) C-frame masks */ |
| 2186 | qh->hw_info2 &= __constant_cpu_to_le32(~(QH_CMASK | QH_SMASK)); | 2186 | qh->hw_info2 &= cpu_to_le32(~(QH_CMASK | QH_SMASK)); |
| 2187 | qh->hw_info2 |= qh->period | 2187 | qh->hw_info2 |= qh->period |
| 2188 | ? cpu_to_le32(1 << uframe) | 2188 | ? cpu_to_le32(1 << uframe) |
| 2189 | : __constant_cpu_to_le32(QH_SMASK); | 2189 | : cpu_to_le32(QH_SMASK); |
| 2190 | qh->hw_info2 |= c_mask; | 2190 | qh->hw_info2 |= c_mask; |
| 2191 | } else | 2191 | } else |
| 2192 | oxu_dbg(oxu, "reused qh %p schedule\n", qh); | 2192 | oxu_dbg(oxu, "reused qh %p schedule\n", qh); |
| @@ -2684,7 +2684,7 @@ static int oxu_reset(struct usb_hcd *hcd) | |||
| 2684 | oxu->urb_len = 0; | 2684 | oxu->urb_len = 0; |
| 2685 | 2685 | ||
| 2686 | /* FIMXE */ | 2686 | /* FIMXE */ |
| 2687 | hcd->self.controller->dma_mask = 0UL; | 2687 | hcd->self.controller->dma_mask = NULL; |
| 2688 | 2688 | ||
| 2689 | if (oxu->is_otg) { | 2689 | if (oxu->is_otg) { |
| 2690 | oxu->caps = hcd->regs + OXU_OTG_CAP_OFFSET; | 2690 | oxu->caps = hcd->regs + OXU_OTG_CAP_OFFSET; |
diff --git a/drivers/usb/host/oxu210hp.h b/drivers/usb/host/oxu210hp.h index 8910e271cc7d..1c216ad9aad2 100644 --- a/drivers/usb/host/oxu210hp.h +++ b/drivers/usb/host/oxu210hp.h | |||
| @@ -235,21 +235,21 @@ struct ehci_qtd { | |||
| 235 | } __attribute__ ((aligned(32))); | 235 | } __attribute__ ((aligned(32))); |
| 236 | 236 | ||
| 237 | /* mask NakCnt+T in qh->hw_alt_next */ | 237 | /* mask NakCnt+T in qh->hw_alt_next */ |
| 238 | #define QTD_MASK __constant_cpu_to_le32 (~0x1f) | 238 | #define QTD_MASK cpu_to_le32 (~0x1f) |
| 239 | 239 | ||
| 240 | #define IS_SHORT_READ(token) (QTD_LENGTH(token) != 0 && QTD_PID(token) == 1) | 240 | #define IS_SHORT_READ(token) (QTD_LENGTH(token) != 0 && QTD_PID(token) == 1) |
| 241 | 241 | ||
| 242 | /* Type tag from {qh, itd, sitd, fstn}->hw_next */ | 242 | /* Type tag from {qh, itd, sitd, fstn}->hw_next */ |
| 243 | #define Q_NEXT_TYPE(dma) ((dma) & __constant_cpu_to_le32 (3 << 1)) | 243 | #define Q_NEXT_TYPE(dma) ((dma) & cpu_to_le32 (3 << 1)) |
| 244 | 244 | ||
| 245 | /* values for that type tag */ | 245 | /* values for that type tag */ |
| 246 | #define Q_TYPE_QH __constant_cpu_to_le32 (1 << 1) | 246 | #define Q_TYPE_QH cpu_to_le32 (1 << 1) |
| 247 | 247 | ||
| 248 | /* next async queue entry, or pointer to interrupt/periodic QH */ | 248 | /* next async queue entry, or pointer to interrupt/periodic QH */ |
| 249 | #define QH_NEXT(dma) (cpu_to_le32(((u32)dma)&~0x01f)|Q_TYPE_QH) | 249 | #define QH_NEXT(dma) (cpu_to_le32(((u32)dma)&~0x01f)|Q_TYPE_QH) |
| 250 | 250 | ||
| 251 | /* for periodic/async schedules and qtd lists, mark end of list */ | 251 | /* for periodic/async schedules and qtd lists, mark end of list */ |
| 252 | #define EHCI_LIST_END __constant_cpu_to_le32(1) /* "null pointer" to hw */ | 252 | #define EHCI_LIST_END cpu_to_le32(1) /* "null pointer" to hw */ |
| 253 | 253 | ||
| 254 | /* | 254 | /* |
| 255 | * Entries in periodic shadow table are pointers to one of four kinds | 255 | * Entries in periodic shadow table are pointers to one of four kinds |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index 75b69847918e..033c2846ce59 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
| @@ -234,7 +234,7 @@ static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) | |||
| 234 | */ | 234 | */ |
| 235 | hcc_params = readl(base + EHCI_HCC_PARAMS); | 235 | hcc_params = readl(base + EHCI_HCC_PARAMS); |
| 236 | offset = (hcc_params >> 8) & 0xff; | 236 | offset = (hcc_params >> 8) & 0xff; |
| 237 | while (offset && count--) { | 237 | while (offset && --count) { |
| 238 | u32 cap; | 238 | u32 cap; |
| 239 | int msec; | 239 | int msec; |
| 240 | 240 | ||
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index 319041205b57..f1626e58c141 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c | |||
| @@ -660,9 +660,9 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597, | |||
| 660 | u16 array[R8A66597_MAX_NUM_PIPE], i = 0, min; | 660 | u16 array[R8A66597_MAX_NUM_PIPE], i = 0, min; |
| 661 | 661 | ||
| 662 | memset(array, 0, sizeof(array)); | 662 | memset(array, 0, sizeof(array)); |
| 663 | switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | 663 | switch (usb_endpoint_type(ep)) { |
| 664 | case USB_ENDPOINT_XFER_BULK: | 664 | case USB_ENDPOINT_XFER_BULK: |
| 665 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 665 | if (usb_endpoint_dir_in(ep)) |
| 666 | array[i++] = 4; | 666 | array[i++] = 4; |
| 667 | else { | 667 | else { |
| 668 | array[i++] = 3; | 668 | array[i++] = 3; |
| @@ -670,7 +670,7 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597, | |||
| 670 | } | 670 | } |
| 671 | break; | 671 | break; |
| 672 | case USB_ENDPOINT_XFER_INT: | 672 | case USB_ENDPOINT_XFER_INT: |
| 673 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) { | 673 | if (usb_endpoint_dir_in(ep)) { |
| 674 | array[i++] = 6; | 674 | array[i++] = 6; |
| 675 | array[i++] = 7; | 675 | array[i++] = 7; |
| 676 | array[i++] = 8; | 676 | array[i++] = 8; |
| @@ -678,7 +678,7 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597, | |||
| 678 | array[i++] = 9; | 678 | array[i++] = 9; |
| 679 | break; | 679 | break; |
| 680 | case USB_ENDPOINT_XFER_ISOC: | 680 | case USB_ENDPOINT_XFER_ISOC: |
| 681 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 681 | if (usb_endpoint_dir_in(ep)) |
| 682 | array[i++] = 2; | 682 | array[i++] = 2; |
| 683 | else | 683 | else |
| 684 | array[i++] = 1; | 684 | array[i++] = 1; |
| @@ -928,10 +928,9 @@ static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb, | |||
| 928 | 928 | ||
| 929 | info.pipenum = get_empty_pipenum(r8a66597, ep); | 929 | info.pipenum = get_empty_pipenum(r8a66597, ep); |
| 930 | info.address = get_urb_to_r8a66597_addr(r8a66597, urb); | 930 | info.address = get_urb_to_r8a66597_addr(r8a66597, urb); |
| 931 | info.epnum = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; | 931 | info.epnum = usb_endpoint_num(ep); |
| 932 | info.maxpacket = le16_to_cpu(ep->wMaxPacketSize); | 932 | info.maxpacket = le16_to_cpu(ep->wMaxPacketSize); |
| 933 | info.type = get_r8a66597_type(ep->bmAttributes | 933 | info.type = get_r8a66597_type(usb_endpoint_type(ep)); |
| 934 | & USB_ENDPOINT_XFERTYPE_MASK); | ||
| 935 | info.bufnum = get_bufnum(info.pipenum); | 934 | info.bufnum = get_bufnum(info.pipenum); |
| 936 | info.buf_bsize = get_buf_bsize(info.pipenum); | 935 | info.buf_bsize = get_buf_bsize(info.pipenum); |
| 937 | if (info.type == R8A66597_BULK) { | 936 | if (info.type == R8A66597_BULK) { |
| @@ -941,7 +940,7 @@ static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb, | |||
| 941 | info.interval = get_interval(urb, ep->bInterval); | 940 | info.interval = get_interval(urb, ep->bInterval); |
| 942 | info.timer_interval = get_timer_interval(urb, ep->bInterval); | 941 | info.timer_interval = get_timer_interval(urb, ep->bInterval); |
| 943 | } | 942 | } |
| 944 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 943 | if (usb_endpoint_dir_in(ep)) |
| 945 | info.dir_in = 1; | 944 | info.dir_in = 1; |
| 946 | else | 945 | else |
| 947 | info.dir_in = 0; | 946 | info.dir_in = 0; |
| @@ -1014,6 +1013,9 @@ static void r8a66597_check_syssts(struct r8a66597 *r8a66597, int port, | |||
| 1014 | 1013 | ||
| 1015 | r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port)); | 1014 | r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port)); |
| 1016 | r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port)); | 1015 | r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port)); |
| 1016 | |||
| 1017 | if (r8a66597->bus_suspended) | ||
| 1018 | usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597)); | ||
| 1017 | } | 1019 | } |
| 1018 | 1020 | ||
| 1019 | /* this function must be called with interrupt disabled */ | 1021 | /* this function must be called with interrupt disabled */ |
| @@ -1395,7 +1397,7 @@ static void packet_write(struct r8a66597 *r8a66597, u16 pipenum) | |||
| 1395 | (int)urb->iso_frame_desc[td->iso_cnt].length); | 1397 | (int)urb->iso_frame_desc[td->iso_cnt].length); |
| 1396 | } else { | 1398 | } else { |
| 1397 | buf = (u16 *)(urb->transfer_buffer + urb->actual_length); | 1399 | buf = (u16 *)(urb->transfer_buffer + urb->actual_length); |
| 1398 | size = min((int)bufsize, | 1400 | size = min_t(u32, bufsize, |
| 1399 | urb->transfer_buffer_length - urb->actual_length); | 1401 | urb->transfer_buffer_length - urb->actual_length); |
| 1400 | } | 1402 | } |
| 1401 | 1403 | ||
| @@ -1615,6 +1617,11 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) | |||
| 1615 | r8a66597_bclr(r8a66597, DTCHE, INTENB2); | 1617 | r8a66597_bclr(r8a66597, DTCHE, INTENB2); |
| 1616 | r8a66597_usb_disconnect(r8a66597, 1); | 1618 | r8a66597_usb_disconnect(r8a66597, 1); |
| 1617 | } | 1619 | } |
| 1620 | if (mask2 & BCHG) { | ||
| 1621 | r8a66597_write(r8a66597, ~BCHG, INTSTS2); | ||
| 1622 | r8a66597_bclr(r8a66597, BCHGE, INTENB2); | ||
| 1623 | usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597)); | ||
| 1624 | } | ||
| 1618 | } | 1625 | } |
| 1619 | 1626 | ||
| 1620 | if (mask1) { | 1627 | if (mask1) { |
| @@ -1630,6 +1637,12 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) | |||
| 1630 | r8a66597_bclr(r8a66597, DTCHE, INTENB1); | 1637 | r8a66597_bclr(r8a66597, DTCHE, INTENB1); |
| 1631 | r8a66597_usb_disconnect(r8a66597, 0); | 1638 | r8a66597_usb_disconnect(r8a66597, 0); |
| 1632 | } | 1639 | } |
| 1640 | if (mask1 & BCHG) { | ||
| 1641 | r8a66597_write(r8a66597, ~BCHG, INTSTS1); | ||
| 1642 | r8a66597_bclr(r8a66597, BCHGE, INTENB1); | ||
| 1643 | usb_hcd_resume_root_hub(r8a66597_to_hcd(r8a66597)); | ||
| 1644 | } | ||
| 1645 | |||
| 1633 | if (mask1 & SIGN) { | 1646 | if (mask1 & SIGN) { |
| 1634 | r8a66597_write(r8a66597, ~SIGN, INTSTS1); | 1647 | r8a66597_write(r8a66597, ~SIGN, INTSTS1); |
| 1635 | status = get_urb_error(r8a66597, 0); | 1648 | status = get_urb_error(r8a66597, 0); |
| @@ -2141,7 +2154,7 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
| 2141 | 2154 | ||
| 2142 | switch (wValue) { | 2155 | switch (wValue) { |
| 2143 | case USB_PORT_FEAT_ENABLE: | 2156 | case USB_PORT_FEAT_ENABLE: |
| 2144 | rh->port &= (1 << USB_PORT_FEAT_POWER); | 2157 | rh->port &= ~(1 << USB_PORT_FEAT_POWER); |
| 2145 | break; | 2158 | break; |
| 2146 | case USB_PORT_FEAT_SUSPEND: | 2159 | case USB_PORT_FEAT_SUSPEND: |
| 2147 | break; | 2160 | break; |
| @@ -2213,6 +2226,68 @@ error: | |||
| 2213 | return ret; | 2226 | return ret; |
| 2214 | } | 2227 | } |
| 2215 | 2228 | ||
| 2229 | #if defined(CONFIG_PM) | ||
| 2230 | static int r8a66597_bus_suspend(struct usb_hcd *hcd) | ||
| 2231 | { | ||
| 2232 | struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); | ||
| 2233 | int port; | ||
| 2234 | |||
| 2235 | dbg("%s", __func__); | ||
| 2236 | |||
| 2237 | for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) { | ||
| 2238 | struct r8a66597_root_hub *rh = &r8a66597->root_hub[port]; | ||
| 2239 | unsigned long dvstctr_reg = get_dvstctr_reg(port); | ||
| 2240 | |||
| 2241 | if (!(rh->port & (1 << USB_PORT_FEAT_ENABLE))) | ||
| 2242 | continue; | ||
| 2243 | |||
| 2244 | dbg("suspend port = %d", port); | ||
| 2245 | r8a66597_bclr(r8a66597, UACT, dvstctr_reg); /* suspend */ | ||
| 2246 | rh->port |= 1 << USB_PORT_FEAT_SUSPEND; | ||
| 2247 | |||
| 2248 | if (rh->dev->udev->do_remote_wakeup) { | ||
| 2249 | msleep(3); /* waiting last SOF */ | ||
| 2250 | r8a66597_bset(r8a66597, RWUPE, dvstctr_reg); | ||
| 2251 | r8a66597_write(r8a66597, ~BCHG, get_intsts_reg(port)); | ||
| 2252 | r8a66597_bset(r8a66597, BCHGE, get_intenb_reg(port)); | ||
| 2253 | } | ||
| 2254 | } | ||
| 2255 | |||
| 2256 | r8a66597->bus_suspended = 1; | ||
| 2257 | |||
| 2258 | return 0; | ||
| 2259 | } | ||
| 2260 | |||
| 2261 | static int r8a66597_bus_resume(struct usb_hcd *hcd) | ||
| 2262 | { | ||
| 2263 | struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); | ||
| 2264 | int port; | ||
| 2265 | |||
| 2266 | dbg("%s", __func__); | ||
| 2267 | |||
| 2268 | for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) { | ||
| 2269 | struct r8a66597_root_hub *rh = &r8a66597->root_hub[port]; | ||
| 2270 | unsigned long dvstctr_reg = get_dvstctr_reg(port); | ||
| 2271 | |||
| 2272 | if (!(rh->port & (1 << USB_PORT_FEAT_SUSPEND))) | ||
| 2273 | continue; | ||
| 2274 | |||
| 2275 | dbg("resume port = %d", port); | ||
| 2276 | rh->port &= ~(1 << USB_PORT_FEAT_SUSPEND); | ||
| 2277 | rh->port |= 1 << USB_PORT_FEAT_C_SUSPEND; | ||
| 2278 | r8a66597_mdfy(r8a66597, RESUME, RESUME | UACT, dvstctr_reg); | ||
| 2279 | msleep(50); | ||
| 2280 | r8a66597_mdfy(r8a66597, UACT, RESUME | UACT, dvstctr_reg); | ||
| 2281 | } | ||
| 2282 | |||
| 2283 | return 0; | ||
| 2284 | |||
| 2285 | } | ||
| 2286 | #else | ||
| 2287 | #define r8a66597_bus_suspend NULL | ||
| 2288 | #define r8a66597_bus_resume NULL | ||
| 2289 | #endif | ||
| 2290 | |||
| 2216 | static struct hc_driver r8a66597_hc_driver = { | 2291 | static struct hc_driver r8a66597_hc_driver = { |
| 2217 | .description = hcd_name, | 2292 | .description = hcd_name, |
| 2218 | .hcd_priv_size = sizeof(struct r8a66597), | 2293 | .hcd_priv_size = sizeof(struct r8a66597), |
| @@ -2243,16 +2318,39 @@ static struct hc_driver r8a66597_hc_driver = { | |||
| 2243 | */ | 2318 | */ |
| 2244 | .hub_status_data = r8a66597_hub_status_data, | 2319 | .hub_status_data = r8a66597_hub_status_data, |
| 2245 | .hub_control = r8a66597_hub_control, | 2320 | .hub_control = r8a66597_hub_control, |
| 2321 | .bus_suspend = r8a66597_bus_suspend, | ||
| 2322 | .bus_resume = r8a66597_bus_resume, | ||
| 2246 | }; | 2323 | }; |
| 2247 | 2324 | ||
| 2248 | #if defined(CONFIG_PM) | 2325 | #if defined(CONFIG_PM) |
| 2249 | static int r8a66597_suspend(struct platform_device *pdev, pm_message_t state) | 2326 | static int r8a66597_suspend(struct platform_device *pdev, pm_message_t state) |
| 2250 | { | 2327 | { |
| 2328 | struct r8a66597 *r8a66597 = dev_get_drvdata(&pdev->dev); | ||
| 2329 | int port; | ||
| 2330 | |||
| 2331 | dbg("%s", __func__); | ||
| 2332 | |||
| 2333 | disable_controller(r8a66597); | ||
| 2334 | |||
| 2335 | for (port = 0; port < R8A66597_MAX_ROOT_HUB; port++) { | ||
| 2336 | struct r8a66597_root_hub *rh = &r8a66597->root_hub[port]; | ||
| 2337 | |||
| 2338 | rh->port = 0x00000000; | ||
| 2339 | } | ||
| 2340 | |||
| 2251 | return 0; | 2341 | return 0; |
| 2252 | } | 2342 | } |
| 2253 | 2343 | ||
| 2254 | static int r8a66597_resume(struct platform_device *pdev) | 2344 | static int r8a66597_resume(struct platform_device *pdev) |
| 2255 | { | 2345 | { |
| 2346 | struct r8a66597 *r8a66597 = dev_get_drvdata(&pdev->dev); | ||
| 2347 | struct usb_hcd *hcd = r8a66597_to_hcd(r8a66597); | ||
| 2348 | |||
| 2349 | dbg("%s", __func__); | ||
| 2350 | |||
| 2351 | enable_controller(r8a66597); | ||
| 2352 | usb_root_hub_lost_power(hcd->self.root_hub); | ||
| 2353 | |||
| 2256 | return 0; | 2354 | return 0; |
| 2257 | } | 2355 | } |
| 2258 | #else /* if defined(CONFIG_PM) */ | 2356 | #else /* if defined(CONFIG_PM) */ |
diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h index ecacde4d69b0..f49208f1bb74 100644 --- a/drivers/usb/host/r8a66597.h +++ b/drivers/usb/host/r8a66597.h | |||
| @@ -504,6 +504,8 @@ struct r8a66597 { | |||
| 504 | 504 | ||
| 505 | struct list_head child_device; | 505 | struct list_head child_device; |
| 506 | unsigned long child_connect_map[4]; | 506 | unsigned long child_connect_map[4]; |
| 507 | |||
| 508 | unsigned bus_suspended:1; | ||
| 507 | }; | 509 | }; |
| 508 | 510 | ||
| 509 | static inline struct r8a66597 *hcd_to_r8a66597(struct usb_hcd *hcd) | 511 | static inline struct r8a66597 *hcd_to_r8a66597(struct usb_hcd *hcd) |
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index e106e9d48d4a..a949259f18b9 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
| @@ -230,7 +230,7 @@ static void in_packet( | |||
| 230 | writeb(usb_pipedevice(urb->pipe), data_reg); | 230 | writeb(usb_pipedevice(urb->pipe), data_reg); |
| 231 | 231 | ||
| 232 | sl811_write(sl811, bank + SL11H_HOSTCTLREG, control); | 232 | sl811_write(sl811, bank + SL11H_HOSTCTLREG, control); |
| 233 | ep->length = min((int)len, | 233 | ep->length = min_t(u32, len, |
| 234 | urb->transfer_buffer_length - urb->actual_length); | 234 | urb->transfer_buffer_length - urb->actual_length); |
| 235 | PACKET("IN%s/%d qh%p len%d\n", ep->nak_count ? "/retry" : "", | 235 | PACKET("IN%s/%d qh%p len%d\n", ep->nak_count ? "/retry" : "", |
| 236 | !!usb_gettoggle(urb->dev, ep->epnum, 0), ep, len); | 236 | !!usb_gettoggle(urb->dev, ep->epnum, 0), ep, len); |
| @@ -255,7 +255,7 @@ static void out_packet( | |||
| 255 | buf = urb->transfer_buffer + urb->actual_length; | 255 | buf = urb->transfer_buffer + urb->actual_length; |
| 256 | prefetch(buf); | 256 | prefetch(buf); |
| 257 | 257 | ||
| 258 | len = min((int)ep->maxpacket, | 258 | len = min_t(u32, ep->maxpacket, |
| 259 | urb->transfer_buffer_length - urb->actual_length); | 259 | urb->transfer_buffer_length - urb->actual_length); |
| 260 | 260 | ||
| 261 | if (!(control & SL11H_HCTLMASK_ISOCH) | 261 | if (!(control & SL11H_HCTLMASK_ISOCH) |
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 20cc58b97807..e52b954dda47 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c | |||
| @@ -118,7 +118,9 @@ static int uhci_show_urbp(struct urb_priv *urbp, char *buf, int len, int space) | |||
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | out += sprintf(out, "%s%s", ptype, (urbp->fsbr ? " FSBR" : "")); | 120 | out += sprintf(out, "%s%s", ptype, (urbp->fsbr ? " FSBR" : "")); |
| 121 | out += sprintf(out, " Actlen=%d", urbp->urb->actual_length); | 121 | out += sprintf(out, " Actlen=%d%s", urbp->urb->actual_length, |
| 122 | (urbp->qh->type == USB_ENDPOINT_XFER_CONTROL ? | ||
| 123 | "-8" : "")); | ||
| 122 | 124 | ||
| 123 | if (urbp->urb->unlinked) | 125 | if (urbp->urb->unlinked) |
| 124 | out += sprintf(out, " Unlinked=%d", urbp->urb->unlinked); | 126 | out += sprintf(out, " Unlinked=%d", urbp->urb->unlinked); |
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 7d01c5677f92..26bd1b2bcbfc 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h | |||
| @@ -73,11 +73,11 @@ | |||
| 73 | #define USBLEGSUP_RWC 0x8f00 /* the R/WC bits */ | 73 | #define USBLEGSUP_RWC 0x8f00 /* the R/WC bits */ |
| 74 | #define USBLEGSUP_RO 0x5040 /* R/O and reserved bits */ | 74 | #define USBLEGSUP_RO 0x5040 /* R/O and reserved bits */ |
| 75 | 75 | ||
| 76 | #define UHCI_PTR_BITS __constant_cpu_to_le32(0x000F) | 76 | #define UHCI_PTR_BITS cpu_to_le32(0x000F) |
| 77 | #define UHCI_PTR_TERM __constant_cpu_to_le32(0x0001) | 77 | #define UHCI_PTR_TERM cpu_to_le32(0x0001) |
| 78 | #define UHCI_PTR_QH __constant_cpu_to_le32(0x0002) | 78 | #define UHCI_PTR_QH cpu_to_le32(0x0002) |
| 79 | #define UHCI_PTR_DEPTH __constant_cpu_to_le32(0x0004) | 79 | #define UHCI_PTR_DEPTH cpu_to_le32(0x0004) |
| 80 | #define UHCI_PTR_BREADTH __constant_cpu_to_le32(0x0000) | 80 | #define UHCI_PTR_BREADTH cpu_to_le32(0x0000) |
| 81 | 81 | ||
| 82 | #define UHCI_NUMFRAMES 1024 /* in the frame list [array] */ | 82 | #define UHCI_NUMFRAMES 1024 /* in the frame list [array] */ |
| 83 | #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ | 83 | #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 5631d89c8730..3e5807d14ffb 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
| @@ -402,7 +402,7 @@ static void uhci_fixup_toggles(struct uhci_qh *qh, int skip_first) | |||
| 402 | /* Otherwise all the toggles in the URB have to be switched */ | 402 | /* Otherwise all the toggles in the URB have to be switched */ |
| 403 | } else { | 403 | } else { |
| 404 | list_for_each_entry(td, &urbp->td_list, list) { | 404 | list_for_each_entry(td, &urbp->td_list, list) { |
| 405 | td->token ^= __constant_cpu_to_le32( | 405 | td->token ^= cpu_to_le32( |
| 406 | TD_TOKEN_TOGGLE); | 406 | TD_TOKEN_TOGGLE); |
| 407 | toggle ^= 1; | 407 | toggle ^= 1; |
| 408 | } | 408 | } |
| @@ -883,7 +883,7 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
| 883 | 883 | ||
| 884 | uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); | 884 | uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); |
| 885 | wmb(); | 885 | wmb(); |
| 886 | qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE); | 886 | qh->dummy_td->status |= cpu_to_le32(TD_CTRL_ACTIVE); |
| 887 | qh->dummy_td = td; | 887 | qh->dummy_td = td; |
| 888 | 888 | ||
| 889 | /* Low-speed transfers get a different queue, and won't hog the bus. | 889 | /* Low-speed transfers get a different queue, and won't hog the bus. |
| @@ -899,8 +899,6 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
| 899 | } | 899 | } |
| 900 | if (qh->state != QH_STATE_ACTIVE) | 900 | if (qh->state != QH_STATE_ACTIVE) |
| 901 | qh->skel = skel; | 901 | qh->skel = skel; |
| 902 | |||
| 903 | urb->actual_length = -8; /* Account for the SETUP packet */ | ||
| 904 | return 0; | 902 | return 0; |
| 905 | 903 | ||
| 906 | nomem: | 904 | nomem: |
| @@ -1003,7 +1001,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
| 1003 | * fast side but not enough to justify delaying an interrupt | 1001 | * fast side but not enough to justify delaying an interrupt |
| 1004 | * more than 2 or 3 URBs, so we will ignore the URB_NO_INTERRUPT | 1002 | * more than 2 or 3 URBs, so we will ignore the URB_NO_INTERRUPT |
| 1005 | * flag setting. */ | 1003 | * flag setting. */ |
| 1006 | td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); | 1004 | td->status |= cpu_to_le32(TD_CTRL_IOC); |
| 1007 | 1005 | ||
| 1008 | /* | 1006 | /* |
| 1009 | * Build the new dummy TD and activate the old one | 1007 | * Build the new dummy TD and activate the old one |
| @@ -1015,7 +1013,7 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
| 1015 | 1013 | ||
| 1016 | uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); | 1014 | uhci_fill_td(td, 0, USB_PID_OUT | uhci_explen(0), 0); |
| 1017 | wmb(); | 1015 | wmb(); |
| 1018 | qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE); | 1016 | qh->dummy_td->status |= cpu_to_le32(TD_CTRL_ACTIVE); |
| 1019 | qh->dummy_td = td; | 1017 | qh->dummy_td = td; |
| 1020 | 1018 | ||
| 1021 | usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), | 1019 | usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), |
| @@ -1317,7 +1315,7 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, | |||
| 1317 | } | 1315 | } |
| 1318 | 1316 | ||
| 1319 | /* Set the interrupt-on-completion flag on the last packet. */ | 1317 | /* Set the interrupt-on-completion flag on the last packet. */ |
| 1320 | td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); | 1318 | td->status |= cpu_to_le32(TD_CTRL_IOC); |
| 1321 | 1319 | ||
| 1322 | /* Add the TDs to the frame list */ | 1320 | /* Add the TDs to the frame list */ |
| 1323 | frame = urb->start_frame; | 1321 | frame = urb->start_frame; |
| @@ -1494,11 +1492,10 @@ __acquires(uhci->lock) | |||
| 1494 | 1492 | ||
| 1495 | if (qh->type == USB_ENDPOINT_XFER_CONTROL) { | 1493 | if (qh->type == USB_ENDPOINT_XFER_CONTROL) { |
| 1496 | 1494 | ||
| 1497 | /* urb->actual_length < 0 means the setup transaction didn't | 1495 | /* Subtract off the length of the SETUP packet from |
| 1498 | * complete successfully. Either it failed or the URB was | 1496 | * urb->actual_length. |
| 1499 | * unlinked first. Regardless, don't confuse people with a | 1497 | */ |
| 1500 | * negative length. */ | 1498 | urb->actual_length -= min_t(u32, 8, urb->actual_length); |
| 1501 | urb->actual_length = max(urb->actual_length, 0); | ||
| 1502 | } | 1499 | } |
| 1503 | 1500 | ||
| 1504 | /* When giving back the first URB in an Isochronous queue, | 1501 | /* When giving back the first URB in an Isochronous queue, |
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index 972f20b3406c..eca355dccf65 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c | |||
| @@ -188,7 +188,7 @@ static struct usb_endpoint_descriptor mdc800_ed [4] = | |||
| 188 | .bDescriptorType = 0, | 188 | .bDescriptorType = 0, |
| 189 | .bEndpointAddress = 0x01, | 189 | .bEndpointAddress = 0x01, |
| 190 | .bmAttributes = 0x02, | 190 | .bmAttributes = 0x02, |
| 191 | .wMaxPacketSize = __constant_cpu_to_le16(8), | 191 | .wMaxPacketSize = cpu_to_le16(8), |
| 192 | .bInterval = 0, | 192 | .bInterval = 0, |
| 193 | .bRefresh = 0, | 193 | .bRefresh = 0, |
| 194 | .bSynchAddress = 0, | 194 | .bSynchAddress = 0, |
| @@ -198,7 +198,7 @@ static struct usb_endpoint_descriptor mdc800_ed [4] = | |||
| 198 | .bDescriptorType = 0, | 198 | .bDescriptorType = 0, |
| 199 | .bEndpointAddress = 0x82, | 199 | .bEndpointAddress = 0x82, |
| 200 | .bmAttributes = 0x03, | 200 | .bmAttributes = 0x03, |
| 201 | .wMaxPacketSize = __constant_cpu_to_le16(8), | 201 | .wMaxPacketSize = cpu_to_le16(8), |
| 202 | .bInterval = 0, | 202 | .bInterval = 0, |
| 203 | .bRefresh = 0, | 203 | .bRefresh = 0, |
| 204 | .bSynchAddress = 0, | 204 | .bSynchAddress = 0, |
| @@ -208,7 +208,7 @@ static struct usb_endpoint_descriptor mdc800_ed [4] = | |||
| 208 | .bDescriptorType = 0, | 208 | .bDescriptorType = 0, |
| 209 | .bEndpointAddress = 0x03, | 209 | .bEndpointAddress = 0x03, |
| 210 | .bmAttributes = 0x02, | 210 | .bmAttributes = 0x02, |
| 211 | .wMaxPacketSize = __constant_cpu_to_le16(64), | 211 | .wMaxPacketSize = cpu_to_le16(64), |
| 212 | .bInterval = 0, | 212 | .bInterval = 0, |
| 213 | .bRefresh = 0, | 213 | .bRefresh = 0, |
| 214 | .bSynchAddress = 0, | 214 | .bSynchAddress = 0, |
| @@ -218,7 +218,7 @@ static struct usb_endpoint_descriptor mdc800_ed [4] = | |||
| 218 | .bDescriptorType = 0, | 218 | .bDescriptorType = 0, |
| 219 | .bEndpointAddress = 0x84, | 219 | .bEndpointAddress = 0x84, |
| 220 | .bmAttributes = 0x02, | 220 | .bmAttributes = 0x02, |
| 221 | .wMaxPacketSize = __constant_cpu_to_le16(64), | 221 | .wMaxPacketSize = cpu_to_le16(64), |
| 222 | .bInterval = 0, | 222 | .bInterval = 0, |
| 223 | .bRefresh = 0, | 223 | .bRefresh = 0, |
| 224 | .bSynchAddress = 0, | 224 | .bSynchAddress = 0, |
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index e463db5d8188..a68d91a11bee 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig | |||
| @@ -135,45 +135,6 @@ config USB_CYTHERM | |||
| 135 | To compile this driver as a module, choose M here: the | 135 | To compile this driver as a module, choose M here: the |
| 136 | module will be called cytherm. | 136 | module will be called cytherm. |
| 137 | 137 | ||
| 138 | config USB_PHIDGET | ||
| 139 | tristate "USB Phidgets drivers" | ||
| 140 | depends on USB | ||
| 141 | help | ||
| 142 | Say Y here to enable the various drivers for devices from | ||
| 143 | Phidgets inc. | ||
| 144 | |||
| 145 | config USB_PHIDGETKIT | ||
| 146 | tristate "USB PhidgetInterfaceKit support" | ||
| 147 | depends on USB_PHIDGET | ||
| 148 | help | ||
| 149 | Say Y here if you want to connect a PhidgetInterfaceKit USB device | ||
| 150 | from Phidgets Inc. | ||
| 151 | |||
| 152 | To compile this driver as a module, choose M here: the | ||
| 153 | module will be called phidgetkit. | ||
| 154 | |||
| 155 | config USB_PHIDGETMOTORCONTROL | ||
| 156 | tristate "USB PhidgetMotorControl support" | ||
| 157 | depends on USB_PHIDGET | ||
| 158 | help | ||
| 159 | Say Y here if you want to connect a PhidgetMotorControl USB device | ||
| 160 | from Phidgets Inc. | ||
| 161 | |||
| 162 | To compile this driver as a module, choose M here: the | ||
| 163 | module will be called phidgetmotorcontrol. | ||
| 164 | |||
| 165 | config USB_PHIDGETSERVO | ||
| 166 | tristate "USB PhidgetServo support" | ||
| 167 | depends on USB_PHIDGET | ||
| 168 | help | ||
| 169 | Say Y here if you want to connect an 1 or 4 Motor PhidgetServo | ||
| 170 | servo controller version 2.0 or 3.0. | ||
| 171 | |||
| 172 | Phidgets Inc. has a web page at <http://www.phidgets.com/>. | ||
| 173 | |||
| 174 | To compile this driver as a module, choose M here: the | ||
| 175 | module will be called phidgetservo. | ||
| 176 | |||
| 177 | config USB_IDMOUSE | 138 | config USB_IDMOUSE |
| 178 | tristate "Siemens ID USB Mouse Fingerprint sensor support" | 139 | tristate "Siemens ID USB Mouse Fingerprint sensor support" |
| 179 | depends on USB | 140 | depends on USB |
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile index 1334f7bdd7be..0826aab8303f 100644 --- a/drivers/usb/misc/Makefile +++ b/drivers/usb/misc/Makefile | |||
| @@ -18,10 +18,6 @@ obj-$(CONFIG_USB_LCD) += usblcd.o | |||
| 18 | obj-$(CONFIG_USB_LD) += ldusb.o | 18 | obj-$(CONFIG_USB_LD) += ldusb.o |
| 19 | obj-$(CONFIG_USB_LED) += usbled.o | 19 | obj-$(CONFIG_USB_LED) += usbled.o |
| 20 | obj-$(CONFIG_USB_LEGOTOWER) += legousbtower.o | 20 | obj-$(CONFIG_USB_LEGOTOWER) += legousbtower.o |
| 21 | obj-$(CONFIG_USB_PHIDGET) += phidget.o | ||
| 22 | obj-$(CONFIG_USB_PHIDGETKIT) += phidgetkit.o | ||
| 23 | obj-$(CONFIG_USB_PHIDGETMOTORCONTROL) += phidgetmotorcontrol.o | ||
| 24 | obj-$(CONFIG_USB_PHIDGETSERVO) += phidgetservo.o | ||
| 25 | obj-$(CONFIG_USB_RIO500) += rio500.o | 21 | obj-$(CONFIG_USB_RIO500) += rio500.o |
| 26 | obj-$(CONFIG_USB_TEST) += usbtest.o | 22 | obj-$(CONFIG_USB_TEST) += usbtest.o |
| 27 | obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o | 23 | obj-$(CONFIG_USB_TRANCEVIBRATOR) += trancevibrator.o |
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index 79a7668ef264..9d0675ed0d4c 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c | |||
| @@ -1568,7 +1568,7 @@ static int ftdi_elan_edset_input(struct usb_ftdi *ftdi, u8 ed_number, | |||
| 1568 | struct u132_target *target = &ftdi->target[ed]; | 1568 | struct u132_target *target = &ftdi->target[ed]; |
| 1569 | struct u132_command *command = &ftdi->command[ | 1569 | struct u132_command *command = &ftdi->command[ |
| 1570 | COMMAND_MASK & ftdi->command_next]; | 1570 | COMMAND_MASK & ftdi->command_next]; |
| 1571 | int remaining_length = urb->transfer_buffer_length - | 1571 | u32 remaining_length = urb->transfer_buffer_length - |
| 1572 | urb->actual_length; | 1572 | urb->actual_length; |
| 1573 | command->header = 0x82 | (ed << 5); | 1573 | command->header = 0x82 | (ed << 5); |
| 1574 | if (remaining_length == 0) { | 1574 | if (remaining_length == 0) { |
| @@ -1702,7 +1702,7 @@ static int ftdi_elan_edset_output(struct usb_ftdi *ftdi, u8 ed_number, | |||
| 1702 | | (address << 0); | 1702 | | (address << 0); |
| 1703 | command->width = usb_maxpacket(urb->dev, urb->pipe, | 1703 | command->width = usb_maxpacket(urb->dev, urb->pipe, |
| 1704 | usb_pipeout(urb->pipe)); | 1704 | usb_pipeout(urb->pipe)); |
| 1705 | command->follows = min(1024, | 1705 | command->follows = min_t(u32, 1024, |
| 1706 | urb->transfer_buffer_length - | 1706 | urb->transfer_buffer_length - |
| 1707 | urb->actual_length); | 1707 | urb->actual_length); |
| 1708 | command->value = 0; | 1708 | command->value = 0; |
| @@ -1766,7 +1766,7 @@ static int ftdi_elan_edset_single(struct usb_ftdi *ftdi, u8 ed_number, | |||
| 1766 | mutex_lock(&ftdi->u132_lock); | 1766 | mutex_lock(&ftdi->u132_lock); |
| 1767 | command_size = ftdi->command_next - ftdi->command_head; | 1767 | command_size = ftdi->command_next - ftdi->command_head; |
| 1768 | if (command_size < COMMAND_SIZE) { | 1768 | if (command_size < COMMAND_SIZE) { |
| 1769 | int remaining_length = urb->transfer_buffer_length - | 1769 | u32 remaining_length = urb->transfer_buffer_length - |
| 1770 | urb->actual_length; | 1770 | urb->actual_length; |
| 1771 | struct u132_target *target = &ftdi->target[ed]; | 1771 | struct u132_target *target = &ftdi->target[ed]; |
| 1772 | struct u132_command *command = &ftdi->command[ | 1772 | struct u132_command *command = &ftdi->command[ |
diff --git a/drivers/usb/misc/phidget.c b/drivers/usb/misc/phidget.c deleted file mode 100644 index 735ed33f4f7f..000000000000 --- a/drivers/usb/misc/phidget.c +++ /dev/null | |||
| @@ -1,43 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * USB Phidgets class | ||
| 3 | * | ||
| 4 | * Copyright (C) 2006 Sean Young <sean@mess.org> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/module.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/err.h> | ||
| 16 | #include <linux/device.h> | ||
| 17 | |||
| 18 | struct class *phidget_class; | ||
| 19 | |||
| 20 | static int __init init_phidget(void) | ||
| 21 | { | ||
| 22 | phidget_class = class_create(THIS_MODULE, "phidget"); | ||
| 23 | |||
| 24 | if (IS_ERR(phidget_class)) | ||
| 25 | return PTR_ERR(phidget_class); | ||
| 26 | |||
| 27 | return 0; | ||
| 28 | } | ||
| 29 | |||
| 30 | static void __exit cleanup_phidget(void) | ||
| 31 | { | ||
| 32 | class_destroy(phidget_class); | ||
| 33 | } | ||
| 34 | |||
| 35 | EXPORT_SYMBOL_GPL(phidget_class); | ||
| 36 | |||
| 37 | module_init(init_phidget); | ||
| 38 | module_exit(cleanup_phidget); | ||
| 39 | |||
| 40 | MODULE_LICENSE("GPL"); | ||
| 41 | MODULE_AUTHOR("Sean Young <sean@mess.org>"); | ||
| 42 | MODULE_DESCRIPTION("Container module for phidget class"); | ||
| 43 | |||
diff --git a/drivers/usb/misc/phidget.h b/drivers/usb/misc/phidget.h deleted file mode 100644 index c4011907d431..000000000000 --- a/drivers/usb/misc/phidget.h +++ /dev/null | |||
| @@ -1,12 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * USB Phidgets class | ||
| 3 | * | ||
| 4 | * Copyright (C) 2006 Sean Young <sean@mess.org> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | extern struct class *phidget_class; | ||
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c deleted file mode 100644 index cc8e0a926f99..000000000000 --- a/drivers/usb/misc/phidgetkit.c +++ /dev/null | |||
| @@ -1,740 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * USB PhidgetInterfaceKit driver 1.0 | ||
| 3 | * | ||
| 4 | * Copyright (C) 2004, 2006 Sean Young <sean@mess.org> | ||
| 5 | * Copyright (C) 2005 Daniel Saakes <daniel@saakes.net> | ||
| 6 | * Copyright (C) 2004 Greg Kroah-Hartman <greg@kroah.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | * | ||
| 13 | * This is a driver for the USB PhidgetInterfaceKit. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/kernel.h> | ||
| 17 | #include <linux/errno.h> | ||
| 18 | #include <linux/init.h> | ||
| 19 | #include <linux/slab.h> | ||
| 20 | #include <linux/module.h> | ||
| 21 | #include <linux/usb.h> | ||
| 22 | |||
| 23 | #include "phidget.h" | ||
| 24 | |||
| 25 | #define DRIVER_AUTHOR "Sean Young <sean@mess.org>" | ||
| 26 | #define DRIVER_DESC "USB PhidgetInterfaceKit Driver" | ||
| 27 | |||
| 28 | #define USB_VENDOR_ID_GLAB 0x06c2 | ||
| 29 | #define USB_DEVICE_ID_INTERFACEKIT004 0x0040 | ||
| 30 | #define USB_DEVICE_ID_INTERFACEKIT01616 0x0044 | ||
| 31 | #define USB_DEVICE_ID_INTERFACEKIT888 0x0045 | ||
| 32 | #define USB_DEVICE_ID_INTERFACEKIT047 0x0051 | ||
| 33 | #define USB_DEVICE_ID_INTERFACEKIT088 0x0053 | ||
| 34 | |||
| 35 | #define USB_VENDOR_ID_WISEGROUP 0x0925 | ||
| 36 | #define USB_DEVICE_ID_INTERFACEKIT884 0x8201 | ||
| 37 | |||
| 38 | #define MAX_INTERFACES 16 | ||
| 39 | |||
| 40 | #define URB_INT_SIZE 8 | ||
| 41 | |||
| 42 | struct driver_interfacekit { | ||
| 43 | int sensors; | ||
| 44 | int inputs; | ||
| 45 | int outputs; | ||
| 46 | int has_lcd; | ||
| 47 | int amnesiac; | ||
| 48 | }; | ||
| 49 | |||
| 50 | #define ifkit(_sensors, _inputs, _outputs, _lcd, _amnesiac) \ | ||
| 51 | { \ | ||
| 52 | .sensors = _sensors, \ | ||
| 53 | .inputs = _inputs, \ | ||
| 54 | .outputs = _outputs, \ | ||
| 55 | .has_lcd = _lcd, \ | ||
| 56 | .amnesiac = _amnesiac \ | ||
| 57 | }; | ||
| 58 | |||
| 59 | static const struct driver_interfacekit ph_004 = ifkit(0, 0, 4, 0, 0); | ||
| 60 | static const struct driver_interfacekit ph_888n = ifkit(8, 8, 8, 0, 1); | ||
| 61 | static const struct driver_interfacekit ph_888o = ifkit(8, 8, 8, 0, 0); | ||
| 62 | static const struct driver_interfacekit ph_047 = ifkit(0, 4, 7, 1, 0); | ||
| 63 | static const struct driver_interfacekit ph_884 = ifkit(8, 8, 4, 0, 0); | ||
| 64 | static const struct driver_interfacekit ph_088 = ifkit(0, 8, 8, 1, 0); | ||
| 65 | static const struct driver_interfacekit ph_01616 = ifkit(0, 16, 16, 0, 0); | ||
| 66 | |||
| 67 | static unsigned long device_no; | ||
| 68 | |||
| 69 | struct interfacekit { | ||
| 70 | struct usb_device *udev; | ||
| 71 | struct usb_interface *intf; | ||
| 72 | struct driver_interfacekit *ifkit; | ||
| 73 | struct device *dev; | ||
| 74 | unsigned long outputs; | ||
| 75 | int dev_no; | ||
| 76 | u8 inputs[MAX_INTERFACES]; | ||
| 77 | u16 sensors[MAX_INTERFACES]; | ||
| 78 | u8 lcd_files_on; | ||
| 79 | |||
| 80 | struct urb *irq; | ||
| 81 | unsigned char *data; | ||
| 82 | dma_addr_t data_dma; | ||
| 83 | |||
| 84 | struct delayed_work do_notify; | ||
| 85 | struct delayed_work do_resubmit; | ||
| 86 | unsigned long input_events; | ||
| 87 | unsigned long sensor_events; | ||
| 88 | }; | ||
| 89 | |||
| 90 | static struct usb_device_id id_table[] = { | ||
| 91 | {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT004), | ||
| 92 | .driver_info = (kernel_ulong_t)&ph_004}, | ||
| 93 | {USB_DEVICE_VER(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT888, 0, 0x814), | ||
| 94 | .driver_info = (kernel_ulong_t)&ph_888o}, | ||
| 95 | {USB_DEVICE_VER(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT888, 0x0815, 0xffff), | ||
| 96 | .driver_info = (kernel_ulong_t)&ph_888n}, | ||
| 97 | {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT047), | ||
| 98 | .driver_info = (kernel_ulong_t)&ph_047}, | ||
| 99 | {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT088), | ||
| 100 | .driver_info = (kernel_ulong_t)&ph_088}, | ||
| 101 | {USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_INTERFACEKIT01616), | ||
| 102 | .driver_info = (kernel_ulong_t)&ph_01616}, | ||
| 103 | {USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_INTERFACEKIT884), | ||
| 104 | .driver_info = (kernel_ulong_t)&ph_884}, | ||
| 105 | {} | ||
| 106 | }; | ||
| 107 | MODULE_DEVICE_TABLE(usb, id_table); | ||
| 108 | |||
| 109 | static int set_outputs(struct interfacekit *kit) | ||
| 110 | { | ||
| 111 | u8 *buffer; | ||
| 112 | int retval; | ||
| 113 | |||
| 114 | buffer = kzalloc(4, GFP_KERNEL); | ||
| 115 | if (!buffer) { | ||
| 116 | dev_err(&kit->udev->dev, "%s - out of memory\n", __func__); | ||
| 117 | return -ENOMEM; | ||
| 118 | } | ||
| 119 | buffer[0] = (u8)kit->outputs; | ||
| 120 | buffer[1] = (u8)(kit->outputs >> 8); | ||
| 121 | |||
| 122 | dev_dbg(&kit->udev->dev, "sending data: 0x%04x\n", (u16)kit->outputs); | ||
| 123 | |||
| 124 | retval = usb_control_msg(kit->udev, | ||
| 125 | usb_sndctrlpipe(kit->udev, 0), | ||
| 126 | 0x09, 0x21, 0x0200, 0x0000, buffer, 4, 2000); | ||
| 127 | |||
| 128 | if (retval != 4) | ||
| 129 | dev_err(&kit->udev->dev, "usb_control_msg returned %d\n", | ||
| 130 | retval); | ||
| 131 | kfree(buffer); | ||
| 132 | |||
| 133 | if (kit->ifkit->amnesiac) | ||
| 134 | schedule_delayed_work(&kit->do_resubmit, HZ / 2); | ||
| 135 | |||
| 136 | return retval < 0 ? retval : 0; | ||
| 137 | } | ||
| 138 | |||
| 139 | static int change_string(struct interfacekit *kit, const char *display, unsigned char row) | ||
| 140 | { | ||
| 141 | unsigned char *buffer; | ||
| 142 | unsigned char *form_buffer; | ||
| 143 | int retval = -ENOMEM; | ||
| 144 | int i,j, len, buf_ptr; | ||
| 145 | |||
| 146 | buffer = kmalloc(8, GFP_KERNEL); | ||
| 147 | form_buffer = kmalloc(30, GFP_KERNEL); | ||
| 148 | if ((!buffer) || (!form_buffer)) { | ||
| 149 | dev_err(&kit->udev->dev, "%s - out of memory\n", __func__); | ||
| 150 | goto exit; | ||
| 151 | } | ||
| 152 | |||
| 153 | len = strlen(display); | ||
| 154 | if (len > 20) | ||
| 155 | len = 20; | ||
| 156 | |||
| 157 | dev_dbg(&kit->udev->dev, "Setting LCD line %d to %s\n", row, display); | ||
| 158 | |||
| 159 | form_buffer[0] = row * 0x40 + 0x80; | ||
| 160 | form_buffer[1] = 0x02; | ||
| 161 | buf_ptr = 2; | ||
| 162 | for (i = 0; i<len; i++) | ||
| 163 | form_buffer[buf_ptr++] = display[i]; | ||
| 164 | |||
| 165 | for (i = 0; i < (20 - len); i++) | ||
| 166 | form_buffer[buf_ptr++] = 0x20; | ||
| 167 | form_buffer[buf_ptr++] = 0x01; | ||
| 168 | form_buffer[buf_ptr++] = row * 0x40 + 0x80 + strlen(display); | ||
| 169 | |||
| 170 | for (i = 0; i < buf_ptr; i += 7) { | ||
| 171 | if ((buf_ptr - i) > 7) | ||
| 172 | len = 7; | ||
| 173 | else | ||
| 174 | len = (buf_ptr - i); | ||
| 175 | for (j = 0; j < len; j++) | ||
| 176 | buffer[j] = form_buffer[i + j]; | ||
| 177 | buffer[7] = len; | ||
| 178 | |||
| 179 | retval = usb_control_msg(kit->udev, | ||
| 180 | usb_sndctrlpipe(kit->udev, 0), | ||
| 181 | 0x09, 0x21, 0x0200, 0x0000, buffer, 8, 2000); | ||
| 182 | if (retval < 0) | ||
| 183 | goto exit; | ||
| 184 | } | ||
| 185 | |||
| 186 | retval = 0; | ||
| 187 | exit: | ||
| 188 | kfree(buffer); | ||
| 189 | kfree(form_buffer); | ||
| 190 | |||
| 191 | return retval; | ||
| 192 | } | ||
| 193 | |||
| 194 | #define set_lcd_line(number) \ | ||
| 195 | static ssize_t lcd_line_##number(struct device *dev, \ | ||
| 196 | struct device_attribute *attr, \ | ||
| 197 | const char *buf, size_t count) \ | ||
| 198 | { \ | ||
| 199 | struct interfacekit *kit = dev_get_drvdata(dev); \ | ||
| 200 | change_string(kit, buf, number - 1); \ | ||
| 201 | return count; \ | ||
| 202 | } | ||
| 203 | |||
| 204 | #define lcd_line_attr(number) \ | ||
| 205 | __ATTR(lcd_line_##number, S_IWUGO, NULL, lcd_line_##number) | ||
| 206 | |||
| 207 | set_lcd_line(1); | ||
| 208 | set_lcd_line(2); | ||
| 209 | |||
| 210 | static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | ||
| 211 | { | ||
| 212 | struct interfacekit *kit = dev_get_drvdata(dev); | ||
| 213 | int enabled; | ||
| 214 | unsigned char *buffer; | ||
| 215 | int retval = -ENOMEM; | ||
| 216 | |||
| 217 | buffer = kzalloc(8, GFP_KERNEL); | ||
| 218 | if (!buffer) { | ||
| 219 | dev_err(&kit->udev->dev, "%s - out of memory\n", __func__); | ||
| 220 | goto exit; | ||
| 221 | } | ||
| 222 | |||
| 223 | if (sscanf(buf, "%d", &enabled) < 1) { | ||
| 224 | retval = -EINVAL; | ||
| 225 | goto exit; | ||
| 226 | } | ||
| 227 | if (enabled) | ||
| 228 | buffer[0] = 0x01; | ||
| 229 | buffer[7] = 0x11; | ||
| 230 | |||
| 231 | dev_dbg(&kit->udev->dev, "Setting backlight to %s\n", enabled ? "on" : "off"); | ||
| 232 | |||
| 233 | retval = usb_control_msg(kit->udev, | ||
| 234 | usb_sndctrlpipe(kit->udev, 0), | ||
| 235 | 0x09, 0x21, 0x0200, 0x0000, buffer, 8, 2000); | ||
| 236 | if (retval < 0) | ||
| 237 | goto exit; | ||
| 238 | |||
| 239 | retval = count; | ||
| 240 | exit: | ||
| 241 | kfree(buffer); | ||
| 242 | return retval; | ||
| 243 | } | ||
| 244 | |||
| 245 | static struct device_attribute dev_lcd_line_attrs[] = { | ||
| 246 | lcd_line_attr(1), | ||
| 247 | lcd_line_attr(2), | ||
| 248 | __ATTR(backlight, S_IWUGO, NULL, set_backlight) | ||
| 249 | }; | ||
| 250 | |||
| 251 | static void remove_lcd_files(struct interfacekit *kit) | ||
| 252 | { | ||
| 253 | int i; | ||
| 254 | |||
| 255 | if (kit->lcd_files_on) { | ||
| 256 | dev_dbg(&kit->udev->dev, "Removing lcd files\n"); | ||
| 257 | |||
| 258 | for (i=0; i<ARRAY_SIZE(dev_lcd_line_attrs); i++) | ||
| 259 | device_remove_file(kit->dev, &dev_lcd_line_attrs[i]); | ||
| 260 | } | ||
| 261 | } | ||
| 262 | |||
| 263 | static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | ||
| 264 | { | ||
| 265 | struct interfacekit *kit = dev_get_drvdata(dev); | ||
| 266 | int enable; | ||
| 267 | int i, rc; | ||
| 268 | |||
| 269 | if (kit->ifkit->has_lcd == 0) | ||
| 270 | return -ENODEV; | ||
| 271 | |||
| 272 | if (sscanf(buf, "%d", &enable) < 1) | ||
| 273 | return -EINVAL; | ||
| 274 | |||
| 275 | if (enable) { | ||
| 276 | if (!kit->lcd_files_on) { | ||
| 277 | dev_dbg(&kit->udev->dev, "Adding lcd files\n"); | ||
| 278 | for (i=0; i<ARRAY_SIZE(dev_lcd_line_attrs); i++) { | ||
| 279 | rc = device_create_file(kit->dev, | ||
| 280 | &dev_lcd_line_attrs[i]); | ||
| 281 | if (rc) | ||
| 282 | goto out; | ||
| 283 | } | ||
| 284 | kit->lcd_files_on = 1; | ||
| 285 | } | ||
| 286 | } else { | ||
| 287 | if (kit->lcd_files_on) { | ||
| 288 | remove_lcd_files(kit); | ||
| 289 | kit->lcd_files_on = 0; | ||
| 290 | } | ||
| 291 | } | ||
| 292 | |||
| 293 | return count; | ||
| 294 | out: | ||
| 295 | while (i-- > 0) | ||
| 296 | device_remove_file(kit->dev, &dev_lcd_line_attrs[i]); | ||
| 297 | |||
| 298 | return rc; | ||
| 299 | } | ||
| 300 | |||
| 301 | static DEVICE_ATTR(lcd, S_IWUGO, NULL, enable_lcd_files); | ||
| 302 | |||
| 303 | static void interfacekit_irq(struct urb *urb) | ||
| 304 | { | ||
| 305 | struct interfacekit *kit = urb->context; | ||
| 306 | unsigned char *buffer = kit->data; | ||
| 307 | int i, level, sensor; | ||
| 308 | int retval; | ||
| 309 | int status = urb->status; | ||
| 310 | |||
| 311 | switch (status) { | ||
| 312 | case 0: /* success */ | ||
| 313 | break; | ||
| 314 | case -ECONNRESET: /* unlink */ | ||
| 315 | case -ENOENT: | ||
| 316 | case -ESHUTDOWN: | ||
| 317 | return; | ||
| 318 | /* -EPIPE: should clear the halt */ | ||
| 319 | default: /* error */ | ||
| 320 | goto resubmit; | ||
| 321 | } | ||
| 322 | |||
| 323 | /* digital inputs */ | ||
| 324 | if (kit->ifkit->inputs == 16) { | ||
| 325 | for (i=0; i < 8; i++) { | ||
| 326 | level = (buffer[0] >> i) & 1; | ||
| 327 | if (kit->inputs[i] != level) { | ||
| 328 | kit->inputs[i] = level; | ||
| 329 | set_bit(i, &kit->input_events); | ||
| 330 | } | ||
| 331 | level = (buffer[1] >> i) & 1; | ||
| 332 | if (kit->inputs[8 + i] != level) { | ||
| 333 | kit->inputs[8 + i] = level; | ||
| 334 | set_bit(8 + i, &kit->input_events); | ||
| 335 | } | ||
| 336 | } | ||
| 337 | } | ||
| 338 | else if (kit->ifkit->inputs == 8) { | ||
| 339 | for (i=0; i < 8; i++) { | ||
| 340 | level = (buffer[1] >> i) & 1; | ||
| 341 | if (kit->inputs[i] != level) { | ||
| 342 | kit->inputs[i] = level; | ||
| 343 | set_bit(i, &kit->input_events); | ||
| 344 | } | ||
| 345 | } | ||
| 346 | } | ||
| 347 | |||
| 348 | /* analog inputs */ | ||
| 349 | if (kit->ifkit->sensors) { | ||
| 350 | sensor = (buffer[0] & 1) ? 4 : 0; | ||
| 351 | |||
| 352 | level = buffer[2] + (buffer[3] & 0x0f) * 256; | ||
| 353 | if (level != kit->sensors[sensor]) { | ||
| 354 | kit->sensors[sensor] = level; | ||
| 355 | set_bit(sensor, &kit->sensor_events); | ||
| 356 | } | ||
| 357 | sensor++; | ||
| 358 | level = buffer[4] + (buffer[3] & 0xf0) * 16; | ||
| 359 | if (level != kit->sensors[sensor]) { | ||
| 360 | kit->sensors[sensor] = level; | ||
| 361 | set_bit(sensor, &kit->sensor_events); | ||
| 362 | } | ||
| 363 | sensor++; | ||
| 364 | level = buffer[5] + (buffer[6] & 0x0f) * 256; | ||
| 365 | if (level != kit->sensors[sensor]) { | ||
| 366 | kit->sensors[sensor] = level; | ||
| 367 | set_bit(sensor, &kit->sensor_events); | ||
| 368 | } | ||
| 369 | sensor++; | ||
| 370 | level = buffer[7] + (buffer[6] & 0xf0) * 16; | ||
| 371 | if (level != kit->sensors[sensor]) { | ||
| 372 | kit->sensors[sensor] = level; | ||
| 373 | set_bit(sensor, &kit->sensor_events); | ||
| 374 | } | ||
| 375 | } | ||
| 376 | |||
| 377 | if (kit->input_events || kit->sensor_events) | ||
| 378 | schedule_delayed_work(&kit->do_notify, 0); | ||
| 379 | |||
| 380 | resubmit: | ||
| 381 | retval = usb_submit_urb(urb, GFP_ATOMIC); | ||
| 382 | if (retval) | ||
| 383 | err("can't resubmit intr, %s-%s/interfacekit0, retval %d", | ||
| 384 | kit->udev->bus->bus_name, | ||
| 385 | kit->udev->devpath, retval); | ||
| 386 | } | ||
| 387 | |||
| 388 | static void do_notify(struct work_struct *work) | ||
| 389 | { | ||
| 390 | struct interfacekit *kit = | ||
| 391 | container_of(work, struct interfacekit, do_notify.work); | ||
| 392 | int i; | ||
| 393 | char sysfs_file[8]; | ||
| 394 | |||
| 395 | for (i=0; i<kit->ifkit->inputs; i++) { | ||
| 396 | if (test_and_clear_bit(i, &kit->input_events)) { | ||
| 397 | sprintf(sysfs_file, "input%d", i + 1); | ||
| 398 | sysfs_notify(&kit->dev->kobj, NULL, sysfs_file); | ||
| 399 | } | ||
| 400 | } | ||
| 401 | |||
| 402 | for (i=0; i<kit->ifkit->sensors; i++) { | ||
| 403 | if (test_and_clear_bit(i, &kit->sensor_events)) { | ||
| 404 | sprintf(sysfs_file, "sensor%d", i + 1); | ||
| 405 | sysfs_notify(&kit->dev->kobj, NULL, sysfs_file); | ||
| 406 | } | ||
| 407 | } | ||
| 408 | } | ||
| 409 | |||
| 410 | static void do_resubmit(struct work_struct *work) | ||
| 411 | { | ||
| 412 | struct interfacekit *kit = | ||
| 413 | container_of(work, struct interfacekit, do_resubmit.work); | ||
| 414 | set_outputs(kit); | ||
| 415 | } | ||
| 416 | |||
| 417 | #define show_set_output(value) \ | ||
| 418 | static ssize_t set_output##value(struct device *dev, \ | ||
| 419 | struct device_attribute *attr, \ | ||
| 420 | const char *buf, size_t count) \ | ||
| 421 | { \ | ||
| 422 | struct interfacekit *kit = dev_get_drvdata(dev); \ | ||
| 423 | int enable; \ | ||
| 424 | int retval; \ | ||
| 425 | \ | ||
| 426 | if (sscanf(buf, "%d", &enable) < 1) \ | ||
| 427 | return -EINVAL; \ | ||
| 428 | \ | ||
| 429 | if (enable) \ | ||
| 430 | set_bit(value - 1, &kit->outputs); \ | ||
| 431 | else \ | ||
| 432 | clear_bit(value - 1, &kit->outputs); \ | ||
| 433 | \ | ||
| 434 | retval = set_outputs(kit); \ | ||
| 435 | \ | ||
| 436 | return retval ? retval : count; \ | ||
| 437 | } \ | ||
| 438 | \ | ||
| 439 | static ssize_t show_output##value(struct device *dev, \ | ||
| 440 | struct device_attribute *attr, \ | ||
| 441 | char *buf) \ | ||
| 442 | { \ | ||
| 443 | struct interfacekit *kit = dev_get_drvdata(dev); \ | ||
| 444 | \ | ||
| 445 | return sprintf(buf, "%d\n", !!test_bit(value - 1, &kit->outputs));\ | ||
| 446 | } | ||
| 447 | |||
| 448 | #define output_attr(value) \ | ||
| 449 | __ATTR(output##value, S_IWUGO | S_IRUGO, \ | ||
| 450 | show_output##value, set_output##value) | ||
| 451 | |||
| 452 | show_set_output(1); | ||
| 453 | show_set_output(2); | ||
| 454 | show_set_output(3); | ||
| 455 | show_set_output(4); | ||
| 456 | show_set_output(5); | ||
| 457 | show_set_output(6); | ||
| 458 | show_set_output(7); | ||
| 459 | show_set_output(8); | ||
| 460 | show_set_output(9); | ||
| 461 | show_set_output(10); | ||
| 462 | show_set_output(11); | ||
| 463 | show_set_output(12); | ||
| 464 | show_set_output(13); | ||
| 465 | show_set_output(14); | ||
| 466 | show_set_output(15); | ||
| 467 | show_set_output(16); | ||
| 468 | |||
| 469 | static struct device_attribute dev_output_attrs[] = { | ||
| 470 | output_attr(1), output_attr(2), output_attr(3), output_attr(4), | ||
| 471 | output_attr(5), output_attr(6), output_attr(7), output_attr(8), | ||
| 472 | output_attr(9), output_attr(10), output_attr(11), output_attr(12), | ||
| 473 | output_attr(13), output_attr(14), output_attr(15), output_attr(16) | ||
| 474 | }; | ||
| 475 | |||
| 476 | #define show_input(value) \ | ||
| 477 | static ssize_t show_input##value(struct device *dev, \ | ||
| 478 | struct device_attribute *attr, char *buf) \ | ||
| 479 | { \ | ||
| 480 | struct interfacekit *kit = dev_get_drvdata(dev); \ | ||
| 481 | \ | ||
| 482 | return sprintf(buf, "%d\n", (int)kit->inputs[value - 1]); \ | ||
| 483 | } | ||
| 484 | |||
| 485 | #define input_attr(value) \ | ||
| 486 | __ATTR(input##value, S_IRUGO, show_input##value, NULL) | ||
| 487 | |||
| 488 | show_input(1); | ||
| 489 | show_input(2); | ||
| 490 | show_input(3); | ||
| 491 | show_input(4); | ||
| 492 | show_input(5); | ||
| 493 | show_input(6); | ||
| 494 | show_input(7); | ||
| 495 | show_input(8); | ||
| 496 | show_input(9); | ||
| 497 | show_input(10); | ||
| 498 | show_input(11); | ||
| 499 | show_input(12); | ||
| 500 | show_input(13); | ||
| 501 | show_input(14); | ||
| 502 | show_input(15); | ||
| 503 | show_input(16); | ||
| 504 | |||
| 505 | static struct device_attribute dev_input_attrs[] = { | ||
| 506 | input_attr(1), input_attr(2), input_attr(3), input_attr(4), | ||
| 507 | input_attr(5), input_attr(6), input_attr(7), input_attr(8), | ||
| 508 | input_attr(9), input_attr(10), input_attr(11), input_attr(12), | ||
| 509 | input_attr(13), input_attr(14), input_attr(15), input_attr(16) | ||
| 510 | }; | ||
| 511 | |||
| 512 | #define show_sensor(value) \ | ||
| 513 | static ssize_t show_sensor##value(struct device *dev, \ | ||
| 514 | struct device_attribute *attr, \ | ||
| 515 | char *buf) \ | ||
| 516 | { \ | ||
| 517 | struct interfacekit *kit = dev_get_drvdata(dev); \ | ||
| 518 | \ | ||
| 519 | return sprintf(buf, "%d\n", (int)kit->sensors[value - 1]); \ | ||
| 520 | } | ||
| 521 | |||
| 522 | #define sensor_attr(value) \ | ||
| 523 | __ATTR(sensor##value, S_IRUGO, show_sensor##value, NULL) | ||
| 524 | |||
| 525 | show_sensor(1); | ||
| 526 | show_sensor(2); | ||
| 527 | show_sensor(3); | ||
| 528 | show_sensor(4); | ||
| 529 | show_sensor(5); | ||
| 530 | show_sensor(6); | ||
| 531 | show_sensor(7); | ||
| 532 | show_sensor(8); | ||
| 533 | |||
| 534 | static struct device_attribute dev_sensor_attrs[] = { | ||
| 535 | sensor_attr(1), sensor_attr(2), sensor_attr(3), sensor_attr(4), | ||
| 536 | sensor_attr(5), sensor_attr(6), sensor_attr(7), sensor_attr(8) | ||
| 537 | }; | ||
| 538 | |||
| 539 | static int interfacekit_probe(struct usb_interface *intf, const struct usb_device_id *id) | ||
| 540 | { | ||
| 541 | struct usb_device *dev = interface_to_usbdev(intf); | ||
| 542 | struct usb_host_interface *interface; | ||
| 543 | struct usb_endpoint_descriptor *endpoint; | ||
| 544 | struct interfacekit *kit; | ||
| 545 | struct driver_interfacekit *ifkit; | ||
| 546 | int pipe, maxp, rc = -ENOMEM; | ||
| 547 | int bit, value, i; | ||
| 548 | |||
| 549 | ifkit = (struct driver_interfacekit *)id->driver_info; | ||
| 550 | if (!ifkit) | ||
| 551 | return -ENODEV; | ||
| 552 | |||
| 553 | interface = intf->cur_altsetting; | ||
| 554 | if (interface->desc.bNumEndpoints != 1) | ||
| 555 | return -ENODEV; | ||
| 556 | |||
| 557 | endpoint = &interface->endpoint[0].desc; | ||
| 558 | if (!usb_endpoint_dir_in(endpoint)) | ||
| 559 | return -ENODEV; | ||
| 560 | /* | ||
| 561 | * bmAttributes | ||
| 562 | */ | ||
| 563 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); | ||
| 564 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); | ||
| 565 | |||
| 566 | kit = kzalloc(sizeof(*kit), GFP_KERNEL); | ||
| 567 | if (!kit) | ||
| 568 | goto out; | ||
| 569 | |||
| 570 | kit->dev_no = -1; | ||
| 571 | kit->ifkit = ifkit; | ||
| 572 | kit->data = usb_buffer_alloc(dev, URB_INT_SIZE, GFP_ATOMIC, &kit->data_dma); | ||
| 573 | if (!kit->data) | ||
| 574 | goto out; | ||
| 575 | |||
| 576 | kit->irq = usb_alloc_urb(0, GFP_KERNEL); | ||
| 577 | if (!kit->irq) | ||
| 578 | goto out; | ||
| 579 | |||
| 580 | kit->udev = usb_get_dev(dev); | ||
| 581 | kit->intf = intf; | ||
| 582 | INIT_DELAYED_WORK(&kit->do_notify, do_notify); | ||
| 583 | INIT_DELAYED_WORK(&kit->do_resubmit, do_resubmit); | ||
| 584 | usb_fill_int_urb(kit->irq, kit->udev, pipe, kit->data, | ||
| 585 | maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp, | ||
| 586 | interfacekit_irq, kit, endpoint->bInterval); | ||
| 587 | kit->irq->transfer_dma = kit->data_dma; | ||
| 588 | kit->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
| 589 | |||
| 590 | usb_set_intfdata(intf, kit); | ||
| 591 | |||
| 592 | do { | ||
| 593 | bit = find_first_zero_bit(&device_no, sizeof(device_no)); | ||
| 594 | value = test_and_set_bit(bit, &device_no); | ||
| 595 | } while(value); | ||
| 596 | kit->dev_no = bit; | ||
| 597 | |||
| 598 | kit->dev = device_create(phidget_class, &kit->udev->dev, MKDEV(0, 0), | ||
| 599 | kit, "interfacekit%d", kit->dev_no); | ||
| 600 | if (IS_ERR(kit->dev)) { | ||
| 601 | rc = PTR_ERR(kit->dev); | ||
| 602 | kit->dev = NULL; | ||
| 603 | goto out; | ||
| 604 | } | ||
| 605 | |||
| 606 | if (usb_submit_urb(kit->irq, GFP_KERNEL)) { | ||
| 607 | rc = -EIO; | ||
| 608 | goto out; | ||
| 609 | } | ||
| 610 | |||
| 611 | for (i=0; i<ifkit->outputs; i++ ) { | ||
| 612 | rc = device_create_file(kit->dev, &dev_output_attrs[i]); | ||
| 613 | if (rc) | ||
| 614 | goto out2; | ||
| 615 | } | ||
| 616 | |||
| 617 | for (i=0; i<ifkit->inputs; i++ ) { | ||
| 618 | rc = device_create_file(kit->dev, &dev_input_attrs[i]); | ||
| 619 | if (rc) | ||
| 620 | goto out3; | ||
| 621 | } | ||
| 622 | |||
| 623 | for (i=0; i<ifkit->sensors; i++ ) { | ||
| 624 | rc = device_create_file(kit->dev, &dev_sensor_attrs[i]); | ||
| 625 | if (rc) | ||
| 626 | goto out4; | ||
| 627 | } | ||
| 628 | |||
| 629 | if (ifkit->has_lcd) { | ||
| 630 | rc = device_create_file(kit->dev, &dev_attr_lcd); | ||
| 631 | if (rc) | ||
| 632 | goto out4; | ||
| 633 | |||
| 634 | } | ||
| 635 | |||
| 636 | dev_info(&intf->dev, "USB PhidgetInterfaceKit %d/%d/%d attached\n", | ||
| 637 | ifkit->sensors, ifkit->inputs, ifkit->outputs); | ||
| 638 | |||
| 639 | return 0; | ||
| 640 | |||
| 641 | out4: | ||
| 642 | while (i-- > 0) | ||
| 643 | device_remove_file(kit->dev, &dev_sensor_attrs[i]); | ||
| 644 | |||
| 645 | i = ifkit->inputs; | ||
| 646 | out3: | ||
| 647 | while (i-- > 0) | ||
| 648 | device_remove_file(kit->dev, &dev_input_attrs[i]); | ||
| 649 | |||
| 650 | i = ifkit->outputs; | ||
| 651 | out2: | ||
| 652 | while (i-- > 0) | ||
| 653 | device_remove_file(kit->dev, &dev_output_attrs[i]); | ||
| 654 | out: | ||
| 655 | if (kit) { | ||
| 656 | usb_free_urb(kit->irq); | ||
| 657 | if (kit->data) | ||
| 658 | usb_buffer_free(dev, URB_INT_SIZE, kit->data, kit->data_dma); | ||
| 659 | if (kit->dev) | ||
| 660 | device_unregister(kit->dev); | ||
| 661 | if (kit->dev_no >= 0) | ||
| 662 | clear_bit(kit->dev_no, &device_no); | ||
| 663 | |||
| 664 | kfree(kit); | ||
| 665 | } | ||
| 666 | |||
| 667 | return rc; | ||
| 668 | } | ||
| 669 | |||
| 670 | static void interfacekit_disconnect(struct usb_interface *interface) | ||
| 671 | { | ||
| 672 | struct interfacekit *kit; | ||
| 673 | int i; | ||
| 674 | |||
| 675 | kit = usb_get_intfdata(interface); | ||
| 676 | usb_set_intfdata(interface, NULL); | ||
| 677 | if (!kit) | ||
| 678 | return; | ||
| 679 | |||
| 680 | usb_kill_urb(kit->irq); | ||
| 681 | usb_free_urb(kit->irq); | ||
| 682 | usb_buffer_free(kit->udev, URB_INT_SIZE, kit->data, kit->data_dma); | ||
| 683 | |||
| 684 | cancel_delayed_work(&kit->do_notify); | ||
| 685 | cancel_delayed_work(&kit->do_resubmit); | ||
| 686 | |||
| 687 | for (i=0; i<kit->ifkit->outputs; i++) | ||
| 688 | device_remove_file(kit->dev, &dev_output_attrs[i]); | ||
| 689 | |||
| 690 | for (i=0; i<kit->ifkit->inputs; i++) | ||
| 691 | device_remove_file(kit->dev, &dev_input_attrs[i]); | ||
| 692 | |||
| 693 | for (i=0; i<kit->ifkit->sensors; i++) | ||
| 694 | device_remove_file(kit->dev, &dev_sensor_attrs[i]); | ||
| 695 | |||
| 696 | if (kit->ifkit->has_lcd) { | ||
| 697 | device_remove_file(kit->dev, &dev_attr_lcd); | ||
| 698 | remove_lcd_files(kit); | ||
| 699 | } | ||
| 700 | |||
| 701 | device_unregister(kit->dev); | ||
| 702 | |||
| 703 | dev_info(&interface->dev, "USB PhidgetInterfaceKit %d/%d/%d detached\n", | ||
| 704 | kit->ifkit->sensors, kit->ifkit->inputs, kit->ifkit->outputs); | ||
| 705 | |||
| 706 | usb_put_dev(kit->udev); | ||
| 707 | clear_bit(kit->dev_no, &device_no); | ||
| 708 | |||
| 709 | kfree(kit); | ||
| 710 | } | ||
| 711 | |||
| 712 | static struct usb_driver interfacekit_driver = { | ||
| 713 | .name = "phidgetkit", | ||
| 714 | .probe = interfacekit_probe, | ||
| 715 | .disconnect = interfacekit_disconnect, | ||
| 716 | .id_table = id_table | ||
| 717 | }; | ||
| 718 | |||
| 719 | static int __init interfacekit_init(void) | ||
| 720 | { | ||
| 721 | int retval = 0; | ||
| 722 | |||
| 723 | retval = usb_register(&interfacekit_driver); | ||
| 724 | if (retval) | ||
| 725 | err("usb_register failed. Error number %d", retval); | ||
| 726 | |||
| 727 | return retval; | ||
| 728 | } | ||
| 729 | |||
| 730 | static void __exit interfacekit_exit(void) | ||
| 731 | { | ||
| 732 | usb_deregister(&interfacekit_driver); | ||
| 733 | } | ||
| 734 | |||
| 735 | module_init(interfacekit_init); | ||
| 736 | module_exit(interfacekit_exit); | ||
| 737 | |||
| 738 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
| 739 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
| 740 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/misc/phidgetmotorcontrol.c b/drivers/usb/misc/phidgetmotorcontrol.c deleted file mode 100644 index 38088b44349e..000000000000 --- a/drivers/usb/misc/phidgetmotorcontrol.c +++ /dev/null | |||
| @@ -1,465 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * USB Phidget MotorControl driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2006 Sean Young <sean@mess.org> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/errno.h> | ||
| 14 | #include <linux/init.h> | ||
| 15 | #include <linux/module.h> | ||
| 16 | #include <linux/usb.h> | ||
| 17 | |||
| 18 | #include "phidget.h" | ||
| 19 | |||
| 20 | #define DRIVER_AUTHOR "Sean Young <sean@mess.org>" | ||
| 21 | #define DRIVER_DESC "USB PhidgetMotorControl Driver" | ||
| 22 | |||
| 23 | #define USB_VENDOR_ID_GLAB 0x06c2 | ||
| 24 | #define USB_DEVICE_ID_MOTORCONTROL 0x0058 | ||
| 25 | |||
| 26 | #define URB_INT_SIZE 8 | ||
| 27 | |||
| 28 | static unsigned long device_no; | ||
| 29 | |||
| 30 | struct motorcontrol { | ||
| 31 | struct usb_device *udev; | ||
| 32 | struct usb_interface *intf; | ||
| 33 | struct device *dev; | ||
| 34 | int dev_no; | ||
| 35 | u8 inputs[4]; | ||
| 36 | s8 desired_speed[2]; | ||
| 37 | s8 speed[2]; | ||
| 38 | s16 _current[2]; | ||
| 39 | s8 acceleration[2]; | ||
| 40 | struct urb *irq; | ||
| 41 | unsigned char *data; | ||
| 42 | dma_addr_t data_dma; | ||
| 43 | |||
| 44 | struct delayed_work do_notify; | ||
| 45 | unsigned long input_events; | ||
| 46 | unsigned long speed_events; | ||
| 47 | unsigned long exceed_events; | ||
| 48 | }; | ||
| 49 | |||
| 50 | static struct usb_device_id id_table[] = { | ||
| 51 | { USB_DEVICE(USB_VENDOR_ID_GLAB, USB_DEVICE_ID_MOTORCONTROL) }, | ||
| 52 | {} | ||
| 53 | }; | ||
| 54 | MODULE_DEVICE_TABLE(usb, id_table); | ||
| 55 | |||
| 56 | static int set_motor(struct motorcontrol *mc, int motor) | ||
| 57 | { | ||
| 58 | u8 *buffer; | ||
| 59 | int speed, speed2, acceleration; | ||
| 60 | int retval; | ||
| 61 | |||
| 62 | buffer = kzalloc(8, GFP_KERNEL); | ||
| 63 | if (!buffer) { | ||
| 64 | dev_err(&mc->intf->dev, "%s - out of memory\n", __func__); | ||
| 65 | return -ENOMEM; | ||
| 66 | } | ||
| 67 | |||
| 68 | acceleration = mc->acceleration[motor] * 10; | ||
| 69 | /* -127 <= speed <= 127 */ | ||
| 70 | speed = (mc->desired_speed[motor] * 127) / 100; | ||
| 71 | /* -0x7300 <= speed2 <= 0x7300 */ | ||
| 72 | speed2 = (mc->desired_speed[motor] * 230 * 128) / 100; | ||
| 73 | |||
| 74 | buffer[0] = motor; | ||
| 75 | buffer[1] = speed; | ||
| 76 | buffer[2] = acceleration >> 8; | ||
| 77 | buffer[3] = acceleration; | ||
| 78 | buffer[4] = speed2 >> 8; | ||
| 79 | buffer[5] = speed2; | ||
| 80 | |||
| 81 | retval = usb_control_msg(mc->udev, | ||
| 82 | usb_sndctrlpipe(mc->udev, 0), | ||
| 83 | 0x09, 0x21, 0x0200, 0x0000, buffer, 8, 2000); | ||
| 84 | |||
| 85 | if (retval != 8) | ||
| 86 | dev_err(&mc->intf->dev, "usb_control_msg returned %d\n", | ||
| 87 | retval); | ||
| 88 | kfree(buffer); | ||
| 89 | |||
| 90 | return retval < 0 ? retval : 0; | ||
| 91 | } | ||
| 92 | |||
| 93 | static void motorcontrol_irq(struct urb *urb) | ||
| 94 | { | ||
| 95 | struct motorcontrol *mc = urb->context; | ||
| 96 | unsigned char *buffer = mc->data; | ||
| 97 | int i, level; | ||
| 98 | int retval; | ||
| 99 | int status = urb->status;; | ||
| 100 | |||
| 101 | switch (status) { | ||
| 102 | case 0: /* success */ | ||
| 103 | break; | ||
| 104 | case -ECONNRESET: /* unlink */ | ||
| 105 | case -ENOENT: | ||
| 106 | case -ESHUTDOWN: | ||
| 107 | return; | ||
| 108 | /* -EPIPE: should clear the halt */ | ||
| 109 | default: /* error */ | ||
| 110 | goto resubmit; | ||
| 111 | } | ||
| 112 | |||
| 113 | /* digital inputs */ | ||
| 114 | for (i=0; i<4; i++) { | ||
| 115 | level = (buffer[0] >> i) & 1; | ||
| 116 | if (mc->inputs[i] != level) { | ||
| 117 | mc->inputs[i] = level; | ||
| 118 | set_bit(i, &mc->input_events); | ||
| 119 | } | ||
| 120 | } | ||
| 121 | |||
| 122 | /* motor speed */ | ||
| 123 | if (buffer[2] == 0) { | ||
| 124 | for (i=0; i<2; i++) { | ||
| 125 | level = ((s8)buffer[4+i]) * 100 / 127; | ||
| 126 | if (mc->speed[i] != level) { | ||
| 127 | mc->speed[i] = level; | ||
| 128 | set_bit(i, &mc->speed_events); | ||
| 129 | } | ||
| 130 | } | ||
| 131 | } else { | ||
| 132 | int index = buffer[3] & 1; | ||
| 133 | |||
| 134 | level = ((s8)buffer[4] << 8) | buffer[5]; | ||
| 135 | level = level * 100 / 29440; | ||
| 136 | if (mc->speed[index] != level) { | ||
| 137 | mc->speed[index] = level; | ||
| 138 | set_bit(index, &mc->speed_events); | ||
| 139 | } | ||
| 140 | |||
| 141 | level = ((s8)buffer[6] << 8) | buffer[7]; | ||
| 142 | mc->_current[index] = level * 100 / 1572; | ||
| 143 | } | ||
| 144 | |||
| 145 | if (buffer[1] & 1) | ||
| 146 | set_bit(0, &mc->exceed_events); | ||
| 147 | |||
| 148 | if (buffer[1] & 2) | ||
| 149 | set_bit(1, &mc->exceed_events); | ||
| 150 | |||
| 151 | if (mc->input_events || mc->exceed_events || mc->speed_events) | ||
| 152 | schedule_delayed_work(&mc->do_notify, 0); | ||
| 153 | |||
| 154 | resubmit: | ||
| 155 | retval = usb_submit_urb(urb, GFP_ATOMIC); | ||
| 156 | if (retval) | ||
| 157 | dev_err(&mc->intf->dev, | ||
| 158 | "can't resubmit intr, %s-%s/motorcontrol0, retval %d\n", | ||
| 159 | mc->udev->bus->bus_name, | ||
| 160 | mc->udev->devpath, retval); | ||
| 161 | } | ||
| 162 | |||
| 163 | static void do_notify(struct work_struct *work) | ||
| 164 | { | ||
| 165 | struct motorcontrol *mc = | ||
| 166 | container_of(work, struct motorcontrol, do_notify.work); | ||
| 167 | int i; | ||
| 168 | char sysfs_file[8]; | ||
| 169 | |||
| 170 | for (i=0; i<4; i++) { | ||
| 171 | if (test_and_clear_bit(i, &mc->input_events)) { | ||
| 172 | sprintf(sysfs_file, "input%d", i); | ||
| 173 | sysfs_notify(&mc->dev->kobj, NULL, sysfs_file); | ||
| 174 | } | ||
| 175 | } | ||
| 176 | |||
| 177 | for (i=0; i<2; i++) { | ||
| 178 | if (test_and_clear_bit(i, &mc->speed_events)) { | ||
| 179 | sprintf(sysfs_file, "speed%d", i); | ||
| 180 | sysfs_notify(&mc->dev->kobj, NULL, sysfs_file); | ||
| 181 | } | ||
| 182 | } | ||
| 183 | |||
| 184 | for (i=0; i<2; i++) { | ||
| 185 | if (test_and_clear_bit(i, &mc->exceed_events)) | ||
| 186 | dev_warn(&mc->intf->dev, | ||
| 187 | "motor #%d exceeds 1.5 Amp current limit\n", i); | ||
| 188 | } | ||
| 189 | } | ||
| 190 | |||
| 191 | #define show_set_speed(value) \ | ||
| 192 | static ssize_t set_speed##value(struct device *dev, \ | ||
| 193 | struct device_attribute *attr, \ | ||
| 194 | const char *buf, size_t count) \ | ||
| 195 | { \ | ||
| 196 | struct motorcontrol *mc = dev_get_drvdata(dev); \ | ||
| 197 | int speed; \ | ||
| 198 | int retval; \ | ||
| 199 | \ | ||
| 200 | if (sscanf(buf, "%d", &speed) < 1) \ | ||
| 201 | return -EINVAL; \ | ||
| 202 | \ | ||
| 203 | if (speed < -100 || speed > 100) \ | ||
| 204 | return -EINVAL; \ | ||
| 205 | \ | ||
| 206 | mc->desired_speed[value] = speed; \ | ||
| 207 | \ | ||
| 208 | retval = set_motor(mc, value); \ | ||
| 209 | \ | ||
| 210 | return retval ? retval : count; \ | ||
| 211 | } \ | ||
| 212 | \ | ||
| 213 | static ssize_t show_speed##value(struct device *dev, \ | ||
| 214 | struct device_attribute *attr, \ | ||
| 215 | char *buf) \ | ||
| 216 | { \ | ||
| 217 | struct motorcontrol *mc = dev_get_drvdata(dev); \ | ||
| 218 | \ | ||
| 219 | return sprintf(buf, "%d\n", mc->speed[value]); \ | ||
| 220 | } | ||
| 221 | |||
| 222 | #define speed_attr(value) \ | ||
| 223 | __ATTR(speed##value, S_IWUGO | S_IRUGO, \ | ||
| 224 | show_speed##value, set_speed##value) | ||
| 225 | |||
| 226 | show_set_speed(0); | ||
| 227 | show_set_speed(1); | ||
| 228 | |||
| 229 | #define show_set_acceleration(value) \ | ||
| 230 | static ssize_t set_acceleration##value(struct device *dev, \ | ||
| 231 | struct device_attribute *attr, \ | ||
| 232 | const char *buf, size_t count) \ | ||
| 233 | { \ | ||
| 234 | struct motorcontrol *mc = dev_get_drvdata(dev); \ | ||
| 235 | int acceleration; \ | ||
| 236 | int retval; \ | ||
| 237 | \ | ||
| 238 | if (sscanf(buf, "%d", &acceleration) < 1) \ | ||
| 239 | return -EINVAL; \ | ||
| 240 | \ | ||
| 241 | if (acceleration < 0 || acceleration > 100) \ | ||
| 242 | return -EINVAL; \ | ||
| 243 | \ | ||
| 244 | mc->acceleration[value] = acceleration; \ | ||
| 245 | \ | ||
| 246 | retval = set_motor(mc, value); \ | ||
| 247 | \ | ||
| 248 | return retval ? retval : count; \ | ||
| 249 | } \ | ||
| 250 | \ | ||
| 251 | static ssize_t show_acceleration##value(struct device *dev, \ | ||
| 252 | struct device_attribute *attr, \ | ||
| 253 | char *buf) \ | ||
| 254 | { \ | ||
| 255 | struct motorcontrol *mc = dev_get_drvdata(dev); \ | ||
| 256 | \ | ||
| 257 | return sprintf(buf, "%d\n", mc->acceleration[value]); \ | ||
| 258 | } | ||
| 259 | |||
| 260 | #define acceleration_attr(value) \ | ||
| 261 | __ATTR(acceleration##value, S_IWUGO | S_IRUGO, \ | ||
| 262 | show_acceleration##value, set_acceleration##value) | ||
| 263 | |||
| 264 | show_set_acceleration(0); | ||
| 265 | show_set_acceleration(1); | ||
| 266 | |||
| 267 | #define show_current(value) \ | ||
| 268 | static ssize_t show_current##value(struct device *dev, \ | ||
| 269 | struct device_attribute *attr, \ | ||
| 270 | char *buf) \ | ||
| 271 | { \ | ||
| 272 | struct motorcontrol *mc = dev_get_drvdata(dev); \ | ||
| 273 | \ | ||
| 274 | return sprintf(buf, "%dmA\n", (int)mc->_current[value]); \ | ||
| 275 | } | ||
| 276 | |||
| 277 | #define current_attr(value) \ | ||
| 278 | __ATTR(current##value, S_IRUGO, show_current##value, NULL) | ||
| 279 | |||
| 280 | show_current(0); | ||
| 281 | show_current(1); | ||
| 282 | |||
| 283 | #define show_input(value) \ | ||
| 284 | static ssize_t show_input##value(struct device *dev, \ | ||
| 285 | struct device_attribute *attr, \ | ||
| 286 | char *buf) \ | ||
| 287 | { \ | ||
| 288 | struct motorcontrol *mc = dev_get_drvdata(dev); \ | ||
| 289 | \ | ||
| 290 | return sprintf(buf, "%d\n", (int)mc->inputs[value]); \ | ||
| 291 | } | ||
| 292 | |||
| 293 | #define input_attr(value) \ | ||
| 294 | __ATTR(input##value, S_IRUGO, show_input##value, NULL) | ||
| 295 | |||
| 296 | show_input(0); | ||
| 297 | show_input(1); | ||
| 298 | show_input(2); | ||
| 299 | show_input(3); | ||
| 300 | |||
| 301 | static struct device_attribute dev_attrs[] = { | ||
| 302 | input_attr(0), | ||
| 303 | input_attr(1), | ||
| 304 | input_attr(2), | ||
| 305 | input_attr(3), | ||
| 306 | speed_attr(0), | ||
| 307 | speed_attr(1), | ||
| 308 | acceleration_attr(0), | ||
| 309 | acceleration_attr(1), | ||
| 310 | current_attr(0), | ||
| 311 | current_attr(1) | ||
| 312 | }; | ||
| 313 | |||
| 314 | static int motorcontrol_probe(struct usb_interface *intf, const struct usb_device_id *id) | ||
| 315 | { | ||
| 316 | struct usb_device *dev = interface_to_usbdev(intf); | ||
| 317 | struct usb_host_interface *interface; | ||
| 318 | struct usb_endpoint_descriptor *endpoint; | ||
| 319 | struct motorcontrol *mc; | ||
| 320 | int pipe, maxp, rc = -ENOMEM; | ||
| 321 | int bit, value, i; | ||
| 322 | |||
| 323 | interface = intf->cur_altsetting; | ||
| 324 | if (interface->desc.bNumEndpoints != 1) | ||
| 325 | return -ENODEV; | ||
| 326 | |||
| 327 | endpoint = &interface->endpoint[0].desc; | ||
| 328 | if (!usb_endpoint_dir_in(endpoint)) | ||
| 329 | return -ENODEV; | ||
| 330 | |||
| 331 | /* | ||
| 332 | * bmAttributes | ||
| 333 | */ | ||
| 334 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); | ||
| 335 | maxp = usb_maxpacket(dev, pipe, usb_pipeout(pipe)); | ||
| 336 | |||
| 337 | mc = kzalloc(sizeof(*mc), GFP_KERNEL); | ||
| 338 | if (!mc) | ||
| 339 | goto out; | ||
| 340 | |||
| 341 | mc->dev_no = -1; | ||
| 342 | mc->data = usb_buffer_alloc(dev, URB_INT_SIZE, GFP_ATOMIC, &mc->data_dma); | ||
| 343 | if (!mc->data) | ||
| 344 | goto out; | ||
| 345 | |||
| 346 | mc->irq = usb_alloc_urb(0, GFP_KERNEL); | ||
| 347 | if (!mc->irq) | ||
| 348 | goto out; | ||
| 349 | |||
| 350 | mc->udev = usb_get_dev(dev); | ||
| 351 | mc->intf = intf; | ||
| 352 | mc->acceleration[0] = mc->acceleration[1] = 10; | ||
| 353 | INIT_DELAYED_WORK(&mc->do_notify, do_notify); | ||
| 354 | usb_fill_int_urb(mc->irq, mc->udev, pipe, mc->data, | ||
| 355 | maxp > URB_INT_SIZE ? URB_INT_SIZE : maxp, | ||
| 356 | motorcontrol_irq, mc, endpoint->bInterval); | ||
| 357 | mc->irq->transfer_dma = mc->data_dma; | ||
| 358 | mc->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
| 359 | |||
| 360 | usb_set_intfdata(intf, mc); | ||
| 361 | |||
| 362 | do { | ||
| 363 | bit = find_first_zero_bit(&device_no, sizeof(device_no)); | ||
| 364 | value = test_and_set_bit(bit, &device_no); | ||
| 365 | } while(value); | ||
| 366 | mc->dev_no = bit; | ||
| 367 | |||
| 368 | mc->dev = device_create(phidget_class, &mc->udev->dev, MKDEV(0, 0), mc, | ||
| 369 | "motorcontrol%d", mc->dev_no); | ||
| 370 | if (IS_ERR(mc->dev)) { | ||
| 371 | rc = PTR_ERR(mc->dev); | ||
| 372 | mc->dev = NULL; | ||
| 373 | goto out; | ||
| 374 | } | ||
| 375 | |||
| 376 | if (usb_submit_urb(mc->irq, GFP_KERNEL)) { | ||
| 377 | rc = -EIO; | ||
| 378 | goto out; | ||
| 379 | } | ||
| 380 | |||
| 381 | for (i=0; i<ARRAY_SIZE(dev_attrs); i++) { | ||
| 382 | rc = device_create_file(mc->dev, &dev_attrs[i]); | ||
| 383 | if (rc) | ||
| 384 | goto out2; | ||
| 385 | } | ||
| 386 | |||
| 387 | dev_info(&intf->dev, "USB PhidgetMotorControl attached\n"); | ||
| 388 | |||
| 389 | return 0; | ||
| 390 | out2: | ||
| 391 | while (i-- > 0) | ||
| 392 | device_remove_file(mc->dev, &dev_attrs[i]); | ||
| 393 | out: | ||
| 394 | if (mc) { | ||
| 395 | usb_free_urb(mc->irq); | ||
| 396 | if (mc->data) | ||
| 397 | usb_buffer_free(dev, URB_INT_SIZE, mc->data, mc->data_dma); | ||
| 398 | if (mc->dev) | ||
| 399 | device_unregister(mc->dev); | ||
| 400 | if (mc->dev_no >= 0) | ||
| 401 | clear_bit(mc->dev_no, &device_no); | ||
| 402 | |||
| 403 | kfree(mc); | ||
| 404 | } | ||
| 405 | |||
| 406 | return rc; | ||
| 407 | } | ||
| 408 | |||
| 409 | static void motorcontrol_disconnect(struct usb_interface *interface) | ||
| 410 | { | ||
| 411 | struct motorcontrol *mc; | ||
| 412 | int i; | ||
| 413 | |||
| 414 | mc = usb_get_intfdata(interface); | ||
| 415 | usb_set_intfdata(interface, NULL); | ||
| 416 | if (!mc) | ||
| 417 | return; | ||
| 418 | |||
| 419 | usb_kill_urb(mc->irq); | ||
| 420 | usb_free_urb(mc->irq); | ||
| 421 | usb_buffer_free(mc->udev, URB_INT_SIZE, mc->data, mc->data_dma); | ||
| 422 | |||
| 423 | cancel_delayed_work(&mc->do_notify); | ||
| 424 | |||
| 425 | for (i=0; i<ARRAY_SIZE(dev_attrs); i++) | ||
| 426 | device_remove_file(mc->dev, &dev_attrs[i]); | ||
| 427 | |||
| 428 | device_unregister(mc->dev); | ||
| 429 | |||
| 430 | usb_put_dev(mc->udev); | ||
| 431 | clear_bit(mc->dev_no, &device_no); | ||
| 432 | kfree(mc); | ||
| 433 | |||
| 434 | dev_info(&interface->dev, "USB PhidgetMotorControl detached\n"); | ||
| 435 | } | ||
| 436 | |||
| 437 | static struct usb_driver motorcontrol_driver = { | ||
| 438 | .name = "phidgetmotorcontrol", | ||
| 439 | .probe = motorcontrol_probe, | ||
| 440 | .disconnect = motorcontrol_disconnect, | ||
| 441 | .id_table = id_table | ||
| 442 | }; | ||
| 443 | |||
| 444 | static int __init motorcontrol_init(void) | ||
| 445 | { | ||
| 446 | int retval = 0; | ||
| 447 | |||
| 448 | retval = usb_register(&motorcontrol_driver); | ||
| 449 | if (retval) | ||
| 450 | err("usb_register failed. Error number %d", retval); | ||
| 451 | |||
| 452 | return retval; | ||
| 453 | } | ||
| 454 | |||
| 455 | static void __exit motorcontrol_exit(void) | ||
| 456 | { | ||
| 457 | usb_deregister(&motorcontrol_driver); | ||
| 458 | } | ||
| 459 | |||
| 460 | module_init(motorcontrol_init); | ||
| 461 | module_exit(motorcontrol_exit); | ||
| 462 | |||
| 463 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
| 464 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
| 465 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c deleted file mode 100644 index bef6fe16364b..000000000000 --- a/drivers/usb/misc/phidgetservo.c +++ /dev/null | |||
| @@ -1,375 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * USB PhidgetServo driver 1.0 | ||
| 3 | * | ||
| 4 | * Copyright (C) 2004, 2006 Sean Young <sean@mess.org> | ||
| 5 | * | ||
| 6 | * This program is free software; you can redistribute it and/or modify | ||
| 7 | * it under the terms of the GNU General Public License as published by | ||
| 8 | * the Free Software Foundation; either version 2 of the License, or | ||
| 9 | * (at your option) any later version. | ||
| 10 | * | ||
| 11 | * This is a driver for the USB PhidgetServo version 2.0 and 3.0 servo | ||
| 12 | * controllers available at: http://www.phidgets.com/ | ||
| 13 | * | ||
| 14 | * Note that the driver takes input as: degrees.minutes | ||
| 15 | * | ||
| 16 | * CAUTION: Generally you should use 0 < degrees < 180 as anything else | ||
| 17 | * is probably beyond the range of your servo and may damage it. | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <linux/kernel.h> | ||
| 21 | #include <linux/errno.h> | ||
| 22 | #include <linux/init.h> | ||
| 23 | #include <linux/slab.h> | ||
| 24 | #include <linux/module.h> | ||
| 25 | #include <linux/usb.h> | ||
| 26 | |||
| 27 | #include "phidget.h" | ||
| 28 | |||
| 29 | #define DRIVER_AUTHOR "Sean Young <sean@mess.org>" | ||
| 30 | #define DRIVER_DESC "USB PhidgetServo Driver" | ||
| 31 | |||
| 32 | #define VENDOR_ID_GLAB 0x06c2 | ||
| 33 | #define DEVICE_ID_GLAB_PHIDGETSERVO_QUAD 0x0038 | ||
| 34 | #define DEVICE_ID_GLAB_PHIDGETSERVO_UNI 0x0039 | ||
| 35 | |||
| 36 | #define VENDOR_ID_WISEGROUP 0x0925 | ||
| 37 | #define VENDOR_ID_WISEGROUP_PHIDGETSERVO_QUAD 0x8101 | ||
| 38 | #define VENDOR_ID_WISEGROUP_PHIDGETSERVO_UNI 0x8104 | ||
| 39 | |||
| 40 | #define SERVO_VERSION_30 0x01 | ||
| 41 | #define SERVO_COUNT_QUAD 0x02 | ||
| 42 | |||
| 43 | static struct usb_device_id id_table[] = { | ||
| 44 | { | ||
| 45 | USB_DEVICE(VENDOR_ID_GLAB, DEVICE_ID_GLAB_PHIDGETSERVO_QUAD), | ||
| 46 | .driver_info = SERVO_VERSION_30 | SERVO_COUNT_QUAD | ||
| 47 | }, | ||
| 48 | { | ||
| 49 | USB_DEVICE(VENDOR_ID_GLAB, DEVICE_ID_GLAB_PHIDGETSERVO_UNI), | ||
| 50 | .driver_info = SERVO_VERSION_30 | ||
| 51 | }, | ||
| 52 | { | ||
| 53 | USB_DEVICE(VENDOR_ID_WISEGROUP, | ||
| 54 | VENDOR_ID_WISEGROUP_PHIDGETSERVO_QUAD), | ||
| 55 | .driver_info = SERVO_COUNT_QUAD | ||
| 56 | }, | ||
| 57 | { | ||
| 58 | USB_DEVICE(VENDOR_ID_WISEGROUP, | ||
| 59 | VENDOR_ID_WISEGROUP_PHIDGETSERVO_UNI), | ||
| 60 | .driver_info = 0 | ||
| 61 | }, | ||
| 62 | {} | ||
| 63 | }; | ||
| 64 | |||
| 65 | MODULE_DEVICE_TABLE(usb, id_table); | ||
| 66 | |||
| 67 | static int unsigned long device_no; | ||
| 68 | |||
| 69 | struct phidget_servo { | ||
| 70 | struct usb_device *udev; | ||
| 71 | struct device *dev; | ||
| 72 | int dev_no; | ||
| 73 | ulong type; | ||
| 74 | int pulse[4]; | ||
| 75 | int degrees[4]; | ||
| 76 | int minutes[4]; | ||
| 77 | }; | ||
| 78 | |||
| 79 | static int | ||
| 80 | change_position_v30(struct phidget_servo *servo, int servo_no, int degrees, | ||
| 81 | int minutes) | ||
| 82 | { | ||
| 83 | int retval; | ||
| 84 | unsigned char *buffer; | ||
| 85 | |||
| 86 | if (degrees < -23 || degrees > 362) | ||
| 87 | return -EINVAL; | ||
| 88 | |||
| 89 | buffer = kmalloc(6, GFP_KERNEL); | ||
| 90 | if (!buffer) { | ||
| 91 | dev_err(&servo->udev->dev, "%s - out of memory\n", | ||
| 92 | __func__); | ||
| 93 | return -ENOMEM; | ||
| 94 | } | ||
| 95 | |||
| 96 | /* | ||
| 97 | * pulse = 0 - 4095 | ||
| 98 | * angle = 0 - 180 degrees | ||
| 99 | * | ||
| 100 | * pulse = angle * 10.6 + 243.8 | ||
| 101 | */ | ||
| 102 | servo->pulse[servo_no] = ((degrees*60 + minutes)*106 + 2438*60)/600; | ||
| 103 | servo->degrees[servo_no]= degrees; | ||
| 104 | servo->minutes[servo_no]= minutes; | ||
| 105 | |||
| 106 | /* | ||
| 107 | * The PhidgetServo v3.0 is controlled by sending 6 bytes, | ||
| 108 | * 4 * 12 bits for each servo. | ||
| 109 | * | ||
| 110 | * low = lower 8 bits pulse | ||
| 111 | * high = higher 4 bits pulse | ||
| 112 | * | ||
| 113 | * offset bits | ||
| 114 | * +---+-----------------+ | ||
| 115 | * | 0 | low 0 | | ||
| 116 | * +---+--------+--------+ | ||
| 117 | * | 1 | high 1 | high 0 | | ||
| 118 | * +---+--------+--------+ | ||
| 119 | * | 2 | low 1 | | ||
| 120 | * +---+-----------------+ | ||
| 121 | * | 3 | low 2 | | ||
| 122 | * +---+--------+--------+ | ||
| 123 | * | 4 | high 3 | high 2 | | ||
| 124 | * +---+--------+--------+ | ||
| 125 | * | 5 | low 3 | | ||
| 126 | * +---+-----------------+ | ||
| 127 | */ | ||
| 128 | |||
| 129 | buffer[0] = servo->pulse[0] & 0xff; | ||
| 130 | buffer[1] = (servo->pulse[0] >> 8 & 0x0f) | ||
| 131 | | (servo->pulse[1] >> 4 & 0xf0); | ||
| 132 | buffer[2] = servo->pulse[1] & 0xff; | ||
| 133 | buffer[3] = servo->pulse[2] & 0xff; | ||
| 134 | buffer[4] = (servo->pulse[2] >> 8 & 0x0f) | ||
| 135 | | (servo->pulse[3] >> 4 & 0xf0); | ||
| 136 | buffer[5] = servo->pulse[3] & 0xff; | ||
| 137 | |||
| 138 | dev_dbg(&servo->udev->dev, | ||
| 139 | "data: %02x %02x %02x %02x %02x %02x\n", | ||
| 140 | buffer[0], buffer[1], buffer[2], | ||
| 141 | buffer[3], buffer[4], buffer[5]); | ||
| 142 | |||
| 143 | retval = usb_control_msg(servo->udev, | ||
| 144 | usb_sndctrlpipe(servo->udev, 0), | ||
| 145 | 0x09, 0x21, 0x0200, 0x0000, buffer, 6, 2000); | ||
| 146 | |||
| 147 | kfree(buffer); | ||
| 148 | |||
| 149 | return retval; | ||
| 150 | } | ||
| 151 | |||
| 152 | static int | ||
| 153 | change_position_v20(struct phidget_servo *servo, int servo_no, int degrees, | ||
| 154 | int minutes) | ||
| 155 | { | ||
| 156 | int retval; | ||
| 157 | unsigned char *buffer; | ||
| 158 | |||
| 159 | if (degrees < -23 || degrees > 278) | ||
| 160 | return -EINVAL; | ||
| 161 | |||
| 162 | buffer = kmalloc(2, GFP_KERNEL); | ||
| 163 | if (!buffer) { | ||
| 164 | dev_err(&servo->udev->dev, "%s - out of memory\n", | ||
| 165 | __func__); | ||
| 166 | return -ENOMEM; | ||
| 167 | } | ||
| 168 | |||
| 169 | /* | ||
| 170 | * angle = 0 - 180 degrees | ||
| 171 | * pulse = angle + 23 | ||
| 172 | */ | ||
| 173 | servo->pulse[servo_no]= degrees + 23; | ||
| 174 | servo->degrees[servo_no]= degrees; | ||
| 175 | servo->minutes[servo_no]= 0; | ||
| 176 | |||
| 177 | /* | ||
| 178 | * The PhidgetServo v2.0 is controlled by sending two bytes. The | ||
| 179 | * first byte is the servo number xor'ed with 2: | ||
| 180 | * | ||
| 181 | * servo 0 = 2 | ||
| 182 | * servo 1 = 3 | ||
| 183 | * servo 2 = 0 | ||
| 184 | * servo 3 = 1 | ||
| 185 | * | ||
| 186 | * The second byte is the position. | ||
| 187 | */ | ||
| 188 | |||
| 189 | buffer[0] = servo_no ^ 2; | ||
| 190 | buffer[1] = servo->pulse[servo_no]; | ||
| 191 | |||
| 192 | dev_dbg(&servo->udev->dev, "data: %02x %02x\n", buffer[0], buffer[1]); | ||
| 193 | |||
| 194 | retval = usb_control_msg(servo->udev, | ||
| 195 | usb_sndctrlpipe(servo->udev, 0), | ||
| 196 | 0x09, 0x21, 0x0200, 0x0000, buffer, 2, 2000); | ||
| 197 | |||
| 198 | kfree(buffer); | ||
| 199 | |||
| 200 | return retval; | ||
| 201 | } | ||
| 202 | |||
| 203 | #define show_set(value) \ | ||
| 204 | static ssize_t set_servo##value (struct device *dev, \ | ||
| 205 | struct device_attribute *attr, \ | ||
| 206 | const char *buf, size_t count) \ | ||
| 207 | { \ | ||
| 208 | int degrees, minutes, retval; \ | ||
| 209 | struct phidget_servo *servo = dev_get_drvdata(dev); \ | ||
| 210 | \ | ||
| 211 | minutes = 0; \ | ||
| 212 | /* must at least convert degrees */ \ | ||
| 213 | if (sscanf(buf, "%d.%d", °rees, &minutes) < 1) { \ | ||
| 214 | return -EINVAL; \ | ||
| 215 | } \ | ||
| 216 | \ | ||
| 217 | if (minutes < 0 || minutes > 59) \ | ||
| 218 | return -EINVAL; \ | ||
| 219 | \ | ||
| 220 | if (servo->type & SERVO_VERSION_30) \ | ||
| 221 | retval = change_position_v30(servo, value, degrees, \ | ||
| 222 | minutes); \ | ||
| 223 | else \ | ||
| 224 | retval = change_position_v20(servo, value, degrees, \ | ||
| 225 | minutes); \ | ||
| 226 | \ | ||
| 227 | return retval < 0 ? retval : count; \ | ||
| 228 | } \ | ||
| 229 | \ | ||
| 230 | static ssize_t show_servo##value (struct device *dev, \ | ||
| 231 | struct device_attribute *attr, \ | ||
| 232 | char *buf) \ | ||
| 233 | { \ | ||
| 234 | struct phidget_servo *servo = dev_get_drvdata(dev); \ | ||
| 235 | \ | ||
| 236 | return sprintf(buf, "%d.%02d\n", servo->degrees[value], \ | ||
| 237 | servo->minutes[value]); \ | ||
| 238 | } | ||
| 239 | |||
| 240 | #define servo_attr(value) \ | ||
| 241 | __ATTR(servo##value, S_IWUGO | S_IRUGO, \ | ||
| 242 | show_servo##value, set_servo##value) | ||
| 243 | show_set(0); | ||
| 244 | show_set(1); | ||
| 245 | show_set(2); | ||
| 246 | show_set(3); | ||
| 247 | |||
| 248 | static struct device_attribute dev_attrs[] = { | ||
| 249 | servo_attr(0), servo_attr(1), servo_attr(2), servo_attr(3) | ||
| 250 | }; | ||
| 251 | |||
| 252 | static int | ||
| 253 | servo_probe(struct usb_interface *interface, const struct usb_device_id *id) | ||
| 254 | { | ||
| 255 | struct usb_device *udev = interface_to_usbdev(interface); | ||
| 256 | struct phidget_servo *dev; | ||
| 257 | int bit, value, rc; | ||
| 258 | int servo_count, i; | ||
| 259 | |||
| 260 | dev = kzalloc(sizeof (struct phidget_servo), GFP_KERNEL); | ||
| 261 | if (dev == NULL) { | ||
| 262 | dev_err(&interface->dev, "%s - out of memory\n", __func__); | ||
| 263 | rc = -ENOMEM; | ||
| 264 | goto out; | ||
| 265 | } | ||
| 266 | |||
| 267 | dev->udev = usb_get_dev(udev); | ||
| 268 | dev->type = id->driver_info; | ||
| 269 | dev->dev_no = -1; | ||
| 270 | usb_set_intfdata(interface, dev); | ||
| 271 | |||
| 272 | do { | ||
| 273 | bit = find_first_zero_bit(&device_no, sizeof(device_no)); | ||
| 274 | value = test_and_set_bit(bit, &device_no); | ||
| 275 | } while (value); | ||
| 276 | dev->dev_no = bit; | ||
| 277 | |||
| 278 | dev->dev = device_create(phidget_class, &dev->udev->dev, MKDEV(0, 0), | ||
| 279 | dev, "servo%d", dev->dev_no); | ||
| 280 | if (IS_ERR(dev->dev)) { | ||
| 281 | rc = PTR_ERR(dev->dev); | ||
| 282 | dev->dev = NULL; | ||
| 283 | goto out; | ||
| 284 | } | ||
| 285 | |||
| 286 | servo_count = dev->type & SERVO_COUNT_QUAD ? 4 : 1; | ||
| 287 | |||
| 288 | for (i=0; i<servo_count; i++) { | ||
| 289 | rc = device_create_file(dev->dev, &dev_attrs[i]); | ||
| 290 | if (rc) | ||
| 291 | goto out2; | ||
| 292 | } | ||
| 293 | |||
| 294 | dev_info(&interface->dev, "USB %d-Motor PhidgetServo v%d.0 attached\n", | ||
| 295 | servo_count, dev->type & SERVO_VERSION_30 ? 3 : 2); | ||
| 296 | |||
| 297 | if (!(dev->type & SERVO_VERSION_30)) | ||
| 298 | dev_info(&interface->dev, | ||
| 299 | "WARNING: v2.0 not tested! Please report if it works.\n"); | ||
| 300 | |||
| 301 | return 0; | ||
| 302 | out2: | ||
| 303 | while (i-- > 0) | ||
| 304 | device_remove_file(dev->dev, &dev_attrs[i]); | ||
| 305 | out: | ||
| 306 | if (dev) { | ||
| 307 | if (dev->dev) | ||
| 308 | device_unregister(dev->dev); | ||
| 309 | if (dev->dev_no >= 0) | ||
| 310 | clear_bit(dev->dev_no, &device_no); | ||
| 311 | |||
| 312 | kfree(dev); | ||
| 313 | } | ||
| 314 | |||
| 315 | return rc; | ||
| 316 | } | ||
| 317 | |||
| 318 | static void | ||
| 319 | servo_disconnect(struct usb_interface *interface) | ||
| 320 | { | ||
| 321 | struct phidget_servo *dev; | ||
| 322 | int servo_count, i; | ||
| 323 | |||
| 324 | dev = usb_get_intfdata(interface); | ||
| 325 | usb_set_intfdata(interface, NULL); | ||
| 326 | |||
| 327 | if (!dev) | ||
| 328 | return; | ||
| 329 | |||
| 330 | servo_count = dev->type & SERVO_COUNT_QUAD ? 4 : 1; | ||
| 331 | |||
| 332 | for (i=0; i<servo_count; i++) | ||
| 333 | device_remove_file(dev->dev, &dev_attrs[i]); | ||
| 334 | |||
| 335 | device_unregister(dev->dev); | ||
| 336 | usb_put_dev(dev->udev); | ||
| 337 | |||
| 338 | dev_info(&interface->dev, "USB %d-Motor PhidgetServo v%d.0 detached\n", | ||
| 339 | servo_count, dev->type & SERVO_VERSION_30 ? 3 : 2); | ||
| 340 | |||
| 341 | clear_bit(dev->dev_no, &device_no); | ||
| 342 | kfree(dev); | ||
| 343 | } | ||
| 344 | |||
| 345 | static struct usb_driver servo_driver = { | ||
| 346 | .name = "phidgetservo", | ||
| 347 | .probe = servo_probe, | ||
| 348 | .disconnect = servo_disconnect, | ||
| 349 | .id_table = id_table | ||
| 350 | }; | ||
| 351 | |||
| 352 | static int __init | ||
| 353 | phidget_servo_init(void) | ||
| 354 | { | ||
| 355 | int retval; | ||
| 356 | |||
| 357 | retval = usb_register(&servo_driver); | ||
| 358 | if (retval) | ||
| 359 | err("usb_register failed. Error number %d", retval); | ||
| 360 | |||
| 361 | return retval; | ||
| 362 | } | ||
| 363 | |||
| 364 | static void __exit | ||
| 365 | phidget_servo_exit(void) | ||
| 366 | { | ||
| 367 | usb_deregister(&servo_driver); | ||
| 368 | } | ||
| 369 | |||
| 370 | module_init(phidget_servo_init); | ||
| 371 | module_exit(phidget_servo_exit); | ||
| 372 | |||
| 373 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
| 374 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
| 375 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index 4cf27c72423e..f8d9045d668a 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c | |||
| @@ -37,10 +37,13 @@ | |||
| 37 | #define MON_IOCX_GET _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get) | 37 | #define MON_IOCX_GET _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get) |
| 38 | #define MON_IOCX_MFETCH _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch) | 38 | #define MON_IOCX_MFETCH _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch) |
| 39 | #define MON_IOCH_MFLUSH _IO(MON_IOC_MAGIC, 8) | 39 | #define MON_IOCH_MFLUSH _IO(MON_IOC_MAGIC, 8) |
| 40 | /* #9 was MON_IOCT_SETAPI */ | ||
| 41 | #define MON_IOCX_GETX _IOW(MON_IOC_MAGIC, 10, struct mon_bin_get) | ||
| 40 | 42 | ||
| 41 | #ifdef CONFIG_COMPAT | 43 | #ifdef CONFIG_COMPAT |
| 42 | #define MON_IOCX_GET32 _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get32) | 44 | #define MON_IOCX_GET32 _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get32) |
| 43 | #define MON_IOCX_MFETCH32 _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch32) | 45 | #define MON_IOCX_MFETCH32 _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch32) |
| 46 | #define MON_IOCX_GETX32 _IOW(MON_IOC_MAGIC, 10, struct mon_bin_get32) | ||
| 44 | #endif | 47 | #endif |
| 45 | 48 | ||
| 46 | /* | 49 | /* |
| @@ -92,7 +95,29 @@ struct mon_bin_hdr { | |||
| 92 | int status; | 95 | int status; |
| 93 | unsigned int len_urb; /* Length of data (submitted or actual) */ | 96 | unsigned int len_urb; /* Length of data (submitted or actual) */ |
| 94 | unsigned int len_cap; /* Delivered length */ | 97 | unsigned int len_cap; /* Delivered length */ |
| 95 | unsigned char setup[SETUP_LEN]; /* Only for Control S-type */ | 98 | union { |
| 99 | unsigned char setup[SETUP_LEN]; /* Only for Control S-type */ | ||
| 100 | struct iso_rec { | ||
| 101 | int error_count; | ||
| 102 | int numdesc; | ||
| 103 | } iso; | ||
| 104 | } s; | ||
| 105 | int interval; | ||
| 106 | int start_frame; | ||
| 107 | unsigned int xfer_flags; | ||
| 108 | unsigned int ndesc; /* Actual number of ISO descriptors */ | ||
| 109 | }; | ||
| 110 | |||
| 111 | /* | ||
| 112 | * ISO vector, packed into the head of data stream. | ||
| 113 | * This has to take 16 bytes to make sure that the end of buffer | ||
| 114 | * wrap is not happening in the middle of a descriptor. | ||
| 115 | */ | ||
| 116 | struct mon_bin_isodesc { | ||
| 117 | int iso_status; | ||
| 118 | unsigned int iso_off; | ||
| 119 | unsigned int iso_len; | ||
| 120 | u32 _pad; | ||
| 96 | }; | 121 | }; |
| 97 | 122 | ||
| 98 | /* per file statistic */ | 123 | /* per file statistic */ |
| @@ -102,7 +127,7 @@ struct mon_bin_stats { | |||
| 102 | }; | 127 | }; |
| 103 | 128 | ||
| 104 | struct mon_bin_get { | 129 | struct mon_bin_get { |
| 105 | struct mon_bin_hdr __user *hdr; /* Only 48 bytes, not 64. */ | 130 | struct mon_bin_hdr __user *hdr; /* Can be 48 bytes or 64. */ |
| 106 | void __user *data; | 131 | void __user *data; |
| 107 | size_t alloc; /* Length of data (can be zero) */ | 132 | size_t alloc; /* Length of data (can be zero) */ |
| 108 | }; | 133 | }; |
| @@ -131,6 +156,11 @@ struct mon_bin_mfetch32 { | |||
| 131 | #define PKT_ALIGN 64 | 156 | #define PKT_ALIGN 64 |
| 132 | #define PKT_SIZE 64 | 157 | #define PKT_SIZE 64 |
| 133 | 158 | ||
| 159 | #define PKT_SZ_API0 48 /* API 0 (2.6.20) size */ | ||
| 160 | #define PKT_SZ_API1 64 /* API 1 size: extra fields */ | ||
| 161 | |||
| 162 | #define ISODESC_MAX 128 /* Same number as usbfs allows, 2048 bytes. */ | ||
| 163 | |||
| 134 | /* max number of USB bus supported */ | 164 | /* max number of USB bus supported */ |
| 135 | #define MON_BIN_MAX_MINOR 128 | 165 | #define MON_BIN_MAX_MINOR 128 |
| 136 | 166 | ||
| @@ -360,12 +390,8 @@ static inline char mon_bin_get_setup(unsigned char *setupb, | |||
| 360 | const struct urb *urb, char ev_type) | 390 | const struct urb *urb, char ev_type) |
| 361 | { | 391 | { |
| 362 | 392 | ||
| 363 | if (!usb_endpoint_xfer_control(&urb->ep->desc) || ev_type != 'S') | ||
| 364 | return '-'; | ||
| 365 | |||
| 366 | if (urb->setup_packet == NULL) | 393 | if (urb->setup_packet == NULL) |
| 367 | return 'Z'; | 394 | return 'Z'; |
| 368 | |||
| 369 | memcpy(setupb, urb->setup_packet, SETUP_LEN); | 395 | memcpy(setupb, urb->setup_packet, SETUP_LEN); |
| 370 | return 0; | 396 | return 0; |
| 371 | } | 397 | } |
| @@ -387,6 +413,26 @@ static char mon_bin_get_data(const struct mon_reader_bin *rp, | |||
| 387 | return 0; | 413 | return 0; |
| 388 | } | 414 | } |
| 389 | 415 | ||
| 416 | static void mon_bin_get_isodesc(const struct mon_reader_bin *rp, | ||
| 417 | unsigned int offset, struct urb *urb, char ev_type, unsigned int ndesc) | ||
| 418 | { | ||
| 419 | struct mon_bin_isodesc *dp; | ||
| 420 | struct usb_iso_packet_descriptor *fp; | ||
| 421 | |||
| 422 | fp = urb->iso_frame_desc; | ||
| 423 | while (ndesc-- != 0) { | ||
| 424 | dp = (struct mon_bin_isodesc *) | ||
| 425 | (rp->b_vec[offset / CHUNK_SIZE].ptr + offset % CHUNK_SIZE); | ||
| 426 | dp->iso_status = fp->status; | ||
| 427 | dp->iso_off = fp->offset; | ||
| 428 | dp->iso_len = (ev_type == 'S') ? fp->length : fp->actual_length; | ||
| 429 | dp->_pad = 0; | ||
| 430 | if ((offset += sizeof(struct mon_bin_isodesc)) >= rp->b_size) | ||
| 431 | offset = 0; | ||
| 432 | fp++; | ||
| 433 | } | ||
| 434 | } | ||
| 435 | |||
| 390 | static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | 436 | static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, |
| 391 | char ev_type, int status) | 437 | char ev_type, int status) |
| 392 | { | 438 | { |
| @@ -396,6 +442,7 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
| 396 | unsigned int urb_length; | 442 | unsigned int urb_length; |
| 397 | unsigned int offset; | 443 | unsigned int offset; |
| 398 | unsigned int length; | 444 | unsigned int length; |
| 445 | unsigned int ndesc, lendesc; | ||
| 399 | unsigned char dir; | 446 | unsigned char dir; |
| 400 | struct mon_bin_hdr *ep; | 447 | struct mon_bin_hdr *ep; |
| 401 | char data_tag = 0; | 448 | char data_tag = 0; |
| @@ -407,6 +454,19 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
| 407 | /* | 454 | /* |
| 408 | * Find the maximum allowable length, then allocate space. | 455 | * Find the maximum allowable length, then allocate space. |
| 409 | */ | 456 | */ |
| 457 | if (usb_endpoint_xfer_isoc(epd)) { | ||
| 458 | if (urb->number_of_packets < 0) { | ||
| 459 | ndesc = 0; | ||
| 460 | } else if (urb->number_of_packets >= ISODESC_MAX) { | ||
| 461 | ndesc = ISODESC_MAX; | ||
| 462 | } else { | ||
| 463 | ndesc = urb->number_of_packets; | ||
| 464 | } | ||
| 465 | } else { | ||
| 466 | ndesc = 0; | ||
| 467 | } | ||
| 468 | lendesc = ndesc*sizeof(struct mon_bin_isodesc); | ||
| 469 | |||
| 410 | urb_length = (ev_type == 'S') ? | 470 | urb_length = (ev_type == 'S') ? |
| 411 | urb->transfer_buffer_length : urb->actual_length; | 471 | urb->transfer_buffer_length : urb->actual_length; |
| 412 | length = urb_length; | 472 | length = urb_length; |
| @@ -429,10 +489,12 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
| 429 | dir = 0; | 489 | dir = 0; |
| 430 | } | 490 | } |
| 431 | 491 | ||
| 432 | if (rp->mmap_active) | 492 | if (rp->mmap_active) { |
| 433 | offset = mon_buff_area_alloc_contiguous(rp, length + PKT_SIZE); | 493 | offset = mon_buff_area_alloc_contiguous(rp, |
| 434 | else | 494 | length + PKT_SIZE + lendesc); |
| 435 | offset = mon_buff_area_alloc(rp, length + PKT_SIZE); | 495 | } else { |
| 496 | offset = mon_buff_area_alloc(rp, length + PKT_SIZE + lendesc); | ||
| 497 | } | ||
| 436 | if (offset == ~0) { | 498 | if (offset == ~0) { |
| 437 | rp->cnt_lost++; | 499 | rp->cnt_lost++; |
| 438 | spin_unlock_irqrestore(&rp->b_lock, flags); | 500 | spin_unlock_irqrestore(&rp->b_lock, flags); |
| @@ -456,9 +518,31 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
| 456 | ep->ts_usec = ts.tv_usec; | 518 | ep->ts_usec = ts.tv_usec; |
| 457 | ep->status = status; | 519 | ep->status = status; |
| 458 | ep->len_urb = urb_length; | 520 | ep->len_urb = urb_length; |
| 459 | ep->len_cap = length; | 521 | ep->len_cap = length + lendesc; |
| 522 | ep->xfer_flags = urb->transfer_flags; | ||
| 523 | |||
| 524 | if (usb_endpoint_xfer_int(epd)) { | ||
| 525 | ep->interval = urb->interval; | ||
| 526 | } else if (usb_endpoint_xfer_isoc(epd)) { | ||
| 527 | ep->interval = urb->interval; | ||
| 528 | ep->start_frame = urb->start_frame; | ||
| 529 | ep->s.iso.error_count = urb->error_count; | ||
| 530 | ep->s.iso.numdesc = urb->number_of_packets; | ||
| 531 | } | ||
| 532 | |||
| 533 | if (usb_endpoint_xfer_control(epd) && ev_type == 'S') { | ||
| 534 | ep->flag_setup = mon_bin_get_setup(ep->s.setup, urb, ev_type); | ||
| 535 | } else { | ||
| 536 | ep->flag_setup = '-'; | ||
| 537 | } | ||
| 538 | |||
| 539 | if (ndesc != 0) { | ||
| 540 | ep->ndesc = ndesc; | ||
| 541 | mon_bin_get_isodesc(rp, offset, urb, ev_type, ndesc); | ||
| 542 | if ((offset += lendesc) >= rp->b_size) | ||
| 543 | offset -= rp->b_size; | ||
| 544 | } | ||
| 460 | 545 | ||
| 461 | ep->flag_setup = mon_bin_get_setup(ep->setup, urb, ev_type); | ||
| 462 | if (length != 0) { | 546 | if (length != 0) { |
| 463 | ep->flag_data = mon_bin_get_data(rp, offset, urb, length); | 547 | ep->flag_data = mon_bin_get_data(rp, offset, urb, length); |
| 464 | if (ep->flag_data != 0) { /* Yes, it's 0x00, not '0' */ | 548 | if (ep->flag_data != 0) { /* Yes, it's 0x00, not '0' */ |
| @@ -592,7 +676,8 @@ err_alloc: | |||
| 592 | * Returns zero or error. | 676 | * Returns zero or error. |
| 593 | */ | 677 | */ |
| 594 | static int mon_bin_get_event(struct file *file, struct mon_reader_bin *rp, | 678 | static int mon_bin_get_event(struct file *file, struct mon_reader_bin *rp, |
| 595 | struct mon_bin_hdr __user *hdr, void __user *data, unsigned int nbytes) | 679 | struct mon_bin_hdr __user *hdr, unsigned int hdrbytes, |
| 680 | void __user *data, unsigned int nbytes) | ||
| 596 | { | 681 | { |
| 597 | unsigned long flags; | 682 | unsigned long flags; |
| 598 | struct mon_bin_hdr *ep; | 683 | struct mon_bin_hdr *ep; |
| @@ -609,7 +694,7 @@ static int mon_bin_get_event(struct file *file, struct mon_reader_bin *rp, | |||
| 609 | 694 | ||
| 610 | ep = MON_OFF2HDR(rp, rp->b_out); | 695 | ep = MON_OFF2HDR(rp, rp->b_out); |
| 611 | 696 | ||
| 612 | if (copy_to_user(hdr, ep, sizeof(struct mon_bin_hdr))) { | 697 | if (copy_to_user(hdr, ep, hdrbytes)) { |
| 613 | mutex_unlock(&rp->fetch_lock); | 698 | mutex_unlock(&rp->fetch_lock); |
| 614 | return -EFAULT; | 699 | return -EFAULT; |
| 615 | } | 700 | } |
| @@ -657,6 +742,7 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf, | |||
| 657 | size_t nbytes, loff_t *ppos) | 742 | size_t nbytes, loff_t *ppos) |
| 658 | { | 743 | { |
| 659 | struct mon_reader_bin *rp = file->private_data; | 744 | struct mon_reader_bin *rp = file->private_data; |
| 745 | unsigned int hdrbytes = PKT_SZ_API0; | ||
| 660 | unsigned long flags; | 746 | unsigned long flags; |
| 661 | struct mon_bin_hdr *ep; | 747 | struct mon_bin_hdr *ep; |
| 662 | unsigned int offset; | 748 | unsigned int offset; |
| @@ -674,8 +760,8 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf, | |||
| 674 | 760 | ||
| 675 | ep = MON_OFF2HDR(rp, rp->b_out); | 761 | ep = MON_OFF2HDR(rp, rp->b_out); |
| 676 | 762 | ||
| 677 | if (rp->b_read < sizeof(struct mon_bin_hdr)) { | 763 | if (rp->b_read < hdrbytes) { |
| 678 | step_len = min(nbytes, sizeof(struct mon_bin_hdr) - rp->b_read); | 764 | step_len = min(nbytes, (size_t)(hdrbytes - rp->b_read)); |
| 679 | ptr = ((char *)ep) + rp->b_read; | 765 | ptr = ((char *)ep) + rp->b_read; |
| 680 | if (step_len && copy_to_user(buf, ptr, step_len)) { | 766 | if (step_len && copy_to_user(buf, ptr, step_len)) { |
| 681 | mutex_unlock(&rp->fetch_lock); | 767 | mutex_unlock(&rp->fetch_lock); |
| @@ -687,13 +773,13 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf, | |||
| 687 | done += step_len; | 773 | done += step_len; |
| 688 | } | 774 | } |
| 689 | 775 | ||
| 690 | if (rp->b_read >= sizeof(struct mon_bin_hdr)) { | 776 | if (rp->b_read >= hdrbytes) { |
| 691 | step_len = ep->len_cap; | 777 | step_len = ep->len_cap; |
| 692 | step_len -= rp->b_read - sizeof(struct mon_bin_hdr); | 778 | step_len -= rp->b_read - hdrbytes; |
| 693 | if (step_len > nbytes) | 779 | if (step_len > nbytes) |
| 694 | step_len = nbytes; | 780 | step_len = nbytes; |
| 695 | offset = rp->b_out + PKT_SIZE; | 781 | offset = rp->b_out + PKT_SIZE; |
| 696 | offset += rp->b_read - sizeof(struct mon_bin_hdr); | 782 | offset += rp->b_read - hdrbytes; |
| 697 | if (offset >= rp->b_size) | 783 | if (offset >= rp->b_size) |
| 698 | offset -= rp->b_size; | 784 | offset -= rp->b_size; |
| 699 | if (copy_from_buf(rp, offset, buf, step_len)) { | 785 | if (copy_from_buf(rp, offset, buf, step_len)) { |
| @@ -709,7 +795,7 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf, | |||
| 709 | /* | 795 | /* |
| 710 | * Check if whole packet was read, and if so, jump to the next one. | 796 | * Check if whole packet was read, and if so, jump to the next one. |
| 711 | */ | 797 | */ |
| 712 | if (rp->b_read >= sizeof(struct mon_bin_hdr) + ep->len_cap) { | 798 | if (rp->b_read >= hdrbytes + ep->len_cap) { |
| 713 | spin_lock_irqsave(&rp->b_lock, flags); | 799 | spin_lock_irqsave(&rp->b_lock, flags); |
| 714 | mon_buff_area_free(rp, PKT_SIZE + ep->len_cap); | 800 | mon_buff_area_free(rp, PKT_SIZE + ep->len_cap); |
| 715 | spin_unlock_irqrestore(&rp->b_lock, flags); | 801 | spin_unlock_irqrestore(&rp->b_lock, flags); |
| @@ -908,6 +994,7 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file, | |||
| 908 | break; | 994 | break; |
| 909 | 995 | ||
| 910 | case MON_IOCX_GET: | 996 | case MON_IOCX_GET: |
| 997 | case MON_IOCX_GETX: | ||
| 911 | { | 998 | { |
| 912 | struct mon_bin_get getb; | 999 | struct mon_bin_get getb; |
| 913 | 1000 | ||
| @@ -917,8 +1004,9 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file, | |||
| 917 | 1004 | ||
| 918 | if (getb.alloc > 0x10000000) /* Want to cast to u32 */ | 1005 | if (getb.alloc > 0x10000000) /* Want to cast to u32 */ |
| 919 | return -EINVAL; | 1006 | return -EINVAL; |
| 920 | ret = mon_bin_get_event(file, rp, | 1007 | ret = mon_bin_get_event(file, rp, getb.hdr, |
| 921 | getb.hdr, getb.data, (unsigned int)getb.alloc); | 1008 | (cmd == MON_IOCX_GET)? PKT_SZ_API0: PKT_SZ_API1, |
| 1009 | getb.data, (unsigned int)getb.alloc); | ||
| 922 | } | 1010 | } |
| 923 | break; | 1011 | break; |
| 924 | 1012 | ||
| @@ -984,16 +1072,18 @@ static long mon_bin_compat_ioctl(struct file *file, | |||
| 984 | 1072 | ||
| 985 | switch (cmd) { | 1073 | switch (cmd) { |
| 986 | 1074 | ||
| 987 | case MON_IOCX_GET32: { | 1075 | case MON_IOCX_GET32: |
| 1076 | case MON_IOCX_GETX32: | ||
| 1077 | { | ||
| 988 | struct mon_bin_get32 getb; | 1078 | struct mon_bin_get32 getb; |
| 989 | 1079 | ||
| 990 | if (copy_from_user(&getb, (void __user *)arg, | 1080 | if (copy_from_user(&getb, (void __user *)arg, |
| 991 | sizeof(struct mon_bin_get32))) | 1081 | sizeof(struct mon_bin_get32))) |
| 992 | return -EFAULT; | 1082 | return -EFAULT; |
| 993 | 1083 | ||
| 994 | ret = mon_bin_get_event(file, rp, | 1084 | ret = mon_bin_get_event(file, rp, compat_ptr(getb.hdr32), |
| 995 | compat_ptr(getb.hdr32), compat_ptr(getb.data32), | 1085 | (cmd == MON_IOCX_GET32)? PKT_SZ_API0: PKT_SZ_API1, |
| 996 | getb.alloc32); | 1086 | compat_ptr(getb.data32), getb.alloc32); |
| 997 | if (ret < 0) | 1087 | if (ret < 0) |
| 998 | return ret; | 1088 | return ret; |
| 999 | } | 1089 | } |
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 9985db08e7db..b66e8544d8b9 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig | |||
| @@ -20,8 +20,8 @@ config USB_MUSB_HDRC | |||
| 20 | it's being used with, including the USB peripheral role, | 20 | it's being used with, including the USB peripheral role, |
| 21 | or the USB host role, or both. | 21 | or the USB host role, or both. |
| 22 | 22 | ||
| 23 | Texas Instruments parts using this IP include DaVinci 644x, | 23 | Texas Instruments familiies using this IP include DaVinci |
| 24 | OMAP 243x, OMAP 343x, and TUSB 6010. | 24 | (35x, 644x ...), OMAP 243x, OMAP 3, and TUSB 6010. |
| 25 | 25 | ||
| 26 | Analog Devices parts using this IP include Blackfin BF54x, | 26 | Analog Devices parts using this IP include Blackfin BF54x, |
| 27 | BF525 and BF527. | 27 | BF525 and BF527. |
| @@ -40,7 +40,7 @@ config USB_MUSB_SOC | |||
| 40 | default y if (BF54x && !BF544) | 40 | default y if (BF54x && !BF544) |
| 41 | default y if (BF52x && !BF522 && !BF523) | 41 | default y if (BF52x && !BF522 && !BF523) |
| 42 | 42 | ||
| 43 | comment "DaVinci 644x USB support" | 43 | comment "DaVinci 35x and 644x USB support" |
| 44 | depends on USB_MUSB_HDRC && ARCH_DAVINCI | 44 | depends on USB_MUSB_HDRC && ARCH_DAVINCI |
| 45 | 45 | ||
| 46 | comment "OMAP 243x high speed USB support" | 46 | comment "OMAP 243x high speed USB support" |
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 2dc7606f319c..10d11ab113ab 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c | |||
| @@ -48,6 +48,9 @@ | |||
| 48 | #include "cppi_dma.h" | 48 | #include "cppi_dma.h" |
| 49 | 49 | ||
| 50 | 50 | ||
| 51 | #define USB_PHY_CTRL IO_ADDRESS(USBPHY_CTL_PADDR) | ||
| 52 | #define DM355_DEEPSLEEP IO_ADDRESS(DM355_DEEPSLEEP_PADDR) | ||
| 53 | |||
| 51 | /* REVISIT (PM) we should be able to keep the PHY in low power mode most | 54 | /* REVISIT (PM) we should be able to keep the PHY in low power mode most |
| 52 | * of the time (24 MHZ oscillator and PLL off, etc) by setting POWER.D0 | 55 | * of the time (24 MHZ oscillator and PLL off, etc) by setting POWER.D0 |
| 53 | * and, when in host mode, autosuspending idle root ports... PHYPLLON | 56 | * and, when in host mode, autosuspending idle root ports... PHYPLLON |
| @@ -56,20 +59,26 @@ | |||
| 56 | 59 | ||
| 57 | static inline void phy_on(void) | 60 | static inline void phy_on(void) |
| 58 | { | 61 | { |
| 59 | /* start the on-chip PHY and its PLL */ | 62 | u32 phy_ctrl = __raw_readl(USB_PHY_CTRL); |
| 60 | __raw_writel(USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON, | 63 | |
| 61 | (void __force __iomem *) IO_ADDRESS(USBPHY_CTL_PADDR)); | 64 | /* power everything up; start the on-chip PHY and its PLL */ |
| 62 | while ((__raw_readl((void __force __iomem *) | 65 | phy_ctrl &= ~(USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN); |
| 63 | IO_ADDRESS(USBPHY_CTL_PADDR)) | 66 | phy_ctrl |= USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON; |
| 64 | & USBPHY_PHYCLKGD) == 0) | 67 | __raw_writel(phy_ctrl, USB_PHY_CTRL); |
| 68 | |||
| 69 | /* wait for PLL to lock before proceeding */ | ||
| 70 | while ((__raw_readl(USB_PHY_CTRL) & USBPHY_PHYCLKGD) == 0) | ||
| 65 | cpu_relax(); | 71 | cpu_relax(); |
| 66 | } | 72 | } |
| 67 | 73 | ||
| 68 | static inline void phy_off(void) | 74 | static inline void phy_off(void) |
| 69 | { | 75 | { |
| 70 | /* powerdown the on-chip PHY and its oscillator */ | 76 | u32 phy_ctrl = __raw_readl(USB_PHY_CTRL); |
| 71 | __raw_writel(USBPHY_OSCPDWN | USBPHY_PHYPDWN, (void __force __iomem *) | 77 | |
| 72 | IO_ADDRESS(USBPHY_CTL_PADDR)); | 78 | /* powerdown the on-chip PHY, its PLL, and the OTG block */ |
| 79 | phy_ctrl &= ~(USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON); | ||
| 80 | phy_ctrl |= USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN; | ||
| 81 | __raw_writel(phy_ctrl, USB_PHY_CTRL); | ||
| 73 | } | 82 | } |
| 74 | 83 | ||
| 75 | static int dma_off = 1; | 84 | static int dma_off = 1; |
| @@ -126,10 +135,6 @@ void musb_platform_disable(struct musb *musb) | |||
| 126 | } | 135 | } |
| 127 | 136 | ||
| 128 | 137 | ||
| 129 | /* REVISIT it's not clear whether DaVinci can support full OTG. */ | ||
| 130 | |||
| 131 | static int vbus_state = -1; | ||
| 132 | |||
| 133 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | 138 | #ifdef CONFIG_USB_MUSB_HDRC_HCD |
| 134 | #define portstate(stmt) stmt | 139 | #define portstate(stmt) stmt |
| 135 | #else | 140 | #else |
| @@ -137,10 +142,19 @@ static int vbus_state = -1; | |||
| 137 | #endif | 142 | #endif |
| 138 | 143 | ||
| 139 | 144 | ||
| 140 | /* VBUS SWITCHING IS BOARD-SPECIFIC */ | 145 | /* |
| 146 | * VBUS SWITCHING IS BOARD-SPECIFIC ... at least for the DM6446 EVM, | ||
| 147 | * which doesn't wire DRVVBUS to the FET that switches it. Unclear | ||
| 148 | * if that's a problem with the DM6446 chip or just with that board. | ||
| 149 | * | ||
| 150 | * In either case, the DM355 EVM automates DRVVBUS the normal way, | ||
| 151 | * when J10 is out, and TI documents it as handling OTG. | ||
| 152 | */ | ||
| 141 | 153 | ||
| 142 | #ifdef CONFIG_MACH_DAVINCI_EVM | 154 | #ifdef CONFIG_MACH_DAVINCI_EVM |
| 143 | 155 | ||
| 156 | static int vbus_state = -1; | ||
| 157 | |||
| 144 | /* I2C operations are always synchronous, and require a task context. | 158 | /* I2C operations are always synchronous, and require a task context. |
| 145 | * With unloaded systems, using the shared workqueue seems to suffice | 159 | * With unloaded systems, using the shared workqueue seems to suffice |
| 146 | * to satisfy the 100msec A_WAIT_VRISE timeout... | 160 | * to satisfy the 100msec A_WAIT_VRISE timeout... |
| @@ -150,12 +164,12 @@ static void evm_deferred_drvvbus(struct work_struct *ignored) | |||
| 150 | gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); | 164 | gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); |
| 151 | vbus_state = !vbus_state; | 165 | vbus_state = !vbus_state; |
| 152 | } | 166 | } |
| 153 | static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus); | ||
| 154 | 167 | ||
| 155 | #endif /* EVM */ | 168 | #endif /* EVM */ |
| 156 | 169 | ||
| 157 | static void davinci_source_power(struct musb *musb, int is_on, int immediate) | 170 | static void davinci_source_power(struct musb *musb, int is_on, int immediate) |
| 158 | { | 171 | { |
| 172 | #ifdef CONFIG_MACH_DAVINCI_EVM | ||
| 159 | if (is_on) | 173 | if (is_on) |
| 160 | is_on = 1; | 174 | is_on = 1; |
| 161 | 175 | ||
| @@ -163,16 +177,17 @@ static void davinci_source_power(struct musb *musb, int is_on, int immediate) | |||
| 163 | return; | 177 | return; |
| 164 | vbus_state = !is_on; /* 0/1 vs "-1 == unknown/init" */ | 178 | vbus_state = !is_on; /* 0/1 vs "-1 == unknown/init" */ |
| 165 | 179 | ||
| 166 | #ifdef CONFIG_MACH_DAVINCI_EVM | ||
| 167 | if (machine_is_davinci_evm()) { | 180 | if (machine_is_davinci_evm()) { |
| 181 | static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus); | ||
| 182 | |||
| 168 | if (immediate) | 183 | if (immediate) |
| 169 | gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); | 184 | gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); |
| 170 | else | 185 | else |
| 171 | schedule_work(&evm_vbus_work); | 186 | schedule_work(&evm_vbus_work); |
| 172 | } | 187 | } |
| 173 | #endif | ||
| 174 | if (immediate) | 188 | if (immediate) |
| 175 | vbus_state = is_on; | 189 | vbus_state = is_on; |
| 190 | #endif | ||
| 176 | } | 191 | } |
| 177 | 192 | ||
| 178 | static void davinci_set_vbus(struct musb *musb, int is_on) | 193 | static void davinci_set_vbus(struct musb *musb, int is_on) |
| @@ -391,6 +406,17 @@ int __init musb_platform_init(struct musb *musb) | |||
| 391 | musb->board_set_vbus = davinci_set_vbus; | 406 | musb->board_set_vbus = davinci_set_vbus; |
| 392 | davinci_source_power(musb, 0, 1); | 407 | davinci_source_power(musb, 0, 1); |
| 393 | 408 | ||
| 409 | /* dm355 EVM swaps D+/D- for signal integrity, and | ||
| 410 | * is clocked from the main 24 MHz crystal. | ||
| 411 | */ | ||
| 412 | if (machine_is_davinci_dm355_evm()) { | ||
| 413 | u32 phy_ctrl = __raw_readl(USB_PHY_CTRL); | ||
| 414 | |||
| 415 | phy_ctrl &= ~(3 << 9); | ||
| 416 | phy_ctrl |= USBPHY_DATAPOL; | ||
| 417 | __raw_writel(phy_ctrl, USB_PHY_CTRL); | ||
| 418 | } | ||
| 419 | |||
| 394 | /* reset the controller */ | 420 | /* reset the controller */ |
| 395 | musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1); | 421 | musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1); |
| 396 | 422 | ||
| @@ -401,8 +427,7 @@ int __init musb_platform_init(struct musb *musb) | |||
| 401 | 427 | ||
| 402 | /* NOTE: irqs are in mixed mode, not bypass to pure-musb */ | 428 | /* NOTE: irqs are in mixed mode, not bypass to pure-musb */ |
| 403 | pr_debug("DaVinci OTG revision %08x phy %03x control %02x\n", | 429 | pr_debug("DaVinci OTG revision %08x phy %03x control %02x\n", |
| 404 | revision, __raw_readl((void __force __iomem *) | 430 | revision, __raw_readl(USB_PHY_CTRL), |
| 405 | IO_ADDRESS(USBPHY_CTL_PADDR)), | ||
| 406 | musb_readb(tibase, DAVINCI_USB_CTRL_REG)); | 431 | musb_readb(tibase, DAVINCI_USB_CTRL_REG)); |
| 407 | 432 | ||
| 408 | musb->isr = davinci_interrupt; | 433 | musb->isr = davinci_interrupt; |
diff --git a/drivers/usb/musb/davinci.h b/drivers/usb/musb/davinci.h index 7fb6238e270f..046c84433cad 100644 --- a/drivers/usb/musb/davinci.h +++ b/drivers/usb/musb/davinci.h | |||
| @@ -15,14 +15,21 @@ | |||
| 15 | */ | 15 | */ |
| 16 | 16 | ||
| 17 | /* Integrated highspeed/otg PHY */ | 17 | /* Integrated highspeed/otg PHY */ |
| 18 | #define USBPHY_CTL_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x34) | 18 | #define USBPHY_CTL_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x34) |
| 19 | #define USBPHY_PHYCLKGD (1 << 8) | 19 | #define USBPHY_DATAPOL BIT(11) /* (dm355) switch D+/D- */ |
| 20 | #define USBPHY_SESNDEN (1 << 7) /* v(sess_end) comparator */ | 20 | #define USBPHY_PHYCLKGD BIT(8) |
| 21 | #define USBPHY_VBDTCTEN (1 << 6) /* v(bus) comparator */ | 21 | #define USBPHY_SESNDEN BIT(7) /* v(sess_end) comparator */ |
| 22 | #define USBPHY_PHYPLLON (1 << 4) /* override pll suspend */ | 22 | #define USBPHY_VBDTCTEN BIT(6) /* v(bus) comparator */ |
| 23 | #define USBPHY_CLKO1SEL (1 << 3) | 23 | #define USBPHY_VBUSSENS BIT(5) /* (dm355,ro) is vbus > 0.5V */ |
| 24 | #define USBPHY_OSCPDWN (1 << 2) | 24 | #define USBPHY_PHYPLLON BIT(4) /* override pll suspend */ |
| 25 | #define USBPHY_PHYPDWN (1 << 0) | 25 | #define USBPHY_CLKO1SEL BIT(3) |
| 26 | #define USBPHY_OSCPDWN BIT(2) | ||
| 27 | #define USBPHY_OTGPDWN BIT(1) | ||
| 28 | #define USBPHY_PHYPDWN BIT(0) | ||
| 29 | |||
| 30 | #define DM355_DEEPSLEEP_PADDR (DAVINCI_SYSTEM_MODULE_BASE + 0x48) | ||
| 31 | #define DRVVBUS_FORCE BIT(2) | ||
| 32 | #define DRVVBUS_OVERRIDE BIT(1) | ||
| 26 | 33 | ||
| 27 | /* For now include usb OTG module registers here */ | 34 | /* For now include usb OTG module registers here */ |
| 28 | #define DAVINCI_USB_VERSION_REG 0x00 | 35 | #define DAVINCI_USB_VERSION_REG 0x00 |
diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c index af77e4659006..338cd1611ab3 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
| @@ -769,7 +769,7 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb, | |||
| 769 | case OTG_STATE_A_SUSPEND: | 769 | case OTG_STATE_A_SUSPEND: |
| 770 | usb_hcd_resume_root_hub(musb_to_hcd(musb)); | 770 | usb_hcd_resume_root_hub(musb_to_hcd(musb)); |
| 771 | musb_root_disconnect(musb); | 771 | musb_root_disconnect(musb); |
| 772 | if (musb->a_wait_bcon != 0) | 772 | if (musb->a_wait_bcon != 0 && is_otg_enabled(musb)) |
| 773 | musb_platform_try_idle(musb, jiffies | 773 | musb_platform_try_idle(musb, jiffies |
| 774 | + msecs_to_jiffies(musb->a_wait_bcon)); | 774 | + msecs_to_jiffies(musb->a_wait_bcon)); |
| 775 | break; | 775 | break; |
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h index 630946a2d9fc..efb39b5e55b5 100644 --- a/drivers/usb/musb/musb_core.h +++ b/drivers/usb/musb/musb_core.h | |||
| @@ -331,7 +331,6 @@ struct musb { | |||
| 331 | struct list_head control; /* of musb_qh */ | 331 | struct list_head control; /* of musb_qh */ |
| 332 | struct list_head in_bulk; /* of musb_qh */ | 332 | struct list_head in_bulk; /* of musb_qh */ |
| 333 | struct list_head out_bulk; /* of musb_qh */ | 333 | struct list_head out_bulk; /* of musb_qh */ |
| 334 | struct musb_qh *periodic[32]; /* tree of interrupt+iso */ | ||
| 335 | #endif | 334 | #endif |
| 336 | 335 | ||
| 337 | /* called with IRQs blocked; ON/nonzero implies starting a session, | 336 | /* called with IRQs blocked; ON/nonzero implies starting a session, |
| @@ -479,10 +478,11 @@ static inline void musb_configure_ep0(struct musb *musb) | |||
| 479 | static inline int musb_read_fifosize(struct musb *musb, | 478 | static inline int musb_read_fifosize(struct musb *musb, |
| 480 | struct musb_hw_ep *hw_ep, u8 epnum) | 479 | struct musb_hw_ep *hw_ep, u8 epnum) |
| 481 | { | 480 | { |
| 481 | void *mbase = musb->mregs; | ||
| 482 | u8 reg = 0; | 482 | u8 reg = 0; |
| 483 | 483 | ||
| 484 | /* read from core using indexed model */ | 484 | /* read from core using indexed model */ |
| 485 | reg = musb_readb(hw_ep->regs, 0x10 + MUSB_FIFOSIZE); | 485 | reg = musb_readb(mbase, MUSB_EP_OFFSET(epnum, MUSB_FIFOSIZE)); |
| 486 | /* 0's returned when no more endpoints */ | 486 | /* 0's returned when no more endpoints */ |
| 487 | if (!reg) | 487 | if (!reg) |
| 488 | return -ENODEV; | 488 | return -ENODEV; |
| @@ -509,6 +509,7 @@ static inline void musb_configure_ep0(struct musb *musb) | |||
| 509 | { | 509 | { |
| 510 | musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE; | 510 | musb->endpoints[0].max_packet_sz_tx = MUSB_EP0_FIFOSIZE; |
| 511 | musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE; | 511 | musb->endpoints[0].max_packet_sz_rx = MUSB_EP0_FIFOSIZE; |
| 512 | musb->endpoints[0].is_shared_fifo = true; | ||
| 512 | } | 513 | } |
| 513 | #endif /* CONFIG_BLACKFIN */ | 514 | #endif /* CONFIG_BLACKFIN */ |
| 514 | 515 | ||
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 6dbbd0786a6a..499c431a6d62 100644 --- a/drivers/usb/musb/musb_host.c +++ b/drivers/usb/musb/musb_host.c | |||
| @@ -64,11 +64,8 @@ | |||
| 64 | * | 64 | * |
| 65 | * - DMA (Mentor/OMAP) ...has at least toggle update problems | 65 | * - DMA (Mentor/OMAP) ...has at least toggle update problems |
| 66 | * | 66 | * |
| 67 | * - Still no traffic scheduling code to make NAKing for bulk or control | 67 | * - [23-feb-2009] minimal traffic scheduling to avoid bulk RX packet |
| 68 | * transfers unable to starve other requests; or to make efficient use | 68 | * starvation ... nothing yet for TX, interrupt, or bulk. |
| 69 | * of hardware with periodic transfers. (Note that network drivers | ||
| 70 | * commonly post bulk reads that stay pending for a long time; these | ||
| 71 | * would make very visible trouble.) | ||
| 72 | * | 69 | * |
| 73 | * - Not tested with HNP, but some SRP paths seem to behave. | 70 | * - Not tested with HNP, but some SRP paths seem to behave. |
| 74 | * | 71 | * |
| @@ -88,11 +85,8 @@ | |||
| 88 | * | 85 | * |
| 89 | * CONTROL transfers all go through ep0. BULK ones go through dedicated IN | 86 | * CONTROL transfers all go through ep0. BULK ones go through dedicated IN |
| 90 | * and OUT endpoints ... hardware is dedicated for those "async" queue(s). | 87 | * and OUT endpoints ... hardware is dedicated for those "async" queue(s). |
| 91 | * | ||
| 92 | * (Yes, bulk _could_ use more of the endpoints than that, and would even | 88 | * (Yes, bulk _could_ use more of the endpoints than that, and would even |
| 93 | * benefit from it ... one remote device may easily be NAKing while others | 89 | * benefit from it.) |
| 94 | * need to perform transfers in that same direction. The same thing could | ||
| 95 | * be done in software though, assuming dma cooperates.) | ||
| 96 | * | 90 | * |
| 97 | * INTERUPPT and ISOCHRONOUS transfers are scheduled to the other endpoints. | 91 | * INTERUPPT and ISOCHRONOUS transfers are scheduled to the other endpoints. |
| 98 | * So far that scheduling is both dumb and optimistic: the endpoint will be | 92 | * So far that scheduling is both dumb and optimistic: the endpoint will be |
| @@ -201,8 +195,9 @@ musb_start_urb(struct musb *musb, int is_in, struct musb_qh *qh) | |||
| 201 | len = urb->iso_frame_desc[0].length; | 195 | len = urb->iso_frame_desc[0].length; |
| 202 | break; | 196 | break; |
| 203 | default: /* bulk, interrupt */ | 197 | default: /* bulk, interrupt */ |
| 204 | buf = urb->transfer_buffer; | 198 | /* actual_length may be nonzero on retry paths */ |
| 205 | len = urb->transfer_buffer_length; | 199 | buf = urb->transfer_buffer + urb->actual_length; |
| 200 | len = urb->transfer_buffer_length - urb->actual_length; | ||
| 206 | } | 201 | } |
| 207 | 202 | ||
| 208 | DBG(4, "qh %p urb %p dev%d ep%d%s%s, hw_ep %d, %p/%d\n", | 203 | DBG(4, "qh %p urb %p dev%d ep%d%s%s, hw_ep %d, %p/%d\n", |
| @@ -395,7 +390,6 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status) | |||
| 395 | * de-allocated if it's tracked and allocated; | 390 | * de-allocated if it's tracked and allocated; |
| 396 | * and where we'd update the schedule tree... | 391 | * and where we'd update the schedule tree... |
| 397 | */ | 392 | */ |
| 398 | musb->periodic[ep->epnum] = NULL; | ||
| 399 | kfree(qh); | 393 | kfree(qh); |
| 400 | qh = NULL; | 394 | qh = NULL; |
| 401 | break; | 395 | break; |
| @@ -1045,7 +1039,8 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb) | |||
| 1045 | 1039 | ||
| 1046 | /* NOTE: this code path would be a good place to PAUSE a | 1040 | /* NOTE: this code path would be a good place to PAUSE a |
| 1047 | * control transfer, if another one is queued, so that | 1041 | * control transfer, if another one is queued, so that |
| 1048 | * ep0 is more likely to stay busy. | 1042 | * ep0 is more likely to stay busy. That's already done |
| 1043 | * for bulk RX transfers. | ||
| 1049 | * | 1044 | * |
| 1050 | * if (qh->ring.next != &musb->control), then | 1045 | * if (qh->ring.next != &musb->control), then |
| 1051 | * we have a candidate... NAKing is *NOT* an error | 1046 | * we have a candidate... NAKing is *NOT* an error |
| @@ -1197,6 +1192,7 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
| 1197 | /* NOTE: this code path would be a good place to PAUSE a | 1192 | /* NOTE: this code path would be a good place to PAUSE a |
| 1198 | * transfer, if there's some other (nonperiodic) tx urb | 1193 | * transfer, if there's some other (nonperiodic) tx urb |
| 1199 | * that could use this fifo. (dma complicates it...) | 1194 | * that could use this fifo. (dma complicates it...) |
| 1195 | * That's already done for bulk RX transfers. | ||
| 1200 | * | 1196 | * |
| 1201 | * if (bulk && qh->ring.next != &musb->out_bulk), then | 1197 | * if (bulk && qh->ring.next != &musb->out_bulk), then |
| 1202 | * we have a candidate... NAKing is *NOT* an error | 1198 | * we have a candidate... NAKing is *NOT* an error |
| @@ -1358,6 +1354,50 @@ finish: | |||
| 1358 | 1354 | ||
| 1359 | #endif | 1355 | #endif |
| 1360 | 1356 | ||
| 1357 | /* Schedule next QH from musb->in_bulk and move the current qh to | ||
| 1358 | * the end; avoids starvation for other endpoints. | ||
| 1359 | */ | ||
| 1360 | static void musb_bulk_rx_nak_timeout(struct musb *musb, struct musb_hw_ep *ep) | ||
| 1361 | { | ||
| 1362 | struct dma_channel *dma; | ||
| 1363 | struct urb *urb; | ||
| 1364 | void __iomem *mbase = musb->mregs; | ||
| 1365 | void __iomem *epio = ep->regs; | ||
| 1366 | struct musb_qh *cur_qh, *next_qh; | ||
| 1367 | u16 rx_csr; | ||
| 1368 | |||
| 1369 | musb_ep_select(mbase, ep->epnum); | ||
| 1370 | dma = is_dma_capable() ? ep->rx_channel : NULL; | ||
| 1371 | |||
| 1372 | /* clear nak timeout bit */ | ||
| 1373 | rx_csr = musb_readw(epio, MUSB_RXCSR); | ||
| 1374 | rx_csr |= MUSB_RXCSR_H_WZC_BITS; | ||
| 1375 | rx_csr &= ~MUSB_RXCSR_DATAERROR; | ||
| 1376 | musb_writew(epio, MUSB_RXCSR, rx_csr); | ||
| 1377 | |||
| 1378 | cur_qh = first_qh(&musb->in_bulk); | ||
| 1379 | if (cur_qh) { | ||
| 1380 | urb = next_urb(cur_qh); | ||
| 1381 | if (dma_channel_status(dma) == MUSB_DMA_STATUS_BUSY) { | ||
| 1382 | dma->status = MUSB_DMA_STATUS_CORE_ABORT; | ||
| 1383 | musb->dma_controller->channel_abort(dma); | ||
| 1384 | urb->actual_length += dma->actual_len; | ||
| 1385 | dma->actual_len = 0L; | ||
| 1386 | } | ||
| 1387 | musb_save_toggle(ep, 1, urb); | ||
| 1388 | |||
| 1389 | /* move cur_qh to end of queue */ | ||
| 1390 | list_move_tail(&cur_qh->ring, &musb->in_bulk); | ||
| 1391 | |||
| 1392 | /* get the next qh from musb->in_bulk */ | ||
| 1393 | next_qh = first_qh(&musb->in_bulk); | ||
| 1394 | |||
| 1395 | /* set rx_reinit and schedule the next qh */ | ||
| 1396 | ep->rx_reinit = 1; | ||
| 1397 | musb_start_urb(musb, 1, next_qh); | ||
| 1398 | } | ||
| 1399 | } | ||
| 1400 | |||
| 1361 | /* | 1401 | /* |
| 1362 | * Service an RX interrupt for the given IN endpoint; docs cover bulk, iso, | 1402 | * Service an RX interrupt for the given IN endpoint; docs cover bulk, iso, |
| 1363 | * and high-bandwidth IN transfer cases. | 1403 | * and high-bandwidth IN transfer cases. |
| @@ -1421,18 +1461,26 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
| 1421 | } else if (rx_csr & MUSB_RXCSR_DATAERROR) { | 1461 | } else if (rx_csr & MUSB_RXCSR_DATAERROR) { |
| 1422 | 1462 | ||
| 1423 | if (USB_ENDPOINT_XFER_ISOC != qh->type) { | 1463 | if (USB_ENDPOINT_XFER_ISOC != qh->type) { |
| 1424 | /* NOTE this code path would be a good place to PAUSE a | 1464 | DBG(6, "RX end %d NAK timeout\n", epnum); |
| 1425 | * transfer, if there's some other (nonperiodic) rx urb | 1465 | |
| 1426 | * that could use this fifo. (dma complicates it...) | 1466 | /* NOTE: NAKing is *NOT* an error, so we want to |
| 1467 | * continue. Except ... if there's a request for | ||
| 1468 | * another QH, use that instead of starving it. | ||
| 1427 | * | 1469 | * |
| 1428 | * if (bulk && qh->ring.next != &musb->in_bulk), then | 1470 | * Devices like Ethernet and serial adapters keep |
| 1429 | * we have a candidate... NAKing is *NOT* an error | 1471 | * reads posted at all times, which will starve |
| 1472 | * other devices without this logic. | ||
| 1430 | */ | 1473 | */ |
| 1431 | DBG(6, "RX end %d NAK timeout\n", epnum); | 1474 | if (usb_pipebulk(urb->pipe) |
| 1475 | && qh->mux == 1 | ||
| 1476 | && !list_is_singular(&musb->in_bulk)) { | ||
| 1477 | musb_bulk_rx_nak_timeout(musb, hw_ep); | ||
| 1478 | return; | ||
| 1479 | } | ||
| 1432 | musb_ep_select(mbase, epnum); | 1480 | musb_ep_select(mbase, epnum); |
| 1433 | musb_writew(epio, MUSB_RXCSR, | 1481 | rx_csr |= MUSB_RXCSR_H_WZC_BITS; |
| 1434 | MUSB_RXCSR_H_WZC_BITS | 1482 | rx_csr &= ~MUSB_RXCSR_DATAERROR; |
| 1435 | | MUSB_RXCSR_H_REQPKT); | 1483 | musb_writew(epio, MUSB_RXCSR, rx_csr); |
| 1436 | 1484 | ||
| 1437 | goto finish; | 1485 | goto finish; |
| 1438 | } else { | 1486 | } else { |
| @@ -1711,31 +1759,27 @@ static int musb_schedule( | |||
| 1711 | 1759 | ||
| 1712 | /* else, periodic transfers get muxed to other endpoints */ | 1760 | /* else, periodic transfers get muxed to other endpoints */ |
| 1713 | 1761 | ||
| 1714 | /* FIXME this doesn't consider direction, so it can only | 1762 | /* |
| 1715 | * work for one half of the endpoint hardware, and assumes | 1763 | * We know this qh hasn't been scheduled, so all we need to do |
| 1716 | * the previous cases handled all non-shared endpoints... | ||
| 1717 | */ | ||
| 1718 | |||
| 1719 | /* we know this qh hasn't been scheduled, so all we need to do | ||
| 1720 | * is choose which hardware endpoint to put it on ... | 1764 | * is choose which hardware endpoint to put it on ... |
| 1721 | * | 1765 | * |
| 1722 | * REVISIT what we really want here is a regular schedule tree | 1766 | * REVISIT what we really want here is a regular schedule tree |
| 1723 | * like e.g. OHCI uses, but for now musb->periodic is just an | 1767 | * like e.g. OHCI uses. |
| 1724 | * array of the _single_ logical endpoint associated with a | ||
| 1725 | * given physical one (identity mapping logical->physical). | ||
| 1726 | * | ||
| 1727 | * that simplistic approach makes TT scheduling a lot simpler; | ||
| 1728 | * there is none, and thus none of its complexity... | ||
| 1729 | */ | 1768 | */ |
| 1730 | best_diff = 4096; | 1769 | best_diff = 4096; |
| 1731 | best_end = -1; | 1770 | best_end = -1; |
| 1732 | 1771 | ||
| 1733 | for (epnum = 1; epnum < musb->nr_endpoints; epnum++) { | 1772 | for (epnum = 1, hw_ep = musb->endpoints + 1; |
| 1773 | epnum < musb->nr_endpoints; | ||
| 1774 | epnum++, hw_ep++) { | ||
| 1734 | int diff; | 1775 | int diff; |
| 1735 | 1776 | ||
| 1736 | if (musb->periodic[epnum]) | 1777 | if (is_in || hw_ep->is_shared_fifo) { |
| 1778 | if (hw_ep->in_qh != NULL) | ||
| 1779 | continue; | ||
| 1780 | } else if (hw_ep->out_qh != NULL) | ||
| 1737 | continue; | 1781 | continue; |
| 1738 | hw_ep = &musb->endpoints[epnum]; | 1782 | |
| 1739 | if (hw_ep == musb->bulk_ep) | 1783 | if (hw_ep == musb->bulk_ep) |
| 1740 | continue; | 1784 | continue; |
| 1741 | 1785 | ||
| @@ -1756,6 +1800,17 @@ static int musb_schedule( | |||
| 1756 | head = &musb->in_bulk; | 1800 | head = &musb->in_bulk; |
| 1757 | else | 1801 | else |
| 1758 | head = &musb->out_bulk; | 1802 | head = &musb->out_bulk; |
| 1803 | |||
| 1804 | /* Enable bulk RX NAK timeout scheme when bulk requests are | ||
| 1805 | * multiplexed. This scheme doen't work in high speed to full | ||
| 1806 | * speed scenario as NAK interrupts are not coming from a | ||
| 1807 | * full speed device connected to a high speed device. | ||
| 1808 | * NAK timeout interval is 8 (128 uframe or 16ms) for HS and | ||
| 1809 | * 4 (8 frame or 8ms) for FS device. | ||
| 1810 | */ | ||
| 1811 | if (is_in && qh->dev) | ||
| 1812 | qh->intv_reg = | ||
| 1813 | (USB_SPEED_HIGH == qh->dev->speed) ? 8 : 4; | ||
| 1759 | goto success; | 1814 | goto success; |
| 1760 | } else if (best_end < 0) { | 1815 | } else if (best_end < 0) { |
| 1761 | return -ENOSPC; | 1816 | return -ENOSPC; |
| @@ -1764,7 +1819,6 @@ static int musb_schedule( | |||
| 1764 | idle = 1; | 1819 | idle = 1; |
| 1765 | qh->mux = 0; | 1820 | qh->mux = 0; |
| 1766 | hw_ep = musb->endpoints + best_end; | 1821 | hw_ep = musb->endpoints + best_end; |
| 1767 | musb->periodic[best_end] = qh; | ||
| 1768 | DBG(4, "qh %p periodic slot %d\n", qh, best_end); | 1822 | DBG(4, "qh %p periodic slot %d\n", qh, best_end); |
| 1769 | success: | 1823 | success: |
| 1770 | if (head) { | 1824 | if (head) { |
| @@ -1888,13 +1942,11 @@ static int musb_urb_enqueue( | |||
| 1888 | * | 1942 | * |
| 1889 | * The downside of disabling this is that transfer scheduling | 1943 | * The downside of disabling this is that transfer scheduling |
| 1890 | * gets VERY unfair for nonperiodic transfers; a misbehaving | 1944 | * gets VERY unfair for nonperiodic transfers; a misbehaving |
| 1891 | * peripheral could make that hurt. Or for reads, one that's | 1945 | * peripheral could make that hurt. That's perfectly normal |
| 1892 | * perfectly normal: network and other drivers keep reads | 1946 | * for reads from network or serial adapters ... so we have |
| 1893 | * posted at all times, having one pending for a week should | 1947 | * partial NAKlimit support for bulk RX. |
| 1894 | * be perfectly safe. | ||
| 1895 | * | 1948 | * |
| 1896 | * The upside of disabling it is avoidng transfer scheduling | 1949 | * The upside of disabling it is simpler transfer scheduling. |
| 1897 | * code to put this aside for while. | ||
| 1898 | */ | 1950 | */ |
| 1899 | interval = 0; | 1951 | interval = 0; |
| 1900 | } | 1952 | } |
diff --git a/drivers/usb/musb/musb_virthub.c b/drivers/usb/musb/musb_virthub.c index e0e9ce584175..bf677acc83db 100644 --- a/drivers/usb/musb/musb_virthub.c +++ b/drivers/usb/musb/musb_virthub.c | |||
| @@ -285,7 +285,7 @@ int musb_hub_control( | |||
| 285 | desc->bDescLength = 9; | 285 | desc->bDescLength = 9; |
| 286 | desc->bDescriptorType = 0x29; | 286 | desc->bDescriptorType = 0x29; |
| 287 | desc->bNbrPorts = 1; | 287 | desc->bNbrPorts = 1; |
| 288 | desc->wHubCharacteristics = __constant_cpu_to_le16( | 288 | desc->wHubCharacteristics = cpu_to_le16( |
| 289 | 0x0001 /* per-port power switching */ | 289 | 0x0001 /* per-port power switching */ |
| 290 | | 0x0010 /* no overcurrent reporting */ | 290 | | 0x0010 /* no overcurrent reporting */ |
| 291 | ); | 291 | ); |
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig index ee55b449ffde..aa884d072f0b 100644 --- a/drivers/usb/otg/Kconfig +++ b/drivers/usb/otg/Kconfig | |||
| @@ -43,7 +43,7 @@ config ISP1301_OMAP | |||
| 43 | 43 | ||
| 44 | config TWL4030_USB | 44 | config TWL4030_USB |
| 45 | tristate "TWL4030 USB Transceiver Driver" | 45 | tristate "TWL4030 USB Transceiver Driver" |
| 46 | depends on TWL4030_CORE | 46 | depends on TWL4030_CORE && REGULATOR_TWL4030 |
| 47 | select USB_OTG_UTILS | 47 | select USB_OTG_UTILS |
| 48 | help | 48 | help |
| 49 | Enable this to support the USB OTG transceiver on TWL4030 | 49 | Enable this to support the USB OTG transceiver on TWL4030 |
| @@ -51,4 +51,12 @@ config TWL4030_USB | |||
| 51 | This transceiver supports high and full speed devices plus, | 51 | This transceiver supports high and full speed devices plus, |
| 52 | in host mode, low speed. | 52 | in host mode, low speed. |
| 53 | 53 | ||
| 54 | config NOP_USB_XCEIV | ||
| 55 | tristate "NOP USB Transceiver Driver" | ||
| 56 | select USB_OTG_UTILS | ||
| 57 | help | ||
| 58 | this driver is to be used by all the usb transceiver which are either | ||
| 59 | built-in with usb ip or which are autonomous and doesn't require any | ||
| 60 | phy programming such as ISP1x04 etc. | ||
| 61 | |||
| 54 | endif # USB || OTG | 62 | endif # USB || OTG |
diff --git a/drivers/usb/otg/Makefile b/drivers/usb/otg/Makefile index d73c7cf5e2f7..208167856529 100644 --- a/drivers/usb/otg/Makefile +++ b/drivers/usb/otg/Makefile | |||
| @@ -9,6 +9,7 @@ obj-$(CONFIG_USB_OTG_UTILS) += otg.o | |||
| 9 | obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o | 9 | obj-$(CONFIG_USB_GPIO_VBUS) += gpio_vbus.o |
| 10 | obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o | 10 | obj-$(CONFIG_ISP1301_OMAP) += isp1301_omap.o |
| 11 | obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o | 11 | obj-$(CONFIG_TWL4030_USB) += twl4030-usb.o |
| 12 | obj-$(CONFIG_NOP_USB_XCEIV) += nop-usb-xceiv.o | ||
| 12 | 13 | ||
| 13 | ccflags-$(CONFIG_USB_DEBUG) += -DDEBUG | 14 | ccflags-$(CONFIG_USB_DEBUG) += -DDEBUG |
| 14 | ccflags-$(CONFIG_USB_GADGET_DEBUG) += -DDEBUG | 15 | ccflags-$(CONFIG_USB_GADGET_DEBUG) += -DDEBUG |
diff --git a/drivers/usb/otg/gpio_vbus.c b/drivers/usb/otg/gpio_vbus.c index 63a6036f04be..1c26c94513e9 100644 --- a/drivers/usb/otg/gpio_vbus.c +++ b/drivers/usb/otg/gpio_vbus.c | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include <linux/gpio.h> | 13 | #include <linux/gpio.h> |
| 14 | #include <linux/interrupt.h> | 14 | #include <linux/interrupt.h> |
| 15 | #include <linux/usb.h> | 15 | #include <linux/usb.h> |
| 16 | #include <linux/workqueue.h> | ||
| 16 | 17 | ||
| 17 | #include <linux/regulator/consumer.h> | 18 | #include <linux/regulator/consumer.h> |
| 18 | 19 | ||
| @@ -34,6 +35,7 @@ struct gpio_vbus_data { | |||
| 34 | struct regulator *vbus_draw; | 35 | struct regulator *vbus_draw; |
| 35 | int vbus_draw_enabled; | 36 | int vbus_draw_enabled; |
| 36 | unsigned mA; | 37 | unsigned mA; |
| 38 | struct work_struct work; | ||
| 37 | }; | 39 | }; |
| 38 | 40 | ||
| 39 | 41 | ||
| @@ -76,24 +78,26 @@ static void set_vbus_draw(struct gpio_vbus_data *gpio_vbus, unsigned mA) | |||
| 76 | gpio_vbus->mA = mA; | 78 | gpio_vbus->mA = mA; |
| 77 | } | 79 | } |
| 78 | 80 | ||
| 79 | /* VBUS change IRQ handler */ | 81 | static int is_vbus_powered(struct gpio_vbus_mach_info *pdata) |
| 80 | static irqreturn_t gpio_vbus_irq(int irq, void *data) | ||
| 81 | { | 82 | { |
| 82 | struct platform_device *pdev = data; | 83 | int vbus; |
| 83 | struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; | ||
| 84 | struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); | ||
| 85 | int gpio, vbus; | ||
| 86 | 84 | ||
| 87 | vbus = gpio_get_value(pdata->gpio_vbus); | 85 | vbus = gpio_get_value(pdata->gpio_vbus); |
| 88 | if (pdata->gpio_vbus_inverted) | 86 | if (pdata->gpio_vbus_inverted) |
| 89 | vbus = !vbus; | 87 | vbus = !vbus; |
| 90 | 88 | ||
| 91 | dev_dbg(&pdev->dev, "VBUS %s (gadget: %s)\n", | 89 | return vbus; |
| 92 | vbus ? "supplied" : "inactive", | 90 | } |
| 93 | gpio_vbus->otg.gadget ? gpio_vbus->otg.gadget->name : "none"); | 91 | |
| 92 | static void gpio_vbus_work(struct work_struct *work) | ||
| 93 | { | ||
| 94 | struct gpio_vbus_data *gpio_vbus = | ||
| 95 | container_of(work, struct gpio_vbus_data, work); | ||
| 96 | struct gpio_vbus_mach_info *pdata = gpio_vbus->dev->platform_data; | ||
| 97 | int gpio; | ||
| 94 | 98 | ||
| 95 | if (!gpio_vbus->otg.gadget) | 99 | if (!gpio_vbus->otg.gadget) |
| 96 | return IRQ_HANDLED; | 100 | return; |
| 97 | 101 | ||
| 98 | /* Peripheral controllers which manage the pullup themselves won't have | 102 | /* Peripheral controllers which manage the pullup themselves won't have |
| 99 | * gpio_pullup configured here. If it's configured here, we'll do what | 103 | * gpio_pullup configured here. If it's configured here, we'll do what |
| @@ -101,7 +105,7 @@ static irqreturn_t gpio_vbus_irq(int irq, void *data) | |||
| 101 | * that may complicate usb_gadget_{,dis}connect() support. | 105 | * that may complicate usb_gadget_{,dis}connect() support. |
| 102 | */ | 106 | */ |
| 103 | gpio = pdata->gpio_pullup; | 107 | gpio = pdata->gpio_pullup; |
| 104 | if (vbus) { | 108 | if (is_vbus_powered(pdata)) { |
| 105 | gpio_vbus->otg.state = OTG_STATE_B_PERIPHERAL; | 109 | gpio_vbus->otg.state = OTG_STATE_B_PERIPHERAL; |
| 106 | usb_gadget_vbus_connect(gpio_vbus->otg.gadget); | 110 | usb_gadget_vbus_connect(gpio_vbus->otg.gadget); |
| 107 | 111 | ||
| @@ -121,6 +125,21 @@ static irqreturn_t gpio_vbus_irq(int irq, void *data) | |||
| 121 | usb_gadget_vbus_disconnect(gpio_vbus->otg.gadget); | 125 | usb_gadget_vbus_disconnect(gpio_vbus->otg.gadget); |
| 122 | gpio_vbus->otg.state = OTG_STATE_B_IDLE; | 126 | gpio_vbus->otg.state = OTG_STATE_B_IDLE; |
| 123 | } | 127 | } |
| 128 | } | ||
| 129 | |||
| 130 | /* VBUS change IRQ handler */ | ||
| 131 | static irqreturn_t gpio_vbus_irq(int irq, void *data) | ||
| 132 | { | ||
| 133 | struct platform_device *pdev = data; | ||
| 134 | struct gpio_vbus_mach_info *pdata = pdev->dev.platform_data; | ||
| 135 | struct gpio_vbus_data *gpio_vbus = platform_get_drvdata(pdev); | ||
| 136 | |||
| 137 | dev_dbg(&pdev->dev, "VBUS %s (gadget: %s)\n", | ||
| 138 | is_vbus_powered(pdata) ? "supplied" : "inactive", | ||
| 139 | gpio_vbus->otg.gadget ? gpio_vbus->otg.gadget->name : "none"); | ||
| 140 | |||
| 141 | if (gpio_vbus->otg.gadget) | ||
| 142 | schedule_work(&gpio_vbus->work); | ||
| 124 | 143 | ||
| 125 | return IRQ_HANDLED; | 144 | return IRQ_HANDLED; |
| 126 | } | 145 | } |
| @@ -257,6 +276,7 @@ static int __init gpio_vbus_probe(struct platform_device *pdev) | |||
| 257 | irq, err); | 276 | irq, err); |
| 258 | goto err_irq; | 277 | goto err_irq; |
| 259 | } | 278 | } |
| 279 | INIT_WORK(&gpio_vbus->work, gpio_vbus_work); | ||
| 260 | 280 | ||
| 261 | /* only active when a gadget is registered */ | 281 | /* only active when a gadget is registered */ |
| 262 | err = otg_set_transceiver(&gpio_vbus->otg); | 282 | err = otg_set_transceiver(&gpio_vbus->otg); |
diff --git a/drivers/usb/otg/nop-usb-xceiv.c b/drivers/usb/otg/nop-usb-xceiv.c new file mode 100644 index 000000000000..4b933f646f2e --- /dev/null +++ b/drivers/usb/otg/nop-usb-xceiv.c | |||
| @@ -0,0 +1,180 @@ | |||
| 1 | /* | ||
| 2 | * drivers/usb/otg/nop-usb-xceiv.c | ||
| 3 | * | ||
| 4 | * NOP USB transceiver for all USB transceiver which are either built-in | ||
| 5 | * into USB IP or which are mostly autonomous. | ||
| 6 | * | ||
| 7 | * Copyright (C) 2009 Texas Instruments Inc | ||
| 8 | * Author: Ajay Kumar Gupta <ajay.gupta@ti.com> | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify | ||
| 11 | * it under the terms of the GNU General Public License as published by | ||
| 12 | * the Free Software Foundation; either version 2 of the License, or | ||
| 13 | * (at your option) any later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, | ||
| 16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 18 | * GNU General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License | ||
| 21 | * along with this program; if not, write to the Free Software | ||
| 22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 23 | * | ||
| 24 | * Current status: | ||
| 25 | * this is to add "nop" transceiver for all those phy which is | ||
| 26 | * autonomous such as isp1504 etc. | ||
| 27 | */ | ||
| 28 | |||
| 29 | #include <linux/module.h> | ||
| 30 | #include <linux/platform_device.h> | ||
| 31 | #include <linux/dma-mapping.h> | ||
| 32 | #include <linux/usb/otg.h> | ||
| 33 | |||
| 34 | struct nop_usb_xceiv { | ||
| 35 | struct otg_transceiver otg; | ||
| 36 | struct device *dev; | ||
| 37 | }; | ||
| 38 | |||
| 39 | static u64 nop_xceiv_dmamask = DMA_32BIT_MASK; | ||
| 40 | |||
| 41 | static struct platform_device nop_xceiv_device = { | ||
| 42 | .name = "nop_usb_xceiv", | ||
| 43 | .id = -1, | ||
| 44 | .dev = { | ||
| 45 | .dma_mask = &nop_xceiv_dmamask, | ||
| 46 | .coherent_dma_mask = DMA_32BIT_MASK, | ||
| 47 | .platform_data = NULL, | ||
| 48 | }, | ||
| 49 | }; | ||
| 50 | |||
| 51 | void usb_nop_xceiv_register(void) | ||
| 52 | { | ||
| 53 | if (platform_device_register(&nop_xceiv_device) < 0) { | ||
| 54 | printk(KERN_ERR "Unable to register usb nop transceiver\n"); | ||
| 55 | return; | ||
| 56 | } | ||
| 57 | } | ||
| 58 | |||
| 59 | void usb_nop_xceiv_unregister(void) | ||
| 60 | { | ||
| 61 | platform_device_unregister(&nop_xceiv_device); | ||
| 62 | } | ||
| 63 | |||
| 64 | static inline struct nop_usb_xceiv *xceiv_to_nop(struct otg_transceiver *x) | ||
| 65 | { | ||
| 66 | return container_of(x, struct nop_usb_xceiv, otg); | ||
| 67 | } | ||
| 68 | |||
| 69 | static int nop_set_suspend(struct otg_transceiver *x, int suspend) | ||
| 70 | { | ||
| 71 | return 0; | ||
| 72 | } | ||
| 73 | |||
| 74 | static int nop_set_peripheral(struct otg_transceiver *x, | ||
| 75 | struct usb_gadget *gadget) | ||
| 76 | { | ||
| 77 | struct nop_usb_xceiv *nop; | ||
| 78 | |||
| 79 | if (!x) | ||
| 80 | return -ENODEV; | ||
| 81 | |||
| 82 | nop = xceiv_to_nop(x); | ||
| 83 | |||
| 84 | if (!gadget) { | ||
| 85 | nop->otg.gadget = NULL; | ||
| 86 | return -ENODEV; | ||
| 87 | } | ||
| 88 | |||
| 89 | nop->otg.gadget = gadget; | ||
| 90 | nop->otg.state = OTG_STATE_B_IDLE; | ||
| 91 | return 0; | ||
| 92 | } | ||
| 93 | |||
| 94 | static int nop_set_host(struct otg_transceiver *x, struct usb_bus *host) | ||
| 95 | { | ||
| 96 | struct nop_usb_xceiv *nop; | ||
| 97 | |||
| 98 | if (!x) | ||
| 99 | return -ENODEV; | ||
| 100 | |||
| 101 | nop = xceiv_to_nop(x); | ||
| 102 | |||
| 103 | if (!host) { | ||
| 104 | nop->otg.host = NULL; | ||
| 105 | return -ENODEV; | ||
| 106 | } | ||
| 107 | |||
| 108 | nop->otg.host = host; | ||
| 109 | return 0; | ||
| 110 | } | ||
| 111 | |||
| 112 | static int __devinit nop_usb_xceiv_probe(struct platform_device *pdev) | ||
| 113 | { | ||
| 114 | struct nop_usb_xceiv *nop; | ||
| 115 | int err; | ||
| 116 | |||
| 117 | nop = kzalloc(sizeof *nop, GFP_KERNEL); | ||
| 118 | if (!nop) | ||
| 119 | return -ENOMEM; | ||
| 120 | |||
| 121 | nop->dev = &pdev->dev; | ||
| 122 | nop->otg.dev = nop->dev; | ||
| 123 | nop->otg.label = "nop-xceiv"; | ||
| 124 | nop->otg.state = OTG_STATE_UNDEFINED; | ||
| 125 | nop->otg.set_host = nop_set_host; | ||
| 126 | nop->otg.set_peripheral = nop_set_peripheral; | ||
| 127 | nop->otg.set_suspend = nop_set_suspend; | ||
| 128 | |||
| 129 | err = otg_set_transceiver(&nop->otg); | ||
| 130 | if (err) { | ||
| 131 | dev_err(&pdev->dev, "can't register transceiver, err: %d\n", | ||
| 132 | err); | ||
| 133 | goto exit; | ||
| 134 | } | ||
| 135 | |||
| 136 | platform_set_drvdata(pdev, nop); | ||
| 137 | |||
| 138 | return 0; | ||
| 139 | exit: | ||
| 140 | kfree(nop); | ||
| 141 | return err; | ||
| 142 | } | ||
| 143 | |||
| 144 | static int __devexit nop_usb_xceiv_remove(struct platform_device *pdev) | ||
| 145 | { | ||
| 146 | struct nop_usb_xceiv *nop = platform_get_drvdata(pdev); | ||
| 147 | |||
| 148 | otg_set_transceiver(NULL); | ||
| 149 | |||
| 150 | platform_set_drvdata(pdev, NULL); | ||
| 151 | kfree(nop); | ||
| 152 | |||
| 153 | return 0; | ||
| 154 | } | ||
| 155 | |||
| 156 | static struct platform_driver nop_usb_xceiv_driver = { | ||
| 157 | .probe = nop_usb_xceiv_probe, | ||
| 158 | .remove = __devexit_p(nop_usb_xceiv_remove), | ||
| 159 | .driver = { | ||
| 160 | .name = "nop_usb_xceiv", | ||
| 161 | .owner = THIS_MODULE, | ||
| 162 | }, | ||
| 163 | }; | ||
| 164 | |||
| 165 | static int __init nop_usb_xceiv_init(void) | ||
| 166 | { | ||
| 167 | return platform_driver_register(&nop_usb_xceiv_driver); | ||
| 168 | } | ||
| 169 | subsys_initcall(nop_usb_xceiv_init); | ||
| 170 | |||
| 171 | static void __exit nop_usb_xceiv_exit(void) | ||
| 172 | { | ||
| 173 | platform_driver_unregister(&nop_usb_xceiv_driver); | ||
| 174 | } | ||
| 175 | module_exit(nop_usb_xceiv_exit); | ||
| 176 | |||
| 177 | MODULE_ALIAS("platform:nop_usb_xceiv"); | ||
| 178 | MODULE_AUTHOR("Texas Instruments Inc"); | ||
| 179 | MODULE_DESCRIPTION("NOP USB Transceiver driver"); | ||
| 180 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/otg/twl4030-usb.c b/drivers/usb/otg/twl4030-usb.c index 416e4410be02..d9478d0e1c8b 100644 --- a/drivers/usb/otg/twl4030-usb.c +++ b/drivers/usb/otg/twl4030-usb.c | |||
| @@ -34,6 +34,8 @@ | |||
| 34 | #include <linux/delay.h> | 34 | #include <linux/delay.h> |
| 35 | #include <linux/usb/otg.h> | 35 | #include <linux/usb/otg.h> |
| 36 | #include <linux/i2c/twl4030.h> | 36 | #include <linux/i2c/twl4030.h> |
| 37 | #include <linux/regulator/consumer.h> | ||
| 38 | #include <linux/err.h> | ||
| 37 | 39 | ||
| 38 | 40 | ||
| 39 | /* Register defines */ | 41 | /* Register defines */ |
| @@ -246,6 +248,11 @@ struct twl4030_usb { | |||
| 246 | struct otg_transceiver otg; | 248 | struct otg_transceiver otg; |
| 247 | struct device *dev; | 249 | struct device *dev; |
| 248 | 250 | ||
| 251 | /* TWL4030 internal USB regulator supplies */ | ||
| 252 | struct regulator *usb1v5; | ||
| 253 | struct regulator *usb1v8; | ||
| 254 | struct regulator *usb3v1; | ||
| 255 | |||
| 249 | /* for vbus reporting with irqs disabled */ | 256 | /* for vbus reporting with irqs disabled */ |
| 250 | spinlock_t lock; | 257 | spinlock_t lock; |
| 251 | 258 | ||
| @@ -434,6 +441,18 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on) | |||
| 434 | 441 | ||
| 435 | pwr = twl4030_usb_read(twl, PHY_PWR_CTRL); | 442 | pwr = twl4030_usb_read(twl, PHY_PWR_CTRL); |
| 436 | if (on) { | 443 | if (on) { |
| 444 | regulator_enable(twl->usb3v1); | ||
| 445 | regulator_enable(twl->usb1v8); | ||
| 446 | /* | ||
| 447 | * Disabling usb3v1 regulator (= writing 0 to VUSB3V1_DEV_GRP | ||
| 448 | * in twl4030) resets the VUSB_DEDICATED2 register. This reset | ||
| 449 | * enables VUSB3V1_SLEEP bit that remaps usb3v1 ACTIVE state to | ||
| 450 | * SLEEP. We work around this by clearing the bit after usv3v1 | ||
| 451 | * is re-activated. This ensures that VUSB3V1 is really active. | ||
| 452 | */ | ||
| 453 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, | ||
| 454 | VUSB_DEDICATED2); | ||
| 455 | regulator_enable(twl->usb1v5); | ||
| 437 | pwr &= ~PHY_PWR_PHYPWD; | 456 | pwr &= ~PHY_PWR_PHYPWD; |
| 438 | WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0); | 457 | WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0); |
| 439 | twl4030_usb_write(twl, PHY_CLK_CTRL, | 458 | twl4030_usb_write(twl, PHY_CLK_CTRL, |
| @@ -443,6 +462,9 @@ static void twl4030_phy_power(struct twl4030_usb *twl, int on) | |||
| 443 | } else { | 462 | } else { |
| 444 | pwr |= PHY_PWR_PHYPWD; | 463 | pwr |= PHY_PWR_PHYPWD; |
| 445 | WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0); | 464 | WARN_ON(twl4030_usb_write_verify(twl, PHY_PWR_CTRL, pwr) < 0); |
| 465 | regulator_disable(twl->usb1v5); | ||
| 466 | regulator_disable(twl->usb1v8); | ||
| 467 | regulator_disable(twl->usb3v1); | ||
| 446 | } | 468 | } |
| 447 | } | 469 | } |
| 448 | 470 | ||
| @@ -468,7 +490,7 @@ static void twl4030_phy_resume(struct twl4030_usb *twl) | |||
| 468 | twl->asleep = 0; | 490 | twl->asleep = 0; |
| 469 | } | 491 | } |
| 470 | 492 | ||
| 471 | static void twl4030_usb_ldo_init(struct twl4030_usb *twl) | 493 | static int twl4030_usb_ldo_init(struct twl4030_usb *twl) |
| 472 | { | 494 | { |
| 473 | /* Enable writing to power configuration registers */ | 495 | /* Enable writing to power configuration registers */ |
| 474 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0xC0, PROTECT_KEY); | 496 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0xC0, PROTECT_KEY); |
| @@ -480,20 +502,45 @@ static void twl4030_usb_ldo_init(struct twl4030_usb *twl) | |||
| 480 | /* input to VUSB3V1 LDO is from VBAT, not VBUS */ | 502 | /* input to VUSB3V1 LDO is from VBAT, not VBUS */ |
| 481 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1); | 503 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x14, VUSB_DEDICATED1); |
| 482 | 504 | ||
| 483 | /* turn on 3.1V regulator */ | 505 | /* Initialize 3.1V regulator */ |
| 484 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x20, VUSB3V1_DEV_GRP); | 506 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_DEV_GRP); |
| 507 | |||
| 508 | twl->usb3v1 = regulator_get(twl->dev, "usb3v1"); | ||
| 509 | if (IS_ERR(twl->usb3v1)) | ||
| 510 | return -ENODEV; | ||
| 511 | |||
| 485 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE); | 512 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB3V1_TYPE); |
| 486 | 513 | ||
| 487 | /* turn on 1.5V regulator */ | 514 | /* Initialize 1.5V regulator */ |
| 488 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x20, VUSB1V5_DEV_GRP); | 515 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_DEV_GRP); |
| 516 | |||
| 517 | twl->usb1v5 = regulator_get(twl->dev, "usb1v5"); | ||
| 518 | if (IS_ERR(twl->usb1v5)) | ||
| 519 | goto fail1; | ||
| 520 | |||
| 489 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE); | 521 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V5_TYPE); |
| 490 | 522 | ||
| 491 | /* turn on 1.8V regulator */ | 523 | /* Initialize 1.8V regulator */ |
| 492 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x20, VUSB1V8_DEV_GRP); | 524 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_DEV_GRP); |
| 525 | |||
| 526 | twl->usb1v8 = regulator_get(twl->dev, "usb1v8"); | ||
| 527 | if (IS_ERR(twl->usb1v8)) | ||
| 528 | goto fail2; | ||
| 529 | |||
| 493 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE); | 530 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0, VUSB1V8_TYPE); |
| 494 | 531 | ||
| 495 | /* disable access to power configuration registers */ | 532 | /* disable access to power configuration registers */ |
| 496 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, PROTECT_KEY); | 533 | twl4030_i2c_write_u8(TWL4030_MODULE_PM_MASTER, 0, PROTECT_KEY); |
| 534 | |||
| 535 | return 0; | ||
| 536 | |||
| 537 | fail2: | ||
| 538 | regulator_put(twl->usb1v5); | ||
| 539 | twl->usb1v5 = NULL; | ||
| 540 | fail1: | ||
| 541 | regulator_put(twl->usb3v1); | ||
| 542 | twl->usb3v1 = NULL; | ||
| 543 | return -ENODEV; | ||
| 497 | } | 544 | } |
| 498 | 545 | ||
| 499 | static ssize_t twl4030_usb_vbus_show(struct device *dev, | 546 | static ssize_t twl4030_usb_vbus_show(struct device *dev, |
| @@ -598,7 +645,7 @@ static int __init twl4030_usb_probe(struct platform_device *pdev) | |||
| 598 | { | 645 | { |
| 599 | struct twl4030_usb_data *pdata = pdev->dev.platform_data; | 646 | struct twl4030_usb_data *pdata = pdev->dev.platform_data; |
| 600 | struct twl4030_usb *twl; | 647 | struct twl4030_usb *twl; |
| 601 | int status; | 648 | int status, err; |
| 602 | 649 | ||
| 603 | if (!pdata) { | 650 | if (!pdata) { |
| 604 | dev_dbg(&pdev->dev, "platform_data not available\n"); | 651 | dev_dbg(&pdev->dev, "platform_data not available\n"); |
| @@ -622,7 +669,12 @@ static int __init twl4030_usb_probe(struct platform_device *pdev) | |||
| 622 | /* init spinlock for workqueue */ | 669 | /* init spinlock for workqueue */ |
| 623 | spin_lock_init(&twl->lock); | 670 | spin_lock_init(&twl->lock); |
| 624 | 671 | ||
| 625 | twl4030_usb_ldo_init(twl); | 672 | err = twl4030_usb_ldo_init(twl); |
| 673 | if (err) { | ||
| 674 | dev_err(&pdev->dev, "ldo init failed\n"); | ||
| 675 | kfree(twl); | ||
| 676 | return err; | ||
| 677 | } | ||
| 626 | otg_set_transceiver(&twl->otg); | 678 | otg_set_transceiver(&twl->otg); |
| 627 | 679 | ||
| 628 | platform_set_drvdata(pdev, twl); | 680 | platform_set_drvdata(pdev, twl); |
| @@ -688,6 +740,9 @@ static int __exit twl4030_usb_remove(struct platform_device *pdev) | |||
| 688 | twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); | 740 | twl4030_usb_clear_bits(twl, POWER_CTRL, POWER_CTRL_OTG_ENAB); |
| 689 | 741 | ||
| 690 | twl4030_phy_power(twl, 0); | 742 | twl4030_phy_power(twl, 0); |
| 743 | regulator_put(twl->usb1v5); | ||
| 744 | regulator_put(twl->usb1v8); | ||
| 745 | regulator_put(twl->usb3v1); | ||
| 691 | 746 | ||
| 692 | kfree(twl); | 747 | kfree(twl); |
| 693 | 748 | ||
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index b361f05cafac..a65f9196b0a0 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
| @@ -116,14 +116,14 @@ config USB_SERIAL_DIGI_ACCELEPORT | |||
| 116 | To compile this driver as a module, choose M here: the | 116 | To compile this driver as a module, choose M here: the |
| 117 | module will be called digi_acceleport. | 117 | module will be called digi_acceleport. |
| 118 | 118 | ||
| 119 | config USB_SERIAL_CP2101 | 119 | config USB_SERIAL_CP210X |
| 120 | tristate "USB CP2101 UART Bridge Controller" | 120 | tristate "USB CP210x family of UART Bridge Controllers" |
| 121 | help | 121 | help |
| 122 | Say Y here if you want to use a CP2101/CP2102 based USB to RS232 | 122 | Say Y here if you want to use a CP2101/CP2102/CP2103 based USB |
| 123 | converter. | 123 | to RS232 converters. |
| 124 | 124 | ||
| 125 | To compile this driver as a module, choose M here: the | 125 | To compile this driver as a module, choose M here: the |
| 126 | module will be called cp2101. | 126 | module will be called cp210x. |
| 127 | 127 | ||
| 128 | config USB_SERIAL_CYPRESS_M8 | 128 | config USB_SERIAL_CYPRESS_M8 |
| 129 | tristate "USB Cypress M8 USB Serial Driver" | 129 | tristate "USB Cypress M8 USB Serial Driver" |
| @@ -472,6 +472,15 @@ config USB_SERIAL_OTI6858 | |||
| 472 | To compile this driver as a module, choose M here: the | 472 | To compile this driver as a module, choose M here: the |
| 473 | module will be called oti6858. | 473 | module will be called oti6858. |
| 474 | 474 | ||
| 475 | config USB_SERIAL_QUALCOMM | ||
| 476 | tristate "USB Qualcomm Serial modem" | ||
| 477 | help | ||
| 478 | Say Y here if you have a Qualcomm USB modem device. These are | ||
| 479 | usually wireless cellular modems. | ||
| 480 | |||
| 481 | To compile this driver as a module, choose M here: the | ||
| 482 | module will be called qcserial. | ||
| 483 | |||
| 475 | config USB_SERIAL_SPCP8X5 | 484 | config USB_SERIAL_SPCP8X5 |
| 476 | tristate "USB SPCP8x5 USB To Serial Driver" | 485 | tristate "USB SPCP8x5 USB To Serial Driver" |
| 477 | help | 486 | help |
| @@ -515,6 +524,15 @@ config USB_SERIAL_SIERRAWIRELESS | |||
| 515 | To compile this driver as a module, choose M here: the | 524 | To compile this driver as a module, choose M here: the |
| 516 | module will be called sierra. | 525 | module will be called sierra. |
| 517 | 526 | ||
| 527 | config USB_SERIAL_SYMBOL | ||
| 528 | tristate "USB Symbol Barcode driver (serial mode)" | ||
| 529 | help | ||
| 530 | Say Y here if you want to use a Symbol USB Barcode device | ||
| 531 | in serial emulation mode. | ||
| 532 | |||
| 533 | To compile this driver as a module, choose M here: the | ||
| 534 | module will be called symbolserial. | ||
| 535 | |||
| 518 | config USB_SERIAL_TI | 536 | config USB_SERIAL_TI |
| 519 | tristate "USB TI 3410/5052 Serial Driver" | 537 | tristate "USB TI 3410/5052 Serial Driver" |
| 520 | help | 538 | help |
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index b75be91eb8f1..66619beb6cc0 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile | |||
| @@ -15,7 +15,7 @@ obj-$(CONFIG_USB_SERIAL_AIRCABLE) += aircable.o | |||
| 15 | obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o | 15 | obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o |
| 16 | obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o | 16 | obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o |
| 17 | obj-$(CONFIG_USB_SERIAL_CH341) += ch341.o | 17 | obj-$(CONFIG_USB_SERIAL_CH341) += ch341.o |
| 18 | obj-$(CONFIG_USB_SERIAL_CP2101) += cp2101.o | 18 | obj-$(CONFIG_USB_SERIAL_CP210X) += cp210x.o |
| 19 | obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o | 19 | obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o |
| 20 | obj-$(CONFIG_USB_SERIAL_CYPRESS_M8) += cypress_m8.o | 20 | obj-$(CONFIG_USB_SERIAL_CYPRESS_M8) += cypress_m8.o |
| 21 | obj-$(CONFIG_USB_SERIAL_DEBUG) += usb_debug.o | 21 | obj-$(CONFIG_USB_SERIAL_DEBUG) += usb_debug.o |
| @@ -45,10 +45,12 @@ obj-$(CONFIG_USB_SERIAL_OPTICON) += opticon.o | |||
| 45 | obj-$(CONFIG_USB_SERIAL_OPTION) += option.o | 45 | obj-$(CONFIG_USB_SERIAL_OPTION) += option.o |
| 46 | obj-$(CONFIG_USB_SERIAL_OTI6858) += oti6858.o | 46 | obj-$(CONFIG_USB_SERIAL_OTI6858) += oti6858.o |
| 47 | obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o | 47 | obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o |
| 48 | obj-$(CONFIG_USB_SERIAL_QUALCOMM) += qcserial.o | ||
| 48 | obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o | 49 | obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o |
| 49 | obj-$(CONFIG_USB_SERIAL_SIEMENS_MPI) += siemens_mpi.o | 50 | obj-$(CONFIG_USB_SERIAL_SIEMENS_MPI) += siemens_mpi.o |
| 50 | obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o | 51 | obj-$(CONFIG_USB_SERIAL_SIERRAWIRELESS) += sierra.o |
| 51 | obj-$(CONFIG_USB_SERIAL_SPCP8X5) += spcp8x5.o | 52 | obj-$(CONFIG_USB_SERIAL_SPCP8X5) += spcp8x5.o |
| 53 | obj-$(CONFIG_USB_SERIAL_SYMBOL) += symbolserial.o | ||
| 52 | obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o | 54 | obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o |
| 53 | obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o | 55 | obj-$(CONFIG_USB_SERIAL_VISOR) += visor.o |
| 54 | obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o | 56 | obj-$(CONFIG_USB_SERIAL_WHITEHEAT) += whiteheat.o |
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c index f61e3ca64305..ab4cc277aa65 100644 --- a/drivers/usb/serial/ch341.c +++ b/drivers/usb/serial/ch341.c | |||
| @@ -1,5 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Copyright 2007, Frank A Kingswood <frank@kingswood-consulting.co.uk> | 2 | * Copyright 2007, Frank A Kingswood <frank@kingswood-consulting.co.uk> |
| 3 | * Copyright 2007, Werner Cornelius <werner@cornelius-consult.de> | ||
| 4 | * Copyright 2009, Boris Hajduk <boris@hajduk.org> | ||
| 3 | * | 5 | * |
| 4 | * ch341.c implements a serial port driver for the Winchiphead CH341. | 6 | * ch341.c implements a serial port driver for the Winchiphead CH341. |
| 5 | * | 7 | * |
| @@ -21,9 +23,39 @@ | |||
| 21 | #include <linux/usb/serial.h> | 23 | #include <linux/usb/serial.h> |
| 22 | #include <linux/serial.h> | 24 | #include <linux/serial.h> |
| 23 | 25 | ||
| 24 | #define DEFAULT_BAUD_RATE 2400 | 26 | #define DEFAULT_BAUD_RATE 9600 |
| 25 | #define DEFAULT_TIMEOUT 1000 | 27 | #define DEFAULT_TIMEOUT 1000 |
| 26 | 28 | ||
| 29 | /* flags for IO-Bits */ | ||
| 30 | #define CH341_BIT_RTS (1 << 6) | ||
| 31 | #define CH341_BIT_DTR (1 << 5) | ||
| 32 | |||
| 33 | /******************************/ | ||
| 34 | /* interrupt pipe definitions */ | ||
| 35 | /******************************/ | ||
| 36 | /* always 4 interrupt bytes */ | ||
| 37 | /* first irq byte normally 0x08 */ | ||
| 38 | /* second irq byte base 0x7d + below */ | ||
| 39 | /* third irq byte base 0x94 + below */ | ||
| 40 | /* fourth irq byte normally 0xee */ | ||
| 41 | |||
| 42 | /* second interrupt byte */ | ||
| 43 | #define CH341_MULT_STAT 0x04 /* multiple status since last interrupt event */ | ||
| 44 | |||
| 45 | /* status returned in third interrupt answer byte, inverted in data | ||
| 46 | from irq */ | ||
| 47 | #define CH341_BIT_CTS 0x01 | ||
| 48 | #define CH341_BIT_DSR 0x02 | ||
| 49 | #define CH341_BIT_RI 0x04 | ||
| 50 | #define CH341_BIT_DCD 0x08 | ||
| 51 | #define CH341_BITS_MODEM_STAT 0x0f /* all bits */ | ||
| 52 | |||
| 53 | /*******************************/ | ||
| 54 | /* baudrate calculation factor */ | ||
| 55 | /*******************************/ | ||
| 56 | #define CH341_BAUDBASE_FACTOR 1532620800 | ||
| 57 | #define CH341_BAUDBASE_DIVMAX 3 | ||
| 58 | |||
| 27 | static int debug; | 59 | static int debug; |
| 28 | 60 | ||
| 29 | static struct usb_device_id id_table [] = { | 61 | static struct usb_device_id id_table [] = { |
| @@ -34,9 +66,12 @@ static struct usb_device_id id_table [] = { | |||
| 34 | MODULE_DEVICE_TABLE(usb, id_table); | 66 | MODULE_DEVICE_TABLE(usb, id_table); |
| 35 | 67 | ||
| 36 | struct ch341_private { | 68 | struct ch341_private { |
| 37 | unsigned baud_rate; | 69 | spinlock_t lock; /* access lock */ |
| 38 | u8 dtr; | 70 | wait_queue_head_t delta_msr_wait; /* wait queue for modem status */ |
| 39 | u8 rts; | 71 | unsigned baud_rate; /* set baud rate */ |
| 72 | u8 line_control; /* set line control value RTS/DTR */ | ||
| 73 | u8 line_status; /* active status of modem control inputs */ | ||
| 74 | u8 multi_status_change; /* status changed multiple since last call */ | ||
| 40 | }; | 75 | }; |
| 41 | 76 | ||
| 42 | static int ch341_control_out(struct usb_device *dev, u8 request, | 77 | static int ch341_control_out(struct usb_device *dev, u8 request, |
| @@ -72,37 +107,28 @@ static int ch341_set_baudrate(struct usb_device *dev, | |||
| 72 | { | 107 | { |
| 73 | short a, b; | 108 | short a, b; |
| 74 | int r; | 109 | int r; |
| 110 | unsigned long factor; | ||
| 111 | short divisor; | ||
| 75 | 112 | ||
| 76 | dbg("ch341_set_baudrate(%d)", priv->baud_rate); | 113 | dbg("ch341_set_baudrate(%d)", priv->baud_rate); |
| 77 | switch (priv->baud_rate) { | 114 | |
| 78 | case 2400: | 115 | if (!priv->baud_rate) |
| 79 | a = 0xd901; | ||
| 80 | b = 0x0038; | ||
| 81 | break; | ||
| 82 | case 4800: | ||
| 83 | a = 0x6402; | ||
| 84 | b = 0x001f; | ||
| 85 | break; | ||
| 86 | case 9600: | ||
| 87 | a = 0xb202; | ||
| 88 | b = 0x0013; | ||
| 89 | break; | ||
| 90 | case 19200: | ||
| 91 | a = 0xd902; | ||
| 92 | b = 0x000d; | ||
| 93 | break; | ||
| 94 | case 38400: | ||
| 95 | a = 0x6403; | ||
| 96 | b = 0x000a; | ||
| 97 | break; | ||
| 98 | case 115200: | ||
| 99 | a = 0xcc03; | ||
| 100 | b = 0x0008; | ||
| 101 | break; | ||
| 102 | default: | ||
| 103 | return -EINVAL; | 116 | return -EINVAL; |
| 117 | factor = (CH341_BAUDBASE_FACTOR / priv->baud_rate); | ||
| 118 | divisor = CH341_BAUDBASE_DIVMAX; | ||
| 119 | |||
| 120 | while ((factor > 0xfff0) && divisor) { | ||
| 121 | factor >>= 3; | ||
| 122 | divisor--; | ||
| 104 | } | 123 | } |
| 105 | 124 | ||
| 125 | if (factor > 0xfff0) | ||
| 126 | return -EINVAL; | ||
| 127 | |||
| 128 | factor = 0x10000 - factor; | ||
| 129 | a = (factor & 0xff00) | divisor; | ||
| 130 | b = factor & 0xff; | ||
| 131 | |||
| 106 | r = ch341_control_out(dev, 0x9a, 0x1312, a); | 132 | r = ch341_control_out(dev, 0x9a, 0x1312, a); |
| 107 | if (!r) | 133 | if (!r) |
| 108 | r = ch341_control_out(dev, 0x9a, 0x0f2c, b); | 134 | r = ch341_control_out(dev, 0x9a, 0x0f2c, b); |
| @@ -110,19 +136,18 @@ static int ch341_set_baudrate(struct usb_device *dev, | |||
| 110 | return r; | 136 | return r; |
| 111 | } | 137 | } |
| 112 | 138 | ||
| 113 | static int ch341_set_handshake(struct usb_device *dev, | 139 | static int ch341_set_handshake(struct usb_device *dev, u8 control) |
| 114 | struct ch341_private *priv) | ||
| 115 | { | 140 | { |
| 116 | dbg("ch341_set_handshake(%d,%d)", priv->dtr, priv->rts); | 141 | dbg("ch341_set_handshake(0x%02x)", control); |
| 117 | return ch341_control_out(dev, 0xa4, | 142 | return ch341_control_out(dev, 0xa4, ~control, 0); |
| 118 | ~((priv->dtr?1<<5:0)|(priv->rts?1<<6:0)), 0); | ||
| 119 | } | 143 | } |
| 120 | 144 | ||
| 121 | static int ch341_get_status(struct usb_device *dev) | 145 | static int ch341_get_status(struct usb_device *dev, struct ch341_private *priv) |
| 122 | { | 146 | { |
| 123 | char *buffer; | 147 | char *buffer; |
| 124 | int r; | 148 | int r; |
| 125 | const unsigned size = 8; | 149 | const unsigned size = 8; |
| 150 | unsigned long flags; | ||
| 126 | 151 | ||
| 127 | dbg("ch341_get_status()"); | 152 | dbg("ch341_get_status()"); |
| 128 | 153 | ||
| @@ -134,10 +159,15 @@ static int ch341_get_status(struct usb_device *dev) | |||
| 134 | if (r < 0) | 159 | if (r < 0) |
| 135 | goto out; | 160 | goto out; |
| 136 | 161 | ||
| 137 | /* Not having the datasheet for the CH341, we ignore the bytes returned | 162 | /* setup the private status if available */ |
| 138 | * from the device. Return error if the device did not respond in time. | 163 | if (r == 2) { |
| 139 | */ | 164 | r = 0; |
| 140 | r = 0; | 165 | spin_lock_irqsave(&priv->lock, flags); |
| 166 | priv->line_status = (~(*buffer)) & CH341_BITS_MODEM_STAT; | ||
| 167 | priv->multi_status_change = 0; | ||
| 168 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 169 | } else | ||
| 170 | r = -EPROTO; | ||
| 141 | 171 | ||
| 142 | out: kfree(buffer); | 172 | out: kfree(buffer); |
| 143 | return r; | 173 | return r; |
| @@ -180,7 +210,7 @@ static int ch341_configure(struct usb_device *dev, struct ch341_private *priv) | |||
| 180 | goto out; | 210 | goto out; |
| 181 | 211 | ||
| 182 | /* expect 0xff 0xee */ | 212 | /* expect 0xff 0xee */ |
| 183 | r = ch341_get_status(dev); | 213 | r = ch341_get_status(dev, priv); |
| 184 | if (r < 0) | 214 | if (r < 0) |
| 185 | goto out; | 215 | goto out; |
| 186 | 216 | ||
| @@ -192,12 +222,12 @@ static int ch341_configure(struct usb_device *dev, struct ch341_private *priv) | |||
| 192 | if (r < 0) | 222 | if (r < 0) |
| 193 | goto out; | 223 | goto out; |
| 194 | 224 | ||
| 195 | r = ch341_set_handshake(dev, priv); | 225 | r = ch341_set_handshake(dev, priv->line_control); |
| 196 | if (r < 0) | 226 | if (r < 0) |
| 197 | goto out; | 227 | goto out; |
| 198 | 228 | ||
| 199 | /* expect 0x9f 0xee */ | 229 | /* expect 0x9f 0xee */ |
| 200 | r = ch341_get_status(dev); | 230 | r = ch341_get_status(dev, priv); |
| 201 | 231 | ||
| 202 | out: kfree(buffer); | 232 | out: kfree(buffer); |
| 203 | return r; | 233 | return r; |
| @@ -216,9 +246,10 @@ static int ch341_attach(struct usb_serial *serial) | |||
| 216 | if (!priv) | 246 | if (!priv) |
| 217 | return -ENOMEM; | 247 | return -ENOMEM; |
| 218 | 248 | ||
| 249 | spin_lock_init(&priv->lock); | ||
| 250 | init_waitqueue_head(&priv->delta_msr_wait); | ||
| 219 | priv->baud_rate = DEFAULT_BAUD_RATE; | 251 | priv->baud_rate = DEFAULT_BAUD_RATE; |
| 220 | priv->dtr = 1; | 252 | priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR; |
| 221 | priv->rts = 1; | ||
| 222 | 253 | ||
| 223 | r = ch341_configure(serial->dev, priv); | 254 | r = ch341_configure(serial->dev, priv); |
| 224 | if (r < 0) | 255 | if (r < 0) |
| @@ -231,6 +262,35 @@ error: kfree(priv); | |||
| 231 | return r; | 262 | return r; |
| 232 | } | 263 | } |
| 233 | 264 | ||
| 265 | static void ch341_close(struct tty_struct *tty, struct usb_serial_port *port, | ||
| 266 | struct file *filp) | ||
| 267 | { | ||
| 268 | struct ch341_private *priv = usb_get_serial_port_data(port); | ||
| 269 | unsigned long flags; | ||
| 270 | unsigned int c_cflag; | ||
| 271 | |||
| 272 | dbg("%s - port %d", __func__, port->number); | ||
| 273 | |||
| 274 | /* shutdown our urbs */ | ||
| 275 | dbg("%s - shutting down urbs", __func__); | ||
| 276 | usb_kill_urb(port->write_urb); | ||
| 277 | usb_kill_urb(port->read_urb); | ||
| 278 | usb_kill_urb(port->interrupt_in_urb); | ||
| 279 | |||
| 280 | if (tty) { | ||
| 281 | c_cflag = tty->termios->c_cflag; | ||
| 282 | if (c_cflag & HUPCL) { | ||
| 283 | /* drop DTR and RTS */ | ||
| 284 | spin_lock_irqsave(&priv->lock, flags); | ||
| 285 | priv->line_control = 0; | ||
| 286 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 287 | ch341_set_handshake(port->serial->dev, 0); | ||
| 288 | } | ||
| 289 | } | ||
| 290 | wake_up_interruptible(&priv->delta_msr_wait); | ||
| 291 | } | ||
| 292 | |||
| 293 | |||
| 234 | /* open this device, set default parameters */ | 294 | /* open this device, set default parameters */ |
| 235 | static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port, | 295 | static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port, |
| 236 | struct file *filp) | 296 | struct file *filp) |
| @@ -242,14 +302,13 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 242 | dbg("ch341_open()"); | 302 | dbg("ch341_open()"); |
| 243 | 303 | ||
| 244 | priv->baud_rate = DEFAULT_BAUD_RATE; | 304 | priv->baud_rate = DEFAULT_BAUD_RATE; |
| 245 | priv->dtr = 1; | 305 | priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR; |
| 246 | priv->rts = 1; | ||
| 247 | 306 | ||
| 248 | r = ch341_configure(serial->dev, priv); | 307 | r = ch341_configure(serial->dev, priv); |
| 249 | if (r) | 308 | if (r) |
| 250 | goto out; | 309 | goto out; |
| 251 | 310 | ||
| 252 | r = ch341_set_handshake(serial->dev, priv); | 311 | r = ch341_set_handshake(serial->dev, priv->line_control); |
| 253 | if (r) | 312 | if (r) |
| 254 | goto out; | 313 | goto out; |
| 255 | 314 | ||
| @@ -257,6 +316,16 @@ static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 257 | if (r) | 316 | if (r) |
| 258 | goto out; | 317 | goto out; |
| 259 | 318 | ||
| 319 | dbg("%s - submitting interrupt urb", __func__); | ||
| 320 | port->interrupt_in_urb->dev = serial->dev; | ||
| 321 | r = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); | ||
| 322 | if (r) { | ||
| 323 | dev_err(&port->dev, "%s - failed submitting interrupt urb," | ||
| 324 | " error %d\n", __func__, r); | ||
| 325 | ch341_close(tty, port, NULL); | ||
| 326 | return -EPROTO; | ||
| 327 | } | ||
| 328 | |||
| 260 | r = usb_serial_generic_open(tty, port, filp); | 329 | r = usb_serial_generic_open(tty, port, filp); |
| 261 | 330 | ||
| 262 | out: return r; | 331 | out: return r; |
| @@ -270,46 +339,224 @@ static void ch341_set_termios(struct tty_struct *tty, | |||
| 270 | { | 339 | { |
| 271 | struct ch341_private *priv = usb_get_serial_port_data(port); | 340 | struct ch341_private *priv = usb_get_serial_port_data(port); |
| 272 | unsigned baud_rate; | 341 | unsigned baud_rate; |
| 342 | unsigned long flags; | ||
| 273 | 343 | ||
| 274 | dbg("ch341_set_termios()"); | 344 | dbg("ch341_set_termios()"); |
| 275 | 345 | ||
| 346 | if (!tty || !tty->termios) | ||
| 347 | return; | ||
| 348 | |||
| 276 | baud_rate = tty_get_baud_rate(tty); | 349 | baud_rate = tty_get_baud_rate(tty); |
| 277 | 350 | ||
| 278 | switch (baud_rate) { | 351 | priv->baud_rate = baud_rate; |
| 279 | case 2400: | 352 | |
| 280 | case 4800: | 353 | if (baud_rate) { |
| 281 | case 9600: | 354 | spin_lock_irqsave(&priv->lock, flags); |
| 282 | case 19200: | 355 | priv->line_control |= (CH341_BIT_DTR | CH341_BIT_RTS); |
| 283 | case 38400: | 356 | spin_unlock_irqrestore(&priv->lock, flags); |
| 284 | case 115200: | 357 | ch341_set_baudrate(port->serial->dev, priv); |
| 285 | priv->baud_rate = baud_rate; | 358 | } else { |
| 286 | break; | 359 | spin_lock_irqsave(&priv->lock, flags); |
| 287 | default: | 360 | priv->line_control &= ~(CH341_BIT_DTR | CH341_BIT_RTS); |
| 288 | dbg("Rate %d not supported, using %d", | 361 | spin_unlock_irqrestore(&priv->lock, flags); |
| 289 | baud_rate, DEFAULT_BAUD_RATE); | ||
| 290 | priv->baud_rate = DEFAULT_BAUD_RATE; | ||
| 291 | } | 362 | } |
| 292 | 363 | ||
| 293 | ch341_set_baudrate(port->serial->dev, priv); | 364 | ch341_set_handshake(port->serial->dev, priv->line_control); |
| 294 | 365 | ||
| 295 | /* Unimplemented: | 366 | /* Unimplemented: |
| 296 | * (cflag & CSIZE) : data bits [5, 8] | 367 | * (cflag & CSIZE) : data bits [5, 8] |
| 297 | * (cflag & PARENB) : parity {NONE, EVEN, ODD} | 368 | * (cflag & PARENB) : parity {NONE, EVEN, ODD} |
| 298 | * (cflag & CSTOPB) : stop bits [1, 2] | 369 | * (cflag & CSTOPB) : stop bits [1, 2] |
| 299 | */ | 370 | */ |
| 371 | } | ||
| 372 | |||
| 373 | static int ch341_tiocmset(struct tty_struct *tty, struct file *file, | ||
| 374 | unsigned int set, unsigned int clear) | ||
| 375 | { | ||
| 376 | struct usb_serial_port *port = tty->driver_data; | ||
| 377 | struct ch341_private *priv = usb_get_serial_port_data(port); | ||
| 378 | unsigned long flags; | ||
| 379 | u8 control; | ||
| 380 | |||
| 381 | spin_lock_irqsave(&priv->lock, flags); | ||
| 382 | if (set & TIOCM_RTS) | ||
| 383 | priv->line_control |= CH341_BIT_RTS; | ||
| 384 | if (set & TIOCM_DTR) | ||
| 385 | priv->line_control |= CH341_BIT_DTR; | ||
| 386 | if (clear & TIOCM_RTS) | ||
| 387 | priv->line_control &= ~CH341_BIT_RTS; | ||
| 388 | if (clear & TIOCM_DTR) | ||
| 389 | priv->line_control &= ~CH341_BIT_DTR; | ||
| 390 | control = priv->line_control; | ||
| 391 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 392 | |||
| 393 | return ch341_set_handshake(port->serial->dev, control); | ||
| 394 | } | ||
| 395 | |||
| 396 | static void ch341_read_int_callback(struct urb *urb) | ||
| 397 | { | ||
| 398 | struct usb_serial_port *port = (struct usb_serial_port *) urb->context; | ||
| 399 | unsigned char *data = urb->transfer_buffer; | ||
| 400 | unsigned int actual_length = urb->actual_length; | ||
| 401 | int status; | ||
| 402 | |||
| 403 | dbg("%s (%d)", __func__, port->number); | ||
| 404 | |||
| 405 | switch (urb->status) { | ||
| 406 | case 0: | ||
| 407 | /* success */ | ||
| 408 | break; | ||
| 409 | case -ECONNRESET: | ||
| 410 | case -ENOENT: | ||
| 411 | case -ESHUTDOWN: | ||
| 412 | /* this urb is terminated, clean up */ | ||
| 413 | dbg("%s - urb shutting down with status: %d", __func__, | ||
| 414 | urb->status); | ||
| 415 | return; | ||
| 416 | default: | ||
| 417 | dbg("%s - nonzero urb status received: %d", __func__, | ||
| 418 | urb->status); | ||
| 419 | goto exit; | ||
| 420 | } | ||
| 300 | 421 | ||
| 301 | /* Copy back the old hardware settings */ | 422 | usb_serial_debug_data(debug, &port->dev, __func__, |
| 302 | tty_termios_copy_hw(tty->termios, old_termios); | 423 | urb->actual_length, urb->transfer_buffer); |
| 303 | /* And re-encode with the new baud */ | 424 | |
| 304 | tty_encode_baud_rate(tty, baud_rate, baud_rate); | 425 | if (actual_length >= 4) { |
| 426 | struct ch341_private *priv = usb_get_serial_port_data(port); | ||
| 427 | unsigned long flags; | ||
| 428 | |||
| 429 | spin_lock_irqsave(&priv->lock, flags); | ||
| 430 | priv->line_status = (~(data[2])) & CH341_BITS_MODEM_STAT; | ||
| 431 | if ((data[1] & CH341_MULT_STAT)) | ||
| 432 | priv->multi_status_change = 1; | ||
| 433 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 434 | wake_up_interruptible(&priv->delta_msr_wait); | ||
| 435 | } | ||
| 436 | |||
| 437 | exit: | ||
| 438 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
| 439 | if (status) | ||
| 440 | dev_err(&urb->dev->dev, | ||
| 441 | "%s - usb_submit_urb failed with result %d\n", | ||
| 442 | __func__, status); | ||
| 443 | } | ||
| 444 | |||
| 445 | static int wait_modem_info(struct usb_serial_port *port, unsigned int arg) | ||
| 446 | { | ||
| 447 | struct ch341_private *priv = usb_get_serial_port_data(port); | ||
| 448 | unsigned long flags; | ||
| 449 | u8 prevstatus; | ||
| 450 | u8 status; | ||
| 451 | u8 changed; | ||
| 452 | u8 multi_change = 0; | ||
| 453 | |||
| 454 | spin_lock_irqsave(&priv->lock, flags); | ||
| 455 | prevstatus = priv->line_status; | ||
| 456 | priv->multi_status_change = 0; | ||
| 457 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 458 | |||
| 459 | while (!multi_change) { | ||
| 460 | interruptible_sleep_on(&priv->delta_msr_wait); | ||
| 461 | /* see if a signal did it */ | ||
| 462 | if (signal_pending(current)) | ||
| 463 | return -ERESTARTSYS; | ||
| 464 | |||
| 465 | spin_lock_irqsave(&priv->lock, flags); | ||
| 466 | status = priv->line_status; | ||
| 467 | multi_change = priv->multi_status_change; | ||
| 468 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 469 | |||
| 470 | changed = prevstatus ^ status; | ||
| 471 | |||
| 472 | if (((arg & TIOCM_RNG) && (changed & CH341_BIT_RI)) || | ||
| 473 | ((arg & TIOCM_DSR) && (changed & CH341_BIT_DSR)) || | ||
| 474 | ((arg & TIOCM_CD) && (changed & CH341_BIT_DCD)) || | ||
| 475 | ((arg & TIOCM_CTS) && (changed & CH341_BIT_CTS))) { | ||
| 476 | return 0; | ||
| 477 | } | ||
| 478 | prevstatus = status; | ||
| 479 | } | ||
| 480 | |||
| 481 | return 0; | ||
| 482 | } | ||
| 483 | |||
| 484 | /*static int ch341_ioctl(struct usb_serial_port *port, struct file *file,*/ | ||
| 485 | static int ch341_ioctl(struct tty_struct *tty, struct file *file, | ||
| 486 | unsigned int cmd, unsigned long arg) | ||
| 487 | { | ||
| 488 | struct usb_serial_port *port = tty->driver_data; | ||
| 489 | dbg("%s (%d) cmd = 0x%04x", __func__, port->number, cmd); | ||
| 490 | |||
| 491 | switch (cmd) { | ||
| 492 | case TIOCMIWAIT: | ||
| 493 | dbg("%s (%d) TIOCMIWAIT", __func__, port->number); | ||
| 494 | return wait_modem_info(port, arg); | ||
| 495 | |||
| 496 | default: | ||
| 497 | dbg("%s not supported = 0x%04x", __func__, cmd); | ||
| 498 | break; | ||
| 499 | } | ||
| 500 | |||
| 501 | return -ENOIOCTLCMD; | ||
| 502 | } | ||
| 503 | |||
| 504 | static int ch341_tiocmget(struct tty_struct *tty, struct file *file) | ||
| 505 | { | ||
| 506 | struct usb_serial_port *port = tty->driver_data; | ||
| 507 | struct ch341_private *priv = usb_get_serial_port_data(port); | ||
| 508 | unsigned long flags; | ||
| 509 | u8 mcr; | ||
| 510 | u8 status; | ||
| 511 | unsigned int result; | ||
| 512 | |||
| 513 | dbg("%s (%d)", __func__, port->number); | ||
| 514 | |||
| 515 | spin_lock_irqsave(&priv->lock, flags); | ||
| 516 | mcr = priv->line_control; | ||
| 517 | status = priv->line_status; | ||
| 518 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 519 | |||
| 520 | result = ((mcr & CH341_BIT_DTR) ? TIOCM_DTR : 0) | ||
| 521 | | ((mcr & CH341_BIT_RTS) ? TIOCM_RTS : 0) | ||
| 522 | | ((status & CH341_BIT_CTS) ? TIOCM_CTS : 0) | ||
| 523 | | ((status & CH341_BIT_DSR) ? TIOCM_DSR : 0) | ||
| 524 | | ((status & CH341_BIT_RI) ? TIOCM_RI : 0) | ||
| 525 | | ((status & CH341_BIT_DCD) ? TIOCM_CD : 0); | ||
| 526 | |||
| 527 | dbg("%s - result = %x", __func__, result); | ||
| 528 | |||
| 529 | return result; | ||
| 530 | } | ||
| 531 | |||
| 532 | |||
| 533 | static int ch341_reset_resume(struct usb_interface *intf) | ||
| 534 | { | ||
| 535 | struct usb_device *dev = interface_to_usbdev(intf); | ||
| 536 | struct usb_serial *serial = NULL; | ||
| 537 | struct ch341_private *priv; | ||
| 538 | |||
| 539 | serial = usb_get_intfdata(intf); | ||
| 540 | priv = usb_get_serial_port_data(serial->port[0]); | ||
| 541 | |||
| 542 | /*reconfigure ch341 serial port after bus-reset*/ | ||
| 543 | ch341_configure(dev, priv); | ||
| 544 | |||
| 545 | usb_serial_resume(intf); | ||
| 546 | |||
| 547 | return 0; | ||
| 305 | } | 548 | } |
| 306 | 549 | ||
| 307 | static struct usb_driver ch341_driver = { | 550 | static struct usb_driver ch341_driver = { |
| 308 | .name = "ch341", | 551 | .name = "ch341", |
| 309 | .probe = usb_serial_probe, | 552 | .probe = usb_serial_probe, |
| 310 | .disconnect = usb_serial_disconnect, | 553 | .disconnect = usb_serial_disconnect, |
| 554 | .suspend = usb_serial_suspend, | ||
| 555 | .resume = usb_serial_resume, | ||
| 556 | .reset_resume = ch341_reset_resume, | ||
| 311 | .id_table = id_table, | 557 | .id_table = id_table, |
| 312 | .no_dynamic_id = 1, | 558 | .no_dynamic_id = 1, |
| 559 | .supports_autosuspend = 1, | ||
| 313 | }; | 560 | }; |
| 314 | 561 | ||
| 315 | static struct usb_serial_driver ch341_device = { | 562 | static struct usb_serial_driver ch341_device = { |
| @@ -317,12 +564,17 @@ static struct usb_serial_driver ch341_device = { | |||
| 317 | .owner = THIS_MODULE, | 564 | .owner = THIS_MODULE, |
| 318 | .name = "ch341-uart", | 565 | .name = "ch341-uart", |
| 319 | }, | 566 | }, |
| 320 | .id_table = id_table, | 567 | .id_table = id_table, |
| 321 | .usb_driver = &ch341_driver, | 568 | .usb_driver = &ch341_driver, |
| 322 | .num_ports = 1, | 569 | .num_ports = 1, |
| 323 | .open = ch341_open, | 570 | .open = ch341_open, |
| 324 | .set_termios = ch341_set_termios, | 571 | .close = ch341_close, |
| 325 | .attach = ch341_attach, | 572 | .ioctl = ch341_ioctl, |
| 573 | .set_termios = ch341_set_termios, | ||
| 574 | .tiocmget = ch341_tiocmget, | ||
| 575 | .tiocmset = ch341_tiocmset, | ||
| 576 | .read_int_callback = ch341_read_int_callback, | ||
| 577 | .attach = ch341_attach, | ||
| 326 | }; | 578 | }; |
| 327 | 579 | ||
| 328 | static int __init ch341_init(void) | 580 | static int __init ch341_init(void) |
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp210x.c index 9b4082b58c5b..e8d5133ce9c8 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp210x.c | |||
| @@ -11,10 +11,6 @@ | |||
| 11 | * thanks to Karl Hiramoto karl@hiramoto.org. RTSCTS hardware flow | 11 | * thanks to Karl Hiramoto karl@hiramoto.org. RTSCTS hardware flow |
| 12 | * control thanks to Munir Nassar nassarmu@real-time.com | 12 | * control thanks to Munir Nassar nassarmu@real-time.com |
| 13 | * | 13 | * |
| 14 | * Outstanding Issues: | ||
| 15 | * Buffers are not flushed when the port is opened. | ||
| 16 | * Multiple calls to write() may fail with "Resource temporarily unavailable" | ||
| 17 | * | ||
| 18 | */ | 14 | */ |
| 19 | 15 | ||
| 20 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
| @@ -31,7 +27,7 @@ | |||
| 31 | /* | 27 | /* |
| 32 | * Version Information | 28 | * Version Information |
| 33 | */ | 29 | */ |
| 34 | #define DRIVER_VERSION "v0.07" | 30 | #define DRIVER_VERSION "v0.08" |
| 35 | #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver" | 31 | #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver" |
| 36 | 32 | ||
| 37 | /* | 33 | /* |
| @@ -42,17 +38,21 @@ static int cp2101_open(struct tty_struct *, struct usb_serial_port *, | |||
| 42 | static void cp2101_cleanup(struct usb_serial_port *); | 38 | static void cp2101_cleanup(struct usb_serial_port *); |
| 43 | static void cp2101_close(struct tty_struct *, struct usb_serial_port *, | 39 | static void cp2101_close(struct tty_struct *, struct usb_serial_port *, |
| 44 | struct file*); | 40 | struct file*); |
| 45 | static void cp2101_get_termios(struct tty_struct *); | 41 | static void cp2101_get_termios(struct tty_struct *, |
| 42 | struct usb_serial_port *port); | ||
| 43 | static void cp2101_get_termios_port(struct usb_serial_port *port, | ||
| 44 | unsigned int *cflagp, unsigned int *baudp); | ||
| 46 | static void cp2101_set_termios(struct tty_struct *, struct usb_serial_port *, | 45 | static void cp2101_set_termios(struct tty_struct *, struct usb_serial_port *, |
| 47 | struct ktermios*); | 46 | struct ktermios*); |
| 48 | static int cp2101_tiocmget(struct tty_struct *, struct file *); | 47 | static int cp2101_tiocmget(struct tty_struct *, struct file *); |
| 49 | static int cp2101_tiocmset(struct tty_struct *, struct file *, | 48 | static int cp2101_tiocmset(struct tty_struct *, struct file *, |
| 50 | unsigned int, unsigned int); | 49 | unsigned int, unsigned int); |
| 50 | static int cp2101_tiocmset_port(struct usb_serial_port *port, struct file *, | ||
| 51 | unsigned int, unsigned int); | ||
| 51 | static void cp2101_break_ctl(struct tty_struct *, int); | 52 | static void cp2101_break_ctl(struct tty_struct *, int); |
| 52 | static int cp2101_startup(struct usb_serial *); | 53 | static int cp2101_startup(struct usb_serial *); |
| 53 | static void cp2101_shutdown(struct usb_serial *); | 54 | static void cp2101_shutdown(struct usb_serial *); |
| 54 | 55 | ||
| 55 | |||
| 56 | static int debug; | 56 | static int debug; |
| 57 | 57 | ||
| 58 | static struct usb_device_id id_table [] = { | 58 | static struct usb_device_id id_table [] = { |
| @@ -91,6 +91,7 @@ static struct usb_device_id id_table [] = { | |||
| 91 | { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */ | 91 | { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */ |
| 92 | { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ | 92 | { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ |
| 93 | { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */ | 93 | { USB_DEVICE(0x10C4, 0x83A8) }, /* Amber Wireless AMB2560 */ |
| 94 | { USB_DEVICE(0x10C4, 0x846E) }, /* BEI USB Sensor Interface (VCP) */ | ||
| 94 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ | 95 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ |
| 95 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ | 96 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ |
| 96 | { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */ | 97 | { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */ |
| @@ -225,7 +226,7 @@ static int cp2101_get_config(struct usb_serial_port *port, u8 request, | |||
| 225 | kfree(buf); | 226 | kfree(buf); |
| 226 | 227 | ||
| 227 | if (result != size) { | 228 | if (result != size) { |
| 228 | dev_err(&port->dev, "%s - Unable to send config request, " | 229 | dbg("%s - Unable to send config request, " |
| 229 | "request=0x%x size=%d result=%d\n", | 230 | "request=0x%x size=%d result=%d\n", |
| 230 | __func__, request, size, result); | 231 | __func__, request, size, result); |
| 231 | return -EPROTO; | 232 | return -EPROTO; |
| @@ -276,7 +277,7 @@ static int cp2101_set_config(struct usb_serial_port *port, u8 request, | |||
| 276 | kfree(buf); | 277 | kfree(buf); |
| 277 | 278 | ||
| 278 | if ((size > 2 && result != size) || result < 0) { | 279 | if ((size > 2 && result != size) || result < 0) { |
| 279 | dev_err(&port->dev, "%s - Unable to send request, " | 280 | dbg("%s - Unable to send request, " |
| 280 | "request=0x%x size=%d result=%d\n", | 281 | "request=0x%x size=%d result=%d\n", |
| 281 | __func__, request, size, result); | 282 | __func__, request, size, result); |
| 282 | return -EPROTO; | 283 | return -EPROTO; |
| @@ -301,6 +302,47 @@ static inline int cp2101_set_config_single(struct usb_serial_port *port, | |||
| 301 | return cp2101_set_config(port, request, &data, 2); | 302 | return cp2101_set_config(port, request, &data, 2); |
| 302 | } | 303 | } |
| 303 | 304 | ||
| 305 | /* | ||
| 306 | * cp2101_quantise_baudrate | ||
| 307 | * Quantises the baud rate as per AN205 Table 1 | ||
| 308 | */ | ||
| 309 | static unsigned int cp2101_quantise_baudrate(unsigned int baud) { | ||
| 310 | if (baud <= 56) baud = 0; | ||
| 311 | else if (baud <= 300) baud = 300; | ||
| 312 | else if (baud <= 600) baud = 600; | ||
| 313 | else if (baud <= 1200) baud = 1200; | ||
| 314 | else if (baud <= 1800) baud = 1800; | ||
| 315 | else if (baud <= 2400) baud = 2400; | ||
| 316 | else if (baud <= 4000) baud = 4000; | ||
| 317 | else if (baud <= 4803) baud = 4800; | ||
| 318 | else if (baud <= 7207) baud = 7200; | ||
| 319 | else if (baud <= 9612) baud = 9600; | ||
| 320 | else if (baud <= 14428) baud = 14400; | ||
| 321 | else if (baud <= 16062) baud = 16000; | ||
| 322 | else if (baud <= 19250) baud = 19200; | ||
| 323 | else if (baud <= 28912) baud = 28800; | ||
| 324 | else if (baud <= 38601) baud = 38400; | ||
| 325 | else if (baud <= 51558) baud = 51200; | ||
| 326 | else if (baud <= 56280) baud = 56000; | ||
| 327 | else if (baud <= 58053) baud = 57600; | ||
| 328 | else if (baud <= 64111) baud = 64000; | ||
| 329 | else if (baud <= 77608) baud = 76800; | ||
| 330 | else if (baud <= 117028) baud = 115200; | ||
| 331 | else if (baud <= 129347) baud = 128000; | ||
| 332 | else if (baud <= 156868) baud = 153600; | ||
| 333 | else if (baud <= 237832) baud = 230400; | ||
| 334 | else if (baud <= 254234) baud = 250000; | ||
| 335 | else if (baud <= 273066) baud = 256000; | ||
| 336 | else if (baud <= 491520) baud = 460800; | ||
| 337 | else if (baud <= 567138) baud = 500000; | ||
| 338 | else if (baud <= 670254) baud = 576000; | ||
| 339 | else if (baud <= 1053257) baud = 921600; | ||
| 340 | else if (baud <= 1474560) baud = 1228800; | ||
| 341 | else if (baud <= 2457600) baud = 1843200; | ||
| 342 | else baud = 3686400; | ||
| 343 | return baud; | ||
| 344 | } | ||
| 345 | |||
| 304 | static int cp2101_open(struct tty_struct *tty, struct usb_serial_port *port, | 346 | static int cp2101_open(struct tty_struct *tty, struct usb_serial_port *port, |
| 305 | struct file *filp) | 347 | struct file *filp) |
| 306 | { | 348 | { |
| @@ -331,10 +373,12 @@ static int cp2101_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 331 | } | 373 | } |
| 332 | 374 | ||
| 333 | /* Configure the termios structure */ | 375 | /* Configure the termios structure */ |
| 334 | cp2101_get_termios(tty); | 376 | cp2101_get_termios(tty, port); |
| 335 | 377 | ||
| 336 | /* Set the DTR and RTS pins low */ | 378 | /* Set the DTR and RTS pins low */ |
| 337 | cp2101_tiocmset(tty, NULL, TIOCM_DTR | TIOCM_RTS, 0); | 379 | cp2101_tiocmset_port(tty ? (struct usb_serial_port *) tty->driver_data |
| 380 | : port, | ||
| 381 | NULL, TIOCM_DTR | TIOCM_RTS, 0); | ||
| 338 | 382 | ||
| 339 | return 0; | 383 | return 0; |
| 340 | } | 384 | } |
| @@ -376,9 +420,31 @@ static void cp2101_close(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 376 | * from the device, corrects any unsupported values, and configures the | 420 | * from the device, corrects any unsupported values, and configures the |
| 377 | * termios structure to reflect the state of the device | 421 | * termios structure to reflect the state of the device |
| 378 | */ | 422 | */ |
| 379 | static void cp2101_get_termios (struct tty_struct *tty) | 423 | static void cp2101_get_termios(struct tty_struct *tty, |
| 424 | struct usb_serial_port *port) | ||
| 425 | { | ||
| 426 | unsigned int baud; | ||
| 427 | |||
| 428 | if (tty) { | ||
| 429 | cp2101_get_termios_port(tty->driver_data, | ||
| 430 | &tty->termios->c_cflag, &baud); | ||
| 431 | tty_encode_baud_rate(tty, baud, baud); | ||
| 432 | } | ||
| 433 | |||
| 434 | else { | ||
| 435 | unsigned int cflag; | ||
| 436 | cflag = 0; | ||
| 437 | cp2101_get_termios_port(port, &cflag, &baud); | ||
| 438 | } | ||
| 439 | } | ||
| 440 | |||
| 441 | /* | ||
| 442 | * cp2101_get_termios_port | ||
| 443 | * This is the heart of cp2101_get_termios which always uses a &usb_serial_port. | ||
| 444 | */ | ||
| 445 | static void cp2101_get_termios_port(struct usb_serial_port *port, | ||
| 446 | unsigned int *cflagp, unsigned int *baudp) | ||
| 380 | { | 447 | { |
| 381 | struct usb_serial_port *port = tty->driver_data; | ||
| 382 | unsigned int cflag, modem_ctl[4]; | 448 | unsigned int cflag, modem_ctl[4]; |
| 383 | unsigned int baud; | 449 | unsigned int baud; |
| 384 | unsigned int bits; | 450 | unsigned int bits; |
| @@ -388,12 +454,12 @@ static void cp2101_get_termios (struct tty_struct *tty) | |||
| 388 | cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2); | 454 | cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2); |
| 389 | /* Convert to baudrate */ | 455 | /* Convert to baudrate */ |
| 390 | if (baud) | 456 | if (baud) |
| 391 | baud = BAUD_RATE_GEN_FREQ / baud; | 457 | baud = cp2101_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud); |
| 392 | 458 | ||
| 393 | dbg("%s - baud rate = %d", __func__, baud); | 459 | dbg("%s - baud rate = %d", __func__, baud); |
| 460 | *baudp = baud; | ||
| 394 | 461 | ||
| 395 | tty_encode_baud_rate(tty, baud, baud); | 462 | cflag = *cflagp; |
| 396 | cflag = tty->termios->c_cflag; | ||
| 397 | 463 | ||
| 398 | cp2101_get_config(port, CP2101_BITS, &bits, 2); | 464 | cp2101_get_config(port, CP2101_BITS, &bits, 2); |
| 399 | cflag &= ~CSIZE; | 465 | cflag &= ~CSIZE; |
| @@ -499,7 +565,7 @@ static void cp2101_get_termios (struct tty_struct *tty) | |||
| 499 | cflag &= ~CRTSCTS; | 565 | cflag &= ~CRTSCTS; |
| 500 | } | 566 | } |
| 501 | 567 | ||
| 502 | tty->termios->c_cflag = cflag; | 568 | *cflagp = cflag; |
| 503 | } | 569 | } |
| 504 | 570 | ||
| 505 | static void cp2101_set_termios(struct tty_struct *tty, | 571 | static void cp2101_set_termios(struct tty_struct *tty, |
| @@ -517,46 +583,16 @@ static void cp2101_set_termios(struct tty_struct *tty, | |||
| 517 | tty->termios->c_cflag &= ~CMSPAR; | 583 | tty->termios->c_cflag &= ~CMSPAR; |
| 518 | cflag = tty->termios->c_cflag; | 584 | cflag = tty->termios->c_cflag; |
| 519 | old_cflag = old_termios->c_cflag; | 585 | old_cflag = old_termios->c_cflag; |
| 520 | baud = tty_get_baud_rate(tty); | 586 | baud = cp2101_quantise_baudrate(tty_get_baud_rate(tty)); |
| 521 | 587 | ||
| 522 | /* If the baud rate is to be updated*/ | 588 | /* If the baud rate is to be updated*/ |
| 523 | if (baud != tty_termios_baud_rate(old_termios)) { | 589 | if (baud != tty_termios_baud_rate(old_termios) && baud != 0) { |
| 524 | switch (baud) { | 590 | dbg("%s - Setting baud rate to %d baud", __func__, |
| 525 | case 0: | 591 | baud); |
| 526 | case 600: | 592 | if (cp2101_set_config_single(port, CP2101_BAUDRATE, |
| 527 | case 1200: | 593 | ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) { |
| 528 | case 1800: | 594 | dbg("Baud rate requested not supported by device\n"); |
| 529 | case 2400: | 595 | baud = tty_termios_baud_rate(old_termios); |
| 530 | case 4800: | ||
| 531 | case 7200: | ||
| 532 | case 9600: | ||
| 533 | case 14400: | ||
| 534 | case 19200: | ||
| 535 | case 28800: | ||
| 536 | case 38400: | ||
| 537 | case 55854: | ||
| 538 | case 57600: | ||
| 539 | case 115200: | ||
| 540 | case 127117: | ||
| 541 | case 230400: | ||
| 542 | case 460800: | ||
| 543 | case 921600: | ||
| 544 | case 3686400: | ||
| 545 | break; | ||
| 546 | default: | ||
| 547 | baud = 9600; | ||
| 548 | break; | ||
| 549 | } | ||
| 550 | |||
| 551 | if (baud) { | ||
| 552 | dbg("%s - Setting baud rate to %d baud", __func__, | ||
| 553 | baud); | ||
| 554 | if (cp2101_set_config_single(port, CP2101_BAUDRATE, | ||
| 555 | (BAUD_RATE_GEN_FREQ / baud))) { | ||
| 556 | dev_err(&port->dev, "Baud rate requested not " | ||
| 557 | "supported by device\n"); | ||
| 558 | baud = tty_termios_baud_rate(old_termios); | ||
| 559 | } | ||
| 560 | } | 596 | } |
| 561 | } | 597 | } |
| 562 | /* Report back the resulting baud rate */ | 598 | /* Report back the resulting baud rate */ |
| @@ -588,14 +624,14 @@ static void cp2101_set_termios(struct tty_struct *tty, | |||
| 588 | dbg("%s - data bits = 9", __func__); | 624 | dbg("%s - data bits = 9", __func__); |
| 589 | break;*/ | 625 | break;*/ |
| 590 | default: | 626 | default: |
| 591 | dev_err(&port->dev, "cp2101 driver does not " | 627 | dbg("cp2101 driver does not " |
| 592 | "support the number of bits requested," | 628 | "support the number of bits requested," |
| 593 | " using 8 bit mode\n"); | 629 | " using 8 bit mode\n"); |
| 594 | bits |= BITS_DATA_8; | 630 | bits |= BITS_DATA_8; |
| 595 | break; | 631 | break; |
| 596 | } | 632 | } |
| 597 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) | 633 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) |
| 598 | dev_err(&port->dev, "Number of data bits requested " | 634 | dbg("Number of data bits requested " |
| 599 | "not supported by device\n"); | 635 | "not supported by device\n"); |
| 600 | } | 636 | } |
| 601 | 637 | ||
| @@ -612,7 +648,7 @@ static void cp2101_set_termios(struct tty_struct *tty, | |||
| 612 | } | 648 | } |
| 613 | } | 649 | } |
| 614 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) | 650 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) |
| 615 | dev_err(&port->dev, "Parity mode not supported " | 651 | dbg("Parity mode not supported " |
| 616 | "by device\n"); | 652 | "by device\n"); |
| 617 | } | 653 | } |
| 618 | 654 | ||
| @@ -627,7 +663,7 @@ static void cp2101_set_termios(struct tty_struct *tty, | |||
| 627 | dbg("%s - stop bits = 1", __func__); | 663 | dbg("%s - stop bits = 1", __func__); |
| 628 | } | 664 | } |
| 629 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) | 665 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) |
| 630 | dev_err(&port->dev, "Number of stop bits requested " | 666 | dbg("Number of stop bits requested " |
| 631 | "not supported by device\n"); | 667 | "not supported by device\n"); |
| 632 | } | 668 | } |
| 633 | 669 | ||
| @@ -661,6 +697,12 @@ static int cp2101_tiocmset (struct tty_struct *tty, struct file *file, | |||
| 661 | unsigned int set, unsigned int clear) | 697 | unsigned int set, unsigned int clear) |
| 662 | { | 698 | { |
| 663 | struct usb_serial_port *port = tty->driver_data; | 699 | struct usb_serial_port *port = tty->driver_data; |
| 700 | return cp2101_tiocmset_port(port, file, set, clear); | ||
| 701 | } | ||
| 702 | |||
| 703 | static int cp2101_tiocmset_port(struct usb_serial_port *port, struct file *file, | ||
| 704 | unsigned int set, unsigned int clear) | ||
| 705 | { | ||
| 664 | unsigned int control = 0; | 706 | unsigned int control = 0; |
| 665 | 707 | ||
| 666 | dbg("%s - port %d", __func__, port->number); | 708 | dbg("%s - port %d", __func__, port->number); |
| @@ -685,7 +727,6 @@ static int cp2101_tiocmset (struct tty_struct *tty, struct file *file, | |||
| 685 | dbg("%s - control = 0x%.4x", __func__, control); | 727 | dbg("%s - control = 0x%.4x", __func__, control); |
| 686 | 728 | ||
| 687 | return cp2101_set_config(port, CP2101_CONTROL, &control, 2); | 729 | return cp2101_set_config(port, CP2101_CONTROL, &control, 2); |
| 688 | |||
| 689 | } | 730 | } |
| 690 | 731 | ||
| 691 | static int cp2101_tiocmget (struct tty_struct *tty, struct file *file) | 732 | static int cp2101_tiocmget (struct tty_struct *tty, struct file *file) |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index ae84c326a540..dcc87aaa8628 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
| @@ -1938,18 +1938,16 @@ static void ftdi_process_read(struct work_struct *work) | |||
| 1938 | /* Compare new line status to the old one, signal if different/ | 1938 | /* Compare new line status to the old one, signal if different/ |
| 1939 | N.B. packet may be processed more than once, but differences | 1939 | N.B. packet may be processed more than once, but differences |
| 1940 | are only processed once. */ | 1940 | are only processed once. */ |
| 1941 | if (priv != NULL) { | 1941 | char new_status = data[packet_offset + 0] & |
| 1942 | char new_status = data[packet_offset + 0] & | 1942 | FTDI_STATUS_B0_MASK; |
| 1943 | FTDI_STATUS_B0_MASK; | 1943 | if (new_status != priv->prev_status) { |
| 1944 | if (new_status != priv->prev_status) { | 1944 | priv->diff_status |= |
| 1945 | priv->diff_status |= | 1945 | new_status ^ priv->prev_status; |
| 1946 | new_status ^ priv->prev_status; | 1946 | wake_up_interruptible(&priv->delta_msr_wait); |
| 1947 | wake_up_interruptible(&priv->delta_msr_wait); | 1947 | priv->prev_status = new_status; |
| 1948 | priv->prev_status = new_status; | ||
| 1949 | } | ||
| 1950 | } | 1948 | } |
| 1951 | 1949 | ||
| 1952 | length = min(PKTSZ, urb->actual_length-packet_offset)-2; | 1950 | length = min_t(u32, PKTSZ, urb->actual_length-packet_offset)-2; |
| 1953 | if (length < 0) { | 1951 | if (length < 0) { |
| 1954 | dev_err(&port->dev, "%s - bad packet length: %d\n", | 1952 | dev_err(&port->dev, "%s - bad packet length: %d\n", |
| 1955 | __func__, length+2); | 1953 | __func__, length+2); |
| @@ -2294,11 +2292,8 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) | |||
| 2294 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, | 2292 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, |
| 2295 | 0, 0, | 2293 | 0, 0, |
| 2296 | buf, 1, WDR_TIMEOUT); | 2294 | buf, 1, WDR_TIMEOUT); |
| 2297 | if (ret < 0) { | 2295 | if (ret < 0) |
| 2298 | dbg("%s Could not get modem status of device - err: %d", __func__, | ||
| 2299 | ret); | ||
| 2300 | return ret; | 2296 | return ret; |
| 2301 | } | ||
| 2302 | break; | 2297 | break; |
| 2303 | case FT8U232AM: | 2298 | case FT8U232AM: |
| 2304 | case FT232BM: | 2299 | case FT232BM: |
| @@ -2313,15 +2308,11 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) | |||
| 2313 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, | 2308 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, |
| 2314 | 0, priv->interface, | 2309 | 0, priv->interface, |
| 2315 | buf, 2, WDR_TIMEOUT); | 2310 | buf, 2, WDR_TIMEOUT); |
| 2316 | if (ret < 0) { | 2311 | if (ret < 0) |
| 2317 | dbg("%s Could not get modem status of device - err: %d", __func__, | ||
| 2318 | ret); | ||
| 2319 | return ret; | 2312 | return ret; |
| 2320 | } | ||
| 2321 | break; | 2313 | break; |
| 2322 | default: | 2314 | default: |
| 2323 | return -EFAULT; | 2315 | return -EFAULT; |
| 2324 | break; | ||
| 2325 | } | 2316 | } |
| 2326 | 2317 | ||
| 2327 | return (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | | 2318 | return (buf[0] & FTDI_SIO_DSR_MASK ? TIOCM_DSR : 0) | |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 814909f1ee63..9d57cace3731 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
| @@ -177,14 +177,6 @@ int usb_serial_generic_resume(struct usb_serial *serial) | |||
| 177 | struct usb_serial_port *port; | 177 | struct usb_serial_port *port; |
| 178 | int i, c = 0, r; | 178 | int i, c = 0, r; |
| 179 | 179 | ||
| 180 | #ifdef CONFIG_PM | ||
| 181 | /* | ||
| 182 | * If this is an autoresume, don't submit URBs. | ||
| 183 | * They will be submitted in the open function instead. | ||
| 184 | */ | ||
| 185 | if (serial->dev->auto_pm) | ||
| 186 | return 0; | ||
| 187 | #endif | ||
| 188 | for (i = 0; i < serial->num_ports; i++) { | 180 | for (i = 0; i < serial->num_ports; i++) { |
| 189 | port = serial->port[i]; | 181 | port = serial->port[i]; |
| 190 | if (port->port.count && port->read_urb) { | 182 | if (port->port.count && port->read_urb) { |
| @@ -196,6 +188,7 @@ int usb_serial_generic_resume(struct usb_serial *serial) | |||
| 196 | 188 | ||
| 197 | return c ? -EIO : 0; | 189 | return c ? -EIO : 0; |
| 198 | } | 190 | } |
| 191 | EXPORT_SYMBOL_GPL(usb_serial_generic_resume); | ||
| 199 | 192 | ||
| 200 | void usb_serial_generic_close(struct tty_struct *tty, | 193 | void usb_serial_generic_close(struct tty_struct *tty, |
| 201 | struct usb_serial_port *port, struct file *filp) | 194 | struct usb_serial_port *port, struct file *filp) |
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 132be74d2b89..ef92095b0732 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
| @@ -78,6 +78,7 @@ static int ipaq_open(struct tty_struct *tty, | |||
| 78 | struct usb_serial_port *port, struct file *filp); | 78 | struct usb_serial_port *port, struct file *filp); |
| 79 | static void ipaq_close(struct tty_struct *tty, | 79 | static void ipaq_close(struct tty_struct *tty, |
| 80 | struct usb_serial_port *port, struct file *filp); | 80 | struct usb_serial_port *port, struct file *filp); |
| 81 | static int ipaq_calc_num_ports(struct usb_serial *serial); | ||
| 81 | static int ipaq_startup(struct usb_serial *serial); | 82 | static int ipaq_startup(struct usb_serial *serial); |
| 82 | static void ipaq_shutdown(struct usb_serial *serial); | 83 | static void ipaq_shutdown(struct usb_serial *serial); |
| 83 | static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port, | 84 | static int ipaq_write(struct tty_struct *tty, struct usb_serial_port *port, |
| @@ -572,15 +573,10 @@ static struct usb_serial_driver ipaq_device = { | |||
| 572 | .description = "PocketPC PDA", | 573 | .description = "PocketPC PDA", |
| 573 | .usb_driver = &ipaq_driver, | 574 | .usb_driver = &ipaq_driver, |
| 574 | .id_table = ipaq_id_table, | 575 | .id_table = ipaq_id_table, |
| 575 | /* | ||
| 576 | * some devices have an extra endpoint, which | ||
| 577 | * must be ignored as it would make the core | ||
| 578 | * create a second port which oopses when used | ||
| 579 | */ | ||
| 580 | .num_ports = 1, | ||
| 581 | .open = ipaq_open, | 576 | .open = ipaq_open, |
| 582 | .close = ipaq_close, | 577 | .close = ipaq_close, |
| 583 | .attach = ipaq_startup, | 578 | .attach = ipaq_startup, |
| 579 | .calc_num_ports = ipaq_calc_num_ports, | ||
| 584 | .shutdown = ipaq_shutdown, | 580 | .shutdown = ipaq_shutdown, |
| 585 | .write = ipaq_write, | 581 | .write = ipaq_write, |
| 586 | .write_room = ipaq_write_room, | 582 | .write_room = ipaq_write_room, |
| @@ -956,14 +952,49 @@ static void ipaq_destroy_lists(struct usb_serial_port *port) | |||
| 956 | } | 952 | } |
| 957 | 953 | ||
| 958 | 954 | ||
| 955 | static int ipaq_calc_num_ports(struct usb_serial *serial) | ||
| 956 | { | ||
| 957 | /* | ||
| 958 | * some devices have 3 endpoints, the 3rd of which | ||
| 959 | * must be ignored as it would make the core | ||
| 960 | * create a second port which oopses when used | ||
| 961 | */ | ||
| 962 | int ipaq_num_ports = 1; | ||
| 963 | |||
| 964 | dbg("%s - numberofendpoints: %d", __FUNCTION__, | ||
| 965 | (int)serial->interface->cur_altsetting->desc.bNumEndpoints); | ||
| 966 | |||
| 967 | /* | ||
| 968 | * a few devices have 4 endpoints, seemingly Yakuma devices, | ||
| 969 | * and we need the second pair, so let them have 2 ports | ||
| 970 | * | ||
| 971 | * TODO: can we drop port 1 ? | ||
| 972 | */ | ||
| 973 | if (serial->interface->cur_altsetting->desc.bNumEndpoints > 3) { | ||
| 974 | ipaq_num_ports = 2; | ||
| 975 | } | ||
| 976 | |||
| 977 | return ipaq_num_ports; | ||
| 978 | } | ||
| 979 | |||
| 980 | |||
| 959 | static int ipaq_startup(struct usb_serial *serial) | 981 | static int ipaq_startup(struct usb_serial *serial) |
| 960 | { | 982 | { |
| 961 | dbg("%s", __func__); | 983 | dbg("%s", __func__); |
| 962 | if (serial->dev->actconfig->desc.bConfigurationValue != 1) { | 984 | if (serial->dev->actconfig->desc.bConfigurationValue != 1) { |
| 985 | /* | ||
| 986 | * FIXME: HP iPaq rx3715, possibly others, have 1 config that | ||
| 987 | * is labeled as 2 | ||
| 988 | */ | ||
| 989 | |||
| 963 | dev_err(&serial->dev->dev, "active config #%d != 1 ??\n", | 990 | dev_err(&serial->dev->dev, "active config #%d != 1 ??\n", |
| 964 | serial->dev->actconfig->desc.bConfigurationValue); | 991 | serial->dev->actconfig->desc.bConfigurationValue); |
| 965 | return -ENODEV; | 992 | return -ENODEV; |
| 966 | } | 993 | } |
| 994 | |||
| 995 | dbg("%s - iPAQ module configured for %d ports", | ||
| 996 | __FUNCTION__, serial->num_ports); | ||
| 997 | |||
| 967 | return usb_reset_configuration(serial->dev); | 998 | return usb_reset_configuration(serial->dev); |
| 968 | } | 999 | } |
| 969 | 1000 | ||
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 9878c0fb3859..00daa8f7759a 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
| @@ -1507,7 +1507,7 @@ static struct urb *keyspan_setup_urb(struct usb_serial *serial, int endpoint, | |||
| 1507 | } else { | 1507 | } else { |
| 1508 | dev_warn(&serial->interface->dev, | 1508 | dev_warn(&serial->interface->dev, |
| 1509 | "unsupported endpoint type %x\n", | 1509 | "unsupported endpoint type %x\n", |
| 1510 | ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); | 1510 | usb_endpoint_type(ep_desc)); |
| 1511 | usb_free_urb(urb); | 1511 | usb_free_urb(urb); |
| 1512 | return NULL; | 1512 | return NULL; |
| 1513 | } | 1513 | } |
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index cea326f1f105..839583dc8b6a 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c | |||
| @@ -1,8 +1,8 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * Opticon USB barcode to serial driver | 2 | * Opticon USB barcode to serial driver |
| 3 | * | 3 | * |
| 4 | * Copyright (C) 2008 Greg Kroah-Hartman <gregkh@suse.de> | 4 | * Copyright (C) 2008 - 2009 Greg Kroah-Hartman <gregkh@suse.de> |
| 5 | * Copyright (C) 2008 Novell Inc. | 5 | * Copyright (C) 2008 - 2009 Novell Inc. |
| 6 | * | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or | 7 | * This program is free software; you can redistribute it and/or |
| 8 | * modify it under the terms of the GNU General Public License version | 8 | * modify it under the terms of the GNU General Public License version |
| @@ -14,6 +14,7 @@ | |||
| 14 | #include <linux/tty.h> | 14 | #include <linux/tty.h> |
| 15 | #include <linux/tty_driver.h> | 15 | #include <linux/tty_driver.h> |
| 16 | #include <linux/tty_flip.h> | 16 | #include <linux/tty_flip.h> |
| 17 | #include <linux/serial.h> | ||
| 17 | #include <linux/module.h> | 18 | #include <linux/module.h> |
| 18 | #include <linux/usb.h> | 19 | #include <linux/usb.h> |
| 19 | #include <linux/usb/serial.h> | 20 | #include <linux/usb/serial.h> |
| @@ -40,8 +41,12 @@ struct opticon_private { | |||
| 40 | bool throttled; | 41 | bool throttled; |
| 41 | bool actually_throttled; | 42 | bool actually_throttled; |
| 42 | bool rts; | 43 | bool rts; |
| 44 | int outstanding_urbs; | ||
| 43 | }; | 45 | }; |
| 44 | 46 | ||
| 47 | /* max number of write urbs in flight */ | ||
| 48 | #define URB_UPPER_LIMIT 4 | ||
| 49 | |||
| 45 | static void opticon_bulk_callback(struct urb *urb) | 50 | static void opticon_bulk_callback(struct urb *urb) |
| 46 | { | 51 | { |
| 47 | struct opticon_private *priv = urb->context; | 52 | struct opticon_private *priv = urb->context; |
| @@ -106,7 +111,6 @@ static void opticon_bulk_callback(struct urb *urb) | |||
| 106 | priv->rts = false; | 111 | priv->rts = false; |
| 107 | else | 112 | else |
| 108 | priv->rts = true; | 113 | priv->rts = true; |
| 109 | /* FIXME change the RTS level */ | ||
| 110 | } else { | 114 | } else { |
| 111 | dev_dbg(&priv->udev->dev, | 115 | dev_dbg(&priv->udev->dev, |
| 112 | "Unknown data packet received from the device:" | 116 | "Unknown data packet received from the device:" |
| @@ -188,6 +192,120 @@ static void opticon_close(struct tty_struct *tty, struct usb_serial_port *port, | |||
| 188 | usb_kill_urb(priv->bulk_read_urb); | 192 | usb_kill_urb(priv->bulk_read_urb); |
| 189 | } | 193 | } |
| 190 | 194 | ||
| 195 | static void opticon_write_bulk_callback(struct urb *urb) | ||
| 196 | { | ||
| 197 | struct opticon_private *priv = urb->context; | ||
| 198 | int status = urb->status; | ||
| 199 | unsigned long flags; | ||
| 200 | |||
| 201 | /* free up the transfer buffer, as usb_free_urb() does not do this */ | ||
| 202 | kfree(urb->transfer_buffer); | ||
| 203 | |||
| 204 | if (status) | ||
| 205 | dbg("%s - nonzero write bulk status received: %d", | ||
| 206 | __func__, status); | ||
| 207 | |||
| 208 | spin_lock_irqsave(&priv->lock, flags); | ||
| 209 | --priv->outstanding_urbs; | ||
| 210 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 211 | |||
| 212 | usb_serial_port_softint(priv->port); | ||
| 213 | } | ||
| 214 | |||
| 215 | static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, | ||
| 216 | const unsigned char *buf, int count) | ||
| 217 | { | ||
| 218 | struct opticon_private *priv = usb_get_serial_data(port->serial); | ||
| 219 | struct usb_serial *serial = port->serial; | ||
| 220 | struct urb *urb; | ||
| 221 | unsigned char *buffer; | ||
| 222 | unsigned long flags; | ||
| 223 | int status; | ||
| 224 | |||
| 225 | dbg("%s - port %d", __func__, port->number); | ||
| 226 | |||
| 227 | spin_lock_irqsave(&priv->lock, flags); | ||
| 228 | if (priv->outstanding_urbs > URB_UPPER_LIMIT) { | ||
| 229 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 230 | dbg("%s - write limit hit\n", __func__); | ||
| 231 | return 0; | ||
| 232 | } | ||
| 233 | priv->outstanding_urbs++; | ||
| 234 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 235 | |||
| 236 | buffer = kmalloc(count, GFP_ATOMIC); | ||
| 237 | if (!buffer) { | ||
| 238 | dev_err(&port->dev, "out of memory\n"); | ||
| 239 | count = -ENOMEM; | ||
| 240 | goto error_no_buffer; | ||
| 241 | } | ||
| 242 | |||
| 243 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
| 244 | if (!urb) { | ||
| 245 | dev_err(&port->dev, "no more free urbs\n"); | ||
| 246 | count = -ENOMEM; | ||
| 247 | goto error_no_urb; | ||
| 248 | } | ||
| 249 | |||
| 250 | memcpy(buffer, buf, count); | ||
| 251 | |||
| 252 | usb_serial_debug_data(debug, &port->dev, __func__, count, buffer); | ||
| 253 | |||
| 254 | usb_fill_bulk_urb(urb, serial->dev, | ||
| 255 | usb_sndbulkpipe(serial->dev, | ||
| 256 | port->bulk_out_endpointAddress), | ||
| 257 | buffer, count, opticon_write_bulk_callback, priv); | ||
| 258 | |||
| 259 | /* send it down the pipe */ | ||
| 260 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
| 261 | if (status) { | ||
| 262 | dev_err(&port->dev, | ||
| 263 | "%s - usb_submit_urb(write bulk) failed with status = %d\n", | ||
| 264 | __func__, status); | ||
| 265 | count = status; | ||
| 266 | goto error; | ||
| 267 | } | ||
| 268 | |||
| 269 | /* we are done with this urb, so let the host driver | ||
| 270 | * really free it when it is finished with it */ | ||
| 271 | usb_free_urb(urb); | ||
| 272 | |||
| 273 | return count; | ||
| 274 | error: | ||
| 275 | usb_free_urb(urb); | ||
| 276 | error_no_urb: | ||
| 277 | kfree(buffer); | ||
| 278 | error_no_buffer: | ||
| 279 | spin_lock_irqsave(&priv->lock, flags); | ||
| 280 | --priv->outstanding_urbs; | ||
| 281 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 282 | return count; | ||
| 283 | } | ||
| 284 | |||
| 285 | static int opticon_write_room(struct tty_struct *tty) | ||
| 286 | { | ||
| 287 | struct usb_serial_port *port = tty->driver_data; | ||
| 288 | struct opticon_private *priv = usb_get_serial_data(port->serial); | ||
| 289 | unsigned long flags; | ||
| 290 | |||
| 291 | dbg("%s - port %d", __func__, port->number); | ||
| 292 | |||
| 293 | /* | ||
| 294 | * We really can take almost anything the user throws at us | ||
| 295 | * but let's pick a nice big number to tell the tty | ||
| 296 | * layer that we have lots of free space, unless we don't. | ||
| 297 | */ | ||
| 298 | spin_lock_irqsave(&priv->lock, flags); | ||
| 299 | if (priv->outstanding_urbs > URB_UPPER_LIMIT * 2 / 3) { | ||
| 300 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 301 | dbg("%s - write limit hit\n", __func__); | ||
| 302 | return 0; | ||
| 303 | } | ||
| 304 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 305 | |||
| 306 | return 2048; | ||
| 307 | } | ||
| 308 | |||
| 191 | static void opticon_throttle(struct tty_struct *tty) | 309 | static void opticon_throttle(struct tty_struct *tty) |
| 192 | { | 310 | { |
| 193 | struct usb_serial_port *port = tty->driver_data; | 311 | struct usb_serial_port *port = tty->driver_data; |
| @@ -223,6 +341,67 @@ static void opticon_unthrottle(struct tty_struct *tty) | |||
| 223 | __func__, result); | 341 | __func__, result); |
| 224 | } | 342 | } |
| 225 | 343 | ||
| 344 | static int opticon_tiocmget(struct tty_struct *tty, struct file *file) | ||
| 345 | { | ||
| 346 | struct usb_serial_port *port = tty->driver_data; | ||
| 347 | struct opticon_private *priv = usb_get_serial_data(port->serial); | ||
| 348 | unsigned long flags; | ||
| 349 | int result = 0; | ||
| 350 | |||
| 351 | dbg("%s - port %d", __func__, port->number); | ||
| 352 | |||
| 353 | spin_lock_irqsave(&priv->lock, flags); | ||
| 354 | if (priv->rts) | ||
| 355 | result = TIOCM_RTS; | ||
| 356 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 357 | |||
| 358 | dbg("%s - %x", __func__, result); | ||
| 359 | return result; | ||
| 360 | } | ||
| 361 | |||
| 362 | static int get_serial_info(struct opticon_private *priv, | ||
| 363 | struct serial_struct __user *serial) | ||
| 364 | { | ||
| 365 | struct serial_struct tmp; | ||
| 366 | |||
| 367 | if (!serial) | ||
| 368 | return -EFAULT; | ||
| 369 | |||
| 370 | memset(&tmp, 0x00, sizeof(tmp)); | ||
| 371 | |||
| 372 | /* fake emulate a 16550 uart to make userspace code happy */ | ||
| 373 | tmp.type = PORT_16550A; | ||
| 374 | tmp.line = priv->serial->minor; | ||
| 375 | tmp.port = 0; | ||
| 376 | tmp.irq = 0; | ||
| 377 | tmp.flags = ASYNC_SKIP_TEST | ASYNC_AUTO_IRQ; | ||
| 378 | tmp.xmit_fifo_size = 1024; | ||
| 379 | tmp.baud_base = 9600; | ||
| 380 | tmp.close_delay = 5*HZ; | ||
| 381 | tmp.closing_wait = 30*HZ; | ||
| 382 | |||
| 383 | if (copy_to_user(serial, &tmp, sizeof(*serial))) | ||
| 384 | return -EFAULT; | ||
| 385 | return 0; | ||
| 386 | } | ||
| 387 | |||
| 388 | static int opticon_ioctl(struct tty_struct *tty, struct file *file, | ||
| 389 | unsigned int cmd, unsigned long arg) | ||
| 390 | { | ||
| 391 | struct usb_serial_port *port = tty->driver_data; | ||
| 392 | struct opticon_private *priv = usb_get_serial_data(port->serial); | ||
| 393 | |||
| 394 | dbg("%s - port %d, cmd = 0x%x", __func__, port->number, cmd); | ||
| 395 | |||
| 396 | switch (cmd) { | ||
| 397 | case TIOCGSERIAL: | ||
| 398 | return get_serial_info(priv, | ||
| 399 | (struct serial_struct __user *)arg); | ||
| 400 | } | ||
| 401 | |||
| 402 | return -ENOIOCTLCMD; | ||
| 403 | } | ||
| 404 | |||
| 226 | static int opticon_startup(struct usb_serial *serial) | 405 | static int opticon_startup(struct usb_serial *serial) |
| 227 | { | 406 | { |
| 228 | struct opticon_private *priv; | 407 | struct opticon_private *priv; |
| @@ -306,11 +485,37 @@ static void opticon_shutdown(struct usb_serial *serial) | |||
| 306 | usb_set_serial_data(serial, NULL); | 485 | usb_set_serial_data(serial, NULL); |
| 307 | } | 486 | } |
| 308 | 487 | ||
| 488 | static int opticon_suspend(struct usb_interface *intf, pm_message_t message) | ||
| 489 | { | ||
| 490 | struct usb_serial *serial = usb_get_intfdata(intf); | ||
| 491 | struct opticon_private *priv = usb_get_serial_data(serial); | ||
| 492 | |||
| 493 | usb_kill_urb(priv->bulk_read_urb); | ||
| 494 | return 0; | ||
| 495 | } | ||
| 496 | |||
| 497 | static int opticon_resume(struct usb_interface *intf) | ||
| 498 | { | ||
| 499 | struct usb_serial *serial = usb_get_intfdata(intf); | ||
| 500 | struct opticon_private *priv = usb_get_serial_data(serial); | ||
| 501 | struct usb_serial_port *port = serial->port[0]; | ||
| 502 | int result; | ||
| 503 | |||
| 504 | mutex_lock(&port->mutex); | ||
| 505 | if (port->port.count) | ||
| 506 | result = usb_submit_urb(priv->bulk_read_urb, GFP_NOIO); | ||
| 507 | else | ||
| 508 | result = 0; | ||
| 509 | mutex_unlock(&port->mutex); | ||
| 510 | return result; | ||
| 511 | } | ||
| 309 | 512 | ||
| 310 | static struct usb_driver opticon_driver = { | 513 | static struct usb_driver opticon_driver = { |
| 311 | .name = "opticon", | 514 | .name = "opticon", |
| 312 | .probe = usb_serial_probe, | 515 | .probe = usb_serial_probe, |
| 313 | .disconnect = usb_serial_disconnect, | 516 | .disconnect = usb_serial_disconnect, |
| 517 | .suspend = opticon_suspend, | ||
| 518 | .resume = opticon_resume, | ||
| 314 | .id_table = id_table, | 519 | .id_table = id_table, |
| 315 | .no_dynamic_id = 1, | 520 | .no_dynamic_id = 1, |
| 316 | }; | 521 | }; |
| @@ -326,9 +531,13 @@ static struct usb_serial_driver opticon_device = { | |||
| 326 | .attach = opticon_startup, | 531 | .attach = opticon_startup, |
| 327 | .open = opticon_open, | 532 | .open = opticon_open, |
| 328 | .close = opticon_close, | 533 | .close = opticon_close, |
| 534 | .write = opticon_write, | ||
| 535 | .write_room = opticon_write_room, | ||
| 329 | .shutdown = opticon_shutdown, | 536 | .shutdown = opticon_shutdown, |
| 330 | .throttle = opticon_throttle, | 537 | .throttle = opticon_throttle, |
| 331 | .unthrottle = opticon_unthrottle, | 538 | .unthrottle = opticon_unthrottle, |
| 539 | .ioctl = opticon_ioctl, | ||
| 540 | .tiocmget = opticon_tiocmget, | ||
| 332 | }; | 541 | }; |
| 333 | 542 | ||
| 334 | static int __init opticon_init(void) | 543 | static int __init opticon_init(void) |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 61ebddc48497..d560c0b54e6e 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
| @@ -62,6 +62,8 @@ static int option_tiocmget(struct tty_struct *tty, struct file *file); | |||
| 62 | static int option_tiocmset(struct tty_struct *tty, struct file *file, | 62 | static int option_tiocmset(struct tty_struct *tty, struct file *file, |
| 63 | unsigned int set, unsigned int clear); | 63 | unsigned int set, unsigned int clear); |
| 64 | static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *port); | 64 | static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *port); |
| 65 | static int option_suspend(struct usb_serial *serial, pm_message_t message); | ||
| 66 | static int option_resume(struct usb_serial *serial); | ||
| 65 | 67 | ||
| 66 | /* Vendor and product IDs */ | 68 | /* Vendor and product IDs */ |
| 67 | #define OPTION_VENDOR_ID 0x0AF0 | 69 | #define OPTION_VENDOR_ID 0x0AF0 |
| @@ -523,6 +525,8 @@ static struct usb_driver option_driver = { | |||
| 523 | .name = "option", | 525 | .name = "option", |
| 524 | .probe = usb_serial_probe, | 526 | .probe = usb_serial_probe, |
| 525 | .disconnect = usb_serial_disconnect, | 527 | .disconnect = usb_serial_disconnect, |
| 528 | .suspend = usb_serial_suspend, | ||
| 529 | .resume = usb_serial_resume, | ||
| 526 | .id_table = option_ids, | 530 | .id_table = option_ids, |
| 527 | .no_dynamic_id = 1, | 531 | .no_dynamic_id = 1, |
| 528 | }; | 532 | }; |
| @@ -551,6 +555,8 @@ static struct usb_serial_driver option_1port_device = { | |||
| 551 | .attach = option_startup, | 555 | .attach = option_startup, |
| 552 | .shutdown = option_shutdown, | 556 | .shutdown = option_shutdown, |
| 553 | .read_int_callback = option_instat_callback, | 557 | .read_int_callback = option_instat_callback, |
| 558 | .suspend = option_suspend, | ||
| 559 | .resume = option_resume, | ||
| 554 | }; | 560 | }; |
| 555 | 561 | ||
| 556 | static int debug; | 562 | static int debug; |
| @@ -821,10 +827,10 @@ static void option_instat_callback(struct urb *urb) | |||
| 821 | req_pkt->bRequestType, req_pkt->bRequest); | 827 | req_pkt->bRequestType, req_pkt->bRequest); |
| 822 | } | 828 | } |
| 823 | } else | 829 | } else |
| 824 | dbg("%s: error %d", __func__, status); | 830 | err("%s: error %d", __func__, status); |
| 825 | 831 | ||
| 826 | /* Resubmit urb so we continue receiving IRQ data */ | 832 | /* Resubmit urb so we continue receiving IRQ data */ |
| 827 | if (status != -ESHUTDOWN) { | 833 | if (status != -ESHUTDOWN && status != -ENOENT) { |
| 828 | urb->dev = serial->dev; | 834 | urb->dev = serial->dev; |
| 829 | err = usb_submit_urb(urb, GFP_ATOMIC); | 835 | err = usb_submit_urb(urb, GFP_ATOMIC); |
| 830 | if (err) | 836 | if (err) |
| @@ -843,7 +849,6 @@ static int option_write_room(struct tty_struct *tty) | |||
| 843 | 849 | ||
| 844 | portdata = usb_get_serial_port_data(port); | 850 | portdata = usb_get_serial_port_data(port); |
| 845 | 851 | ||
| 846 | |||
| 847 | for (i = 0; i < N_OUT_URB; i++) { | 852 | for (i = 0; i < N_OUT_URB; i++) { |
| 848 | this_urb = portdata->out_urbs[i]; | 853 | this_urb = portdata->out_urbs[i]; |
| 849 | if (this_urb && !test_bit(i, &portdata->out_busy)) | 854 | if (this_urb && !test_bit(i, &portdata->out_busy)) |
| @@ -1105,14 +1110,12 @@ bail_out_error: | |||
| 1105 | return 1; | 1110 | return 1; |
| 1106 | } | 1111 | } |
| 1107 | 1112 | ||
| 1108 | static void option_shutdown(struct usb_serial *serial) | 1113 | static void stop_read_write_urbs(struct usb_serial *serial) |
| 1109 | { | 1114 | { |
| 1110 | int i, j; | 1115 | int i, j; |
| 1111 | struct usb_serial_port *port; | 1116 | struct usb_serial_port *port; |
| 1112 | struct option_port_private *portdata; | 1117 | struct option_port_private *portdata; |
| 1113 | 1118 | ||
| 1114 | dbg("%s", __func__); | ||
| 1115 | |||
| 1116 | /* Stop reading/writing urbs */ | 1119 | /* Stop reading/writing urbs */ |
| 1117 | for (i = 0; i < serial->num_ports; ++i) { | 1120 | for (i = 0; i < serial->num_ports; ++i) { |
| 1118 | port = serial->port[i]; | 1121 | port = serial->port[i]; |
| @@ -1122,6 +1125,17 @@ static void option_shutdown(struct usb_serial *serial) | |||
| 1122 | for (j = 0; j < N_OUT_URB; j++) | 1125 | for (j = 0; j < N_OUT_URB; j++) |
| 1123 | usb_kill_urb(portdata->out_urbs[j]); | 1126 | usb_kill_urb(portdata->out_urbs[j]); |
| 1124 | } | 1127 | } |
| 1128 | } | ||
| 1129 | |||
| 1130 | static void option_shutdown(struct usb_serial *serial) | ||
| 1131 | { | ||
| 1132 | int i, j; | ||
| 1133 | struct usb_serial_port *port; | ||
| 1134 | struct option_port_private *portdata; | ||
| 1135 | |||
| 1136 | dbg("%s", __func__); | ||
| 1137 | |||
| 1138 | stop_read_write_urbs(serial); | ||
| 1125 | 1139 | ||
| 1126 | /* Now free them */ | 1140 | /* Now free them */ |
| 1127 | for (i = 0; i < serial->num_ports; ++i) { | 1141 | for (i = 0; i < serial->num_ports; ++i) { |
| @@ -1152,6 +1166,66 @@ static void option_shutdown(struct usb_serial *serial) | |||
| 1152 | } | 1166 | } |
| 1153 | } | 1167 | } |
| 1154 | 1168 | ||
| 1169 | static int option_suspend(struct usb_serial *serial, pm_message_t message) | ||
| 1170 | { | ||
| 1171 | dbg("%s entered", __func__); | ||
| 1172 | stop_read_write_urbs(serial); | ||
| 1173 | |||
| 1174 | return 0; | ||
| 1175 | } | ||
| 1176 | |||
| 1177 | static int option_resume(struct usb_serial *serial) | ||
| 1178 | { | ||
| 1179 | int err, i, j; | ||
| 1180 | struct usb_serial_port *port; | ||
| 1181 | struct urb *urb; | ||
| 1182 | struct option_port_private *portdata; | ||
| 1183 | |||
| 1184 | dbg("%s entered", __func__); | ||
| 1185 | /* get the interrupt URBs resubmitted unconditionally */ | ||
| 1186 | for (i = 0; i < serial->num_ports; i++) { | ||
| 1187 | port = serial->port[i]; | ||
| 1188 | if (!port->interrupt_in_urb) { | ||
| 1189 | dbg("%s: No interrupt URB for port %d\n", __func__, i); | ||
| 1190 | continue; | ||
| 1191 | } | ||
| 1192 | port->interrupt_in_urb->dev = serial->dev; | ||
| 1193 | err = usb_submit_urb(port->interrupt_in_urb, GFP_NOIO); | ||
| 1194 | dbg("Submitted interrupt URB for port %d (result %d)", i, err); | ||
| 1195 | if (err < 0) { | ||
| 1196 | err("%s: Error %d for interrupt URB of port%d", | ||
| 1197 | __func__, err, i); | ||
| 1198 | return err; | ||
| 1199 | } | ||
| 1200 | } | ||
| 1201 | |||
| 1202 | for (i = 0; i < serial->num_ports; i++) { | ||
| 1203 | /* walk all ports */ | ||
| 1204 | port = serial->port[i]; | ||
| 1205 | portdata = usb_get_serial_port_data(port); | ||
| 1206 | mutex_lock(&port->mutex); | ||
| 1207 | |||
| 1208 | /* skip closed ports */ | ||
| 1209 | if (!port->port.count) { | ||
| 1210 | mutex_unlock(&port->mutex); | ||
| 1211 | continue; | ||
| 1212 | } | ||
| 1213 | |||
| 1214 | for (j = 0; j < N_IN_URB; j++) { | ||
| 1215 | urb = portdata->in_urbs[j]; | ||
| 1216 | err = usb_submit_urb(urb, GFP_NOIO); | ||
| 1217 | if (err < 0) { | ||
| 1218 | mutex_unlock(&port->mutex); | ||
| 1219 | err("%s: Error %d for bulk URB %d", | ||
| 1220 | __func__, err, i); | ||
| 1221 | return err; | ||
| 1222 | } | ||
| 1223 | } | ||
| 1224 | mutex_unlock(&port->mutex); | ||
| 1225 | } | ||
| 1226 | return 0; | ||
| 1227 | } | ||
| 1228 | |||
| 1155 | MODULE_AUTHOR(DRIVER_AUTHOR); | 1229 | MODULE_AUTHOR(DRIVER_AUTHOR); |
| 1156 | MODULE_DESCRIPTION(DRIVER_DESC); | 1230 | MODULE_DESCRIPTION(DRIVER_DESC); |
| 1157 | MODULE_VERSION(DRIVER_VERSION); | 1231 | MODULE_VERSION(DRIVER_VERSION); |
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c new file mode 100644 index 000000000000..e6d6b0c17fd9 --- /dev/null +++ b/drivers/usb/serial/qcserial.c | |||
| @@ -0,0 +1,147 @@ | |||
| 1 | /* | ||
| 2 | * Qualcomm Serial USB driver | ||
| 3 | * | ||
| 4 | * Copyright (c) 2008 QUALCOMM Incorporated. | ||
| 5 | * Copyright (c) 2009 Greg Kroah-Hartman <gregkh@suse.de> | ||
| 6 | * Copyright (c) 2009 Novell Inc. | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or | ||
| 9 | * modify it under the terms of the GNU General Public License version | ||
| 10 | * 2 as published by the Free Software Foundation. | ||
| 11 | * | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/tty.h> | ||
| 15 | #include <linux/tty_flip.h> | ||
| 16 | #include <linux/usb.h> | ||
| 17 | #include <linux/usb/serial.h> | ||
| 18 | |||
| 19 | #define DRIVER_AUTHOR "Qualcomm Inc" | ||
| 20 | #define DRIVER_DESC "Qualcomm USB Serial driver" | ||
| 21 | |||
| 22 | static int debug; | ||
| 23 | |||
| 24 | static struct usb_device_id id_table[] = { | ||
| 25 | {USB_DEVICE(0x05c6, 0x9211)}, /* Acer Gobi QDL device */ | ||
| 26 | {USB_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | ||
| 27 | {USB_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ | ||
| 28 | {USB_DEVICE(0x03f0, 0x201d)}, /* HP un2400 Gobi QDL Device */ | ||
| 29 | { } /* Terminating entry */ | ||
| 30 | }; | ||
| 31 | MODULE_DEVICE_TABLE(usb, id_table); | ||
| 32 | |||
| 33 | static struct usb_driver qcdriver = { | ||
| 34 | .name = "qcserial", | ||
| 35 | .probe = usb_serial_probe, | ||
| 36 | .disconnect = usb_serial_disconnect, | ||
| 37 | .id_table = id_table, | ||
| 38 | .suspend = usb_serial_suspend, | ||
| 39 | .resume = usb_serial_resume, | ||
| 40 | .supports_autosuspend = true, | ||
| 41 | }; | ||
| 42 | |||
| 43 | static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | ||
| 44 | { | ||
| 45 | int retval = -ENODEV; | ||
| 46 | __u8 nintf; | ||
| 47 | __u8 ifnum; | ||
| 48 | |||
| 49 | dbg("%s", __func__); | ||
| 50 | |||
| 51 | nintf = serial->dev->actconfig->desc.bNumInterfaces; | ||
| 52 | dbg("Num Interfaces = %d", nintf); | ||
| 53 | ifnum = serial->interface->cur_altsetting->desc.bInterfaceNumber; | ||
| 54 | dbg("This Interface = %d", ifnum); | ||
| 55 | |||
| 56 | switch (nintf) { | ||
| 57 | case 1: | ||
| 58 | /* QDL mode */ | ||
| 59 | if (serial->interface->num_altsetting == 2) { | ||
| 60 | struct usb_host_interface *intf; | ||
| 61 | |||
| 62 | intf = &serial->interface->altsetting[1]; | ||
| 63 | if (intf->desc.bNumEndpoints == 2) { | ||
| 64 | if (usb_endpoint_is_bulk_in(&intf->endpoint[0].desc) && | ||
| 65 | usb_endpoint_is_bulk_out(&intf->endpoint[1].desc)) { | ||
| 66 | dbg("QDL port found"); | ||
| 67 | retval = usb_set_interface(serial->dev, ifnum, 1); | ||
| 68 | if (retval < 0) { | ||
| 69 | dev_err(&serial->dev->dev, | ||
| 70 | "Could not set interface, error %d\n", | ||
| 71 | retval); | ||
| 72 | retval = -ENODEV; | ||
| 73 | } | ||
| 74 | return retval; | ||
| 75 | } | ||
| 76 | } | ||
| 77 | } | ||
| 78 | break; | ||
| 79 | |||
| 80 | case 4: | ||
| 81 | /* Composite mode */ | ||
| 82 | if (ifnum == 2) { | ||
| 83 | dbg("Modem port found"); | ||
| 84 | retval = usb_set_interface(serial->dev, ifnum, 0); | ||
| 85 | if (retval < 0) { | ||
| 86 | dev_err(&serial->dev->dev, | ||
| 87 | "Could not set interface, error %d\n", | ||
| 88 | retval); | ||
| 89 | retval = -ENODEV; | ||
| 90 | } | ||
| 91 | return retval; | ||
| 92 | } | ||
| 93 | break; | ||
| 94 | |||
| 95 | default: | ||
| 96 | dev_err(&serial->dev->dev, | ||
| 97 | "unknown number of interfaces: %d\n", nintf); | ||
| 98 | return -ENODEV; | ||
| 99 | } | ||
| 100 | |||
| 101 | return retval; | ||
| 102 | } | ||
| 103 | |||
| 104 | static struct usb_serial_driver qcdevice = { | ||
| 105 | .driver = { | ||
| 106 | .owner = THIS_MODULE, | ||
| 107 | .name = "qcserial", | ||
| 108 | }, | ||
| 109 | .description = "Qualcomm USB modem", | ||
| 110 | .id_table = id_table, | ||
| 111 | .usb_driver = &qcdriver, | ||
| 112 | .num_ports = 1, | ||
| 113 | .probe = qcprobe, | ||
| 114 | }; | ||
| 115 | |||
| 116 | static int __init qcinit(void) | ||
| 117 | { | ||
| 118 | int retval; | ||
| 119 | |||
| 120 | retval = usb_serial_register(&qcdevice); | ||
| 121 | if (retval) | ||
| 122 | return retval; | ||
| 123 | |||
| 124 | retval = usb_register(&qcdriver); | ||
| 125 | if (retval) { | ||
| 126 | usb_serial_deregister(&qcdevice); | ||
| 127 | return retval; | ||
| 128 | } | ||
| 129 | |||
| 130 | return 0; | ||
| 131 | } | ||
| 132 | |||
| 133 | static void __exit qcexit(void) | ||
| 134 | { | ||
| 135 | usb_deregister(&qcdriver); | ||
| 136 | usb_serial_deregister(&qcdevice); | ||
| 137 | } | ||
| 138 | |||
| 139 | module_init(qcinit); | ||
| 140 | module_exit(qcexit); | ||
| 141 | |||
| 142 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
| 143 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
| 144 | MODULE_LICENSE("GPL v2"); | ||
| 145 | |||
| 146 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
| 147 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | ||
diff --git a/drivers/usb/serial/symbolserial.c b/drivers/usb/serial/symbolserial.c new file mode 100644 index 000000000000..8b3cbc87adc7 --- /dev/null +++ b/drivers/usb/serial/symbolserial.c | |||
| @@ -0,0 +1,399 @@ | |||
| 1 | /* | ||
| 2 | * Symbol USB barcode to serial driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2009 Greg Kroah-Hartman <gregkh@suse.de> | ||
| 5 | * Copyright (C) 2009 Novell Inc. | ||
| 6 | * | ||
| 7 | * This program is free software; you can redistribute it and/or | ||
| 8 | * modify it under the terms of the GNU General Public License version | ||
| 9 | * 2 as published by the Free Software Foundation. | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/kernel.h> | ||
| 13 | #include <linux/init.h> | ||
| 14 | #include <linux/tty.h> | ||
| 15 | #include <linux/tty_driver.h> | ||
| 16 | #include <linux/tty_flip.h> | ||
| 17 | #include <linux/module.h> | ||
| 18 | #include <linux/usb.h> | ||
| 19 | #include <linux/usb/serial.h> | ||
| 20 | #include <linux/uaccess.h> | ||
| 21 | |||
| 22 | static int debug; | ||
| 23 | |||
| 24 | static struct usb_device_id id_table[] = { | ||
| 25 | { USB_DEVICE(0x05e0, 0x0600) }, | ||
| 26 | { }, | ||
| 27 | }; | ||
| 28 | MODULE_DEVICE_TABLE(usb, id_table); | ||
| 29 | |||
| 30 | /* This structure holds all of the individual device information */ | ||
| 31 | struct symbol_private { | ||
| 32 | struct usb_device *udev; | ||
| 33 | struct usb_serial *serial; | ||
| 34 | struct usb_serial_port *port; | ||
| 35 | unsigned char *int_buffer; | ||
| 36 | struct urb *int_urb; | ||
| 37 | int buffer_size; | ||
| 38 | u8 bInterval; | ||
| 39 | u8 int_address; | ||
| 40 | spinlock_t lock; /* protects the following flags */ | ||
| 41 | bool throttled; | ||
| 42 | bool actually_throttled; | ||
| 43 | bool rts; | ||
| 44 | }; | ||
| 45 | |||
| 46 | static void symbol_int_callback(struct urb *urb) | ||
| 47 | { | ||
| 48 | struct symbol_private *priv = urb->context; | ||
| 49 | unsigned char *data = urb->transfer_buffer; | ||
| 50 | struct usb_serial_port *port = priv->port; | ||
| 51 | int status = urb->status; | ||
| 52 | struct tty_struct *tty; | ||
| 53 | int result; | ||
| 54 | int available_room = 0; | ||
| 55 | int data_length; | ||
| 56 | |||
| 57 | dbg("%s - port %d", __func__, port->number); | ||
| 58 | |||
| 59 | switch (status) { | ||
| 60 | case 0: | ||
| 61 | /* success */ | ||
| 62 | break; | ||
| 63 | case -ECONNRESET: | ||
| 64 | case -ENOENT: | ||
| 65 | case -ESHUTDOWN: | ||
| 66 | /* this urb is terminated, clean up */ | ||
| 67 | dbg("%s - urb shutting down with status: %d", | ||
| 68 | __func__, status); | ||
| 69 | return; | ||
| 70 | default: | ||
| 71 | dbg("%s - nonzero urb status received: %d", | ||
| 72 | __func__, status); | ||
| 73 | goto exit; | ||
| 74 | } | ||
| 75 | |||
| 76 | usb_serial_debug_data(debug, &port->dev, __func__, urb->actual_length, | ||
| 77 | data); | ||
| 78 | |||
| 79 | if (urb->actual_length > 1) { | ||
| 80 | data_length = urb->actual_length - 1; | ||
| 81 | |||
| 82 | /* | ||
| 83 | * Data from the device comes with a 1 byte header: | ||
| 84 | * | ||
| 85 | * <size of data>data... | ||
| 86 | * This is real data to be sent to the tty layer | ||
| 87 | * we pretty much just ignore the size and send everything | ||
| 88 | * else to the tty layer. | ||
| 89 | */ | ||
| 90 | tty = tty_port_tty_get(&port->port); | ||
| 91 | if (tty) { | ||
| 92 | available_room = tty_buffer_request_room(tty, | ||
| 93 | data_length); | ||
| 94 | if (available_room) { | ||
| 95 | tty_insert_flip_string(tty, &data[1], | ||
| 96 | available_room); | ||
| 97 | tty_flip_buffer_push(tty); | ||
| 98 | } | ||
| 99 | tty_kref_put(tty); | ||
| 100 | } | ||
| 101 | } else { | ||
| 102 | dev_dbg(&priv->udev->dev, | ||
| 103 | "Improper ammount of data received from the device, " | ||
| 104 | "%d bytes", urb->actual_length); | ||
| 105 | } | ||
| 106 | |||
| 107 | exit: | ||
| 108 | spin_lock(&priv->lock); | ||
| 109 | |||
| 110 | /* Continue trying to always read if we should */ | ||
| 111 | if (!priv->throttled) { | ||
| 112 | usb_fill_int_urb(priv->int_urb, priv->udev, | ||
| 113 | usb_rcvintpipe(priv->udev, | ||
| 114 | priv->int_address), | ||
| 115 | priv->int_buffer, priv->buffer_size, | ||
| 116 | symbol_int_callback, priv, priv->bInterval); | ||
| 117 | result = usb_submit_urb(priv->int_urb, GFP_ATOMIC); | ||
| 118 | if (result) | ||
| 119 | dev_err(&port->dev, | ||
| 120 | "%s - failed resubmitting read urb, error %d\n", | ||
| 121 | __func__, result); | ||
| 122 | } else | ||
| 123 | priv->actually_throttled = true; | ||
| 124 | spin_unlock(&priv->lock); | ||
| 125 | } | ||
| 126 | |||
| 127 | static int symbol_open(struct tty_struct *tty, struct usb_serial_port *port, | ||
| 128 | struct file *filp) | ||
| 129 | { | ||
| 130 | struct symbol_private *priv = usb_get_serial_data(port->serial); | ||
| 131 | unsigned long flags; | ||
| 132 | int result = 0; | ||
| 133 | |||
| 134 | dbg("%s - port %d", __func__, port->number); | ||
| 135 | |||
| 136 | spin_lock_irqsave(&priv->lock, flags); | ||
| 137 | priv->throttled = false; | ||
| 138 | priv->actually_throttled = false; | ||
| 139 | priv->port = port; | ||
| 140 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 141 | |||
| 142 | /* | ||
| 143 | * Force low_latency on so that our tty_push actually forces the data | ||
| 144 | * through, otherwise it is scheduled, and with high data rates (like | ||
| 145 | * with OHCI) data can get lost. | ||
| 146 | */ | ||
| 147 | if (tty) | ||
| 148 | tty->low_latency = 1; | ||
| 149 | |||
| 150 | /* Start reading from the device */ | ||
| 151 | usb_fill_int_urb(priv->int_urb, priv->udev, | ||
| 152 | usb_rcvintpipe(priv->udev, priv->int_address), | ||
| 153 | priv->int_buffer, priv->buffer_size, | ||
| 154 | symbol_int_callback, priv, priv->bInterval); | ||
| 155 | result = usb_submit_urb(priv->int_urb, GFP_KERNEL); | ||
| 156 | if (result) | ||
| 157 | dev_err(&port->dev, | ||
| 158 | "%s - failed resubmitting read urb, error %d\n", | ||
| 159 | __func__, result); | ||
| 160 | return result; | ||
| 161 | } | ||
| 162 | |||
| 163 | static void symbol_close(struct tty_struct *tty, struct usb_serial_port *port, | ||
| 164 | struct file *filp) | ||
| 165 | { | ||
| 166 | struct symbol_private *priv = usb_get_serial_data(port->serial); | ||
| 167 | |||
| 168 | dbg("%s - port %d", __func__, port->number); | ||
| 169 | |||
| 170 | /* shutdown our urbs */ | ||
| 171 | usb_kill_urb(priv->int_urb); | ||
| 172 | } | ||
| 173 | |||
| 174 | static void symbol_throttle(struct tty_struct *tty) | ||
| 175 | { | ||
| 176 | struct usb_serial_port *port = tty->driver_data; | ||
| 177 | struct symbol_private *priv = usb_get_serial_data(port->serial); | ||
| 178 | unsigned long flags; | ||
| 179 | |||
| 180 | dbg("%s - port %d", __func__, port->number); | ||
| 181 | spin_lock_irqsave(&priv->lock, flags); | ||
| 182 | priv->throttled = true; | ||
| 183 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 184 | } | ||
| 185 | |||
| 186 | static void symbol_unthrottle(struct tty_struct *tty) | ||
| 187 | { | ||
| 188 | struct usb_serial_port *port = tty->driver_data; | ||
| 189 | struct symbol_private *priv = usb_get_serial_data(port->serial); | ||
| 190 | unsigned long flags; | ||
| 191 | int result; | ||
| 192 | |||
| 193 | dbg("%s - port %d", __func__, port->number); | ||
| 194 | |||
| 195 | spin_lock_irqsave(&priv->lock, flags); | ||
| 196 | priv->throttled = false; | ||
| 197 | priv->actually_throttled = false; | ||
| 198 | spin_unlock_irqrestore(&priv->lock, flags); | ||
| 199 | |||
| 200 | priv->int_urb->dev = port->serial->dev; | ||
| 201 | result = usb_submit_urb(priv->int_urb, GFP_ATOMIC); | ||
| 202 | if (result) | ||
| 203 | dev_err(&port->dev, | ||
| 204 | "%s - failed submitting read urb, error %d\n", | ||
| 205 | __func__, result); | ||
| 206 | } | ||
| 207 | |||
| 208 | static int symbol_ioctl(struct tty_struct *tty, struct file *file, | ||
| 209 | unsigned int cmd, unsigned long arg) | ||
| 210 | { | ||
| 211 | struct usb_serial_port *port = tty->driver_data; | ||
| 212 | struct device *dev = &port->dev; | ||
| 213 | |||
| 214 | /* | ||
| 215 | * Right now we need to figure out what commands | ||
| 216 | * most userspace tools want to see for this driver, | ||
| 217 | * so just log the things. | ||
| 218 | */ | ||
| 219 | switch (cmd) { | ||
| 220 | case TIOCSERGETLSR: | ||
| 221 | dev_info(dev, "%s: TIOCSERGETLSR\n", __func__); | ||
| 222 | break; | ||
| 223 | |||
| 224 | case TIOCGSERIAL: | ||
| 225 | dev_info(dev, "%s: TIOCGSERIAL\n", __func__); | ||
| 226 | break; | ||
| 227 | |||
| 228 | case TIOCMIWAIT: | ||
| 229 | dev_info(dev, "%s: TIOCMIWAIT\n", __func__); | ||
| 230 | break; | ||
| 231 | |||
| 232 | case TIOCGICOUNT: | ||
| 233 | dev_info(dev, "%s: TIOCGICOUNT\n", __func__); | ||
| 234 | break; | ||
| 235 | default: | ||
| 236 | dev_info(dev, "%s: unknown (%d)\n", __func__, cmd); | ||
| 237 | } | ||
| 238 | return -ENOIOCTLCMD; | ||
| 239 | } | ||
| 240 | |||
| 241 | static int symbol_tiocmget(struct tty_struct *tty, struct file *file) | ||
| 242 | { | ||
| 243 | struct usb_serial_port *port = tty->driver_data; | ||
| 244 | struct device *dev = &port->dev; | ||
| 245 | |||
| 246 | /* TODO */ | ||
| 247 | /* probably just need to shadow whatever was sent to us here */ | ||
| 248 | dev_info(dev, "%s\n", __func__); | ||
| 249 | return 0; | ||
| 250 | } | ||
| 251 | |||
| 252 | static int symbol_tiocmset(struct tty_struct *tty, struct file *file, | ||
| 253 | unsigned int set, unsigned int clear) | ||
| 254 | { | ||
| 255 | struct usb_serial_port *port = tty->driver_data; | ||
| 256 | struct device *dev = &port->dev; | ||
| 257 | |||
| 258 | /* TODO */ | ||
| 259 | /* probably just need to shadow whatever was sent to us here */ | ||
| 260 | dev_info(dev, "%s\n", __func__); | ||
| 261 | return 0; | ||
| 262 | } | ||
| 263 | |||
| 264 | static int symbol_startup(struct usb_serial *serial) | ||
| 265 | { | ||
| 266 | struct symbol_private *priv; | ||
| 267 | struct usb_host_interface *intf; | ||
| 268 | int i; | ||
| 269 | int retval = -ENOMEM; | ||
| 270 | bool int_in_found = false; | ||
| 271 | |||
| 272 | /* create our private serial structure */ | ||
| 273 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
| 274 | if (priv == NULL) { | ||
| 275 | dev_err(&serial->dev->dev, "%s - Out of memory\n", __func__); | ||
| 276 | return -ENOMEM; | ||
| 277 | } | ||
| 278 | spin_lock_init(&priv->lock); | ||
| 279 | priv->serial = serial; | ||
| 280 | priv->port = serial->port[0]; | ||
| 281 | priv->udev = serial->dev; | ||
| 282 | |||
| 283 | /* find our interrupt endpoint */ | ||
| 284 | intf = serial->interface->altsetting; | ||
| 285 | for (i = 0; i < intf->desc.bNumEndpoints; ++i) { | ||
| 286 | struct usb_endpoint_descriptor *endpoint; | ||
| 287 | |||
| 288 | endpoint = &intf->endpoint[i].desc; | ||
| 289 | if (!usb_endpoint_is_int_in(endpoint)) | ||
| 290 | continue; | ||
| 291 | |||
| 292 | priv->int_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
| 293 | if (!priv->int_urb) { | ||
| 294 | dev_err(&priv->udev->dev, "out of memory\n"); | ||
| 295 | goto error; | ||
| 296 | } | ||
| 297 | |||
| 298 | priv->buffer_size = le16_to_cpu(endpoint->wMaxPacketSize) * 2; | ||
| 299 | priv->int_buffer = kmalloc(priv->buffer_size, GFP_KERNEL); | ||
| 300 | if (!priv->int_buffer) { | ||
| 301 | dev_err(&priv->udev->dev, "out of memory\n"); | ||
| 302 | goto error; | ||
| 303 | } | ||
| 304 | |||
| 305 | priv->int_address = endpoint->bEndpointAddress; | ||
| 306 | priv->bInterval = endpoint->bInterval; | ||
| 307 | |||
| 308 | /* set up our int urb */ | ||
| 309 | usb_fill_int_urb(priv->int_urb, priv->udev, | ||
| 310 | usb_rcvintpipe(priv->udev, | ||
| 311 | endpoint->bEndpointAddress), | ||
| 312 | priv->int_buffer, priv->buffer_size, | ||
| 313 | symbol_int_callback, priv, priv->bInterval); | ||
| 314 | |||
| 315 | int_in_found = true; | ||
| 316 | break; | ||
| 317 | } | ||
| 318 | |||
| 319 | if (!int_in_found) { | ||
| 320 | dev_err(&priv->udev->dev, | ||
| 321 | "Error - the proper endpoints were not found!\n"); | ||
| 322 | goto error; | ||
| 323 | } | ||
| 324 | |||
| 325 | usb_set_serial_data(serial, priv); | ||
| 326 | return 0; | ||
| 327 | |||
| 328 | error: | ||
| 329 | usb_free_urb(priv->int_urb); | ||
| 330 | kfree(priv->int_buffer); | ||
| 331 | kfree(priv); | ||
| 332 | return retval; | ||
| 333 | } | ||
| 334 | |||
| 335 | static void symbol_shutdown(struct usb_serial *serial) | ||
| 336 | { | ||
| 337 | struct symbol_private *priv = usb_get_serial_data(serial); | ||
| 338 | |||
| 339 | dbg("%s", __func__); | ||
| 340 | |||
| 341 | usb_kill_urb(priv->int_urb); | ||
| 342 | usb_free_urb(priv->int_urb); | ||
| 343 | kfree(priv->int_buffer); | ||
| 344 | kfree(priv); | ||
| 345 | usb_set_serial_data(serial, NULL); | ||
| 346 | } | ||
| 347 | |||
| 348 | static struct usb_driver symbol_driver = { | ||
| 349 | .name = "symbol", | ||
| 350 | .probe = usb_serial_probe, | ||
| 351 | .disconnect = usb_serial_disconnect, | ||
| 352 | .id_table = id_table, | ||
| 353 | .no_dynamic_id = 1, | ||
| 354 | }; | ||
| 355 | |||
| 356 | static struct usb_serial_driver symbol_device = { | ||
| 357 | .driver = { | ||
| 358 | .owner = THIS_MODULE, | ||
| 359 | .name = "symbol", | ||
| 360 | }, | ||
| 361 | .id_table = id_table, | ||
| 362 | .usb_driver = &symbol_driver, | ||
| 363 | .num_ports = 1, | ||
| 364 | .attach = symbol_startup, | ||
| 365 | .open = symbol_open, | ||
| 366 | .close = symbol_close, | ||
| 367 | .shutdown = symbol_shutdown, | ||
| 368 | .throttle = symbol_throttle, | ||
| 369 | .unthrottle = symbol_unthrottle, | ||
| 370 | .ioctl = symbol_ioctl, | ||
| 371 | .tiocmget = symbol_tiocmget, | ||
| 372 | .tiocmset = symbol_tiocmset, | ||
| 373 | }; | ||
| 374 | |||
| 375 | static int __init symbol_init(void) | ||
| 376 | { | ||
| 377 | int retval; | ||
| 378 | |||
| 379 | retval = usb_serial_register(&symbol_device); | ||
| 380 | if (retval) | ||
| 381 | return retval; | ||
| 382 | retval = usb_register(&symbol_driver); | ||
| 383 | if (retval) | ||
| 384 | usb_serial_deregister(&symbol_device); | ||
| 385 | return retval; | ||
| 386 | } | ||
| 387 | |||
| 388 | static void __exit symbol_exit(void) | ||
| 389 | { | ||
| 390 | usb_deregister(&symbol_driver); | ||
| 391 | usb_serial_deregister(&symbol_device); | ||
| 392 | } | ||
| 393 | |||
| 394 | module_init(symbol_init); | ||
| 395 | module_exit(symbol_exit); | ||
| 396 | MODULE_LICENSE("GPL"); | ||
| 397 | |||
| 398 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
| 399 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | ||
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index cfcfd5ab06ce..742a5bc44be8 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
| @@ -204,6 +204,11 @@ static int serial_open (struct tty_struct *tty, struct file *filp) | |||
| 204 | goto bailout_kref_put; | 204 | goto bailout_kref_put; |
| 205 | } | 205 | } |
| 206 | 206 | ||
| 207 | if (port->serial->disconnected) { | ||
| 208 | retval = -ENODEV; | ||
| 209 | goto bailout_kref_put; | ||
| 210 | } | ||
| 211 | |||
| 207 | if (mutex_lock_interruptible(&port->mutex)) { | 212 | if (mutex_lock_interruptible(&port->mutex)) { |
| 208 | retval = -ERESTARTSYS; | 213 | retval = -ERESTARTSYS; |
| 209 | goto bailout_kref_put; | 214 | goto bailout_kref_put; |
| @@ -1067,6 +1072,8 @@ int usb_serial_suspend(struct usb_interface *intf, pm_message_t message) | |||
| 1067 | struct usb_serial_port *port; | 1072 | struct usb_serial_port *port; |
| 1068 | int i, r = 0; | 1073 | int i, r = 0; |
| 1069 | 1074 | ||
| 1075 | serial->suspending = 1; | ||
| 1076 | |||
| 1070 | for (i = 0; i < serial->num_ports; ++i) { | 1077 | for (i = 0; i < serial->num_ports; ++i) { |
| 1071 | port = serial->port[i]; | 1078 | port = serial->port[i]; |
| 1072 | if (port) | 1079 | if (port) |
| @@ -1083,10 +1090,15 @@ EXPORT_SYMBOL(usb_serial_suspend); | |||
| 1083 | int usb_serial_resume(struct usb_interface *intf) | 1090 | int usb_serial_resume(struct usb_interface *intf) |
| 1084 | { | 1091 | { |
| 1085 | struct usb_serial *serial = usb_get_intfdata(intf); | 1092 | struct usb_serial *serial = usb_get_intfdata(intf); |
| 1093 | int rv; | ||
| 1086 | 1094 | ||
| 1095 | serial->suspending = 0; | ||
| 1087 | if (serial->type->resume) | 1096 | if (serial->type->resume) |
| 1088 | return serial->type->resume(serial); | 1097 | rv = serial->type->resume(serial); |
| 1089 | return 0; | 1098 | else |
| 1099 | rv = usb_serial_generic_resume(serial); | ||
| 1100 | |||
| 1101 | return rv; | ||
| 1090 | } | 1102 | } |
| 1091 | EXPORT_SYMBOL(usb_serial_resume); | 1103 | EXPORT_SYMBOL(usb_serial_resume); |
| 1092 | 1104 | ||
| @@ -1222,7 +1234,6 @@ static void fixup_generic(struct usb_serial_driver *device) | |||
| 1222 | set_to_generic_if_null(device, read_bulk_callback); | 1234 | set_to_generic_if_null(device, read_bulk_callback); |
| 1223 | set_to_generic_if_null(device, write_bulk_callback); | 1235 | set_to_generic_if_null(device, write_bulk_callback); |
| 1224 | set_to_generic_if_null(device, shutdown); | 1236 | set_to_generic_if_null(device, shutdown); |
| 1225 | set_to_generic_if_null(device, resume); | ||
| 1226 | } | 1237 | } |
| 1227 | 1238 | ||
| 1228 | int usb_serial_register(struct usb_serial_driver *driver) | 1239 | int usb_serial_register(struct usb_serial_driver *driver) |
| @@ -1230,6 +1241,9 @@ int usb_serial_register(struct usb_serial_driver *driver) | |||
| 1230 | /* must be called with BKL held */ | 1241 | /* must be called with BKL held */ |
| 1231 | int retval; | 1242 | int retval; |
| 1232 | 1243 | ||
| 1244 | if (usb_disabled()) | ||
| 1245 | return -ENODEV; | ||
| 1246 | |||
| 1233 | fixup_generic(driver); | 1247 | fixup_generic(driver); |
| 1234 | 1248 | ||
| 1235 | if (!driver->description) | 1249 | if (!driver->description) |
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index 9df6887b91f6..8a372bac0e43 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig | |||
| @@ -2,8 +2,8 @@ | |||
| 2 | # USB Storage driver configuration | 2 | # USB Storage driver configuration |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | comment "NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;" | 5 | comment "NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may" |
| 6 | comment "see USB_STORAGE Help for more information" | 6 | comment "also be needed; see USB_STORAGE Help for more info" |
| 7 | depends on USB | 7 | depends on USB |
| 8 | 8 | ||
| 9 | config USB_STORAGE | 9 | config USB_STORAGE |
| @@ -32,21 +32,25 @@ config USB_STORAGE_DEBUG | |||
| 32 | verbose debugging messages. | 32 | verbose debugging messages. |
| 33 | 33 | ||
| 34 | config USB_STORAGE_DATAFAB | 34 | config USB_STORAGE_DATAFAB |
| 35 | bool "Datafab Compact Flash Reader support" | 35 | tristate "Datafab Compact Flash Reader support" |
| 36 | depends on USB_STORAGE | 36 | depends on USB_STORAGE |
| 37 | help | 37 | help |
| 38 | Support for certain Datafab CompactFlash readers. | 38 | Support for certain Datafab CompactFlash readers. |
| 39 | Datafab has a web page at <http://www.datafabusa.com/>. | 39 | Datafab has a web page at <http://www.datafabusa.com/>. |
| 40 | 40 | ||
| 41 | If this driver is compiled as a module, it will be named ums-datafab. | ||
| 42 | |||
| 41 | config USB_STORAGE_FREECOM | 43 | config USB_STORAGE_FREECOM |
| 42 | bool "Freecom USB/ATAPI Bridge support" | 44 | tristate "Freecom USB/ATAPI Bridge support" |
| 43 | depends on USB_STORAGE | 45 | depends on USB_STORAGE |
| 44 | help | 46 | help |
| 45 | Support for the Freecom USB to IDE/ATAPI adaptor. | 47 | Support for the Freecom USB to IDE/ATAPI adaptor. |
| 46 | Freecom has a web page at <http://www.freecom.de/>. | 48 | Freecom has a web page at <http://www.freecom.de/>. |
| 47 | 49 | ||
| 50 | If this driver is compiled as a module, it will be named ums-freecom. | ||
| 51 | |||
| 48 | config USB_STORAGE_ISD200 | 52 | config USB_STORAGE_ISD200 |
| 49 | bool "ISD-200 USB/ATA Bridge support" | 53 | tristate "ISD-200 USB/ATA Bridge support" |
| 50 | depends on USB_STORAGE | 54 | depends on USB_STORAGE |
| 51 | ---help--- | 55 | ---help--- |
| 52 | Say Y here if you want to use USB Mass Store devices based | 56 | Say Y here if you want to use USB Mass Store devices based |
| @@ -61,8 +65,10 @@ config USB_STORAGE_ISD200 | |||
| 61 | - CyQ've CQ8060A CDRW drive | 65 | - CyQ've CQ8060A CDRW drive |
| 62 | - Planex eXtreme Drive RX-25HU USB-IDE cable (not model RX-25U) | 66 | - Planex eXtreme Drive RX-25HU USB-IDE cable (not model RX-25U) |
| 63 | 67 | ||
| 68 | If this driver is compiled as a module, it will be named ums-isd200. | ||
| 69 | |||
| 64 | config USB_STORAGE_USBAT | 70 | config USB_STORAGE_USBAT |
| 65 | bool "USBAT/USBAT02-based storage support" | 71 | tristate "USBAT/USBAT02-based storage support" |
| 66 | depends on USB_STORAGE | 72 | depends on USB_STORAGE |
| 67 | help | 73 | help |
| 68 | Say Y here to include additional code to support storage devices | 74 | Say Y here to include additional code to support storage devices |
| @@ -82,30 +88,38 @@ config USB_STORAGE_USBAT | |||
| 82 | - RCA LYRA MP3 portable | 88 | - RCA LYRA MP3 portable |
| 83 | - Sandisk ImageMate SDDR-05b | 89 | - Sandisk ImageMate SDDR-05b |
| 84 | 90 | ||
| 91 | If this driver is compiled as a module, it will be named ums-usbat. | ||
| 92 | |||
| 85 | config USB_STORAGE_SDDR09 | 93 | config USB_STORAGE_SDDR09 |
| 86 | bool "SanDisk SDDR-09 (and other SmartMedia, including DPCM) support" | 94 | tristate "SanDisk SDDR-09 (and other SmartMedia, including DPCM) support" |
| 87 | depends on USB_STORAGE | 95 | depends on USB_STORAGE |
| 88 | help | 96 | help |
| 89 | Say Y here to include additional code to support the Sandisk SDDR-09 | 97 | Say Y here to include additional code to support the Sandisk SDDR-09 |
| 90 | SmartMedia reader in the USB Mass Storage driver. | 98 | SmartMedia reader in the USB Mass Storage driver. |
| 91 | Also works for the Microtech Zio! CompactFlash/SmartMedia reader. | 99 | Also works for the Microtech Zio! CompactFlash/SmartMedia reader. |
| 92 | 100 | ||
| 101 | If this driver is compiled as a module, it will be named ums-sddr09. | ||
| 102 | |||
| 93 | config USB_STORAGE_SDDR55 | 103 | config USB_STORAGE_SDDR55 |
| 94 | bool "SanDisk SDDR-55 SmartMedia support" | 104 | tristate "SanDisk SDDR-55 SmartMedia support" |
| 95 | depends on USB_STORAGE | 105 | depends on USB_STORAGE |
| 96 | help | 106 | help |
| 97 | Say Y here to include additional code to support the Sandisk SDDR-55 | 107 | Say Y here to include additional code to support the Sandisk SDDR-55 |
| 98 | SmartMedia reader in the USB Mass Storage driver. | 108 | SmartMedia reader in the USB Mass Storage driver. |
| 99 | 109 | ||
| 110 | If this driver is compiled as a module, it will be named ums-sddr55. | ||
| 111 | |||
| 100 | config USB_STORAGE_JUMPSHOT | 112 | config USB_STORAGE_JUMPSHOT |
| 101 | bool "Lexar Jumpshot Compact Flash Reader" | 113 | tristate "Lexar Jumpshot Compact Flash Reader" |
| 102 | depends on USB_STORAGE | 114 | depends on USB_STORAGE |
| 103 | help | 115 | help |
| 104 | Say Y here to include additional code to support the Lexar Jumpshot | 116 | Say Y here to include additional code to support the Lexar Jumpshot |
| 105 | USB CompactFlash reader. | 117 | USB CompactFlash reader. |
| 106 | 118 | ||
| 119 | If this driver is compiled as a module, it will be named ums-jumpshot. | ||
| 120 | |||
| 107 | config USB_STORAGE_ALAUDA | 121 | config USB_STORAGE_ALAUDA |
| 108 | bool "Olympus MAUSB-10/Fuji DPC-R1 support" | 122 | tristate "Olympus MAUSB-10/Fuji DPC-R1 support" |
| 109 | depends on USB_STORAGE | 123 | depends on USB_STORAGE |
| 110 | help | 124 | help |
| 111 | Say Y here to include additional code to support the Olympus MAUSB-10 | 125 | Say Y here to include additional code to support the Olympus MAUSB-10 |
| @@ -114,8 +128,10 @@ config USB_STORAGE_ALAUDA | |||
| 114 | These devices are based on the Alauda chip and support both | 128 | These devices are based on the Alauda chip and support both |
| 115 | XD and SmartMedia cards. | 129 | XD and SmartMedia cards. |
| 116 | 130 | ||
| 131 | If this driver is compiled as a module, it will be named ums-alauda. | ||
| 132 | |||
| 117 | config USB_STORAGE_ONETOUCH | 133 | config USB_STORAGE_ONETOUCH |
| 118 | bool "Support OneTouch Button on Maxtor Hard Drives" | 134 | tristate "Support OneTouch Button on Maxtor Hard Drives" |
| 119 | depends on USB_STORAGE | 135 | depends on USB_STORAGE |
| 120 | depends on INPUT=y || INPUT=USB_STORAGE | 136 | depends on INPUT=y || INPUT=USB_STORAGE |
| 121 | help | 137 | help |
| @@ -127,8 +143,10 @@ config USB_STORAGE_ONETOUCH | |||
| 127 | this input in any keybinding software. (e.g. gnome's keyboard short- | 143 | this input in any keybinding software. (e.g. gnome's keyboard short- |
| 128 | cuts) | 144 | cuts) |
| 129 | 145 | ||
| 146 | If this driver is compiled as a module, it will be named ums-onetouch. | ||
| 147 | |||
| 130 | config USB_STORAGE_KARMA | 148 | config USB_STORAGE_KARMA |
| 131 | bool "Support for Rio Karma music player" | 149 | tristate "Support for Rio Karma music player" |
| 132 | depends on USB_STORAGE | 150 | depends on USB_STORAGE |
| 133 | help | 151 | help |
| 134 | Say Y here to include additional code to support the Rio Karma | 152 | Say Y here to include additional code to support the Rio Karma |
| @@ -139,8 +157,10 @@ config USB_STORAGE_KARMA | |||
| 139 | on the resulting scsi device node returns the Karma to normal | 157 | on the resulting scsi device node returns the Karma to normal |
| 140 | operation. | 158 | operation. |
| 141 | 159 | ||
| 160 | If this driver is compiled as a module, it will be named ums-karma. | ||
| 161 | |||
| 142 | config USB_STORAGE_CYPRESS_ATACB | 162 | config USB_STORAGE_CYPRESS_ATACB |
| 143 | bool "SAT emulation on Cypress USB/ATA Bridge with ATACB" | 163 | tristate "SAT emulation on Cypress USB/ATA Bridge with ATACB" |
| 144 | depends on USB_STORAGE | 164 | depends on USB_STORAGE |
| 145 | ---help--- | 165 | ---help--- |
| 146 | Say Y here if you want to use SAT (ata pass through) on devices based | 166 | Say Y here if you want to use SAT (ata pass through) on devices based |
| @@ -150,6 +170,8 @@ config USB_STORAGE_CYPRESS_ATACB | |||
| 150 | If you say no here your device will still work with the standard usb | 170 | If you say no here your device will still work with the standard usb |
| 151 | mass storage class. | 171 | mass storage class. |
| 152 | 172 | ||
| 173 | If this driver is compiled as a module, it will be named ums-cypress. | ||
| 174 | |||
| 153 | config USB_LIBUSUAL | 175 | config USB_LIBUSUAL |
| 154 | bool "The shared table of common (or usual) storage devices" | 176 | bool "The shared table of common (or usual) storage devices" |
| 155 | depends on USB | 177 | depends on USB |
diff --git a/drivers/usb/storage/Makefile b/drivers/usb/storage/Makefile index b32069313390..5be54c019662 100644 --- a/drivers/usb/storage/Makefile +++ b/drivers/usb/storage/Makefile | |||
| @@ -10,21 +10,36 @@ EXTRA_CFLAGS := -Idrivers/scsi | |||
| 10 | obj-$(CONFIG_USB_STORAGE) += usb-storage.o | 10 | obj-$(CONFIG_USB_STORAGE) += usb-storage.o |
| 11 | 11 | ||
| 12 | usb-storage-obj-$(CONFIG_USB_STORAGE_DEBUG) += debug.o | 12 | usb-storage-obj-$(CONFIG_USB_STORAGE_DEBUG) += debug.o |
| 13 | usb-storage-obj-$(CONFIG_USB_STORAGE_USBAT) += shuttle_usbat.o | ||
| 14 | usb-storage-obj-$(CONFIG_USB_STORAGE_SDDR09) += sddr09.o | ||
| 15 | usb-storage-obj-$(CONFIG_USB_STORAGE_SDDR55) += sddr55.o | ||
| 16 | usb-storage-obj-$(CONFIG_USB_STORAGE_FREECOM) += freecom.o | ||
| 17 | usb-storage-obj-$(CONFIG_USB_STORAGE_ISD200) += isd200.o | ||
| 18 | usb-storage-obj-$(CONFIG_USB_STORAGE_DATAFAB) += datafab.o | ||
| 19 | usb-storage-obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += jumpshot.o | ||
| 20 | usb-storage-obj-$(CONFIG_USB_STORAGE_ALAUDA) += alauda.o | ||
| 21 | usb-storage-obj-$(CONFIG_USB_STORAGE_ONETOUCH) += onetouch.o | ||
| 22 | usb-storage-obj-$(CONFIG_USB_STORAGE_KARMA) += karma.o | ||
| 23 | usb-storage-obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += cypress_atacb.o | ||
| 24 | 13 | ||
| 25 | usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ | 14 | usb-storage-objs := scsiglue.o protocol.o transport.o usb.o \ |
| 26 | initializers.o sierra_ms.o option_ms.o $(usb-storage-obj-y) | 15 | initializers.o sierra_ms.o option_ms.o $(usb-storage-obj-y) |
| 27 | 16 | ||
| 28 | ifneq ($(CONFIG_USB_LIBUSUAL),) | 17 | ifeq ($(CONFIG_USB_LIBUSUAL),) |
| 29 | obj-$(CONFIG_USB) += libusual.o | 18 | usb-storage-objs += usual-tables.o |
| 19 | else | ||
| 20 | obj-$(CONFIG_USB) += libusual.o usual-tables.o | ||
| 30 | endif | 21 | endif |
| 22 | |||
| 23 | obj-$(CONFIG_USB_STORAGE_ALAUDA) += ums-alauda.o | ||
| 24 | obj-$(CONFIG_USB_STORAGE_CYPRESS_ATACB) += ums-cypress.o | ||
| 25 | obj-$(CONFIG_USB_STORAGE_DATAFAB) += ums-datafab.o | ||
| 26 | obj-$(CONFIG_USB_STORAGE_FREECOM) += ums-freecom.o | ||
| 27 | obj-$(CONFIG_USB_STORAGE_ISD200) += ums-isd200.o | ||
| 28 | obj-$(CONFIG_USB_STORAGE_JUMPSHOT) += ums-jumpshot.o | ||
| 29 | obj-$(CONFIG_USB_STORAGE_KARMA) += ums-karma.o | ||
| 30 | obj-$(CONFIG_USB_STORAGE_ONETOUCH) += ums-onetouch.o | ||
| 31 | obj-$(CONFIG_USB_STORAGE_SDDR09) += ums-sddr09.o | ||
| 32 | obj-$(CONFIG_USB_STORAGE_SDDR55) += ums-sddr55.o | ||
| 33 | obj-$(CONFIG_USB_STORAGE_USBAT) += ums-usbat.o | ||
| 34 | |||
| 35 | ums-alauda-objs := alauda.o | ||
| 36 | ums-cypress-objs := cypress_atacb.o | ||
| 37 | ums-datafab-objs := datafab.o | ||
| 38 | ums-freecom-objs := freecom.o | ||
| 39 | ums-isd200-objs := isd200.o | ||
| 40 | ums-jumpshot-objs := jumpshot.o | ||
| 41 | ums-karma-objs := karma.o | ||
| 42 | ums-onetouch-objs := onetouch.o | ||
| 43 | ums-sddr09-objs := sddr09.o | ||
| 44 | ums-sddr55-objs := sddr55.o | ||
| 45 | ums-usbat-objs := shuttle_usbat.o | ||
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c index 8d3711a7ff06..67edc65acb8e 100644 --- a/drivers/usb/storage/alauda.c +++ b/drivers/usb/storage/alauda.c | |||
| @@ -31,6 +31,8 @@ | |||
| 31 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 31 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
| 32 | */ | 32 | */ |
| 33 | 33 | ||
| 34 | #include <linux/module.h> | ||
| 35 | |||
| 34 | #include <scsi/scsi.h> | 36 | #include <scsi/scsi.h> |
| 35 | #include <scsi/scsi_cmnd.h> | 37 | #include <scsi/scsi_cmnd.h> |
| 36 | #include <scsi/scsi_device.h> | 38 | #include <scsi/scsi_device.h> |
| @@ -39,7 +41,79 @@ | |||
| 39 | #include "transport.h" | 41 | #include "transport.h" |
| 40 | #include "protocol.h" | 42 | #include "protocol.h" |
| 41 | #include "debug.h" | 43 | #include "debug.h" |
| 42 | #include "alauda.h" | 44 | |
| 45 | MODULE_DESCRIPTION("Driver for Alauda-based card readers"); | ||
| 46 | MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>"); | ||
| 47 | MODULE_LICENSE("GPL"); | ||
| 48 | |||
| 49 | /* | ||
| 50 | * Status bytes | ||
| 51 | */ | ||
| 52 | #define ALAUDA_STATUS_ERROR 0x01 | ||
| 53 | #define ALAUDA_STATUS_READY 0x40 | ||
| 54 | |||
| 55 | /* | ||
| 56 | * Control opcodes (for request field) | ||
| 57 | */ | ||
| 58 | #define ALAUDA_GET_XD_MEDIA_STATUS 0x08 | ||
| 59 | #define ALAUDA_GET_SM_MEDIA_STATUS 0x98 | ||
| 60 | #define ALAUDA_ACK_XD_MEDIA_CHANGE 0x0a | ||
| 61 | #define ALAUDA_ACK_SM_MEDIA_CHANGE 0x9a | ||
| 62 | #define ALAUDA_GET_XD_MEDIA_SIG 0x86 | ||
| 63 | #define ALAUDA_GET_SM_MEDIA_SIG 0x96 | ||
| 64 | |||
| 65 | /* | ||
| 66 | * Bulk command identity (byte 0) | ||
| 67 | */ | ||
| 68 | #define ALAUDA_BULK_CMD 0x40 | ||
| 69 | |||
| 70 | /* | ||
| 71 | * Bulk opcodes (byte 1) | ||
| 72 | */ | ||
| 73 | #define ALAUDA_BULK_GET_REDU_DATA 0x85 | ||
| 74 | #define ALAUDA_BULK_READ_BLOCK 0x94 | ||
| 75 | #define ALAUDA_BULK_ERASE_BLOCK 0xa3 | ||
| 76 | #define ALAUDA_BULK_WRITE_BLOCK 0xb4 | ||
| 77 | #define ALAUDA_BULK_GET_STATUS2 0xb7 | ||
| 78 | #define ALAUDA_BULK_RESET_MEDIA 0xe0 | ||
| 79 | |||
| 80 | /* | ||
| 81 | * Port to operate on (byte 8) | ||
| 82 | */ | ||
| 83 | #define ALAUDA_PORT_XD 0x00 | ||
| 84 | #define ALAUDA_PORT_SM 0x01 | ||
| 85 | |||
| 86 | /* | ||
| 87 | * LBA and PBA are unsigned ints. Special values. | ||
| 88 | */ | ||
| 89 | #define UNDEF 0xffff | ||
| 90 | #define SPARE 0xfffe | ||
| 91 | #define UNUSABLE 0xfffd | ||
| 92 | |||
| 93 | struct alauda_media_info { | ||
| 94 | unsigned long capacity; /* total media size in bytes */ | ||
| 95 | unsigned int pagesize; /* page size in bytes */ | ||
| 96 | unsigned int blocksize; /* number of pages per block */ | ||
| 97 | unsigned int uzonesize; /* number of usable blocks per zone */ | ||
| 98 | unsigned int zonesize; /* number of blocks per zone */ | ||
| 99 | unsigned int blockmask; /* mask to get page from address */ | ||
| 100 | |||
| 101 | unsigned char pageshift; | ||
| 102 | unsigned char blockshift; | ||
| 103 | unsigned char zoneshift; | ||
| 104 | |||
| 105 | u16 **lba_to_pba; /* logical to physical block map */ | ||
| 106 | u16 **pba_to_lba; /* physical to logical block map */ | ||
| 107 | }; | ||
| 108 | |||
| 109 | struct alauda_info { | ||
| 110 | struct alauda_media_info port[2]; | ||
| 111 | int wr_ep; /* endpoint to write data out of */ | ||
| 112 | |||
| 113 | unsigned char sense_key; | ||
| 114 | unsigned long sense_asc; /* additional sense code */ | ||
| 115 | unsigned long sense_ascq; /* additional sense code qualifier */ | ||
| 116 | }; | ||
| 43 | 117 | ||
| 44 | #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) | 118 | #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) |
| 45 | #define LSB_of(s) ((s)&0xFF) | 119 | #define LSB_of(s) ((s)&0xFF) |
| @@ -52,6 +126,48 @@ | |||
| 52 | #define PBA_HI(pba) (pba >> 3) | 126 | #define PBA_HI(pba) (pba >> 3) |
| 53 | #define PBA_ZONE(pba) (pba >> 11) | 127 | #define PBA_ZONE(pba) (pba >> 11) |
| 54 | 128 | ||
| 129 | static int init_alauda(struct us_data *us); | ||
| 130 | |||
| 131 | |||
| 132 | /* | ||
| 133 | * The table of devices | ||
| 134 | */ | ||
| 135 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
| 136 | vendorName, productName, useProtocol, useTransport, \ | ||
| 137 | initFunction, flags) \ | ||
| 138 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
| 139 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
| 140 | |||
| 141 | struct usb_device_id alauda_usb_ids[] = { | ||
| 142 | # include "unusual_alauda.h" | ||
| 143 | { } /* Terminating entry */ | ||
| 144 | }; | ||
| 145 | MODULE_DEVICE_TABLE(usb, alauda_usb_ids); | ||
| 146 | |||
| 147 | #undef UNUSUAL_DEV | ||
| 148 | |||
| 149 | /* | ||
| 150 | * The flags table | ||
| 151 | */ | ||
| 152 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
| 153 | vendor_name, product_name, use_protocol, use_transport, \ | ||
| 154 | init_function, Flags) \ | ||
| 155 | { \ | ||
| 156 | .vendorName = vendor_name, \ | ||
| 157 | .productName = product_name, \ | ||
| 158 | .useProtocol = use_protocol, \ | ||
| 159 | .useTransport = use_transport, \ | ||
| 160 | .initFunction = init_function, \ | ||
| 161 | } | ||
| 162 | |||
| 163 | static struct us_unusual_dev alauda_unusual_dev_list[] = { | ||
| 164 | # include "unusual_alauda.h" | ||
| 165 | { } /* Terminating entry */ | ||
| 166 | }; | ||
| 167 | |||
| 168 | #undef UNUSUAL_DEV | ||
| 169 | |||
| 170 | |||
| 55 | /* | 171 | /* |
| 56 | * Media handling | 172 | * Media handling |
| 57 | */ | 173 | */ |
| @@ -307,7 +423,8 @@ static int alauda_init_media(struct us_data *us) | |||
| 307 | data[0], data[1], data[2], data[3]); | 423 | data[0], data[1], data[2], data[3]); |
| 308 | media_info = alauda_card_find_id(data[1]); | 424 | media_info = alauda_card_find_id(data[1]); |
| 309 | if (media_info == NULL) { | 425 | if (media_info == NULL) { |
| 310 | printk("alauda_init_media: Unrecognised media signature: " | 426 | printk(KERN_WARNING |
| 427 | "alauda_init_media: Unrecognised media signature: " | ||
| 311 | "%02X %02X %02X %02X\n", | 428 | "%02X %02X %02X %02X\n", |
| 312 | data[0], data[1], data[2], data[3]); | 429 | data[0], data[1], data[2], data[3]); |
| 313 | return USB_STOR_TRANSPORT_ERROR; | 430 | return USB_STOR_TRANSPORT_ERROR; |
| @@ -518,7 +635,8 @@ static int alauda_read_map(struct us_data *us, unsigned int zone) | |||
| 518 | 635 | ||
| 519 | /* check even parity */ | 636 | /* check even parity */ |
| 520 | if (parity[data[6] ^ data[7]]) { | 637 | if (parity[data[6] ^ data[7]]) { |
| 521 | printk("alauda_read_map: Bad parity in LBA for block %d" | 638 | printk(KERN_WARNING |
| 639 | "alauda_read_map: Bad parity in LBA for block %d" | ||
| 522 | " (%02X %02X)\n", i, data[6], data[7]); | 640 | " (%02X %02X)\n", i, data[6], data[7]); |
| 523 | pba_to_lba[i] = UNUSABLE; | 641 | pba_to_lba[i] = UNUSABLE; |
| 524 | continue; | 642 | continue; |
| @@ -538,13 +656,16 @@ static int alauda_read_map(struct us_data *us, unsigned int zone) | |||
| 538 | */ | 656 | */ |
| 539 | 657 | ||
| 540 | if (lba_offset >= uzonesize) { | 658 | if (lba_offset >= uzonesize) { |
| 541 | printk("alauda_read_map: Bad low LBA %d for block %d\n", | 659 | printk(KERN_WARNING |
| 660 | "alauda_read_map: Bad low LBA %d for block %d\n", | ||
| 542 | lba_real, blocknum); | 661 | lba_real, blocknum); |
| 543 | continue; | 662 | continue; |
| 544 | } | 663 | } |
| 545 | 664 | ||
| 546 | if (lba_to_pba[lba_offset] != UNDEF) { | 665 | if (lba_to_pba[lba_offset] != UNDEF) { |
| 547 | printk("alauda_read_map: LBA %d seen for PBA %d and %d\n", | 666 | printk(KERN_WARNING |
| 667 | "alauda_read_map: " | ||
| 668 | "LBA %d seen for PBA %d and %d\n", | ||
| 548 | lba_real, lba_to_pba[lba_offset], blocknum); | 669 | lba_real, lba_to_pba[lba_offset], blocknum); |
| 549 | continue; | 670 | continue; |
| 550 | } | 671 | } |
| @@ -712,13 +833,15 @@ static int alauda_write_lba(struct us_data *us, u16 lba, | |||
| 712 | if (pba == 1) { | 833 | if (pba == 1) { |
| 713 | /* Maybe it is impossible to write to PBA 1. | 834 | /* Maybe it is impossible to write to PBA 1. |
| 714 | Fake success, but don't do anything. */ | 835 | Fake success, but don't do anything. */ |
| 715 | printk("alauda_write_lba: avoid writing to pba 1\n"); | 836 | printk(KERN_WARNING |
| 837 | "alauda_write_lba: avoid writing to pba 1\n"); | ||
| 716 | return USB_STOR_TRANSPORT_GOOD; | 838 | return USB_STOR_TRANSPORT_GOOD; |
| 717 | } | 839 | } |
| 718 | 840 | ||
| 719 | new_pba = alauda_find_unused_pba(&MEDIA_INFO(us), zone); | 841 | new_pba = alauda_find_unused_pba(&MEDIA_INFO(us), zone); |
| 720 | if (!new_pba) { | 842 | if (!new_pba) { |
| 721 | printk("alauda_write_lba: Out of unused blocks\n"); | 843 | printk(KERN_WARNING |
| 844 | "alauda_write_lba: Out of unused blocks\n"); | ||
| 722 | return USB_STOR_TRANSPORT_ERROR; | 845 | return USB_STOR_TRANSPORT_ERROR; |
| 723 | } | 846 | } |
| 724 | 847 | ||
| @@ -818,7 +941,7 @@ static int alauda_read_data(struct us_data *us, unsigned long address, | |||
| 818 | len = min(sectors, blocksize) * (pagesize + 64); | 941 | len = min(sectors, blocksize) * (pagesize + 64); |
| 819 | buffer = kmalloc(len, GFP_NOIO); | 942 | buffer = kmalloc(len, GFP_NOIO); |
| 820 | if (buffer == NULL) { | 943 | if (buffer == NULL) { |
| 821 | printk("alauda_read_data: Out of memory\n"); | 944 | printk(KERN_WARNING "alauda_read_data: Out of memory\n"); |
| 822 | return USB_STOR_TRANSPORT_ERROR; | 945 | return USB_STOR_TRANSPORT_ERROR; |
| 823 | } | 946 | } |
| 824 | 947 | ||
| @@ -911,7 +1034,7 @@ static int alauda_write_data(struct us_data *us, unsigned long address, | |||
| 911 | len = min(sectors, blocksize) * pagesize; | 1034 | len = min(sectors, blocksize) * pagesize; |
| 912 | buffer = kmalloc(len, GFP_NOIO); | 1035 | buffer = kmalloc(len, GFP_NOIO); |
| 913 | if (buffer == NULL) { | 1036 | if (buffer == NULL) { |
| 914 | printk("alauda_write_data: Out of memory\n"); | 1037 | printk(KERN_WARNING "alauda_write_data: Out of memory\n"); |
| 915 | return USB_STOR_TRANSPORT_ERROR; | 1038 | return USB_STOR_TRANSPORT_ERROR; |
| 916 | } | 1039 | } |
| 917 | 1040 | ||
| @@ -921,7 +1044,7 @@ static int alauda_write_data(struct us_data *us, unsigned long address, | |||
| 921 | */ | 1044 | */ |
| 922 | blockbuffer = kmalloc((pagesize + 64) * blocksize, GFP_NOIO); | 1045 | blockbuffer = kmalloc((pagesize + 64) * blocksize, GFP_NOIO); |
| 923 | if (blockbuffer == NULL) { | 1046 | if (blockbuffer == NULL) { |
| 924 | printk("alauda_write_data: Out of memory\n"); | 1047 | printk(KERN_WARNING "alauda_write_data: Out of memory\n"); |
| 925 | kfree(buffer); | 1048 | kfree(buffer); |
| 926 | return USB_STOR_TRANSPORT_ERROR; | 1049 | return USB_STOR_TRANSPORT_ERROR; |
| 927 | } | 1050 | } |
| @@ -991,7 +1114,7 @@ static void alauda_info_destructor(void *extra) | |||
| 991 | /* | 1114 | /* |
| 992 | * Initialize alauda_info struct and find the data-write endpoint | 1115 | * Initialize alauda_info struct and find the data-write endpoint |
| 993 | */ | 1116 | */ |
| 994 | int init_alauda(struct us_data *us) | 1117 | static int init_alauda(struct us_data *us) |
| 995 | { | 1118 | { |
| 996 | struct alauda_info *info; | 1119 | struct alauda_info *info; |
| 997 | struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting; | 1120 | struct usb_host_interface *altsetting = us->pusb_intf->cur_altsetting; |
| @@ -1013,7 +1136,7 @@ int init_alauda(struct us_data *us) | |||
| 1013 | return USB_STOR_TRANSPORT_GOOD; | 1136 | return USB_STOR_TRANSPORT_GOOD; |
| 1014 | } | 1137 | } |
| 1015 | 1138 | ||
| 1016 | int alauda_transport(struct scsi_cmnd *srb, struct us_data *us) | 1139 | static int alauda_transport(struct scsi_cmnd *srb, struct us_data *us) |
| 1017 | { | 1140 | { |
| 1018 | int rc; | 1141 | int rc; |
| 1019 | struct alauda_info *info = (struct alauda_info *) us->extra; | 1142 | struct alauda_info *info = (struct alauda_info *) us->extra; |
| @@ -1121,3 +1244,48 @@ int alauda_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
| 1121 | return USB_STOR_TRANSPORT_FAILED; | 1244 | return USB_STOR_TRANSPORT_FAILED; |
| 1122 | } | 1245 | } |
| 1123 | 1246 | ||
| 1247 | static int alauda_probe(struct usb_interface *intf, | ||
| 1248 | const struct usb_device_id *id) | ||
| 1249 | { | ||
| 1250 | struct us_data *us; | ||
| 1251 | int result; | ||
| 1252 | |||
| 1253 | result = usb_stor_probe1(&us, intf, id, | ||
| 1254 | (id - alauda_usb_ids) + alauda_unusual_dev_list); | ||
| 1255 | if (result) | ||
| 1256 | return result; | ||
| 1257 | |||
| 1258 | us->transport_name = "Alauda Control/Bulk"; | ||
| 1259 | us->transport = alauda_transport; | ||
| 1260 | us->transport_reset = usb_stor_Bulk_reset; | ||
| 1261 | us->max_lun = 1; | ||
| 1262 | |||
| 1263 | result = usb_stor_probe2(us); | ||
| 1264 | return result; | ||
| 1265 | } | ||
| 1266 | |||
| 1267 | static struct usb_driver alauda_driver = { | ||
| 1268 | .name = "ums-alauda", | ||
| 1269 | .probe = alauda_probe, | ||
| 1270 | .disconnect = usb_stor_disconnect, | ||
| 1271 | .suspend = usb_stor_suspend, | ||
| 1272 | .resume = usb_stor_resume, | ||
| 1273 | .reset_resume = usb_stor_reset_resume, | ||
| 1274 | .pre_reset = usb_stor_pre_reset, | ||
| 1275 | .post_reset = usb_stor_post_reset, | ||
| 1276 | .id_table = alauda_usb_ids, | ||
| 1277 | .soft_unbind = 1, | ||
| 1278 | }; | ||
| 1279 | |||
| 1280 | static int __init alauda_init(void) | ||
| 1281 | { | ||
| 1282 | return usb_register(&alauda_driver); | ||
| 1283 | } | ||
| 1284 | |||
| 1285 | static void __exit alauda_exit(void) | ||
| 1286 | { | ||
| 1287 | usb_deregister(&alauda_driver); | ||
| 1288 | } | ||
| 1289 | |||
| 1290 | module_init(alauda_init); | ||
| 1291 | module_exit(alauda_exit); | ||
diff --git a/drivers/usb/storage/alauda.h b/drivers/usb/storage/alauda.h deleted file mode 100644 index a700f87d0803..000000000000 --- a/drivers/usb/storage/alauda.h +++ /dev/null | |||
| @@ -1,100 +0,0 @@ | |||
| 1 | /* | ||
| 2 | * Driver for Alauda-based card readers | ||
| 3 | * | ||
| 4 | * Current development and maintenance by: | ||
| 5 | * (c) 2005 Daniel Drake <dsd@gentoo.org> | ||
| 6 | * | ||
| 7 | * See alauda.c for more explanation. | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify it | ||
| 10 | * under the terms of the GNU General Public License as published by the | ||
| 11 | * Free Software Foundation; either version 2, or (at your option) any | ||
| 12 | * later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, but | ||
| 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 17 | * General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License along | ||
| 20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 21 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #ifndef _USB_ALAUDA_H | ||
| 25 | #define _USB_ALAUDA_H | ||
| 26 | |||
| 27 | /* | ||
| 28 | * Status bytes | ||
| 29 | */ | ||
| 30 | #define ALAUDA_STATUS_ERROR 0x01 | ||
| 31 | #define ALAUDA_STATUS_READY 0x40 | ||
| 32 | |||
| 33 | /* | ||
| 34 | * Control opcodes (for request field) | ||
| 35 | */ | ||
| 36 | #define ALAUDA_GET_XD_MEDIA_STATUS 0x08 | ||
| 37 | #define ALAUDA_GET_SM_MEDIA_STATUS 0x98 | ||
| 38 | #define ALAUDA_ACK_XD_MEDIA_CHANGE 0x0a | ||
| 39 | #define ALAUDA_ACK_SM_MEDIA_CHANGE 0x9a | ||
| 40 | #define ALAUDA_GET_XD_MEDIA_SIG 0x86 | ||
| 41 | #define ALAUDA_GET_SM_MEDIA_SIG 0x96 | ||
| 42 | |||
| 43 | /* | ||
| 44 | * Bulk command identity (byte 0) | ||
| 45 | */ | ||
| 46 | #define ALAUDA_BULK_CMD 0x40 | ||
| 47 | |||
| 48 | /* | ||
| 49 | * Bulk opcodes (byte 1) | ||
| 50 | */ | ||
| 51 | #define ALAUDA_BULK_GET_REDU_DATA 0x85 | ||
| 52 | #define ALAUDA_BULK_READ_BLOCK 0x94 | ||
| 53 | #define ALAUDA_BULK_ERASE_BLOCK 0xa3 | ||
| 54 | #define ALAUDA_BULK_WRITE_BLOCK 0xb4 | ||
| 55 | #define ALAUDA_BULK_GET_STATUS2 0xb7 | ||
| 56 | #define ALAUDA_BULK_RESET_MEDIA 0xe0 | ||
| 57 | |||
| 58 | /* | ||
| 59 | * Port to operate on (byte 8) | ||
| 60 | */ | ||
| 61 | #define ALAUDA_PORT_XD 0x00 | ||
| 62 | #define ALAUDA_PORT_SM 0x01 | ||
| 63 | |||
| 64 | /* | ||
| 65 | * LBA and PBA are unsigned ints. Special values. | ||
| 66 | */ | ||
| 67 | #define UNDEF 0xffff | ||
| 68 | #define SPARE 0xfffe | ||
| 69 | #define UNUSABLE 0xfffd | ||
| 70 | |||
| 71 | int init_alauda(struct us_data *us); | ||
| 72 | int alauda_transport(struct scsi_cmnd *srb, struct us_data *us); | ||
| 73 | |||
| 74 | struct alauda_media_info { | ||
| 75 | unsigned long capacity; /* total media size in bytes */ | ||
| 76 | unsigned int pagesize; /* page size in bytes */ | ||
| 77 | unsigned int blocksize; /* number of pages per block */ | ||
| 78 | unsigned int uzonesize; /* number of usable blocks per zone */ | ||
| 79 | unsigned int zonesize; /* number of blocks per zone */ | ||
| 80 | unsigned int blockmask; /* mask to get page from address */ | ||
| 81 | |||
| 82 | unsigned char pageshift; | ||
| 83 | unsigned char blockshift; | ||
| 84 | unsigned char zoneshift; | ||
| 85 | |||
| 86 | u16 **lba_to_pba; /* logical to physical block map */ | ||
| 87 | u16 **pba_to_lba; /* physical to logical block map */ | ||
| 88 | }; | ||
| 89 | |||
| 90 | struct alauda_info { | ||
| 91 | struct alauda_media_info port[2]; | ||
| 92 | int wr_ep; /* endpoint to write data out of */ | ||
| 93 | |||
| 94 | unsigned char sense_key; | ||
| 95 | unsigned long sense_asc; /* additional sense code */ | ||
| 96 | unsigned long sense_ascq; /* additional sense code qualifier */ | ||
| 97 | }; | ||
| 98 | |||
| 99 | #endif | ||
| 100 | |||
diff --git a/drivers/usb/storage/cypress_atacb.c b/drivers/usb/storage/cypress_atacb.c index 898e67d30e56..c84471821183 100644 --- a/drivers/usb/storage/cypress_atacb.c +++ b/drivers/usb/storage/cypress_atacb.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 19 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #include <linux/module.h> | ||
| 22 | #include <scsi/scsi.h> | 23 | #include <scsi/scsi.h> |
| 23 | #include <scsi/scsi_cmnd.h> | 24 | #include <scsi/scsi_cmnd.h> |
| 24 | #include <scsi/scsi_eh.h> | 25 | #include <scsi/scsi_eh.h> |
| @@ -29,6 +30,49 @@ | |||
| 29 | #include "scsiglue.h" | 30 | #include "scsiglue.h" |
| 30 | #include "debug.h" | 31 | #include "debug.h" |
| 31 | 32 | ||
| 33 | MODULE_DESCRIPTION("SAT support for Cypress USB/ATA bridges with ATACB"); | ||
| 34 | MODULE_AUTHOR("Matthieu Castet <castet.matthieu@free.fr>"); | ||
| 35 | MODULE_LICENSE("GPL"); | ||
| 36 | |||
| 37 | /* | ||
| 38 | * The table of devices | ||
| 39 | */ | ||
| 40 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
| 41 | vendorName, productName, useProtocol, useTransport, \ | ||
| 42 | initFunction, flags) \ | ||
| 43 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
| 44 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
| 45 | |||
| 46 | struct usb_device_id cypress_usb_ids[] = { | ||
| 47 | # include "unusual_cypress.h" | ||
| 48 | { } /* Terminating entry */ | ||
| 49 | }; | ||
| 50 | MODULE_DEVICE_TABLE(usb, cypress_usb_ids); | ||
| 51 | |||
| 52 | #undef UNUSUAL_DEV | ||
| 53 | |||
| 54 | /* | ||
| 55 | * The flags table | ||
| 56 | */ | ||
| 57 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
| 58 | vendor_name, product_name, use_protocol, use_transport, \ | ||
| 59 | init_function, Flags) \ | ||
| 60 | { \ | ||
| 61 | .vendorName = vendor_name, \ | ||
| 62 | .productName = product_name, \ | ||
| 63 | .useProtocol = use_protocol, \ | ||
| 64 | .useTransport = use_transport, \ | ||
| 65 | .initFunction = init_function, \ | ||
| 66 | } | ||
| 67 | |||
| 68 | static struct us_unusual_dev cypress_unusual_dev_list[] = { | ||
| 69 | # include "unusual_cypress.h" | ||
| 70 | { } /* Terminating entry */ | ||
| 71 | }; | ||
| 72 | |||
| 73 | #undef UNUSUAL_DEV | ||
| 74 | |||
| 75 | |||
| 32 | /* | 76 | /* |
| 33 | * ATACB is a protocol used on cypress usb<->ata bridge to | 77 | * ATACB is a protocol used on cypress usb<->ata bridge to |
| 34 | * send raw ATA command over mass storage | 78 | * send raw ATA command over mass storage |
| @@ -36,7 +80,7 @@ | |||
| 36 | * More info that be found on cy7c68310_8.pdf and cy7c68300c_8.pdf | 80 | * More info that be found on cy7c68310_8.pdf and cy7c68300c_8.pdf |
| 37 | * datasheet from cypress.com. | 81 | * datasheet from cypress.com. |
| 38 | */ | 82 | */ |
| 39 | void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us) | 83 | static void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us) |
| 40 | { | 84 | { |
| 41 | unsigned char save_cmnd[MAX_COMMAND_SIZE]; | 85 | unsigned char save_cmnd[MAX_COMMAND_SIZE]; |
| 42 | 86 | ||
| @@ -133,19 +177,18 @@ void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us) | |||
| 133 | 177 | ||
| 134 | /* build the command for | 178 | /* build the command for |
| 135 | * reading the ATA registers */ | 179 | * reading the ATA registers */ |
| 136 | scsi_eh_prep_cmnd(srb, &ses, NULL, 0, 0); | 180 | scsi_eh_prep_cmnd(srb, &ses, NULL, 0, sizeof(regs)); |
| 137 | srb->sdb.length = sizeof(regs); | 181 | |
| 138 | sg_init_one(&ses.sense_sgl, regs, srb->sdb.length); | ||
| 139 | srb->sdb.table.sgl = &ses.sense_sgl; | ||
| 140 | srb->sc_data_direction = DMA_FROM_DEVICE; | ||
| 141 | srb->sdb.table.nents = 1; | ||
| 142 | /* we use the same command as before, but we set | 182 | /* we use the same command as before, but we set |
| 143 | * the read taskfile bit, for not executing atacb command, | 183 | * the read taskfile bit, for not executing atacb command, |
| 144 | * but reading register selected in srb->cmnd[4] | 184 | * but reading register selected in srb->cmnd[4] |
| 145 | */ | 185 | */ |
| 186 | srb->cmd_len = 16; | ||
| 187 | srb->cmnd = ses.cmnd; | ||
| 146 | srb->cmnd[2] = 1; | 188 | srb->cmnd[2] = 1; |
| 147 | 189 | ||
| 148 | usb_stor_transparent_scsi_command(srb, us); | 190 | usb_stor_transparent_scsi_command(srb, us); |
| 191 | memcpy(regs, srb->sense_buffer, sizeof(regs)); | ||
| 149 | tmp_result = srb->result; | 192 | tmp_result = srb->result; |
| 150 | scsi_eh_restore_cmnd(srb, &ses); | 193 | scsi_eh_restore_cmnd(srb, &ses); |
| 151 | /* we fail to get registers, report invalid command */ | 194 | /* we fail to get registers, report invalid command */ |
| @@ -162,8 +205,8 @@ void cypress_atacb_passthrough(struct scsi_cmnd *srb, struct us_data *us) | |||
| 162 | 205 | ||
| 163 | /* XXX we should generate sk, asc, ascq from status and error | 206 | /* XXX we should generate sk, asc, ascq from status and error |
| 164 | * regs | 207 | * regs |
| 165 | * (see 11.1 Error translation ATA device error to SCSI error map) | 208 | * (see 11.1 Error translation ATA device error to SCSI error |
| 166 | * and ata_to_sense_error from libata. | 209 | * map, and ata_to_sense_error from libata.) |
| 167 | */ | 210 | */ |
| 168 | 211 | ||
| 169 | /* Sense data is current and format is descriptor. */ | 212 | /* Sense data is current and format is descriptor. */ |
| @@ -198,3 +241,48 @@ end: | |||
| 198 | if (srb->cmnd[0] == ATA_12) | 241 | if (srb->cmnd[0] == ATA_12) |
| 199 | srb->cmd_len = 12; | 242 | srb->cmd_len = 12; |
| 200 | } | 243 | } |
| 244 | |||
| 245 | |||
| 246 | static int cypress_probe(struct usb_interface *intf, | ||
| 247 | const struct usb_device_id *id) | ||
| 248 | { | ||
| 249 | struct us_data *us; | ||
| 250 | int result; | ||
| 251 | |||
| 252 | result = usb_stor_probe1(&us, intf, id, | ||
| 253 | (id - cypress_usb_ids) + cypress_unusual_dev_list); | ||
| 254 | if (result) | ||
| 255 | return result; | ||
| 256 | |||
| 257 | us->protocol_name = "Transparent SCSI with Cypress ATACB"; | ||
| 258 | us->proto_handler = cypress_atacb_passthrough; | ||
| 259 | |||
| 260 | result = usb_stor_probe2(us); | ||
| 261 | return result; | ||
| 262 | } | ||
| 263 | |||
| 264 | static struct usb_driver cypress_driver = { | ||
| 265 | .name = "ums-cypress", | ||
| 266 | .probe = cypress_probe, | ||
| 267 | .disconnect = usb_stor_disconnect, | ||
| 268 | .suspend = usb_stor_suspend, | ||
| 269 | .resume = usb_stor_resume, | ||
| 270 | .reset_resume = usb_stor_reset_resume, | ||
| 271 | .pre_reset = usb_stor_pre_reset, | ||
| 272 | .post_reset = usb_stor_post_reset, | ||
| 273 | .id_table = cypress_usb_ids, | ||
| 274 | .soft_unbind = 1, | ||
| 275 | }; | ||
| 276 | |||
| 277 | static int __init cypress_init(void) | ||
| 278 | { | ||
| 279 | return usb_register(&cypress_driver); | ||
| 280 | } | ||
| 281 | |||
| 282 | static void __exit cypress_exit(void) | ||
| 283 | { | ||
| 284 | usb_deregister(&cypress_driver); | ||
| 285 | } | ||
| 286 | |||
| 287 | module_init(cypress_init); | ||
| 288 | module_exit(cypress_exit); | ||
diff --git a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c index 17f1ae232919..2b6e565262c2 100644 --- a/drivers/usb/storage/datafab.c +++ b/drivers/usb/storage/datafab.c | |||
| @@ -49,6 +49,7 @@ | |||
| 49 | */ | 49 | */ |
| 50 | 50 | ||
| 51 | #include <linux/errno.h> | 51 | #include <linux/errno.h> |
| 52 | #include <linux/module.h> | ||
| 52 | #include <linux/slab.h> | 53 | #include <linux/slab.h> |
| 53 | 54 | ||
| 54 | #include <scsi/scsi.h> | 55 | #include <scsi/scsi.h> |
| @@ -58,12 +59,65 @@ | |||
| 58 | #include "transport.h" | 59 | #include "transport.h" |
| 59 | #include "protocol.h" | 60 | #include "protocol.h" |
| 60 | #include "debug.h" | 61 | #include "debug.h" |
| 61 | #include "datafab.h" | 62 | |
| 63 | MODULE_DESCRIPTION("Driver for Datafab USB Compact Flash reader"); | ||
| 64 | MODULE_AUTHOR("Jimmie Mayfield <mayfield+datafab@sackheads.org>"); | ||
| 65 | MODULE_LICENSE("GPL"); | ||
| 66 | |||
| 67 | struct datafab_info { | ||
| 68 | unsigned long sectors; /* total sector count */ | ||
| 69 | unsigned long ssize; /* sector size in bytes */ | ||
| 70 | signed char lun; /* used for dual-slot readers */ | ||
| 71 | |||
| 72 | /* the following aren't used yet */ | ||
| 73 | unsigned char sense_key; | ||
| 74 | unsigned long sense_asc; /* additional sense code */ | ||
| 75 | unsigned long sense_ascq; /* additional sense code qualifier */ | ||
| 76 | }; | ||
| 62 | 77 | ||
| 63 | static int datafab_determine_lun(struct us_data *us, | 78 | static int datafab_determine_lun(struct us_data *us, |
| 64 | struct datafab_info *info); | 79 | struct datafab_info *info); |
| 65 | 80 | ||
| 66 | 81 | ||
| 82 | /* | ||
| 83 | * The table of devices | ||
| 84 | */ | ||
| 85 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
| 86 | vendorName, productName, useProtocol, useTransport, \ | ||
| 87 | initFunction, flags) \ | ||
| 88 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
| 89 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
| 90 | |||
| 91 | struct usb_device_id datafab_usb_ids[] = { | ||
| 92 | # include "unusual_datafab.h" | ||
| 93 | { } /* Terminating entry */ | ||
| 94 | }; | ||
| 95 | MODULE_DEVICE_TABLE(usb, datafab_usb_ids); | ||
| 96 | |||
| 97 | #undef UNUSUAL_DEV | ||
| 98 | |||
| 99 | /* | ||
| 100 | * The flags table | ||
| 101 | */ | ||
| 102 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
| 103 | vendor_name, product_name, use_protocol, use_transport, \ | ||
| 104 | init_function, Flags) \ | ||
| 105 | { \ | ||
| 106 | .vendorName = vendor_name, \ | ||
| 107 | .productName = product_name, \ | ||
| 108 | .useProtocol = use_protocol, \ | ||
| 109 | .useTransport = use_transport, \ | ||
| 110 | .initFunction = init_function, \ | ||
| 111 | } | ||
| 112 | |||
| 113 | static struct us_unusual_dev datafab_unusual_dev_list[] = { | ||
| 114 | # include "unusual_datafab.h" | ||
| 115 | { } /* Terminating entry */ | ||
| 116 | }; | ||
| 117 | |||
| 118 | #undef UNUSUAL_DEV | ||
| 119 | |||
| 120 | |||
| 67 | static inline int | 121 | static inline int |
| 68 | datafab_bulk_read(struct us_data *us, unsigned char *data, unsigned int len) { | 122 | datafab_bulk_read(struct us_data *us, unsigned char *data, unsigned int len) { |
| 69 | if (len == 0) | 123 | if (len == 0) |
| @@ -500,7 +554,7 @@ static void datafab_info_destructor(void *extra) | |||
| 500 | 554 | ||
| 501 | // Transport for the Datafab MDCFE-B | 555 | // Transport for the Datafab MDCFE-B |
| 502 | // | 556 | // |
| 503 | int datafab_transport(struct scsi_cmnd * srb, struct us_data *us) | 557 | static int datafab_transport(struct scsi_cmnd *srb, struct us_data *us) |
| 504 | { | 558 | { |
| 505 | struct datafab_info *info; | 559 | struct datafab_info *info; |
| 506 | int rc; | 560 | int rc; |
| @@ -665,3 +719,49 @@ int datafab_transport(struct scsi_cmnd * srb, struct us_data *us) | |||
| 665 | info->sense_ascq = 0x00; | 719 | info->sense_ascq = 0x00; |
| 666 | return USB_STOR_TRANSPORT_FAILED; | 720 | return USB_STOR_TRANSPORT_FAILED; |
| 667 | } | 721 | } |
| 722 | |||
| 723 | static int datafab_probe(struct usb_interface *intf, | ||
| 724 | const struct usb_device_id *id) | ||
| 725 | { | ||
| 726 | struct us_data *us; | ||
| 727 | int result; | ||
| 728 | |||
| 729 | result = usb_stor_probe1(&us, intf, id, | ||
| 730 | (id - datafab_usb_ids) + datafab_unusual_dev_list); | ||
| 731 | if (result) | ||
| 732 | return result; | ||
| 733 | |||
| 734 | us->transport_name = "Datafab Bulk-Only"; | ||
| 735 | us->transport = datafab_transport; | ||
| 736 | us->transport_reset = usb_stor_Bulk_reset; | ||
| 737 | us->max_lun = 1; | ||
| 738 | |||
| 739 | result = usb_stor_probe2(us); | ||
| 740 | return result; | ||
| 741 | } | ||
| 742 | |||
| 743 | static struct usb_driver datafab_driver = { | ||
| 744 | .name = "ums-datafab", | ||
| 745 | .probe = datafab_probe, | ||
| 746 | .disconnect = usb_stor_disconnect, | ||
| 747 | .suspend = usb_stor_suspend, | ||
| 748 | .resume = usb_stor_resume, | ||
| 749 | .reset_resume = usb_stor_reset_resume, | ||
| 750 | .pre_reset = usb_stor_pre_reset, | ||
| 751 | .post_reset = usb_stor_post_reset, | ||
| 752 | .id_table = datafab_usb_ids, | ||
| 753 | .soft_unbind = 1, | ||
| 754 | }; | ||
| 755 | |||
| 756 | static int __init datafab_init(void) | ||
| 757 | { | ||
| 758 | return usb_register(&datafab_driver); | ||
| 759 | } | ||
| 760 | |||
| 761 | static void __exit datafab_exit(void) | ||
| 762 | { | ||
| 763 | usb_deregister(&datafab_driver); | ||
| 764 | } | ||
| 765 | |||
| 766 | module_init(datafab_init); | ||
| 767 | module_exit(datafab_exit); | ||
diff --git a/drivers/usb/storage/datafab.h b/drivers/usb/storage/datafab.h deleted file mode 100644 index 32e3f271e582..000000000000 --- a/drivers/usb/storage/datafab.h +++ /dev/null | |||
| @@ -1,40 +0,0 @@ | |||
| 1 | /* Driver for Datafab MDCFE-B USB Compact Flash reader | ||
| 2 | * Header File | ||
| 3 | * | ||
| 4 | * Current development and maintenance by: | ||
| 5 | * (c) 2000 Jimmie Mayfield (mayfield+datafab@sackheads.org) | ||
| 6 | * | ||
| 7 | * See datafab.c for more explanation | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify it | ||
| 10 | * under the terms of the GNU General Public License as published by the | ||
| 11 | * Free Software Foundation; either version 2, or (at your option) any | ||
| 12 | * later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, but | ||
| 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 17 | * General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License along | ||
| 20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 21 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #ifndef _USB_DATAFAB_MDCFE_B_H | ||
| 25 | #define _USB_DATAFAB_MDCFE_B_H | ||
| 26 | |||
| 27 | extern int datafab_transport(struct scsi_cmnd *srb, struct us_data *us); | ||
| 28 | |||
| 29 | struct datafab_info { | ||
| 30 | unsigned long sectors; // total sector count | ||
| 31 | unsigned long ssize; // sector size in bytes | ||
| 32 | signed char lun; // used for dual-slot readers | ||
| 33 | |||
| 34 | // the following aren't used yet | ||
| 35 | unsigned char sense_key; | ||
| 36 | unsigned long sense_asc; // additional sense code | ||
| 37 | unsigned long sense_ascq; // additional sense code qualifier | ||
| 38 | }; | ||
| 39 | |||
| 40 | #endif | ||
diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c index 73ac7262239e..54cc94277acb 100644 --- a/drivers/usb/storage/freecom.c +++ b/drivers/usb/storage/freecom.c | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | * (http://www.freecom.de/) | 26 | * (http://www.freecom.de/) |
| 27 | */ | 27 | */ |
| 28 | 28 | ||
| 29 | #include <linux/module.h> | ||
| 29 | #include <scsi/scsi.h> | 30 | #include <scsi/scsi.h> |
| 30 | #include <scsi/scsi_cmnd.h> | 31 | #include <scsi/scsi_cmnd.h> |
| 31 | 32 | ||
| @@ -33,7 +34,10 @@ | |||
| 33 | #include "transport.h" | 34 | #include "transport.h" |
| 34 | #include "protocol.h" | 35 | #include "protocol.h" |
| 35 | #include "debug.h" | 36 | #include "debug.h" |
| 36 | #include "freecom.h" | 37 | |
| 38 | MODULE_DESCRIPTION("Driver for Freecom USB/IDE adaptor"); | ||
| 39 | MODULE_AUTHOR("David Brown <usb-storage@davidb.org>"); | ||
| 40 | MODULE_LICENSE("GPL"); | ||
| 37 | 41 | ||
| 38 | #ifdef CONFIG_USB_STORAGE_DEBUG | 42 | #ifdef CONFIG_USB_STORAGE_DEBUG |
| 39 | static void pdump (void *, int); | 43 | static void pdump (void *, int); |
| @@ -103,6 +107,47 @@ struct freecom_status { | |||
| 103 | #define FCM_PACKET_LENGTH 64 | 107 | #define FCM_PACKET_LENGTH 64 |
| 104 | #define FCM_STATUS_PACKET_LENGTH 4 | 108 | #define FCM_STATUS_PACKET_LENGTH 4 |
| 105 | 109 | ||
| 110 | static int init_freecom(struct us_data *us); | ||
| 111 | |||
| 112 | |||
| 113 | /* | ||
| 114 | * The table of devices | ||
| 115 | */ | ||
| 116 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
| 117 | vendorName, productName, useProtocol, useTransport, \ | ||
| 118 | initFunction, flags) \ | ||
| 119 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
| 120 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
| 121 | |||
| 122 | struct usb_device_id freecom_usb_ids[] = { | ||
| 123 | # include "unusual_freecom.h" | ||
| 124 | { } /* Terminating entry */ | ||
| 125 | }; | ||
| 126 | MODULE_DEVICE_TABLE(usb, freecom_usb_ids); | ||
| 127 | |||
| 128 | #undef UNUSUAL_DEV | ||
| 129 | |||
| 130 | /* | ||
| 131 | * The flags table | ||
| 132 | */ | ||
| 133 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
| 134 | vendor_name, product_name, use_protocol, use_transport, \ | ||
| 135 | init_function, Flags) \ | ||
| 136 | { \ | ||
| 137 | .vendorName = vendor_name, \ | ||
| 138 | .productName = product_name, \ | ||
| 139 | .useProtocol = use_protocol, \ | ||
| 140 | .useTransport = use_transport, \ | ||
| 141 | .initFunction = init_function, \ | ||
| 142 | } | ||
| 143 | |||
| 144 | static struct us_unusual_dev freecom_unusual_dev_list[] = { | ||
| 145 | # include "unusual_freecom.h" | ||
| 146 | { } /* Terminating entry */ | ||
| 147 | }; | ||
| 148 | |||
| 149 | #undef UNUSUAL_DEV | ||
| 150 | |||
| 106 | static int | 151 | static int |
| 107 | freecom_readdata (struct scsi_cmnd *srb, struct us_data *us, | 152 | freecom_readdata (struct scsi_cmnd *srb, struct us_data *us, |
| 108 | unsigned int ipipe, unsigned int opipe, int count) | 153 | unsigned int ipipe, unsigned int opipe, int count) |
| @@ -173,7 +218,7 @@ freecom_writedata (struct scsi_cmnd *srb, struct us_data *us, | |||
| 173 | * Transport for the Freecom USB/IDE adaptor. | 218 | * Transport for the Freecom USB/IDE adaptor. |
| 174 | * | 219 | * |
| 175 | */ | 220 | */ |
| 176 | int freecom_transport(struct scsi_cmnd *srb, struct us_data *us) | 221 | static int freecom_transport(struct scsi_cmnd *srb, struct us_data *us) |
| 177 | { | 222 | { |
| 178 | struct freecom_cb_wrap *fcb; | 223 | struct freecom_cb_wrap *fcb; |
| 179 | struct freecom_status *fst; | 224 | struct freecom_status *fst; |
| @@ -377,8 +422,7 @@ int freecom_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
| 377 | return USB_STOR_TRANSPORT_GOOD; | 422 | return USB_STOR_TRANSPORT_GOOD; |
| 378 | } | 423 | } |
| 379 | 424 | ||
| 380 | int | 425 | static int init_freecom(struct us_data *us) |
| 381 | freecom_init (struct us_data *us) | ||
| 382 | { | 426 | { |
| 383 | int result; | 427 | int result; |
| 384 | char *buffer = us->iobuf; | 428 | char *buffer = us->iobuf; |
| @@ -417,7 +461,7 @@ freecom_init (struct us_data *us) | |||
| 417 | return USB_STOR_TRANSPORT_GOOD; | 461 | return USB_STOR_TRANSPORT_GOOD; |
| 418 | } | 462 | } |
| 419 | 463 | ||
| 420 | int usb_stor_freecom_reset(struct us_data *us) | 464 | static int usb_stor_freecom_reset(struct us_data *us) |
| 421 | { | 465 | { |
| 422 | printk (KERN_CRIT "freecom reset called\n"); | 466 | printk (KERN_CRIT "freecom reset called\n"); |
| 423 | 467 | ||
| @@ -479,3 +523,48 @@ static void pdump (void *ibuffer, int length) | |||
| 479 | } | 523 | } |
| 480 | #endif | 524 | #endif |
| 481 | 525 | ||
| 526 | static int freecom_probe(struct usb_interface *intf, | ||
| 527 | const struct usb_device_id *id) | ||
| 528 | { | ||
| 529 | struct us_data *us; | ||
| 530 | int result; | ||
| 531 | |||
| 532 | result = usb_stor_probe1(&us, intf, id, | ||
| 533 | (id - freecom_usb_ids) + freecom_unusual_dev_list); | ||
| 534 | if (result) | ||
| 535 | return result; | ||
| 536 | |||
| 537 | us->transport_name = "Freecom"; | ||
| 538 | us->transport = freecom_transport; | ||
| 539 | us->transport_reset = usb_stor_freecom_reset; | ||
| 540 | us->max_lun = 0; | ||
| 541 | |||
| 542 | result = usb_stor_probe2(us); | ||
| 543 | return result; | ||
| 544 | } | ||
| 545 | |||
| 546 | static struct usb_driver freecom_driver = { | ||
| 547 | .name = "ums-freecom", | ||
| 548 | .probe = freecom_probe, | ||
| 549 | .disconnect = usb_stor_disconnect, | ||
| 550 | .suspend = usb_stor_suspend, | ||
| 551 | .resume = usb_stor_resume, | ||
| 552 | .reset_resume = usb_stor_reset_resume, | ||
| 553 | .pre_reset = usb_stor_pre_reset, | ||
| 554 | .post_reset = usb_stor_post_reset, | ||
| 555 | .id_table = freecom_usb_ids, | ||
| 556 | .soft_unbind = 1, | ||
| 557 | }; | ||
| 558 | |||
| 559 | static int __init freecom_init(void) | ||
| 560 | { | ||
| 561 | return usb_register(&freecom_driver); | ||
| 562 | } | ||
| 563 | |||
| 564 | static void __exit freecom_exit(void) | ||
| 565 | { | ||
| 566 | usb_deregister(&freecom_driver); | ||
| 567 | } | ||
| 568 | |||
| 569 | module_init(freecom_init); | ||
| 570 | module_exit(freecom_exit); | ||
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index 383abf2516a5..882c57b399f7 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c | |||
| @@ -44,6 +44,7 @@ | |||
| 44 | 44 | ||
| 45 | #include <linux/jiffies.h> | 45 | #include <linux/jiffies.h> |
| 46 | #include <linux/errno.h> | 46 | #include <linux/errno.h> |
| 47 | #include <linux/module.h> | ||
| 47 | #include <linux/slab.h> | 48 | #include <linux/slab.h> |
| 48 | #include <linux/hdreg.h> | 49 | #include <linux/hdreg.h> |
| 49 | #include <linux/scatterlist.h> | 50 | #include <linux/scatterlist.h> |
| @@ -57,7 +58,53 @@ | |||
| 57 | #include "protocol.h" | 58 | #include "protocol.h" |
| 58 | #include "debug.h" | 59 | #include "debug.h" |
| 59 | #include "scsiglue.h" | 60 | #include "scsiglue.h" |
| 60 | #include "isd200.h" | 61 | |
| 62 | MODULE_DESCRIPTION("Driver for In-System Design, Inc. ISD200 ASIC"); | ||
| 63 | MODULE_AUTHOR("Björn Stenberg <bjorn@haxx.se>"); | ||
| 64 | MODULE_LICENSE("GPL"); | ||
| 65 | |||
| 66 | static int isd200_Initialization(struct us_data *us); | ||
| 67 | |||
| 68 | |||
| 69 | /* | ||
| 70 | * The table of devices | ||
| 71 | */ | ||
| 72 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
| 73 | vendorName, productName, useProtocol, useTransport, \ | ||
| 74 | initFunction, flags) \ | ||
| 75 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
| 76 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
| 77 | |||
| 78 | struct usb_device_id isd200_usb_ids[] = { | ||
| 79 | # include "unusual_isd200.h" | ||
| 80 | { } /* Terminating entry */ | ||
| 81 | }; | ||
| 82 | MODULE_DEVICE_TABLE(usb, isd200_usb_ids); | ||
| 83 | |||
| 84 | #undef UNUSUAL_DEV | ||
| 85 | #undef USUAL_DEV | ||
| 86 | |||
| 87 | /* | ||
| 88 | * The flags table | ||
| 89 | */ | ||
| 90 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
| 91 | vendor_name, product_name, use_protocol, use_transport, \ | ||
| 92 | init_function, Flags) \ | ||
| 93 | { \ | ||
| 94 | .vendorName = vendor_name, \ | ||
| 95 | .productName = product_name, \ | ||
| 96 | .useProtocol = use_protocol, \ | ||
| 97 | .useTransport = use_transport, \ | ||
| 98 | .initFunction = init_function, \ | ||
| 99 | } | ||
| 100 | |||
| 101 | static struct us_unusual_dev isd200_unusual_dev_list[] = { | ||
| 102 | # include "unusual_isd200.h" | ||
| 103 | { } /* Terminating entry */ | ||
| 104 | }; | ||
| 105 | |||
| 106 | #undef UNUSUAL_DEV | ||
| 107 | #undef USUAL_DEV | ||
| 61 | 108 | ||
| 62 | 109 | ||
| 63 | /* Timeout defines (in Seconds) */ | 110 | /* Timeout defines (in Seconds) */ |
| @@ -1518,7 +1565,7 @@ static int isd200_init_info(struct us_data *us) | |||
| 1518 | * Initialization for the ISD200 | 1565 | * Initialization for the ISD200 |
| 1519 | */ | 1566 | */ |
| 1520 | 1567 | ||
| 1521 | int isd200_Initialization(struct us_data *us) | 1568 | static int isd200_Initialization(struct us_data *us) |
| 1522 | { | 1569 | { |
| 1523 | US_DEBUGP("ISD200 Initialization...\n"); | 1570 | US_DEBUGP("ISD200 Initialization...\n"); |
| 1524 | 1571 | ||
| @@ -1549,7 +1596,7 @@ int isd200_Initialization(struct us_data *us) | |||
| 1549 | * | 1596 | * |
| 1550 | */ | 1597 | */ |
| 1551 | 1598 | ||
| 1552 | void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us) | 1599 | static void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us) |
| 1553 | { | 1600 | { |
| 1554 | int sendToTransport = 1, orig_bufflen; | 1601 | int sendToTransport = 1, orig_bufflen; |
| 1555 | union ata_cdb ataCdb; | 1602 | union ata_cdb ataCdb; |
| @@ -1570,3 +1617,47 @@ void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us) | |||
| 1570 | 1617 | ||
| 1571 | isd200_srb_set_bufflen(srb, orig_bufflen); | 1618 | isd200_srb_set_bufflen(srb, orig_bufflen); |
| 1572 | } | 1619 | } |
| 1620 | |||
| 1621 | static int isd200_probe(struct usb_interface *intf, | ||
| 1622 | const struct usb_device_id *id) | ||
| 1623 | { | ||
| 1624 | struct us_data *us; | ||
| 1625 | int result; | ||
| 1626 | |||
| 1627 | result = usb_stor_probe1(&us, intf, id, | ||
| 1628 | (id - isd200_usb_ids) + isd200_unusual_dev_list); | ||
| 1629 | if (result) | ||
| 1630 | return result; | ||
| 1631 | |||
| 1632 | us->protocol_name = "ISD200 ATA/ATAPI"; | ||
| 1633 | us->proto_handler = isd200_ata_command; | ||
| 1634 | |||
| 1635 | result = usb_stor_probe2(us); | ||
| 1636 | return result; | ||
| 1637 | } | ||
| 1638 | |||
| 1639 | static struct usb_driver isd200_driver = { | ||
| 1640 | .name = "ums-isd200", | ||
| 1641 | .probe = isd200_probe, | ||
| 1642 | .disconnect = usb_stor_disconnect, | ||
| 1643 | .suspend = usb_stor_suspend, | ||
| 1644 | .resume = usb_stor_resume, | ||
| 1645 | .reset_resume = usb_stor_reset_resume, | ||
| 1646 | .pre_reset = usb_stor_pre_reset, | ||
| 1647 | .post_reset = usb_stor_post_reset, | ||
| 1648 | .id_table = isd200_usb_ids, | ||
| 1649 | .soft_unbind = 1, | ||
| 1650 | }; | ||
| 1651 | |||
| 1652 | static int __init isd200_init(void) | ||
| 1653 | { | ||
| 1654 | return usb_register(&isd200_driver); | ||
| 1655 | } | ||
| 1656 | |||
| 1657 | static void __exit isd200_exit(void) | ||
| 1658 | { | ||
| 1659 | usb_deregister(&isd200_driver); | ||
| 1660 | } | ||
| 1661 | |||
| 1662 | module_init(isd200_init); | ||
| 1663 | module_exit(isd200_exit); | ||
diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c index df67f13c9e73..1c69420e3acf 100644 --- a/drivers/usb/storage/jumpshot.c +++ b/drivers/usb/storage/jumpshot.c | |||
| @@ -46,6 +46,7 @@ | |||
| 46 | */ | 46 | */ |
| 47 | 47 | ||
| 48 | #include <linux/errno.h> | 48 | #include <linux/errno.h> |
| 49 | #include <linux/module.h> | ||
| 49 | #include <linux/slab.h> | 50 | #include <linux/slab.h> |
| 50 | 51 | ||
| 51 | #include <scsi/scsi.h> | 52 | #include <scsi/scsi.h> |
| @@ -55,9 +56,61 @@ | |||
| 55 | #include "transport.h" | 56 | #include "transport.h" |
| 56 | #include "protocol.h" | 57 | #include "protocol.h" |
| 57 | #include "debug.h" | 58 | #include "debug.h" |
| 58 | #include "jumpshot.h" | ||
| 59 | 59 | ||
| 60 | 60 | ||
| 61 | MODULE_DESCRIPTION("Driver for Lexar \"Jumpshot\" Compact Flash reader"); | ||
| 62 | MODULE_AUTHOR("Jimmie Mayfield <mayfield+usb@sackheads.org>"); | ||
| 63 | MODULE_LICENSE("GPL"); | ||
| 64 | |||
| 65 | /* | ||
| 66 | * The table of devices | ||
| 67 | */ | ||
| 68 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
| 69 | vendorName, productName, useProtocol, useTransport, \ | ||
| 70 | initFunction, flags) \ | ||
| 71 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
| 72 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
| 73 | |||
| 74 | struct usb_device_id jumpshot_usb_ids[] = { | ||
| 75 | # include "unusual_jumpshot.h" | ||
| 76 | { } /* Terminating entry */ | ||
| 77 | }; | ||
| 78 | MODULE_DEVICE_TABLE(usb, jumpshot_usb_ids); | ||
| 79 | |||
| 80 | #undef UNUSUAL_DEV | ||
| 81 | |||
| 82 | /* | ||
| 83 | * The flags table | ||
| 84 | */ | ||
| 85 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
| 86 | vendor_name, product_name, use_protocol, use_transport, \ | ||
| 87 | init_function, Flags) \ | ||
| 88 | { \ | ||
| 89 | .vendorName = vendor_name, \ | ||
| 90 | .productName = product_name, \ | ||
| 91 | .useProtocol = use_protocol, \ | ||
| 92 | .useTransport = use_transport, \ | ||
| 93 | .initFunction = init_function, \ | ||
| 94 | } | ||
| 95 | |||
| 96 | static struct us_unusual_dev jumpshot_unusual_dev_list[] = { | ||
| 97 | # include "unusual_jumpshot.h" | ||
| 98 | { } /* Terminating entry */ | ||
| 99 | }; | ||
| 100 | |||
| 101 | #undef UNUSUAL_DEV | ||
| 102 | |||
| 103 | |||
| 104 | struct jumpshot_info { | ||
| 105 | unsigned long sectors; /* total sector count */ | ||
| 106 | unsigned long ssize; /* sector size in bytes */ | ||
| 107 | |||
| 108 | /* the following aren't used yet */ | ||
| 109 | unsigned char sense_key; | ||
| 110 | unsigned long sense_asc; /* additional sense code */ | ||
| 111 | unsigned long sense_ascq; /* additional sense code qualifier */ | ||
| 112 | }; | ||
| 113 | |||
| 61 | static inline int jumpshot_bulk_read(struct us_data *us, | 114 | static inline int jumpshot_bulk_read(struct us_data *us, |
| 62 | unsigned char *data, | 115 | unsigned char *data, |
| 63 | unsigned int len) | 116 | unsigned int len) |
| @@ -429,7 +482,7 @@ static void jumpshot_info_destructor(void *extra) | |||
| 429 | 482 | ||
| 430 | // Transport for the Lexar 'Jumpshot' | 483 | // Transport for the Lexar 'Jumpshot' |
| 431 | // | 484 | // |
| 432 | int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us) | 485 | static int jumpshot_transport(struct scsi_cmnd *srb, struct us_data *us) |
| 433 | { | 486 | { |
| 434 | struct jumpshot_info *info; | 487 | struct jumpshot_info *info; |
| 435 | int rc; | 488 | int rc; |
| @@ -592,3 +645,49 @@ int jumpshot_transport(struct scsi_cmnd * srb, struct us_data *us) | |||
| 592 | info->sense_ascq = 0x00; | 645 | info->sense_ascq = 0x00; |
| 593 | return USB_STOR_TRANSPORT_FAILED; | 646 | return USB_STOR_TRANSPORT_FAILED; |
| 594 | } | 647 | } |
| 648 | |||
| 649 | static int jumpshot_probe(struct usb_interface *intf, | ||
| 650 | const struct usb_device_id *id) | ||
| 651 | { | ||
| 652 | struct us_data *us; | ||
| 653 | int result; | ||
| 654 | |||
| 655 | result = usb_stor_probe1(&us, intf, id, | ||
| 656 | (id - jumpshot_usb_ids) + jumpshot_unusual_dev_list); | ||
| 657 | if (result) | ||
| 658 | return result; | ||
| 659 | |||
| 660 | us->transport_name = "Lexar Jumpshot Control/Bulk"; | ||
| 661 | us->transport = jumpshot_transport; | ||
| 662 | us->transport_reset = usb_stor_Bulk_reset; | ||
| 663 | us->max_lun = 1; | ||
| 664 | |||
| 665 | result = usb_stor_probe2(us); | ||
| 666 | return result; | ||
| 667 | } | ||
| 668 | |||
| 669 | static struct usb_driver jumpshot_driver = { | ||
| 670 | .name = "ums-jumpshot", | ||
| 671 | .probe = jumpshot_probe, | ||
| 672 | .disconnect = usb_stor_disconnect, | ||
| 673 | .suspend = usb_stor_suspend, | ||
| 674 | .resume = usb_stor_resume, | ||
| 675 | .reset_resume = usb_stor_reset_resume, | ||
| 676 | .pre_reset = usb_stor_pre_reset, | ||
| 677 | .post_reset = usb_stor_post_reset, | ||
| 678 | .id_table = jumpshot_usb_ids, | ||
| 679 | .soft_unbind = 1, | ||
| 680 | }; | ||
| 681 | |||
| 682 | static int __init jumpshot_init(void) | ||
| 683 | { | ||
| 684 | return usb_register(&jumpshot_driver); | ||
| 685 | } | ||
| 686 | |||
| 687 | static void __exit jumpshot_exit(void) | ||
| 688 | { | ||
| 689 | usb_deregister(&jumpshot_driver); | ||
| 690 | } | ||
| 691 | |||
| 692 | module_init(jumpshot_init); | ||
| 693 | module_exit(jumpshot_exit); | ||
diff --git a/drivers/usb/storage/jumpshot.h b/drivers/usb/storage/jumpshot.h deleted file mode 100644 index 19bac9d1558f..000000000000 --- a/drivers/usb/storage/jumpshot.h +++ /dev/null | |||
| @@ -1,39 +0,0 @@ | |||
| 1 | /* Driver for Lexar "Jumpshot" USB Compact Flash reader | ||
| 2 | * Header File | ||
| 3 | * | ||
| 4 | * Current development and maintenance by: | ||
| 5 | * (c) 2000 Jimmie Mayfield (mayfield+usb@sackheads.org) | ||
| 6 | * | ||
| 7 | * See jumpshot.c for more explanation | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify it | ||
| 10 | * under the terms of the GNU General Public License as published by the | ||
| 11 | * Free Software Foundation; either version 2, or (at your option) any | ||
| 12 | * later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, but | ||
| 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 17 | * General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License along | ||
| 20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 21 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #ifndef _USB_JUMPSHOT_H | ||
| 25 | #define _USB_JUMPSHOT_H | ||
| 26 | |||
| 27 | extern int jumpshot_transport(struct scsi_cmnd *srb, struct us_data *us); | ||
| 28 | |||
| 29 | struct jumpshot_info { | ||
| 30 | unsigned long sectors; // total sector count | ||
| 31 | unsigned long ssize; // sector size in bytes | ||
| 32 | |||
| 33 | // the following aren't used yet | ||
| 34 | unsigned char sense_key; | ||
| 35 | unsigned long sense_asc; // additional sense code | ||
| 36 | unsigned long sense_ascq; // additional sense code qualifier | ||
| 37 | }; | ||
| 38 | |||
| 39 | #endif | ||
diff --git a/drivers/usb/storage/karma.c b/drivers/usb/storage/karma.c index 0d79ae5683f7..7953d93a7739 100644 --- a/drivers/usb/storage/karma.c +++ b/drivers/usb/storage/karma.c | |||
| @@ -18,6 +18,8 @@ | |||
| 18 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 18 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
| 19 | */ | 19 | */ |
| 20 | 20 | ||
| 21 | #include <linux/module.h> | ||
| 22 | |||
| 21 | #include <scsi/scsi.h> | 23 | #include <scsi/scsi.h> |
| 22 | #include <scsi/scsi_cmnd.h> | 24 | #include <scsi/scsi_cmnd.h> |
| 23 | #include <scsi/scsi_device.h> | 25 | #include <scsi/scsi_device.h> |
| @@ -25,7 +27,10 @@ | |||
| 25 | #include "usb.h" | 27 | #include "usb.h" |
| 26 | #include "transport.h" | 28 | #include "transport.h" |
| 27 | #include "debug.h" | 29 | #include "debug.h" |
| 28 | #include "karma.h" | 30 | |
| 31 | MODULE_DESCRIPTION("Driver for Rio Karma"); | ||
| 32 | MODULE_AUTHOR("Bob Copeland <me@bobcopeland.com>, Keith Bennett <keith@mcs.st-and.ac.uk>"); | ||
| 33 | MODULE_LICENSE("GPL"); | ||
| 29 | 34 | ||
| 30 | #define RIO_PREFIX "RIOP\x00" | 35 | #define RIO_PREFIX "RIOP\x00" |
| 31 | #define RIO_PREFIX_LEN 5 | 36 | #define RIO_PREFIX_LEN 5 |
| @@ -36,13 +41,53 @@ | |||
| 36 | #define RIO_LEAVE_STORAGE 0x2 | 41 | #define RIO_LEAVE_STORAGE 0x2 |
| 37 | #define RIO_RESET 0xC | 42 | #define RIO_RESET 0xC |
| 38 | 43 | ||
| 39 | extern int usb_stor_Bulk_transport(struct scsi_cmnd *, struct us_data *); | ||
| 40 | |||
| 41 | struct karma_data { | 44 | struct karma_data { |
| 42 | int in_storage; | 45 | int in_storage; |
| 43 | char *recv; | 46 | char *recv; |
| 44 | }; | 47 | }; |
| 45 | 48 | ||
| 49 | static int rio_karma_init(struct us_data *us); | ||
| 50 | |||
| 51 | |||
| 52 | /* | ||
| 53 | * The table of devices | ||
| 54 | */ | ||
| 55 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
| 56 | vendorName, productName, useProtocol, useTransport, \ | ||
| 57 | initFunction, flags) \ | ||
| 58 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
| 59 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
| 60 | |||
| 61 | struct usb_device_id karma_usb_ids[] = { | ||
| 62 | # include "unusual_karma.h" | ||
| 63 | { } /* Terminating entry */ | ||
| 64 | }; | ||
| 65 | MODULE_DEVICE_TABLE(usb, karma_usb_ids); | ||
| 66 | |||
| 67 | #undef UNUSUAL_DEV | ||
| 68 | |||
| 69 | /* | ||
| 70 | * The flags table | ||
| 71 | */ | ||
| 72 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
| 73 | vendor_name, product_name, use_protocol, use_transport, \ | ||
| 74 | init_function, Flags) \ | ||
| 75 | { \ | ||
| 76 | .vendorName = vendor_name, \ | ||
| 77 | .productName = product_name, \ | ||
| 78 | .useProtocol = use_protocol, \ | ||
| 79 | .useTransport = use_transport, \ | ||
| 80 | .initFunction = init_function, \ | ||
| 81 | } | ||
| 82 | |||
| 83 | static struct us_unusual_dev karma_unusual_dev_list[] = { | ||
| 84 | # include "unusual_karma.h" | ||
| 85 | { } /* Terminating entry */ | ||
| 86 | }; | ||
| 87 | |||
| 88 | #undef UNUSUAL_DEV | ||
| 89 | |||
| 90 | |||
| 46 | /* | 91 | /* |
| 47 | * Send commands to Rio Karma. | 92 | * Send commands to Rio Karma. |
| 48 | * | 93 | * |
| @@ -104,7 +149,7 @@ err: | |||
| 104 | * Trap START_STOP and READ_10 to leave/re-enter storage mode. | 149 | * Trap START_STOP and READ_10 to leave/re-enter storage mode. |
| 105 | * Everything else is propagated to the normal bulk layer. | 150 | * Everything else is propagated to the normal bulk layer. |
| 106 | */ | 151 | */ |
| 107 | int rio_karma_transport(struct scsi_cmnd *srb, struct us_data *us) | 152 | static int rio_karma_transport(struct scsi_cmnd *srb, struct us_data *us) |
| 108 | { | 153 | { |
| 109 | int ret; | 154 | int ret; |
| 110 | struct karma_data *data = (struct karma_data *) us->extra; | 155 | struct karma_data *data = (struct karma_data *) us->extra; |
| @@ -133,7 +178,7 @@ static void rio_karma_destructor(void *extra) | |||
| 133 | kfree(data->recv); | 178 | kfree(data->recv); |
| 134 | } | 179 | } |
| 135 | 180 | ||
| 136 | int rio_karma_init(struct us_data *us) | 181 | static int rio_karma_init(struct us_data *us) |
| 137 | { | 182 | { |
| 138 | int ret = 0; | 183 | int ret = 0; |
| 139 | struct karma_data *data = kzalloc(sizeof(struct karma_data), GFP_NOIO); | 184 | struct karma_data *data = kzalloc(sizeof(struct karma_data), GFP_NOIO); |
| @@ -153,3 +198,48 @@ int rio_karma_init(struct us_data *us) | |||
| 153 | out: | 198 | out: |
| 154 | return ret; | 199 | return ret; |
| 155 | } | 200 | } |
| 201 | |||
| 202 | static int karma_probe(struct usb_interface *intf, | ||
| 203 | const struct usb_device_id *id) | ||
| 204 | { | ||
| 205 | struct us_data *us; | ||
| 206 | int result; | ||
| 207 | |||
| 208 | result = usb_stor_probe1(&us, intf, id, | ||
| 209 | (id - karma_usb_ids) + karma_unusual_dev_list); | ||
| 210 | if (result) | ||
| 211 | return result; | ||
| 212 | |||
| 213 | us->transport_name = "Rio Karma/Bulk"; | ||
| 214 | us->transport = rio_karma_transport; | ||
| 215 | us->transport_reset = usb_stor_Bulk_reset; | ||
| 216 | |||
| 217 | result = usb_stor_probe2(us); | ||
| 218 | return result; | ||
| 219 | } | ||
| 220 | |||
| 221 | static struct usb_driver karma_driver = { | ||
| 222 | .name = "ums-karma", | ||
| 223 | .probe = karma_probe, | ||
| 224 | .disconnect = usb_stor_disconnect, | ||
| 225 | .suspend = usb_stor_suspend, | ||
| 226 | .resume = usb_stor_resume, | ||
| 227 | .reset_resume = usb_stor_reset_resume, | ||
| 228 | .pre_reset = usb_stor_pre_reset, | ||
| 229 | .post_reset = usb_stor_post_reset, | ||
| 230 | .id_table = karma_usb_ids, | ||
| 231 | .soft_unbind = 1, | ||
| 232 | }; | ||
| 233 | |||
| 234 | static int __init karma_init(void) | ||
| 235 | { | ||
| 236 | return usb_register(&karma_driver); | ||
| 237 | } | ||
| 238 | |||
| 239 | static void __exit karma_exit(void) | ||
| 240 | { | ||
| 241 | usb_deregister(&karma_driver); | ||
| 242 | } | ||
| 243 | |||
| 244 | module_init(karma_init); | ||
| 245 | module_exit(karma_exit); | ||
diff --git a/drivers/usb/storage/karma.h b/drivers/usb/storage/karma.h deleted file mode 100644 index 8a60972af8c5..000000000000 --- a/drivers/usb/storage/karma.h +++ /dev/null | |||
| @@ -1,7 +0,0 @@ | |||
| 1 | #ifndef _KARMA_USB_H | ||
| 2 | #define _KARMA_USB_H | ||
| 3 | |||
| 4 | extern int rio_karma_init(struct us_data *us); | ||
| 5 | extern int rio_karma_transport(struct scsi_cmnd *srb, struct us_data *us); | ||
| 6 | |||
| 7 | #endif | ||
diff --git a/drivers/usb/storage/libusual.c b/drivers/usb/storage/libusual.c index f970b27ba308..fe3ffe1459b2 100644 --- a/drivers/usb/storage/libusual.c +++ b/drivers/usb/storage/libusual.c | |||
| @@ -38,37 +38,6 @@ static atomic_t total_threads = ATOMIC_INIT(0); | |||
| 38 | static int usu_probe_thread(void *arg); | 38 | static int usu_probe_thread(void *arg); |
| 39 | 39 | ||
| 40 | /* | 40 | /* |
| 41 | * The table. | ||
| 42 | */ | ||
| 43 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
| 44 | vendorName, productName,useProtocol, useTransport, \ | ||
| 45 | initFunction, flags) \ | ||
| 46 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \ | ||
| 47 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
| 48 | |||
| 49 | #define COMPLIANT_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
| 50 | vendorName, productName, useProtocol, useTransport, \ | ||
| 51 | initFunction, flags) \ | ||
| 52 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
| 53 | .driver_info = (flags) } | ||
| 54 | |||
| 55 | #define USUAL_DEV(useProto, useTrans, useType) \ | ||
| 56 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ | ||
| 57 | .driver_info = ((useType)<<24) } | ||
| 58 | |||
| 59 | struct usb_device_id storage_usb_ids [] = { | ||
| 60 | # include "unusual_devs.h" | ||
| 61 | { } /* Terminating entry */ | ||
| 62 | }; | ||
| 63 | |||
| 64 | #undef USUAL_DEV | ||
| 65 | #undef UNUSUAL_DEV | ||
| 66 | #undef COMPLIANT_DEV | ||
| 67 | |||
| 68 | MODULE_DEVICE_TABLE(usb, storage_usb_ids); | ||
| 69 | EXPORT_SYMBOL_GPL(storage_usb_ids); | ||
| 70 | |||
| 71 | /* | ||
| 72 | * @type: the module type as an integer | 41 | * @type: the module type as an integer |
| 73 | */ | 42 | */ |
| 74 | void usb_usual_set_present(int type) | 43 | void usb_usual_set_present(int type) |
| @@ -167,7 +136,7 @@ static struct usb_driver usu_driver = { | |||
| 167 | .name = "libusual", | 136 | .name = "libusual", |
| 168 | .probe = usu_probe, | 137 | .probe = usu_probe, |
| 169 | .disconnect = usu_disconnect, | 138 | .disconnect = usu_disconnect, |
| 170 | .id_table = storage_usb_ids, | 139 | .id_table = usb_storage_usb_ids, |
| 171 | }; | 140 | }; |
| 172 | 141 | ||
| 173 | /* | 142 | /* |
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index c7bf8954b4e4..380233bd6a39 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c | |||
| @@ -35,9 +35,16 @@ | |||
| 35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
| 36 | #include <linux/usb/input.h> | 36 | #include <linux/usb/input.h> |
| 37 | #include "usb.h" | 37 | #include "usb.h" |
| 38 | #include "onetouch.h" | ||
| 39 | #include "debug.h" | 38 | #include "debug.h" |
| 40 | 39 | ||
| 40 | MODULE_DESCRIPTION("Maxtor USB OneTouch hard drive button driver"); | ||
| 41 | MODULE_AUTHOR("Nick Sillik <n.sillik@temple.edu>"); | ||
| 42 | MODULE_LICENSE("GPL"); | ||
| 43 | |||
| 44 | #define ONETOUCH_PKT_LEN 0x02 | ||
| 45 | #define ONETOUCH_BUTTON KEY_PROG1 | ||
| 46 | |||
| 47 | static int onetouch_connect_input(struct us_data *ss); | ||
| 41 | static void onetouch_release_input(void *onetouch_); | 48 | static void onetouch_release_input(void *onetouch_); |
| 42 | 49 | ||
| 43 | struct usb_onetouch { | 50 | struct usb_onetouch { |
| @@ -52,6 +59,46 @@ struct usb_onetouch { | |||
| 52 | unsigned int is_open:1; | 59 | unsigned int is_open:1; |
| 53 | }; | 60 | }; |
| 54 | 61 | ||
| 62 | |||
| 63 | /* | ||
| 64 | * The table of devices | ||
| 65 | */ | ||
| 66 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
| 67 | vendorName, productName, useProtocol, useTransport, \ | ||
| 68 | initFunction, flags) \ | ||
| 69 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
| 70 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
| 71 | |||
| 72 | struct usb_device_id onetouch_usb_ids[] = { | ||
| 73 | # include "unusual_onetouch.h" | ||
| 74 | { } /* Terminating entry */ | ||
| 75 | }; | ||
| 76 | MODULE_DEVICE_TABLE(usb, onetouch_usb_ids); | ||
| 77 | |||
| 78 | #undef UNUSUAL_DEV | ||
| 79 | |||
| 80 | /* | ||
| 81 | * The flags table | ||
| 82 | */ | ||
| 83 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
| 84 | vendor_name, product_name, use_protocol, use_transport, \ | ||
| 85 | init_function, Flags) \ | ||
| 86 | { \ | ||
| 87 | .vendorName = vendor_name, \ | ||
| 88 | .productName = product_name, \ | ||
| 89 | .useProtocol = use_protocol, \ | ||
| 90 | .useTransport = use_transport, \ | ||
| 91 | .initFunction = init_function, \ | ||
| 92 | } | ||
| 93 | |||
| 94 | static struct us_unusual_dev onetouch_unusual_dev_list[] = { | ||
| 95 | # include "unusual_onetouch.h" | ||
| 96 | { } /* Terminating entry */ | ||
| 97 | }; | ||
| 98 | |||
| 99 | #undef UNUSUAL_DEV | ||
| 100 | |||
| 101 | |||
| 55 | static void usb_onetouch_irq(struct urb *urb) | 102 | static void usb_onetouch_irq(struct urb *urb) |
| 56 | { | 103 | { |
| 57 | struct usb_onetouch *onetouch = urb->context; | 104 | struct usb_onetouch *onetouch = urb->context; |
| @@ -127,7 +174,7 @@ static void usb_onetouch_pm_hook(struct us_data *us, int action) | |||
| 127 | } | 174 | } |
| 128 | #endif /* CONFIG_PM */ | 175 | #endif /* CONFIG_PM */ |
| 129 | 176 | ||
| 130 | int onetouch_connect_input(struct us_data *ss) | 177 | static int onetouch_connect_input(struct us_data *ss) |
| 131 | { | 178 | { |
| 132 | struct usb_device *udev = ss->pusb_dev; | 179 | struct usb_device *udev = ss->pusb_dev; |
| 133 | struct usb_host_interface *interface; | 180 | struct usb_host_interface *interface; |
| @@ -236,3 +283,46 @@ static void onetouch_release_input(void *onetouch_) | |||
| 236 | onetouch->data, onetouch->data_dma); | 283 | onetouch->data, onetouch->data_dma); |
| 237 | } | 284 | } |
| 238 | } | 285 | } |
| 286 | |||
| 287 | static int onetouch_probe(struct usb_interface *intf, | ||
| 288 | const struct usb_device_id *id) | ||
| 289 | { | ||
| 290 | struct us_data *us; | ||
| 291 | int result; | ||
| 292 | |||
| 293 | result = usb_stor_probe1(&us, intf, id, | ||
| 294 | (id - onetouch_usb_ids) + onetouch_unusual_dev_list); | ||
| 295 | if (result) | ||
| 296 | return result; | ||
| 297 | |||
| 298 | /* Use default transport and protocol */ | ||
| 299 | |||
| 300 | result = usb_stor_probe2(us); | ||
| 301 | return result; | ||
| 302 | } | ||
| 303 | |||
| 304 | static struct usb_driver onetouch_driver = { | ||
| 305 | .name = "ums-onetouch", | ||
| 306 | .probe = onetouch_probe, | ||
| 307 | .disconnect = usb_stor_disconnect, | ||
| 308 | .suspend = usb_stor_suspend, | ||
| 309 | .resume = usb_stor_resume, | ||
| 310 | .reset_resume = usb_stor_reset_resume, | ||
| 311 | .pre_reset = usb_stor_pre_reset, | ||
| 312 | .post_reset = usb_stor_post_reset, | ||
| 313 | .id_table = onetouch_usb_ids, | ||
| 314 | .soft_unbind = 1, | ||
| 315 | }; | ||
| 316 | |||
| 317 | static int __init onetouch_init(void) | ||
| 318 | { | ||
| 319 | return usb_register(&onetouch_driver); | ||
| 320 | } | ||
| 321 | |||
| 322 | static void __exit onetouch_exit(void) | ||
| 323 | { | ||
| 324 | usb_deregister(&onetouch_driver); | ||
| 325 | } | ||
| 326 | |||
| 327 | module_init(onetouch_init); | ||
| 328 | module_exit(onetouch_exit); | ||
diff --git a/drivers/usb/storage/onetouch.h b/drivers/usb/storage/onetouch.h deleted file mode 100644 index 41c7aa8f0446..000000000000 --- a/drivers/usb/storage/onetouch.h +++ /dev/null | |||
| @@ -1,9 +0,0 @@ | |||
| 1 | #ifndef _ONETOUCH_H_ | ||
| 2 | #define _ONETOUCH_H_ | ||
| 3 | |||
| 4 | #define ONETOUCH_PKT_LEN 0x02 | ||
| 5 | #define ONETOUCH_BUTTON KEY_PROG1 | ||
| 6 | |||
| 7 | int onetouch_connect_input(struct us_data *ss); | ||
| 8 | |||
| 9 | #endif | ||
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c index be441d84bc64..fc310f75eada 100644 --- a/drivers/usb/storage/protocol.c +++ b/drivers/usb/storage/protocol.c | |||
| @@ -121,6 +121,7 @@ void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb, | |||
| 121 | /* send the command to the transport layer */ | 121 | /* send the command to the transport layer */ |
| 122 | usb_stor_invoke_transport(srb, us); | 122 | usb_stor_invoke_transport(srb, us); |
| 123 | } | 123 | } |
| 124 | EXPORT_SYMBOL_GPL(usb_stor_transparent_scsi_command); | ||
| 124 | 125 | ||
| 125 | /*********************************************************************** | 126 | /*********************************************************************** |
| 126 | * Scatter-gather transfer buffer access routines | 127 | * Scatter-gather transfer buffer access routines |
| @@ -199,6 +200,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer, | |||
| 199 | /* Return the amount actually transferred */ | 200 | /* Return the amount actually transferred */ |
| 200 | return cnt; | 201 | return cnt; |
| 201 | } | 202 | } |
| 203 | EXPORT_SYMBOL_GPL(usb_stor_access_xfer_buf); | ||
| 202 | 204 | ||
| 203 | /* Store the contents of buffer into srb's transfer buffer and set the | 205 | /* Store the contents of buffer into srb's transfer buffer and set the |
| 204 | * SCSI residue. | 206 | * SCSI residue. |
| @@ -215,3 +217,4 @@ void usb_stor_set_xfer_buf(unsigned char *buffer, | |||
| 215 | if (buflen < scsi_bufflen(srb)) | 217 | if (buflen < scsi_bufflen(srb)) |
| 216 | scsi_set_resid(srb, scsi_bufflen(srb) - buflen); | 218 | scsi_set_resid(srb, scsi_bufflen(srb) - buflen); |
| 217 | } | 219 | } |
| 220 | EXPORT_SYMBOL_GPL(usb_stor_set_xfer_buf); | ||
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 727c506417cc..4ca3b5860643 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c | |||
| @@ -135,6 +135,12 @@ static int slave_configure(struct scsi_device *sdev) | |||
| 135 | if (sdev->request_queue->max_sectors > max_sectors) | 135 | if (sdev->request_queue->max_sectors > max_sectors) |
| 136 | blk_queue_max_sectors(sdev->request_queue, | 136 | blk_queue_max_sectors(sdev->request_queue, |
| 137 | max_sectors); | 137 | max_sectors); |
| 138 | } else if (sdev->type == TYPE_TAPE) { | ||
| 139 | /* Tapes need much higher max_sector limits, so just | ||
| 140 | * raise it to the maximum possible (4 GB / 512) and | ||
| 141 | * let the queue segment size sort out the real limit. | ||
| 142 | */ | ||
| 143 | blk_queue_max_sectors(sdev->request_queue, 0x7FFFFF); | ||
| 138 | } | 144 | } |
| 139 | 145 | ||
| 140 | /* Some USB host controllers can't do DMA; they have to use PIO. | 146 | /* Some USB host controllers can't do DMA; they have to use PIO. |
| @@ -563,4 +569,4 @@ unsigned char usb_stor_sense_invalidCDB[18] = { | |||
| 563 | [7] = 0x0a, /* additional length */ | 569 | [7] = 0x0a, /* additional length */ |
| 564 | [12] = 0x24 /* Invalid Field in CDB */ | 570 | [12] = 0x24 /* Invalid Field in CDB */ |
| 565 | }; | 571 | }; |
| 566 | 572 | EXPORT_SYMBOL_GPL(usb_stor_sense_invalidCDB); | |
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index 531ae5c5abf3..ab5f9f37575a 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c | |||
| @@ -41,6 +41,7 @@ | |||
| 41 | */ | 41 | */ |
| 42 | 42 | ||
| 43 | #include <linux/errno.h> | 43 | #include <linux/errno.h> |
| 44 | #include <linux/module.h> | ||
| 44 | #include <linux/slab.h> | 45 | #include <linux/slab.h> |
| 45 | 46 | ||
| 46 | #include <scsi/scsi.h> | 47 | #include <scsi/scsi.h> |
| @@ -51,7 +52,53 @@ | |||
| 51 | #include "transport.h" | 52 | #include "transport.h" |
| 52 | #include "protocol.h" | 53 | #include "protocol.h" |
| 53 | #include "debug.h" | 54 | #include "debug.h" |
| 54 | #include "sddr09.h" | 55 | |
| 56 | MODULE_DESCRIPTION("Driver for SanDisk SDDR-09 SmartMedia reader"); | ||
| 57 | MODULE_AUTHOR("Andries Brouwer <aeb@cwi.nl>, Robert Baruch <autophile@starband.net>"); | ||
| 58 | MODULE_LICENSE("GPL"); | ||
| 59 | |||
| 60 | static int usb_stor_sddr09_dpcm_init(struct us_data *us); | ||
| 61 | static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us); | ||
| 62 | static int usb_stor_sddr09_init(struct us_data *us); | ||
| 63 | |||
| 64 | |||
| 65 | /* | ||
| 66 | * The table of devices | ||
| 67 | */ | ||
| 68 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
| 69 | vendorName, productName, useProtocol, useTransport, \ | ||
| 70 | initFunction, flags) \ | ||
| 71 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
| 72 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
| 73 | |||
| 74 | struct usb_device_id sddr09_usb_ids[] = { | ||
| 75 | # include "unusual_sddr09.h" | ||
| 76 | { } /* Terminating entry */ | ||
| 77 | }; | ||
| 78 | MODULE_DEVICE_TABLE(usb, sddr09_usb_ids); | ||
| 79 | |||
| 80 | #undef UNUSUAL_DEV | ||
| 81 | |||
| 82 | /* | ||
| 83 | * The flags table | ||
| 84 | */ | ||
| 85 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
| 86 | vendor_name, product_name, use_protocol, use_transport, \ | ||
| 87 | init_function, Flags) \ | ||
| 88 | { \ | ||
| 89 | .vendorName = vendor_name, \ | ||
| 90 | .productName = product_name, \ | ||
| 91 | .useProtocol = use_protocol, \ | ||
| 92 | .useTransport = use_transport, \ | ||
| 93 | .initFunction = init_function, \ | ||
| 94 | } | ||
| 95 | |||
| 96 | static struct us_unusual_dev sddr09_unusual_dev_list[] = { | ||
| 97 | # include "unusual_sddr09.h" | ||
| 98 | { } /* Terminating entry */ | ||
| 99 | }; | ||
| 100 | |||
| 101 | #undef UNUSUAL_DEV | ||
| 55 | 102 | ||
| 56 | 103 | ||
| 57 | #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) | 104 | #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) |
| @@ -723,7 +770,7 @@ sddr09_read_data(struct us_data *us, | |||
| 723 | len = min(sectors, (unsigned int) info->blocksize) * info->pagesize; | 770 | len = min(sectors, (unsigned int) info->blocksize) * info->pagesize; |
| 724 | buffer = kmalloc(len, GFP_NOIO); | 771 | buffer = kmalloc(len, GFP_NOIO); |
| 725 | if (buffer == NULL) { | 772 | if (buffer == NULL) { |
| 726 | printk("sddr09_read_data: Out of memory\n"); | 773 | printk(KERN_WARNING "sddr09_read_data: Out of memory\n"); |
| 727 | return -ENOMEM; | 774 | return -ENOMEM; |
| 728 | } | 775 | } |
| 729 | 776 | ||
| @@ -838,7 +885,8 @@ sddr09_write_lba(struct us_data *us, unsigned int lba, | |||
| 838 | if (pba == UNDEF) { | 885 | if (pba == UNDEF) { |
| 839 | pba = sddr09_find_unused_pba(info, lba); | 886 | pba = sddr09_find_unused_pba(info, lba); |
| 840 | if (!pba) { | 887 | if (!pba) { |
| 841 | printk("sddr09_write_lba: Out of unused blocks\n"); | 888 | printk(KERN_WARNING |
| 889 | "sddr09_write_lba: Out of unused blocks\n"); | ||
| 842 | return -ENOSPC; | 890 | return -ENOSPC; |
| 843 | } | 891 | } |
| 844 | info->pba_to_lba[pba] = lba; | 892 | info->pba_to_lba[pba] = lba; |
| @@ -849,7 +897,7 @@ sddr09_write_lba(struct us_data *us, unsigned int lba, | |||
| 849 | if (pba == 1) { | 897 | if (pba == 1) { |
| 850 | /* Maybe it is impossible to write to PBA 1. | 898 | /* Maybe it is impossible to write to PBA 1. |
| 851 | Fake success, but don't do anything. */ | 899 | Fake success, but don't do anything. */ |
| 852 | printk("sddr09: avoid writing to pba 1\n"); | 900 | printk(KERN_WARNING "sddr09: avoid writing to pba 1\n"); |
| 853 | return 0; | 901 | return 0; |
| 854 | } | 902 | } |
| 855 | 903 | ||
| @@ -954,7 +1002,7 @@ sddr09_write_data(struct us_data *us, | |||
| 954 | blocklen = (pagelen << info->blockshift); | 1002 | blocklen = (pagelen << info->blockshift); |
| 955 | blockbuffer = kmalloc(blocklen, GFP_NOIO); | 1003 | blockbuffer = kmalloc(blocklen, GFP_NOIO); |
| 956 | if (!blockbuffer) { | 1004 | if (!blockbuffer) { |
| 957 | printk("sddr09_write_data: Out of memory\n"); | 1005 | printk(KERN_WARNING "sddr09_write_data: Out of memory\n"); |
| 958 | return -ENOMEM; | 1006 | return -ENOMEM; |
| 959 | } | 1007 | } |
| 960 | 1008 | ||
| @@ -965,7 +1013,7 @@ sddr09_write_data(struct us_data *us, | |||
| 965 | len = min(sectors, (unsigned int) info->blocksize) * info->pagesize; | 1013 | len = min(sectors, (unsigned int) info->blocksize) * info->pagesize; |
| 966 | buffer = kmalloc(len, GFP_NOIO); | 1014 | buffer = kmalloc(len, GFP_NOIO); |
| 967 | if (buffer == NULL) { | 1015 | if (buffer == NULL) { |
| 968 | printk("sddr09_write_data: Out of memory\n"); | 1016 | printk(KERN_WARNING "sddr09_write_data: Out of memory\n"); |
| 969 | kfree(blockbuffer); | 1017 | kfree(blockbuffer); |
| 970 | return -ENOMEM; | 1018 | return -ENOMEM; |
| 971 | } | 1019 | } |
| @@ -1112,7 +1160,7 @@ sddr09_get_cardinfo(struct us_data *us, unsigned char flags) { | |||
| 1112 | 1160 | ||
| 1113 | if (result) { | 1161 | if (result) { |
| 1114 | US_DEBUGP("Result of read_deviceID is %d\n", result); | 1162 | US_DEBUGP("Result of read_deviceID is %d\n", result); |
| 1115 | printk("sddr09: could not read card info\n"); | 1163 | printk(KERN_WARNING "sddr09: could not read card info\n"); |
| 1116 | return NULL; | 1164 | return NULL; |
| 1117 | } | 1165 | } |
| 1118 | 1166 | ||
| @@ -1153,7 +1201,7 @@ sddr09_get_cardinfo(struct us_data *us, unsigned char flags) { | |||
| 1153 | sprintf(blurbtxt + strlen(blurbtxt), | 1201 | sprintf(blurbtxt + strlen(blurbtxt), |
| 1154 | ", WP"); | 1202 | ", WP"); |
| 1155 | 1203 | ||
| 1156 | printk("%s\n", blurbtxt); | 1204 | printk(KERN_WARNING "%s\n", blurbtxt); |
| 1157 | 1205 | ||
| 1158 | return cardinfo; | 1206 | return cardinfo; |
| 1159 | } | 1207 | } |
| @@ -1184,7 +1232,7 @@ sddr09_read_map(struct us_data *us) { | |||
| 1184 | alloc_len = (alloc_blocks << CONTROL_SHIFT); | 1232 | alloc_len = (alloc_blocks << CONTROL_SHIFT); |
| 1185 | buffer = kmalloc(alloc_len, GFP_NOIO); | 1233 | buffer = kmalloc(alloc_len, GFP_NOIO); |
| 1186 | if (buffer == NULL) { | 1234 | if (buffer == NULL) { |
| 1187 | printk("sddr09_read_map: out of memory\n"); | 1235 | printk(KERN_WARNING "sddr09_read_map: out of memory\n"); |
| 1188 | result = -1; | 1236 | result = -1; |
| 1189 | goto done; | 1237 | goto done; |
| 1190 | } | 1238 | } |
| @@ -1198,7 +1246,7 @@ sddr09_read_map(struct us_data *us) { | |||
| 1198 | info->pba_to_lba = kmalloc(numblocks*sizeof(int), GFP_NOIO); | 1246 | info->pba_to_lba = kmalloc(numblocks*sizeof(int), GFP_NOIO); |
| 1199 | 1247 | ||
| 1200 | if (info->lba_to_pba == NULL || info->pba_to_lba == NULL) { | 1248 | if (info->lba_to_pba == NULL || info->pba_to_lba == NULL) { |
| 1201 | printk("sddr09_read_map: out of memory\n"); | 1249 | printk(KERN_WARNING "sddr09_read_map: out of memory\n"); |
| 1202 | result = -1; | 1250 | result = -1; |
| 1203 | goto done; | 1251 | goto done; |
| 1204 | } | 1252 | } |
| @@ -1238,7 +1286,8 @@ sddr09_read_map(struct us_data *us) { | |||
| 1238 | if (ptr[j] != 0) | 1286 | if (ptr[j] != 0) |
| 1239 | goto nonz; | 1287 | goto nonz; |
| 1240 | info->pba_to_lba[i] = UNUSABLE; | 1288 | info->pba_to_lba[i] = UNUSABLE; |
| 1241 | printk("sddr09: PBA %d has no logical mapping\n", i); | 1289 | printk(KERN_WARNING "sddr09: PBA %d has no logical mapping\n", |
| 1290 | i); | ||
| 1242 | continue; | 1291 | continue; |
| 1243 | 1292 | ||
| 1244 | nonz: | 1293 | nonz: |
| @@ -1251,7 +1300,8 @@ sddr09_read_map(struct us_data *us) { | |||
| 1251 | nonff: | 1300 | nonff: |
| 1252 | /* normal PBAs start with six FFs */ | 1301 | /* normal PBAs start with six FFs */ |
| 1253 | if (j < 6) { | 1302 | if (j < 6) { |
| 1254 | printk("sddr09: PBA %d has no logical mapping: " | 1303 | printk(KERN_WARNING |
| 1304 | "sddr09: PBA %d has no logical mapping: " | ||
| 1255 | "reserved area = %02X%02X%02X%02X " | 1305 | "reserved area = %02X%02X%02X%02X " |
| 1256 | "data status %02X block status %02X\n", | 1306 | "data status %02X block status %02X\n", |
| 1257 | i, ptr[0], ptr[1], ptr[2], ptr[3], | 1307 | i, ptr[0], ptr[1], ptr[2], ptr[3], |
| @@ -1261,7 +1311,8 @@ sddr09_read_map(struct us_data *us) { | |||
| 1261 | } | 1311 | } |
| 1262 | 1312 | ||
| 1263 | if ((ptr[6] >> 4) != 0x01) { | 1313 | if ((ptr[6] >> 4) != 0x01) { |
| 1264 | printk("sddr09: PBA %d has invalid address field " | 1314 | printk(KERN_WARNING |
| 1315 | "sddr09: PBA %d has invalid address field " | ||
| 1265 | "%02X%02X/%02X%02X\n", | 1316 | "%02X%02X/%02X%02X\n", |
| 1266 | i, ptr[6], ptr[7], ptr[11], ptr[12]); | 1317 | i, ptr[6], ptr[7], ptr[11], ptr[12]); |
| 1267 | info->pba_to_lba[i] = UNUSABLE; | 1318 | info->pba_to_lba[i] = UNUSABLE; |
| @@ -1270,7 +1321,8 @@ sddr09_read_map(struct us_data *us) { | |||
| 1270 | 1321 | ||
| 1271 | /* check even parity */ | 1322 | /* check even parity */ |
| 1272 | if (parity[ptr[6] ^ ptr[7]]) { | 1323 | if (parity[ptr[6] ^ ptr[7]]) { |
| 1273 | printk("sddr09: Bad parity in LBA for block %d" | 1324 | printk(KERN_WARNING |
| 1325 | "sddr09: Bad parity in LBA for block %d" | ||
| 1274 | " (%02X %02X)\n", i, ptr[6], ptr[7]); | 1326 | " (%02X %02X)\n", i, ptr[6], ptr[7]); |
| 1275 | info->pba_to_lba[i] = UNUSABLE; | 1327 | info->pba_to_lba[i] = UNUSABLE; |
| 1276 | continue; | 1328 | continue; |
| @@ -1289,7 +1341,8 @@ sddr09_read_map(struct us_data *us) { | |||
| 1289 | */ | 1341 | */ |
| 1290 | 1342 | ||
| 1291 | if (lba >= 1000) { | 1343 | if (lba >= 1000) { |
| 1292 | printk("sddr09: Bad low LBA %d for block %d\n", | 1344 | printk(KERN_WARNING |
| 1345 | "sddr09: Bad low LBA %d for block %d\n", | ||
| 1293 | lba, i); | 1346 | lba, i); |
| 1294 | goto possibly_erase; | 1347 | goto possibly_erase; |
| 1295 | } | 1348 | } |
| @@ -1297,7 +1350,8 @@ sddr09_read_map(struct us_data *us) { | |||
| 1297 | lba += 1000*(i/0x400); | 1350 | lba += 1000*(i/0x400); |
| 1298 | 1351 | ||
| 1299 | if (info->lba_to_pba[lba] != UNDEF) { | 1352 | if (info->lba_to_pba[lba] != UNDEF) { |
| 1300 | printk("sddr09: LBA %d seen for PBA %d and %d\n", | 1353 | printk(KERN_WARNING |
| 1354 | "sddr09: LBA %d seen for PBA %d and %d\n", | ||
| 1301 | lba, info->lba_to_pba[lba], i); | 1355 | lba, info->lba_to_pba[lba], i); |
| 1302 | goto possibly_erase; | 1356 | goto possibly_erase; |
| 1303 | } | 1357 | } |
| @@ -1399,7 +1453,7 @@ sddr09_common_init(struct us_data *us) { | |||
| 1399 | * unusual devices list but called from here then LUN 0 of the combo reader | 1453 | * unusual devices list but called from here then LUN 0 of the combo reader |
| 1400 | * is not recognized. But I do not know what precisely these calls do. | 1454 | * is not recognized. But I do not know what precisely these calls do. |
| 1401 | */ | 1455 | */ |
| 1402 | int | 1456 | static int |
| 1403 | usb_stor_sddr09_dpcm_init(struct us_data *us) { | 1457 | usb_stor_sddr09_dpcm_init(struct us_data *us) { |
| 1404 | int result; | 1458 | int result; |
| 1405 | unsigned char *data = us->iobuf; | 1459 | unsigned char *data = us->iobuf; |
| @@ -1449,7 +1503,7 @@ usb_stor_sddr09_dpcm_init(struct us_data *us) { | |||
| 1449 | /* | 1503 | /* |
| 1450 | * Transport for the Microtech DPCM-USB | 1504 | * Transport for the Microtech DPCM-USB |
| 1451 | */ | 1505 | */ |
| 1452 | int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us) | 1506 | static int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us) |
| 1453 | { | 1507 | { |
| 1454 | int ret; | 1508 | int ret; |
| 1455 | 1509 | ||
| @@ -1491,7 +1545,7 @@ int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
| 1491 | /* | 1545 | /* |
| 1492 | * Transport for the Sandisk SDDR-09 | 1546 | * Transport for the Sandisk SDDR-09 |
| 1493 | */ | 1547 | */ |
| 1494 | int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) | 1548 | static int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) |
| 1495 | { | 1549 | { |
| 1496 | static unsigned char sensekey = 0, sensecode = 0; | 1550 | static unsigned char sensekey = 0, sensecode = 0; |
| 1497 | static unsigned char havefakesense = 0; | 1551 | static unsigned char havefakesense = 0; |
| @@ -1690,7 +1744,60 @@ int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
| 1690 | /* | 1744 | /* |
| 1691 | * Initialization routine for the sddr09 subdriver | 1745 | * Initialization routine for the sddr09 subdriver |
| 1692 | */ | 1746 | */ |
| 1693 | int | 1747 | static int |
| 1694 | usb_stor_sddr09_init(struct us_data *us) { | 1748 | usb_stor_sddr09_init(struct us_data *us) { |
| 1695 | return sddr09_common_init(us); | 1749 | return sddr09_common_init(us); |
| 1696 | } | 1750 | } |
| 1751 | |||
| 1752 | static int sddr09_probe(struct usb_interface *intf, | ||
| 1753 | const struct usb_device_id *id) | ||
| 1754 | { | ||
| 1755 | struct us_data *us; | ||
| 1756 | int result; | ||
| 1757 | |||
| 1758 | result = usb_stor_probe1(&us, intf, id, | ||
| 1759 | (id - sddr09_usb_ids) + sddr09_unusual_dev_list); | ||
| 1760 | if (result) | ||
| 1761 | return result; | ||
| 1762 | |||
| 1763 | if (us->protocol == US_PR_DPCM_USB) { | ||
| 1764 | us->transport_name = "Control/Bulk-EUSB/SDDR09"; | ||
| 1765 | us->transport = dpcm_transport; | ||
| 1766 | us->transport_reset = usb_stor_CB_reset; | ||
| 1767 | us->max_lun = 1; | ||
| 1768 | } else { | ||
| 1769 | us->transport_name = "EUSB/SDDR09"; | ||
| 1770 | us->transport = sddr09_transport; | ||
| 1771 | us->transport_reset = usb_stor_CB_reset; | ||
| 1772 | us->max_lun = 0; | ||
| 1773 | } | ||
| 1774 | |||
| 1775 | result = usb_stor_probe2(us); | ||
| 1776 | return result; | ||
| 1777 | } | ||
| 1778 | |||
| 1779 | static struct usb_driver sddr09_driver = { | ||
| 1780 | .name = "ums-sddr09", | ||
| 1781 | .probe = sddr09_probe, | ||
| 1782 | .disconnect = usb_stor_disconnect, | ||
| 1783 | .suspend = usb_stor_suspend, | ||
| 1784 | .resume = usb_stor_resume, | ||
| 1785 | .reset_resume = usb_stor_reset_resume, | ||
| 1786 | .pre_reset = usb_stor_pre_reset, | ||
| 1787 | .post_reset = usb_stor_post_reset, | ||
| 1788 | .id_table = sddr09_usb_ids, | ||
| 1789 | .soft_unbind = 1, | ||
| 1790 | }; | ||
| 1791 | |||
| 1792 | static int __init sddr09_init(void) | ||
| 1793 | { | ||
| 1794 | return usb_register(&sddr09_driver); | ||
| 1795 | } | ||
| 1796 | |||
| 1797 | static void __exit sddr09_exit(void) | ||
| 1798 | { | ||
| 1799 | usb_deregister(&sddr09_driver); | ||
| 1800 | } | ||
| 1801 | |||
| 1802 | module_init(sddr09_init); | ||
| 1803 | module_exit(sddr09_exit); | ||
diff --git a/drivers/usb/storage/sddr09.h b/drivers/usb/storage/sddr09.h deleted file mode 100644 index b701172e12e3..000000000000 --- a/drivers/usb/storage/sddr09.h +++ /dev/null | |||
| @@ -1,38 +0,0 @@ | |||
| 1 | /* Driver for SanDisk SDDR-09 SmartMedia reader | ||
| 2 | * Header File | ||
| 3 | * | ||
| 4 | * Current development and maintenance by: | ||
| 5 | * (c) 2000 Robert Baruch (autophile@dol.net) | ||
| 6 | * (c) 2002 Andries Brouwer (aeb@cwi.nl) | ||
| 7 | * | ||
| 8 | * See sddr09.c for more explanation | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify it | ||
| 11 | * under the terms of the GNU General Public License as published by the | ||
| 12 | * Free Software Foundation; either version 2, or (at your option) any | ||
| 13 | * later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, but | ||
| 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 18 | * General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License along | ||
| 21 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 22 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 23 | */ | ||
| 24 | |||
| 25 | #ifndef _USB_SHUTTLE_EUSB_SDDR09_H | ||
| 26 | #define _USB_SHUTTLE_EUSB_SDDR09_H | ||
| 27 | |||
| 28 | /* Sandisk SDDR-09 stuff */ | ||
| 29 | |||
| 30 | extern int sddr09_transport(struct scsi_cmnd *srb, struct us_data *us); | ||
| 31 | extern int usb_stor_sddr09_init(struct us_data *us); | ||
| 32 | |||
| 33 | /* Microtech DPCM-USB stuff */ | ||
| 34 | |||
| 35 | extern int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us); | ||
| 36 | extern int usb_stor_sddr09_dpcm_init(struct us_data *us); | ||
| 37 | |||
| 38 | #endif | ||
diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c index 0d8df7577899..44dfed7754ed 100644 --- a/drivers/usb/storage/sddr55.c +++ b/drivers/usb/storage/sddr55.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | 24 | ||
| 25 | #include <linux/jiffies.h> | 25 | #include <linux/jiffies.h> |
| 26 | #include <linux/errno.h> | 26 | #include <linux/errno.h> |
| 27 | #include <linux/module.h> | ||
| 27 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
| 28 | 29 | ||
| 29 | #include <scsi/scsi.h> | 30 | #include <scsi/scsi.h> |
| @@ -33,7 +34,48 @@ | |||
| 33 | #include "transport.h" | 34 | #include "transport.h" |
| 34 | #include "protocol.h" | 35 | #include "protocol.h" |
| 35 | #include "debug.h" | 36 | #include "debug.h" |
| 36 | #include "sddr55.h" | 37 | |
| 38 | MODULE_DESCRIPTION("Driver for SanDisk SDDR-55 SmartMedia reader"); | ||
| 39 | MODULE_AUTHOR("Simon Munton"); | ||
| 40 | MODULE_LICENSE("GPL"); | ||
| 41 | |||
| 42 | /* | ||
| 43 | * The table of devices | ||
| 44 | */ | ||
| 45 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
| 46 | vendorName, productName, useProtocol, useTransport, \ | ||
| 47 | initFunction, flags) \ | ||
| 48 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
| 49 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
| 50 | |||
| 51 | struct usb_device_id sddr55_usb_ids[] = { | ||
| 52 | # include "unusual_sddr55.h" | ||
| 53 | { } /* Terminating entry */ | ||
| 54 | }; | ||
| 55 | MODULE_DEVICE_TABLE(usb, sddr55_usb_ids); | ||
| 56 | |||
| 57 | #undef UNUSUAL_DEV | ||
| 58 | |||
| 59 | /* | ||
| 60 | * The flags table | ||
| 61 | */ | ||
| 62 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
| 63 | vendor_name, product_name, use_protocol, use_transport, \ | ||
| 64 | init_function, Flags) \ | ||
| 65 | { \ | ||
| 66 | .vendorName = vendor_name, \ | ||
| 67 | .productName = product_name, \ | ||
| 68 | .useProtocol = use_protocol, \ | ||
| 69 | .useTransport = use_transport, \ | ||
| 70 | .initFunction = init_function, \ | ||
| 71 | } | ||
| 72 | |||
| 73 | static struct us_unusual_dev sddr55_unusual_dev_list[] = { | ||
| 74 | # include "unusual_sddr55.h" | ||
| 75 | { } /* Terminating entry */ | ||
| 76 | }; | ||
| 77 | |||
| 78 | #undef UNUSUAL_DEV | ||
| 37 | 79 | ||
| 38 | 80 | ||
| 39 | #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) | 81 | #define short_pack(lsb,msb) ( ((u16)(lsb)) | ( ((u16)(msb))<<8 ) ) |
| @@ -513,7 +555,8 @@ static int sddr55_read_deviceID(struct us_data *us, | |||
| 513 | } | 555 | } |
| 514 | 556 | ||
| 515 | 557 | ||
| 516 | int sddr55_reset(struct us_data *us) { | 558 | static int sddr55_reset(struct us_data *us) |
| 559 | { | ||
| 517 | return 0; | 560 | return 0; |
| 518 | } | 561 | } |
| 519 | 562 | ||
| @@ -703,7 +746,9 @@ static int sddr55_read_map(struct us_data *us) { | |||
| 703 | 746 | ||
| 704 | if (info->lba_to_pba[lba + zone * 1000] != NOT_ALLOCATED && | 747 | if (info->lba_to_pba[lba + zone * 1000] != NOT_ALLOCATED && |
| 705 | !info->force_read_only) { | 748 | !info->force_read_only) { |
| 706 | printk("sddr55: map inconsistency at LBA %04X\n", lba + zone * 1000); | 749 | printk(KERN_WARNING |
| 750 | "sddr55: map inconsistency at LBA %04X\n", | ||
| 751 | lba + zone * 1000); | ||
| 707 | info->force_read_only = 1; | 752 | info->force_read_only = 1; |
| 708 | } | 753 | } |
| 709 | 754 | ||
| @@ -732,7 +777,7 @@ static void sddr55_card_info_destructor(void *extra) { | |||
| 732 | /* | 777 | /* |
| 733 | * Transport for the Sandisk SDDR-55 | 778 | * Transport for the Sandisk SDDR-55 |
| 734 | */ | 779 | */ |
| 735 | int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us) | 780 | static int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us) |
| 736 | { | 781 | { |
| 737 | int result; | 782 | int result; |
| 738 | static unsigned char inquiry_response[8] = { | 783 | static unsigned char inquiry_response[8] = { |
| @@ -929,3 +974,49 @@ int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
| 929 | return USB_STOR_TRANSPORT_FAILED; // FIXME: sense buffer? | 974 | return USB_STOR_TRANSPORT_FAILED; // FIXME: sense buffer? |
| 930 | } | 975 | } |
| 931 | 976 | ||
| 977 | |||
| 978 | static int sddr55_probe(struct usb_interface *intf, | ||
| 979 | const struct usb_device_id *id) | ||
| 980 | { | ||
| 981 | struct us_data *us; | ||
| 982 | int result; | ||
| 983 | |||
| 984 | result = usb_stor_probe1(&us, intf, id, | ||
| 985 | (id - sddr55_usb_ids) + sddr55_unusual_dev_list); | ||
| 986 | if (result) | ||
| 987 | return result; | ||
| 988 | |||
| 989 | us->transport_name = "SDDR55"; | ||
| 990 | us->transport = sddr55_transport; | ||
| 991 | us->transport_reset = sddr55_reset; | ||
| 992 | us->max_lun = 0; | ||
| 993 | |||
| 994 | result = usb_stor_probe2(us); | ||
| 995 | return result; | ||
| 996 | } | ||
| 997 | |||
| 998 | static struct usb_driver sddr55_driver = { | ||
| 999 | .name = "ums-sddr55", | ||
| 1000 | .probe = sddr55_probe, | ||
| 1001 | .disconnect = usb_stor_disconnect, | ||
| 1002 | .suspend = usb_stor_suspend, | ||
| 1003 | .resume = usb_stor_resume, | ||
| 1004 | .reset_resume = usb_stor_reset_resume, | ||
| 1005 | .pre_reset = usb_stor_pre_reset, | ||
| 1006 | .post_reset = usb_stor_post_reset, | ||
| 1007 | .id_table = sddr55_usb_ids, | ||
| 1008 | .soft_unbind = 1, | ||
| 1009 | }; | ||
| 1010 | |||
| 1011 | static int __init sddr55_init(void) | ||
| 1012 | { | ||
| 1013 | return usb_register(&sddr55_driver); | ||
| 1014 | } | ||
| 1015 | |||
| 1016 | static void __exit sddr55_exit(void) | ||
| 1017 | { | ||
| 1018 | usb_deregister(&sddr55_driver); | ||
| 1019 | } | ||
| 1020 | |||
| 1021 | module_init(sddr55_init); | ||
| 1022 | module_exit(sddr55_exit); | ||
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index ae6d64810d2a..b62a28814ebe 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c | |||
| @@ -42,6 +42,7 @@ | |||
| 42 | */ | 42 | */ |
| 43 | 43 | ||
| 44 | #include <linux/errno.h> | 44 | #include <linux/errno.h> |
| 45 | #include <linux/module.h> | ||
| 45 | #include <linux/slab.h> | 46 | #include <linux/slab.h> |
| 46 | #include <linux/cdrom.h> | 47 | #include <linux/cdrom.h> |
| 47 | 48 | ||
| @@ -52,7 +53,100 @@ | |||
| 52 | #include "transport.h" | 53 | #include "transport.h" |
| 53 | #include "protocol.h" | 54 | #include "protocol.h" |
| 54 | #include "debug.h" | 55 | #include "debug.h" |
| 55 | #include "shuttle_usbat.h" | 56 | |
| 57 | MODULE_DESCRIPTION("Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable"); | ||
| 58 | MODULE_AUTHOR("Daniel Drake <dsd@gentoo.org>, Robert Baruch <autophile@starband.net>"); | ||
| 59 | MODULE_LICENSE("GPL"); | ||
| 60 | |||
| 61 | /* Supported device types */ | ||
| 62 | #define USBAT_DEV_HP8200 0x01 | ||
| 63 | #define USBAT_DEV_FLASH 0x02 | ||
| 64 | |||
| 65 | #define USBAT_EPP_PORT 0x10 | ||
| 66 | #define USBAT_EPP_REGISTER 0x30 | ||
| 67 | #define USBAT_ATA 0x40 | ||
| 68 | #define USBAT_ISA 0x50 | ||
| 69 | |||
| 70 | /* Commands (need to be logically OR'd with an access type */ | ||
| 71 | #define USBAT_CMD_READ_REG 0x00 | ||
| 72 | #define USBAT_CMD_WRITE_REG 0x01 | ||
| 73 | #define USBAT_CMD_READ_BLOCK 0x02 | ||
| 74 | #define USBAT_CMD_WRITE_BLOCK 0x03 | ||
| 75 | #define USBAT_CMD_COND_READ_BLOCK 0x04 | ||
| 76 | #define USBAT_CMD_COND_WRITE_BLOCK 0x05 | ||
| 77 | #define USBAT_CMD_WRITE_REGS 0x07 | ||
| 78 | |||
| 79 | /* Commands (these don't need an access type) */ | ||
| 80 | #define USBAT_CMD_EXEC_CMD 0x80 | ||
| 81 | #define USBAT_CMD_SET_FEAT 0x81 | ||
| 82 | #define USBAT_CMD_UIO 0x82 | ||
| 83 | |||
| 84 | /* Methods of accessing UIO register */ | ||
| 85 | #define USBAT_UIO_READ 1 | ||
| 86 | #define USBAT_UIO_WRITE 0 | ||
| 87 | |||
| 88 | /* Qualifier bits */ | ||
| 89 | #define USBAT_QUAL_FCQ 0x20 /* full compare */ | ||
| 90 | #define USBAT_QUAL_ALQ 0x10 /* auto load subcount */ | ||
| 91 | |||
| 92 | /* USBAT Flash Media status types */ | ||
| 93 | #define USBAT_FLASH_MEDIA_NONE 0 | ||
| 94 | #define USBAT_FLASH_MEDIA_CF 1 | ||
| 95 | |||
| 96 | /* USBAT Flash Media change types */ | ||
| 97 | #define USBAT_FLASH_MEDIA_SAME 0 | ||
| 98 | #define USBAT_FLASH_MEDIA_CHANGED 1 | ||
| 99 | |||
| 100 | /* USBAT ATA registers */ | ||
| 101 | #define USBAT_ATA_DATA 0x10 /* read/write data (R/W) */ | ||
| 102 | #define USBAT_ATA_FEATURES 0x11 /* set features (W) */ | ||
| 103 | #define USBAT_ATA_ERROR 0x11 /* error (R) */ | ||
| 104 | #define USBAT_ATA_SECCNT 0x12 /* sector count (R/W) */ | ||
| 105 | #define USBAT_ATA_SECNUM 0x13 /* sector number (R/W) */ | ||
| 106 | #define USBAT_ATA_LBA_ME 0x14 /* cylinder low (R/W) */ | ||
| 107 | #define USBAT_ATA_LBA_HI 0x15 /* cylinder high (R/W) */ | ||
| 108 | #define USBAT_ATA_DEVICE 0x16 /* head/device selection (R/W) */ | ||
| 109 | #define USBAT_ATA_STATUS 0x17 /* device status (R) */ | ||
| 110 | #define USBAT_ATA_CMD 0x17 /* device command (W) */ | ||
| 111 | #define USBAT_ATA_ALTSTATUS 0x0E /* status (no clear IRQ) (R) */ | ||
| 112 | |||
| 113 | /* USBAT User I/O Data registers */ | ||
| 114 | #define USBAT_UIO_EPAD 0x80 /* Enable Peripheral Control Signals */ | ||
| 115 | #define USBAT_UIO_CDT 0x40 /* Card Detect (Read Only) */ | ||
| 116 | /* CDT = ACKD & !UI1 & !UI0 */ | ||
| 117 | #define USBAT_UIO_1 0x20 /* I/O 1 */ | ||
| 118 | #define USBAT_UIO_0 0x10 /* I/O 0 */ | ||
| 119 | #define USBAT_UIO_EPP_ATA 0x08 /* 1=EPP mode, 0=ATA mode */ | ||
| 120 | #define USBAT_UIO_UI1 0x04 /* Input 1 */ | ||
| 121 | #define USBAT_UIO_UI0 0x02 /* Input 0 */ | ||
| 122 | #define USBAT_UIO_INTR_ACK 0x01 /* Interrupt (ATA/ISA)/Acknowledge (EPP) */ | ||
| 123 | |||
| 124 | /* USBAT User I/O Enable registers */ | ||
| 125 | #define USBAT_UIO_DRVRST 0x80 /* Reset Peripheral */ | ||
| 126 | #define USBAT_UIO_ACKD 0x40 /* Enable Card Detect */ | ||
| 127 | #define USBAT_UIO_OE1 0x20 /* I/O 1 set=output/clr=input */ | ||
| 128 | /* If ACKD=1, set OE1 to 1 also. */ | ||
| 129 | #define USBAT_UIO_OE0 0x10 /* I/O 0 set=output/clr=input */ | ||
| 130 | #define USBAT_UIO_ADPRST 0x01 /* Reset SCM chip */ | ||
| 131 | |||
| 132 | /* USBAT Features */ | ||
| 133 | #define USBAT_FEAT_ETEN 0x80 /* External trigger enable */ | ||
| 134 | #define USBAT_FEAT_U1 0x08 | ||
| 135 | #define USBAT_FEAT_U0 0x04 | ||
| 136 | #define USBAT_FEAT_ET1 0x02 | ||
| 137 | #define USBAT_FEAT_ET2 0x01 | ||
| 138 | |||
| 139 | struct usbat_info { | ||
| 140 | int devicetype; | ||
| 141 | |||
| 142 | /* Used for Flash readers only */ | ||
| 143 | unsigned long sectors; /* total sector count */ | ||
| 144 | unsigned long ssize; /* sector size in bytes */ | ||
| 145 | |||
| 146 | unsigned char sense_key; | ||
| 147 | unsigned long sense_asc; /* additional sense code */ | ||
| 148 | unsigned long sense_ascq; /* additional sense code qualifier */ | ||
| 149 | }; | ||
| 56 | 150 | ||
| 57 | #define short_pack(LSB,MSB) ( ((u16)(LSB)) | ( ((u16)(MSB))<<8 ) ) | 151 | #define short_pack(LSB,MSB) ( ((u16)(LSB)) | ( ((u16)(MSB))<<8 ) ) |
| 58 | #define LSB_of(s) ((s)&0xFF) | 152 | #define LSB_of(s) ((s)&0xFF) |
| @@ -63,6 +157,48 @@ static int transferred = 0; | |||
| 63 | static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us); | 157 | static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us); |
| 64 | static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us); | 158 | static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us); |
| 65 | 159 | ||
| 160 | static int init_usbat_cd(struct us_data *us); | ||
| 161 | static int init_usbat_flash(struct us_data *us); | ||
| 162 | |||
| 163 | |||
| 164 | /* | ||
| 165 | * The table of devices | ||
| 166 | */ | ||
| 167 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
| 168 | vendorName, productName, useProtocol, useTransport, \ | ||
| 169 | initFunction, flags) \ | ||
| 170 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
| 171 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
| 172 | |||
| 173 | struct usb_device_id usbat_usb_ids[] = { | ||
| 174 | # include "unusual_usbat.h" | ||
| 175 | { } /* Terminating entry */ | ||
| 176 | }; | ||
| 177 | MODULE_DEVICE_TABLE(usb, usbat_usb_ids); | ||
| 178 | |||
| 179 | #undef UNUSUAL_DEV | ||
| 180 | |||
| 181 | /* | ||
| 182 | * The flags table | ||
| 183 | */ | ||
| 184 | #define UNUSUAL_DEV(idVendor, idProduct, bcdDeviceMin, bcdDeviceMax, \ | ||
| 185 | vendor_name, product_name, use_protocol, use_transport, \ | ||
| 186 | init_function, Flags) \ | ||
| 187 | { \ | ||
| 188 | .vendorName = vendor_name, \ | ||
| 189 | .productName = product_name, \ | ||
| 190 | .useProtocol = use_protocol, \ | ||
| 191 | .useTransport = use_transport, \ | ||
| 192 | .initFunction = init_function, \ | ||
| 193 | } | ||
| 194 | |||
| 195 | static struct us_unusual_dev usbat_unusual_dev_list[] = { | ||
| 196 | # include "unusual_usbat.h" | ||
| 197 | { } /* Terminating entry */ | ||
| 198 | }; | ||
| 199 | |||
| 200 | #undef UNUSUAL_DEV | ||
| 201 | |||
| 66 | /* | 202 | /* |
| 67 | * Convenience function to produce an ATA read/write sectors command | 203 | * Convenience function to produce an ATA read/write sectors command |
| 68 | * Use cmd=0x20 for read, cmd=0x30 for write | 204 | * Use cmd=0x20 for read, cmd=0x30 for write |
| @@ -1684,37 +1820,61 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) | |||
| 1684 | return USB_STOR_TRANSPORT_FAILED; | 1820 | return USB_STOR_TRANSPORT_FAILED; |
| 1685 | } | 1821 | } |
| 1686 | 1822 | ||
| 1687 | int init_usbat_cd(struct us_data *us) | 1823 | static int init_usbat_cd(struct us_data *us) |
| 1688 | { | 1824 | { |
| 1689 | return init_usbat(us, USBAT_DEV_HP8200); | 1825 | return init_usbat(us, USBAT_DEV_HP8200); |
| 1690 | } | 1826 | } |
| 1691 | 1827 | ||
| 1692 | 1828 | static int init_usbat_flash(struct us_data *us) | |
| 1693 | int init_usbat_flash(struct us_data *us) | ||
| 1694 | { | 1829 | { |
| 1695 | return init_usbat(us, USBAT_DEV_FLASH); | 1830 | return init_usbat(us, USBAT_DEV_FLASH); |
| 1696 | } | 1831 | } |
| 1697 | 1832 | ||
| 1698 | int init_usbat_probe(struct us_data *us) | 1833 | static int usbat_probe(struct usb_interface *intf, |
| 1834 | const struct usb_device_id *id) | ||
| 1699 | { | 1835 | { |
| 1700 | return init_usbat(us, 0); | 1836 | struct us_data *us; |
| 1837 | int result; | ||
| 1838 | |||
| 1839 | result = usb_stor_probe1(&us, intf, id, | ||
| 1840 | (id - usbat_usb_ids) + usbat_unusual_dev_list); | ||
| 1841 | if (result) | ||
| 1842 | return result; | ||
| 1843 | |||
| 1844 | /* The actual transport will be determined later by the | ||
| 1845 | * initialization routine; this is just a placeholder. | ||
| 1846 | */ | ||
| 1847 | us->transport_name = "Shuttle USBAT"; | ||
| 1848 | us->transport = usbat_flash_transport; | ||
| 1849 | us->transport_reset = usb_stor_CB_reset; | ||
| 1850 | us->max_lun = 1; | ||
| 1851 | |||
| 1852 | result = usb_stor_probe2(us); | ||
| 1853 | return result; | ||
| 1701 | } | 1854 | } |
| 1702 | 1855 | ||
| 1703 | /* | 1856 | static struct usb_driver usbat_driver = { |
| 1704 | * Default transport function. Attempts to detect which transport function | 1857 | .name = "ums-usbat", |
| 1705 | * should be called, makes it the new default, and calls it. | 1858 | .probe = usbat_probe, |
| 1706 | * | 1859 | .disconnect = usb_stor_disconnect, |
| 1707 | * This function should never be called. Our usbat_init() function detects the | 1860 | .suspend = usb_stor_suspend, |
| 1708 | * device type and changes the us->transport ptr to the transport function | 1861 | .resume = usb_stor_resume, |
| 1709 | * relevant to the device. | 1862 | .reset_resume = usb_stor_reset_resume, |
| 1710 | * However, we'll support this impossible(?) case anyway. | 1863 | .pre_reset = usb_stor_pre_reset, |
| 1711 | */ | 1864 | .post_reset = usb_stor_post_reset, |
| 1712 | int usbat_transport(struct scsi_cmnd *srb, struct us_data *us) | 1865 | .id_table = usbat_usb_ids, |
| 1866 | .soft_unbind = 1, | ||
| 1867 | }; | ||
| 1868 | |||
| 1869 | static int __init usbat_init(void) | ||
| 1713 | { | 1870 | { |
| 1714 | struct usbat_info *info = (struct usbat_info*) (us->extra); | 1871 | return usb_register(&usbat_driver); |
| 1715 | 1872 | } | |
| 1716 | if (usbat_set_transport(us, info, 0)) | ||
| 1717 | return USB_STOR_TRANSPORT_ERROR; | ||
| 1718 | 1873 | ||
| 1719 | return us->transport(srb, us); | 1874 | static void __exit usbat_exit(void) |
| 1875 | { | ||
| 1876 | usb_deregister(&usbat_driver); | ||
| 1720 | } | 1877 | } |
| 1878 | |||
| 1879 | module_init(usbat_init); | ||
| 1880 | module_exit(usbat_exit); | ||
diff --git a/drivers/usb/storage/shuttle_usbat.h b/drivers/usb/storage/shuttle_usbat.h deleted file mode 100644 index d8bfc43e9044..000000000000 --- a/drivers/usb/storage/shuttle_usbat.h +++ /dev/null | |||
| @@ -1,123 +0,0 @@ | |||
| 1 | /* Driver for SCM Microsystems USB-ATAPI cable | ||
| 2 | * Header File | ||
| 3 | * | ||
| 4 | * Current development and maintenance by: | ||
| 5 | * (c) 2000 Robert Baruch (autophile@dol.net) | ||
| 6 | * (c) 2004, 2005 Daniel Drake <dsd@gentoo.org> | ||
| 7 | * | ||
| 8 | * See shuttle_usbat.c for more explanation | ||
| 9 | * | ||
| 10 | * This program is free software; you can redistribute it and/or modify it | ||
| 11 | * under the terms of the GNU General Public License as published by the | ||
| 12 | * Free Software Foundation; either version 2, or (at your option) any | ||
| 13 | * later version. | ||
| 14 | * | ||
| 15 | * This program is distributed in the hope that it will be useful, but | ||
| 16 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 18 | * General Public License for more details. | ||
| 19 | * | ||
| 20 | * You should have received a copy of the GNU General Public License along | ||
| 21 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 22 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 23 | */ | ||
| 24 | |||
| 25 | #ifndef _USB_SHUTTLE_USBAT_H | ||
| 26 | #define _USB_SHUTTLE_USBAT_H | ||
| 27 | |||
| 28 | /* Supported device types */ | ||
| 29 | #define USBAT_DEV_HP8200 0x01 | ||
| 30 | #define USBAT_DEV_FLASH 0x02 | ||
| 31 | |||
| 32 | #define USBAT_EPP_PORT 0x10 | ||
| 33 | #define USBAT_EPP_REGISTER 0x30 | ||
| 34 | #define USBAT_ATA 0x40 | ||
| 35 | #define USBAT_ISA 0x50 | ||
| 36 | |||
| 37 | /* Commands (need to be logically OR'd with an access type */ | ||
| 38 | #define USBAT_CMD_READ_REG 0x00 | ||
| 39 | #define USBAT_CMD_WRITE_REG 0x01 | ||
| 40 | #define USBAT_CMD_READ_BLOCK 0x02 | ||
| 41 | #define USBAT_CMD_WRITE_BLOCK 0x03 | ||
| 42 | #define USBAT_CMD_COND_READ_BLOCK 0x04 | ||
| 43 | #define USBAT_CMD_COND_WRITE_BLOCK 0x05 | ||
| 44 | #define USBAT_CMD_WRITE_REGS 0x07 | ||
| 45 | |||
| 46 | /* Commands (these don't need an access type) */ | ||
| 47 | #define USBAT_CMD_EXEC_CMD 0x80 | ||
| 48 | #define USBAT_CMD_SET_FEAT 0x81 | ||
| 49 | #define USBAT_CMD_UIO 0x82 | ||
| 50 | |||
| 51 | /* Methods of accessing UIO register */ | ||
| 52 | #define USBAT_UIO_READ 1 | ||
| 53 | #define USBAT_UIO_WRITE 0 | ||
| 54 | |||
| 55 | /* Qualifier bits */ | ||
| 56 | #define USBAT_QUAL_FCQ 0x20 /* full compare */ | ||
| 57 | #define USBAT_QUAL_ALQ 0x10 /* auto load subcount */ | ||
| 58 | |||
| 59 | /* USBAT Flash Media status types */ | ||
| 60 | #define USBAT_FLASH_MEDIA_NONE 0 | ||
| 61 | #define USBAT_FLASH_MEDIA_CF 1 | ||
| 62 | |||
| 63 | /* USBAT Flash Media change types */ | ||
| 64 | #define USBAT_FLASH_MEDIA_SAME 0 | ||
| 65 | #define USBAT_FLASH_MEDIA_CHANGED 1 | ||
| 66 | |||
| 67 | /* USBAT ATA registers */ | ||
| 68 | #define USBAT_ATA_DATA 0x10 /* read/write data (R/W) */ | ||
| 69 | #define USBAT_ATA_FEATURES 0x11 /* set features (W) */ | ||
| 70 | #define USBAT_ATA_ERROR 0x11 /* error (R) */ | ||
| 71 | #define USBAT_ATA_SECCNT 0x12 /* sector count (R/W) */ | ||
| 72 | #define USBAT_ATA_SECNUM 0x13 /* sector number (R/W) */ | ||
| 73 | #define USBAT_ATA_LBA_ME 0x14 /* cylinder low (R/W) */ | ||
| 74 | #define USBAT_ATA_LBA_HI 0x15 /* cylinder high (R/W) */ | ||
| 75 | #define USBAT_ATA_DEVICE 0x16 /* head/device selection (R/W) */ | ||
| 76 | #define USBAT_ATA_STATUS 0x17 /* device status (R) */ | ||
| 77 | #define USBAT_ATA_CMD 0x17 /* device command (W) */ | ||
| 78 | #define USBAT_ATA_ALTSTATUS 0x0E /* status (no clear IRQ) (R) */ | ||
| 79 | |||
| 80 | /* USBAT User I/O Data registers */ | ||
| 81 | #define USBAT_UIO_EPAD 0x80 /* Enable Peripheral Control Signals */ | ||
| 82 | #define USBAT_UIO_CDT 0x40 /* Card Detect (Read Only) */ | ||
| 83 | /* CDT = ACKD & !UI1 & !UI0 */ | ||
| 84 | #define USBAT_UIO_1 0x20 /* I/O 1 */ | ||
| 85 | #define USBAT_UIO_0 0x10 /* I/O 0 */ | ||
| 86 | #define USBAT_UIO_EPP_ATA 0x08 /* 1=EPP mode, 0=ATA mode */ | ||
| 87 | #define USBAT_UIO_UI1 0x04 /* Input 1 */ | ||
| 88 | #define USBAT_UIO_UI0 0x02 /* Input 0 */ | ||
| 89 | #define USBAT_UIO_INTR_ACK 0x01 /* Interrupt (ATA/ISA)/Acknowledge (EPP) */ | ||
| 90 | |||
| 91 | /* USBAT User I/O Enable registers */ | ||
| 92 | #define USBAT_UIO_DRVRST 0x80 /* Reset Peripheral */ | ||
| 93 | #define USBAT_UIO_ACKD 0x40 /* Enable Card Detect */ | ||
| 94 | #define USBAT_UIO_OE1 0x20 /* I/O 1 set=output/clr=input */ | ||
| 95 | /* If ACKD=1, set OE1 to 1 also. */ | ||
| 96 | #define USBAT_UIO_OE0 0x10 /* I/O 0 set=output/clr=input */ | ||
| 97 | #define USBAT_UIO_ADPRST 0x01 /* Reset SCM chip */ | ||
| 98 | |||
| 99 | /* USBAT Features */ | ||
| 100 | #define USBAT_FEAT_ETEN 0x80 /* External trigger enable */ | ||
| 101 | #define USBAT_FEAT_U1 0x08 | ||
| 102 | #define USBAT_FEAT_U0 0x04 | ||
| 103 | #define USBAT_FEAT_ET1 0x02 | ||
| 104 | #define USBAT_FEAT_ET2 0x01 | ||
| 105 | |||
| 106 | extern int usbat_transport(struct scsi_cmnd *srb, struct us_data *us); | ||
| 107 | extern int init_usbat_cd(struct us_data *us); | ||
| 108 | extern int init_usbat_flash(struct us_data *us); | ||
| 109 | extern int init_usbat_probe(struct us_data *us); | ||
| 110 | |||
| 111 | struct usbat_info { | ||
| 112 | int devicetype; | ||
| 113 | |||
| 114 | /* Used for Flash readers only */ | ||
| 115 | unsigned long sectors; /* total sector count */ | ||
| 116 | unsigned long ssize; /* sector size in bytes */ | ||
| 117 | |||
| 118 | unsigned char sense_key; | ||
| 119 | unsigned long sense_asc; /* additional sense code */ | ||
| 120 | unsigned long sense_ascq; /* additional sense code qualifier */ | ||
| 121 | }; | ||
| 122 | |||
| 123 | #endif | ||
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index fb65d221cedf..d48c8553539d 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c | |||
| @@ -220,6 +220,7 @@ int usb_stor_control_msg(struct us_data *us, unsigned int pipe, | |||
| 220 | status = us->current_urb->actual_length; | 220 | status = us->current_urb->actual_length; |
| 221 | return status; | 221 | return status; |
| 222 | } | 222 | } |
| 223 | EXPORT_SYMBOL_GPL(usb_stor_control_msg); | ||
| 223 | 224 | ||
| 224 | /* This is a version of usb_clear_halt() that allows early termination and | 225 | /* This is a version of usb_clear_halt() that allows early termination and |
| 225 | * doesn't read the status from the device -- this is because some devices | 226 | * doesn't read the status from the device -- this is because some devices |
| @@ -254,6 +255,7 @@ int usb_stor_clear_halt(struct us_data *us, unsigned int pipe) | |||
| 254 | US_DEBUGP("%s: result = %d\n", __func__, result); | 255 | US_DEBUGP("%s: result = %d\n", __func__, result); |
| 255 | return result; | 256 | return result; |
| 256 | } | 257 | } |
| 258 | EXPORT_SYMBOL_GPL(usb_stor_clear_halt); | ||
| 257 | 259 | ||
| 258 | 260 | ||
| 259 | /* | 261 | /* |
| @@ -352,6 +354,7 @@ int usb_stor_ctrl_transfer(struct us_data *us, unsigned int pipe, | |||
| 352 | return interpret_urb_result(us, pipe, size, result, | 354 | return interpret_urb_result(us, pipe, size, result, |
| 353 | us->current_urb->actual_length); | 355 | us->current_urb->actual_length); |
| 354 | } | 356 | } |
| 357 | EXPORT_SYMBOL_GPL(usb_stor_ctrl_transfer); | ||
| 355 | 358 | ||
| 356 | /* | 359 | /* |
| 357 | * Receive one interrupt buffer, without timeouts, but allowing early | 360 | * Receive one interrupt buffer, without timeouts, but allowing early |
| @@ -407,6 +410,7 @@ int usb_stor_bulk_transfer_buf(struct us_data *us, unsigned int pipe, | |||
| 407 | return interpret_urb_result(us, pipe, length, result, | 410 | return interpret_urb_result(us, pipe, length, result, |
| 408 | us->current_urb->actual_length); | 411 | us->current_urb->actual_length); |
| 409 | } | 412 | } |
| 413 | EXPORT_SYMBOL_GPL(usb_stor_bulk_transfer_buf); | ||
| 410 | 414 | ||
| 411 | /* | 415 | /* |
| 412 | * Transfer a scatter-gather list via bulk transfer | 416 | * Transfer a scatter-gather list via bulk transfer |
| @@ -474,6 +478,7 @@ int usb_stor_bulk_srb(struct us_data* us, unsigned int pipe, | |||
| 474 | scsi_set_resid(srb, scsi_bufflen(srb) - partial); | 478 | scsi_set_resid(srb, scsi_bufflen(srb) - partial); |
| 475 | return result; | 479 | return result; |
| 476 | } | 480 | } |
| 481 | EXPORT_SYMBOL_GPL(usb_stor_bulk_srb); | ||
| 477 | 482 | ||
| 478 | /* | 483 | /* |
| 479 | * Transfer an entire SCSI command's worth of data payload over the bulk | 484 | * Transfer an entire SCSI command's worth of data payload over the bulk |
| @@ -509,6 +514,7 @@ int usb_stor_bulk_transfer_sg(struct us_data* us, unsigned int pipe, | |||
| 509 | *residual = length_left; | 514 | *residual = length_left; |
| 510 | return result; | 515 | return result; |
| 511 | } | 516 | } |
| 517 | EXPORT_SYMBOL_GPL(usb_stor_bulk_transfer_sg); | ||
| 512 | 518 | ||
| 513 | /*********************************************************************** | 519 | /*********************************************************************** |
| 514 | * Transport routines | 520 | * Transport routines |
| @@ -940,6 +946,7 @@ int usb_stor_CB_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
| 940 | usb_stor_clear_halt(us, pipe); | 946 | usb_stor_clear_halt(us, pipe); |
| 941 | return USB_STOR_TRANSPORT_FAILED; | 947 | return USB_STOR_TRANSPORT_FAILED; |
| 942 | } | 948 | } |
| 949 | EXPORT_SYMBOL_GPL(usb_stor_CB_transport); | ||
| 943 | 950 | ||
| 944 | /* | 951 | /* |
| 945 | * Bulk only transport | 952 | * Bulk only transport |
| @@ -1156,6 +1163,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
| 1156 | /* we should never get here, but if we do, we're in trouble */ | 1163 | /* we should never get here, but if we do, we're in trouble */ |
| 1157 | return USB_STOR_TRANSPORT_ERROR; | 1164 | return USB_STOR_TRANSPORT_ERROR; |
| 1158 | } | 1165 | } |
| 1166 | EXPORT_SYMBOL_GPL(usb_stor_Bulk_transport); | ||
| 1159 | 1167 | ||
| 1160 | /*********************************************************************** | 1168 | /*********************************************************************** |
| 1161 | * Reset routines | 1169 | * Reset routines |
| @@ -1230,6 +1238,7 @@ int usb_stor_CB_reset(struct us_data *us) | |||
| 1230 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 1238 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
| 1231 | 0, us->ifnum, us->iobuf, CB_RESET_CMD_SIZE); | 1239 | 0, us->ifnum, us->iobuf, CB_RESET_CMD_SIZE); |
| 1232 | } | 1240 | } |
| 1241 | EXPORT_SYMBOL_GPL(usb_stor_CB_reset); | ||
| 1233 | 1242 | ||
| 1234 | /* This issues a Bulk-only Reset to the device in question, including | 1243 | /* This issues a Bulk-only Reset to the device in question, including |
| 1235 | * clearing the subsequent endpoint halts that may occur. | 1244 | * clearing the subsequent endpoint halts that may occur. |
| @@ -1242,6 +1251,7 @@ int usb_stor_Bulk_reset(struct us_data *us) | |||
| 1242 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 1251 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
| 1243 | 0, us->ifnum, NULL, 0); | 1252 | 0, us->ifnum, NULL, 0); |
| 1244 | } | 1253 | } |
| 1254 | EXPORT_SYMBOL_GPL(usb_stor_Bulk_reset); | ||
| 1245 | 1255 | ||
| 1246 | /* Issue a USB port reset to the device. The caller must not hold | 1256 | /* Issue a USB port reset to the device. The caller must not hold |
| 1247 | * us->dev_mutex. | 1257 | * us->dev_mutex. |
diff --git a/drivers/usb/storage/freecom.h b/drivers/usb/storage/unusual_alauda.h index 20d0fe6ba0c8..8c412f885dd2 100644 --- a/drivers/usb/storage/freecom.h +++ b/drivers/usb/storage/unusual_alauda.h | |||
| @@ -1,13 +1,4 @@ | |||
| 1 | /* Driver for Freecom USB/IDE adaptor | 1 | /* Unusual Devices File for the Alauda-based card readers |
| 2 | * | ||
| 3 | * Freecom v0.1: | ||
| 4 | * | ||
| 5 | * First release | ||
| 6 | * | ||
| 7 | * Current development and maintenance by: | ||
| 8 | * (c) 2000 David Brown <usb-storage@davidb.org> | ||
| 9 | * | ||
| 10 | * See freecom.c for more explanation | ||
| 11 | * | 2 | * |
| 12 | * This program is free software; you can redistribute it and/or modify it | 3 | * This program is free software; you can redistribute it and/or modify it |
| 13 | * under the terms of the GNU General Public License as published by the | 4 | * under the terms of the GNU General Public License as published by the |
| @@ -24,11 +15,17 @@ | |||
| 24 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 15 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
| 25 | */ | 16 | */ |
| 26 | 17 | ||
| 27 | #ifndef _FREECOM_USB_H | 18 | #if defined(CONFIG_USB_STORAGE_ALAUDA) || \ |
| 28 | #define _FREECOM_USB_H | 19 | defined(CONFIG_USB_STORAGE_ALAUDA_MODULE) |
| 20 | |||
| 21 | UNUSUAL_DEV( 0x0584, 0x0008, 0x0102, 0x0102, | ||
| 22 | "Fujifilm", | ||
| 23 | "DPC-R1 (Alauda)", | ||
| 24 | US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0), | ||
| 29 | 25 | ||
| 30 | extern int freecom_transport(struct scsi_cmnd *srb, struct us_data *us); | 26 | UNUSUAL_DEV( 0x07b4, 0x010a, 0x0102, 0x0102, |
| 31 | extern int usb_stor_freecom_reset(struct us_data *us); | 27 | "Olympus", |
| 32 | extern int freecom_init (struct us_data *us); | 28 | "MAUSB-10 (Alauda)", |
| 29 | US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0), | ||
| 33 | 30 | ||
| 34 | #endif | 31 | #endif /* defined(CONFIG_USB_STORAGE_ALAUDA) || ... */ |
diff --git a/drivers/usb/storage/unusual_cypress.h b/drivers/usb/storage/unusual_cypress.h new file mode 100644 index 000000000000..44be6d75dab6 --- /dev/null +++ b/drivers/usb/storage/unusual_cypress.h | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | /* Unusual Devices File for devices based on the Cypress USB/ATA bridge | ||
| 2 | * with support for ATACB | ||
| 3 | * | ||
| 4 | * This program is free software; you can redistribute it and/or modify it | ||
| 5 | * under the terms of the GNU General Public License as published by the | ||
| 6 | * Free Software Foundation; either version 2, or (at your option) any | ||
| 7 | * later version. | ||
| 8 | * | ||
| 9 | * This program is distributed in the hope that it will be useful, but | ||
| 10 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 12 | * General Public License for more details. | ||
| 13 | * | ||
| 14 | * You should have received a copy of the GNU General Public License along | ||
| 15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 16 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 17 | */ | ||
| 18 | |||
| 19 | #if defined(CONFIG_USB_STORAGE_CYPRESS_ATACB) || \ | ||
| 20 | defined(CONFIG_USB_STORAGE_CYPRESS_ATACB_MODULE) | ||
| 21 | |||
| 22 | /* CY7C68300 : support atacb */ | ||
| 23 | UNUSUAL_DEV( 0x04b4, 0x6830, 0x0000, 0x9999, | ||
| 24 | "Cypress", | ||
| 25 | "Cypress AT2LP", | ||
| 26 | US_SC_CYP_ATACB, US_PR_DEVICE, NULL, 0), | ||
| 27 | |||
| 28 | /* CY7C68310 : support atacb and atacb2 */ | ||
| 29 | UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999, | ||
| 30 | "Cypress", | ||
| 31 | "Cypress ISD-300LP", | ||
| 32 | US_SC_CYP_ATACB, US_PR_DEVICE, NULL, 0), | ||
| 33 | |||
| 34 | #endif /* defined(CONFIG_USB_STORAGE_CYPRESS_ATACB) || ... */ | ||
diff --git a/drivers/usb/storage/unusual_datafab.h b/drivers/usb/storage/unusual_datafab.h new file mode 100644 index 000000000000..c9298ce9f223 --- /dev/null +++ b/drivers/usb/storage/unusual_datafab.h | |||
| @@ -0,0 +1,98 @@ | |||
| 1 | /* Unusual Devices File for the Datafab USB Compact Flash reader | ||
| 2 | * | ||
| 3 | * This program is free software; you can redistribute it and/or modify it | ||
| 4 | * under the terms of the GNU General Public License as published by the | ||
| 5 | * Free Software Foundation; either version 2, or (at your option) any | ||
| 6 | * later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, but | ||
| 9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 11 | * General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License along | ||
| 14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 15 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #if defined(CONFIG_USB_STORAGE_DATAFAB) || \ | ||
| 19 | defined(CONFIG_USB_STORAGE_DATAFAB_MODULE) | ||
| 20 | |||
| 21 | UNUSUAL_DEV( 0x07c4, 0xa000, 0x0000, 0x0015, | ||
| 22 | "Datafab", | ||
| 23 | "MDCFE-B USB CF Reader", | ||
| 24 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
| 25 | 0), | ||
| 26 | |||
| 27 | /* | ||
| 28 | * The following Datafab-based devices may or may not work | ||
| 29 | * using the current driver...the 0xffff is arbitrary since I | ||
| 30 | * don't know what device versions exist for these guys. | ||
| 31 | * | ||
| 32 | * The 0xa003 and 0xa004 devices in particular I'm curious about. | ||
| 33 | * I'm told they exist but so far nobody has come forward to say that | ||
| 34 | * they work with this driver. Given the success we've had getting | ||
| 35 | * other Datafab-based cards operational with this driver, I've decided | ||
| 36 | * to leave these two devices in the list. | ||
| 37 | */ | ||
| 38 | UNUSUAL_DEV( 0x07c4, 0xa001, 0x0000, 0xffff, | ||
| 39 | "SIIG/Datafab", | ||
| 40 | "SIIG/Datafab Memory Stick+CF Reader/Writer", | ||
| 41 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
| 42 | 0), | ||
| 43 | |||
| 44 | /* Reported by Josef Reisinger <josef.reisinger@netcologne.de> */ | ||
| 45 | UNUSUAL_DEV( 0x07c4, 0xa002, 0x0000, 0xffff, | ||
| 46 | "Datafab/Unknown", | ||
| 47 | "MD2/MD3 Disk enclosure", | ||
| 48 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
| 49 | US_FL_SINGLE_LUN), | ||
| 50 | |||
| 51 | UNUSUAL_DEV( 0x07c4, 0xa003, 0x0000, 0xffff, | ||
| 52 | "Datafab/Unknown", | ||
| 53 | "Datafab-based Reader", | ||
| 54 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
| 55 | 0), | ||
| 56 | |||
| 57 | UNUSUAL_DEV( 0x07c4, 0xa004, 0x0000, 0xffff, | ||
| 58 | "Datafab/Unknown", | ||
| 59 | "Datafab-based Reader", | ||
| 60 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
| 61 | 0), | ||
| 62 | |||
| 63 | UNUSUAL_DEV( 0x07c4, 0xa005, 0x0000, 0xffff, | ||
| 64 | "PNY/Datafab", | ||
| 65 | "PNY/Datafab CF+SM Reader", | ||
| 66 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
| 67 | 0), | ||
| 68 | |||
| 69 | UNUSUAL_DEV( 0x07c4, 0xa006, 0x0000, 0xffff, | ||
| 70 | "Simple Tech/Datafab", | ||
| 71 | "Simple Tech/Datafab CF+SM Reader", | ||
| 72 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
| 73 | 0), | ||
| 74 | |||
| 75 | /* Submitted by Olaf Hering <olh@suse.de> */ | ||
| 76 | UNUSUAL_DEV( 0x07c4, 0xa109, 0x0000, 0xffff, | ||
| 77 | "Datafab Systems, Inc.", | ||
| 78 | "USB to CF + SM Combo (LC1)", | ||
| 79 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
| 80 | 0), | ||
| 81 | |||
| 82 | /* Reported by Felix Moeller <felix@derklecks.de> | ||
| 83 | * in Germany this is sold by Hama with the productnumber 46952 | ||
| 84 | * as "DualSlot CompactFlash(TM) & MStick Drive USB" | ||
| 85 | */ | ||
| 86 | UNUSUAL_DEV( 0x07c4, 0xa10b, 0x0000, 0xffff, | ||
| 87 | "DataFab Systems Inc.", | ||
| 88 | "USB CF+MS", | ||
| 89 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
| 90 | 0), | ||
| 91 | |||
| 92 | UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff, | ||
| 93 | "Acomdata", | ||
| 94 | "CF", | ||
| 95 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
| 96 | US_FL_SINGLE_LUN), | ||
| 97 | |||
| 98 | #endif /* defined(CONFIG_USB_STORAGE_DATAFAB) || ... */ | ||
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index cfde74a6faa3..1c1f643e8a78 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
| @@ -53,6 +53,11 @@ | |||
| 53 | * as opposed to devices that do something strangely or wrongly. | 53 | * as opposed to devices that do something strangely or wrongly. |
| 54 | */ | 54 | */ |
| 55 | 55 | ||
| 56 | #if !defined(CONFIG_USB_STORAGE_SDDR09) && \ | ||
| 57 | !defined(CONFIG_USB_STORAGE_SDDR09_MODULE) | ||
| 58 | #define NO_SDDR09 | ||
| 59 | #endif | ||
| 60 | |||
| 56 | /* patch submitted by Vivian Bregier <Vivian.Bregier@imag.fr> | 61 | /* patch submitted by Vivian Bregier <Vivian.Bregier@imag.fr> |
| 57 | */ | 62 | */ |
| 58 | UNUSUAL_DEV( 0x03eb, 0x2002, 0x0100, 0x0100, | 63 | UNUSUAL_DEV( 0x03eb, 0x2002, 0x0100, 0x0100, |
| @@ -80,18 +85,6 @@ UNUSUAL_DEV( 0x03f0, 0x0107, 0x0200, 0x0200, | |||
| 80 | "CD-Writer+", | 85 | "CD-Writer+", |
| 81 | US_SC_8070, US_PR_CB, NULL, 0), | 86 | US_SC_8070, US_PR_CB, NULL, 0), |
| 82 | 87 | ||
| 83 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
| 84 | UNUSUAL_DEV( 0x03f0, 0x0207, 0x0001, 0x0001, | ||
| 85 | "HP", | ||
| 86 | "CD-Writer+ 8200e", | ||
| 87 | US_SC_8070, US_PR_USBAT, init_usbat_cd, 0), | ||
| 88 | |||
| 89 | UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001, | ||
| 90 | "HP", | ||
| 91 | "CD-Writer+ CD-4e", | ||
| 92 | US_SC_8070, US_PR_USBAT, init_usbat_cd, 0), | ||
| 93 | #endif | ||
| 94 | |||
| 95 | /* Reported by Ben Efros <ben@pc-doctor.com> */ | 88 | /* Reported by Ben Efros <ben@pc-doctor.com> */ |
| 96 | UNUSUAL_DEV( 0x03f0, 0x070c, 0x0000, 0x0000, | 89 | UNUSUAL_DEV( 0x03f0, 0x070c, 0x0000, 0x0000, |
| 97 | "HP", | 90 | "HP", |
| @@ -246,12 +239,7 @@ UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210, | |||
| 246 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 239 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
| 247 | US_FL_SINGLE_LUN ), | 240 | US_FL_SINGLE_LUN ), |
| 248 | 241 | ||
| 249 | #ifdef CONFIG_USB_STORAGE_SDDR09 | 242 | #ifdef NO_SDDR09 |
| 250 | UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100, | ||
| 251 | "Microtech", | ||
| 252 | "CameraMate (DPCM_USB)", | ||
| 253 | US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ), | ||
| 254 | #else | ||
| 255 | UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100, | 243 | UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100, |
| 256 | "Microtech", | 244 | "Microtech", |
| 257 | "CameraMate", | 245 | "CameraMate", |
| @@ -288,13 +276,6 @@ UNUSUAL_DEV( 0x0457, 0x0151, 0x0100, 0x0100, | |||
| 288 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 276 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
| 289 | US_FL_NOT_LOCKABLE ), | 277 | US_FL_NOT_LOCKABLE ), |
| 290 | 278 | ||
| 291 | #ifdef CONFIG_USB_STORAGE_KARMA | ||
| 292 | UNUSUAL_DEV( 0x045a, 0x5210, 0x0101, 0x0101, | ||
| 293 | "Rio", | ||
| 294 | "Rio Karma", | ||
| 295 | US_SC_SCSI, US_PR_KARMA, rio_karma_init, 0), | ||
| 296 | #endif | ||
| 297 | |||
| 298 | /* Reported by Tamas Kerecsen <kerecsen@bigfoot.com> | 279 | /* Reported by Tamas Kerecsen <kerecsen@bigfoot.com> |
| 299 | * Obviously the PROM has not been customized by the VAR; | 280 | * Obviously the PROM has not been customized by the VAR; |
| 300 | * the Vendor and Product string descriptors are: | 281 | * the Vendor and Product string descriptors are: |
| @@ -375,22 +356,6 @@ UNUSUAL_DEV( 0x04b3, 0x4001, 0x0110, 0x0110, | |||
| 375 | US_SC_DEVICE, US_PR_CB, NULL, | 356 | US_SC_DEVICE, US_PR_CB, NULL, |
| 376 | US_FL_MAX_SECTORS_MIN), | 357 | US_FL_MAX_SECTORS_MIN), |
| 377 | 358 | ||
| 378 | #ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB | ||
| 379 | /* CY7C68300 : support atacb */ | ||
| 380 | UNUSUAL_DEV( 0x04b4, 0x6830, 0x0000, 0x9999, | ||
| 381 | "Cypress", | ||
| 382 | "Cypress AT2LP", | ||
| 383 | US_SC_CYP_ATACB, US_PR_DEVICE, NULL, | ||
| 384 | 0), | ||
| 385 | |||
| 386 | /* CY7C68310 : support atacb and atacb2 */ | ||
| 387 | UNUSUAL_DEV( 0x04b4, 0x6831, 0x0000, 0x9999, | ||
| 388 | "Cypress", | ||
| 389 | "Cypress ISD-300LP", | ||
| 390 | US_SC_CYP_ATACB, US_PR_DEVICE, NULL, | ||
| 391 | 0), | ||
| 392 | #endif | ||
| 393 | |||
| 394 | /* Reported by Simon Levitt <simon@whattf.com> | 359 | /* Reported by Simon Levitt <simon@whattf.com> |
| 395 | * This entry needs Sub and Proto fields */ | 360 | * This entry needs Sub and Proto fields */ |
| 396 | UNUSUAL_DEV( 0x04b8, 0x0601, 0x0100, 0x0100, | 361 | UNUSUAL_DEV( 0x04b8, 0x0601, 0x0100, 0x0100, |
| @@ -467,20 +432,7 @@ UNUSUAL_DEV( 0x04e6, 0x0002, 0x0100, 0x0100, | |||
| 467 | US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init, | 432 | US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init, |
| 468 | US_FL_SCM_MULT_TARG ), | 433 | US_FL_SCM_MULT_TARG ), |
| 469 | 434 | ||
| 470 | #ifdef CONFIG_USB_STORAGE_SDDR09 | 435 | #ifdef NO_SDDR09 |
| 471 | UNUSUAL_DEV( 0x04e6, 0x0003, 0x0000, 0x9999, | ||
| 472 | "Sandisk", | ||
| 473 | "ImageMate SDDR09", | ||
| 474 | US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init, | ||
| 475 | 0), | ||
| 476 | |||
| 477 | /* This entry is from Andries.Brouwer@cwi.nl */ | ||
| 478 | UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208, | ||
| 479 | "SCM Microsystems", | ||
| 480 | "eUSB SmartMedia / CompactFlash Adapter", | ||
| 481 | US_SC_SCSI, US_PR_DPCM_USB, usb_stor_sddr09_dpcm_init, | ||
| 482 | 0), | ||
| 483 | #else | ||
| 484 | UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208, | 436 | UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208, |
| 485 | "SCM Microsystems", | 437 | "SCM Microsystems", |
| 486 | "eUSB CompactFlash Adapter", | 438 | "eUSB CompactFlash Adapter", |
| @@ -535,14 +487,6 @@ UNUSUAL_DEV( 0x04e6, 0x0101, 0x0200, 0x0200, | |||
| 535 | "CD-RW Device", | 487 | "CD-RW Device", |
| 536 | US_SC_8020, US_PR_CB, NULL, 0), | 488 | US_SC_8020, US_PR_CB, NULL, 0), |
| 537 | 489 | ||
| 538 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
| 539 | UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999, | ||
| 540 | "Shuttle/SCM", | ||
| 541 | "USBAT-02", | ||
| 542 | US_SC_SCSI, US_PR_USBAT, init_usbat_flash, | ||
| 543 | US_FL_SINGLE_LUN), | ||
| 544 | #endif | ||
| 545 | |||
| 546 | /* Reported by Dmitry Khlystov <adminimus@gmail.com> */ | 490 | /* Reported by Dmitry Khlystov <adminimus@gmail.com> */ |
| 547 | UNUSUAL_DEV( 0x04e8, 0x507c, 0x0220, 0x0220, | 491 | UNUSUAL_DEV( 0x04e8, 0x507c, 0x0220, 0x0220, |
| 548 | "Samsung", | 492 | "Samsung", |
| @@ -645,14 +589,6 @@ UNUSUAL_DEV( 0x054c, 0x0025, 0x0100, 0x0100, | |||
| 645 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 589 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
| 646 | US_FL_SINGLE_LUN ), | 590 | US_FL_SINGLE_LUN ), |
| 647 | 591 | ||
| 648 | #ifdef CONFIG_USB_STORAGE_ISD200 | ||
| 649 | UNUSUAL_DEV( 0x054c, 0x002b, 0x0100, 0x0110, | ||
| 650 | "Sony", | ||
| 651 | "Portable USB Harddrive V2", | ||
| 652 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
| 653 | 0 ), | ||
| 654 | #endif | ||
| 655 | |||
| 656 | /* Submitted by Olaf Hering, <olh@suse.de> SuSE Bugzilla #49049 */ | 592 | /* Submitted by Olaf Hering, <olh@suse.de> SuSE Bugzilla #49049 */ |
| 657 | UNUSUAL_DEV( 0x054c, 0x002c, 0x0501, 0x2000, | 593 | UNUSUAL_DEV( 0x054c, 0x002c, 0x0501, 0x2000, |
| 658 | "Sony", | 594 | "Sony", |
| @@ -749,13 +685,6 @@ UNUSUAL_DEV( 0x057b, 0x0022, 0x0000, 0x9999, | |||
| 749 | "Silicon Media R/W", | 685 | "Silicon Media R/W", |
| 750 | US_SC_DEVICE, US_PR_DEVICE, NULL, 0), | 686 | US_SC_DEVICE, US_PR_DEVICE, NULL, 0), |
| 751 | 687 | ||
| 752 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
| 753 | UNUSUAL_DEV( 0x0584, 0x0008, 0x0102, 0x0102, | ||
| 754 | "Fujifilm", | ||
| 755 | "DPC-R1 (Alauda)", | ||
| 756 | US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ), | ||
| 757 | #endif | ||
| 758 | |||
| 759 | /* Reported by RTE <raszilki@yandex.ru> */ | 688 | /* Reported by RTE <raszilki@yandex.ru> */ |
| 760 | UNUSUAL_DEV( 0x058f, 0x6387, 0x0141, 0x0141, | 689 | UNUSUAL_DEV( 0x058f, 0x6387, 0x0141, 0x0141, |
| 761 | "JetFlash", | 690 | "JetFlash", |
| @@ -798,32 +727,6 @@ UNUSUAL_DEV( 0x05ab, 0x0060, 0x1104, 0x1110, | |||
| 798 | US_SC_SCSI, US_PR_BULK, NULL, | 727 | US_SC_SCSI, US_PR_BULK, NULL, |
| 799 | US_FL_NEED_OVERRIDE ), | 728 | US_FL_NEED_OVERRIDE ), |
| 800 | 729 | ||
| 801 | #ifdef CONFIG_USB_STORAGE_ISD200 | ||
| 802 | UNUSUAL_DEV( 0x05ab, 0x0031, 0x0100, 0x0110, | ||
| 803 | "In-System", | ||
| 804 | "USB/IDE Bridge (ATA/ATAPI)", | ||
| 805 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
| 806 | 0 ), | ||
| 807 | |||
| 808 | UNUSUAL_DEV( 0x05ab, 0x0301, 0x0100, 0x0110, | ||
| 809 | "In-System", | ||
| 810 | "Portable USB Harddrive V2", | ||
| 811 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
| 812 | 0 ), | ||
| 813 | |||
| 814 | UNUSUAL_DEV( 0x05ab, 0x0351, 0x0100, 0x0110, | ||
| 815 | "In-System", | ||
| 816 | "Portable USB Harddrive V2", | ||
| 817 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
| 818 | 0 ), | ||
| 819 | |||
| 820 | UNUSUAL_DEV( 0x05ab, 0x5701, 0x0100, 0x0110, | ||
| 821 | "In-System", | ||
| 822 | "USB Storage Adapter V2", | ||
| 823 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
| 824 | 0 ), | ||
| 825 | #endif | ||
| 826 | |||
| 827 | /* Submitted by Sven Anderson <sven-linux@anderson.de> | 730 | /* Submitted by Sven Anderson <sven-linux@anderson.de> |
| 828 | * There are at least four ProductIDs used for iPods, so I added 0x1202 and | 731 | * There are at least four ProductIDs used for iPods, so I added 0x1202 and |
| 829 | * 0x1204. They just need the US_FL_FIX_CAPACITY. As the bcdDevice appears | 732 | * 0x1204. They just need the US_FL_FIX_CAPACITY. As the bcdDevice appears |
| @@ -877,14 +780,6 @@ UNUSUAL_DEV( 0x05c6, 0x1000, 0x0000, 0x9999, | |||
| 877 | US_SC_DEVICE, US_PR_DEVICE, option_ms_init, | 780 | US_SC_DEVICE, US_PR_DEVICE, option_ms_init, |
| 878 | 0), | 781 | 0), |
| 879 | 782 | ||
| 880 | #ifdef CONFIG_USB_STORAGE_JUMPSHOT | ||
| 881 | UNUSUAL_DEV( 0x05dc, 0x0001, 0x0000, 0x0001, | ||
| 882 | "Lexar", | ||
| 883 | "Jumpshot USB CF Reader", | ||
| 884 | US_SC_SCSI, US_PR_JUMPSHOT, NULL, | ||
| 885 | US_FL_NEED_OVERRIDE ), | ||
| 886 | #endif | ||
| 887 | |||
| 888 | /* Reported by Blake Matheny <bmatheny@purdue.edu> */ | 783 | /* Reported by Blake Matheny <bmatheny@purdue.edu> */ |
| 889 | UNUSUAL_DEV( 0x05dc, 0xb002, 0x0000, 0x0113, | 784 | UNUSUAL_DEV( 0x05dc, 0xb002, 0x0000, 0x0113, |
| 890 | "Lexar", | 785 | "Lexar", |
| @@ -935,14 +830,6 @@ UNUSUAL_DEV( 0x0644, 0x0000, 0x0100, 0x0100, | |||
| 935 | "Floppy Drive", | 830 | "Floppy Drive", |
| 936 | US_SC_UFI, US_PR_CB, NULL, 0 ), | 831 | US_SC_UFI, US_PR_CB, NULL, 0 ), |
| 937 | 832 | ||
| 938 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
| 939 | UNUSUAL_DEV( 0x066b, 0x0105, 0x0100, 0x0100, | ||
| 940 | "Olympus", | ||
| 941 | "Camedia MAUSB-2", | ||
| 942 | US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init, | ||
| 943 | 0), | ||
| 944 | #endif | ||
| 945 | |||
| 946 | /* Reported by Darsen Lu <darsen@micro.ee.nthu.edu.tw> */ | 833 | /* Reported by Darsen Lu <darsen@micro.ee.nthu.edu.tw> */ |
| 947 | UNUSUAL_DEV( 0x066f, 0x8000, 0x0001, 0x0001, | 834 | UNUSUAL_DEV( 0x066f, 0x8000, 0x0001, 0x0001, |
| 948 | "SigmaTel", | 835 | "SigmaTel", |
| @@ -1043,35 +930,12 @@ UNUSUAL_DEV( 0x0781, 0x0002, 0x0009, 0x0009, | |||
| 1043 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 930 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
| 1044 | US_FL_FIX_CAPACITY ), | 931 | US_FL_FIX_CAPACITY ), |
| 1045 | 932 | ||
| 1046 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
| 1047 | UNUSUAL_DEV( 0x0781, 0x0005, 0x0005, 0x0005, | ||
| 1048 | "Sandisk", | ||
| 1049 | "ImageMate SDDR-05b", | ||
| 1050 | US_SC_SCSI, US_PR_USBAT, init_usbat_flash, | ||
| 1051 | US_FL_SINGLE_LUN ), | ||
| 1052 | #endif | ||
| 1053 | |||
| 1054 | UNUSUAL_DEV( 0x0781, 0x0100, 0x0100, 0x0100, | 933 | UNUSUAL_DEV( 0x0781, 0x0100, 0x0100, 0x0100, |
| 1055 | "Sandisk", | 934 | "Sandisk", |
| 1056 | "ImageMate SDDR-12", | 935 | "ImageMate SDDR-12", |
| 1057 | US_SC_SCSI, US_PR_CB, NULL, | 936 | US_SC_SCSI, US_PR_CB, NULL, |
| 1058 | US_FL_SINGLE_LUN ), | 937 | US_FL_SINGLE_LUN ), |
| 1059 | 938 | ||
| 1060 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
| 1061 | UNUSUAL_DEV( 0x0781, 0x0200, 0x0000, 0x9999, | ||
| 1062 | "Sandisk", | ||
| 1063 | "ImageMate SDDR-09", | ||
| 1064 | US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init, | ||
| 1065 | 0), | ||
| 1066 | #endif | ||
| 1067 | |||
| 1068 | #ifdef CONFIG_USB_STORAGE_FREECOM | ||
| 1069 | UNUSUAL_DEV( 0x07ab, 0xfc01, 0x0000, 0x9999, | ||
| 1070 | "Freecom", | ||
| 1071 | "USB-IDE", | ||
| 1072 | US_SC_QIC, US_PR_FREECOM, freecom_init, 0), | ||
| 1073 | #endif | ||
| 1074 | |||
| 1075 | /* Reported by Eero Volotinen <eero@ping-viini.org> */ | 939 | /* Reported by Eero Volotinen <eero@ping-viini.org> */ |
| 1076 | UNUSUAL_DEV( 0x07ab, 0xfccd, 0x0000, 0x9999, | 940 | UNUSUAL_DEV( 0x07ab, 0xfccd, 0x0000, 0x9999, |
| 1077 | "Freecom Technologies", | 941 | "Freecom Technologies", |
| @@ -1091,12 +955,7 @@ UNUSUAL_DEV( 0x07af, 0x0005, 0x0100, 0x0100, | |||
| 1091 | US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init, | 955 | US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init, |
| 1092 | US_FL_SCM_MULT_TARG ), | 956 | US_FL_SCM_MULT_TARG ), |
| 1093 | 957 | ||
| 1094 | #ifdef CONFIG_USB_STORAGE_SDDR09 | 958 | #ifdef NO_SDDR09 |
| 1095 | UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100, | ||
| 1096 | "Microtech", | ||
| 1097 | "CameraMate (DPCM_USB)", | ||
| 1098 | US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ), | ||
| 1099 | #else | ||
| 1100 | UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100, | 959 | UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100, |
| 1101 | "Microtech", | 960 | "Microtech", |
| 1102 | "CameraMate", | 961 | "CameraMate", |
| @@ -1104,108 +963,6 @@ UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100, | |||
| 1104 | US_FL_SINGLE_LUN ), | 963 | US_FL_SINGLE_LUN ), |
| 1105 | #endif | 964 | #endif |
| 1106 | 965 | ||
| 1107 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
| 1108 | UNUSUAL_DEV( 0x07b4, 0x010a, 0x0102, 0x0102, | ||
| 1109 | "Olympus", | ||
| 1110 | "MAUSB-10 (Alauda)", | ||
| 1111 | US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ), | ||
| 1112 | #endif | ||
| 1113 | |||
| 1114 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
| 1115 | UNUSUAL_DEV( 0x07c4, 0xa000, 0x0000, 0x0015, | ||
| 1116 | "Datafab", | ||
| 1117 | "MDCFE-B USB CF Reader", | ||
| 1118 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
| 1119 | 0 ), | ||
| 1120 | |||
| 1121 | /* | ||
| 1122 | * The following Datafab-based devices may or may not work | ||
| 1123 | * using the current driver...the 0xffff is arbitrary since I | ||
| 1124 | * don't know what device versions exist for these guys. | ||
| 1125 | * | ||
| 1126 | * The 0xa003 and 0xa004 devices in particular I'm curious about. | ||
| 1127 | * I'm told they exist but so far nobody has come forward to say that | ||
| 1128 | * they work with this driver. Given the success we've had getting | ||
| 1129 | * other Datafab-based cards operational with this driver, I've decided | ||
| 1130 | * to leave these two devices in the list. | ||
| 1131 | */ | ||
| 1132 | UNUSUAL_DEV( 0x07c4, 0xa001, 0x0000, 0xffff, | ||
| 1133 | "SIIG/Datafab", | ||
| 1134 | "SIIG/Datafab Memory Stick+CF Reader/Writer", | ||
| 1135 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
| 1136 | 0 ), | ||
| 1137 | |||
| 1138 | /* Reported by Josef Reisinger <josef.reisinger@netcologne.de> */ | ||
| 1139 | UNUSUAL_DEV( 0x07c4, 0xa002, 0x0000, 0xffff, | ||
| 1140 | "Datafab/Unknown", | ||
| 1141 | "MD2/MD3 Disk enclosure", | ||
| 1142 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
| 1143 | US_FL_SINGLE_LUN ), | ||
| 1144 | |||
| 1145 | UNUSUAL_DEV( 0x07c4, 0xa003, 0x0000, 0xffff, | ||
| 1146 | "Datafab/Unknown", | ||
| 1147 | "Datafab-based Reader", | ||
| 1148 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
| 1149 | 0 ), | ||
| 1150 | |||
| 1151 | UNUSUAL_DEV( 0x07c4, 0xa004, 0x0000, 0xffff, | ||
| 1152 | "Datafab/Unknown", | ||
| 1153 | "Datafab-based Reader", | ||
| 1154 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
| 1155 | 0 ), | ||
| 1156 | |||
| 1157 | UNUSUAL_DEV( 0x07c4, 0xa005, 0x0000, 0xffff, | ||
| 1158 | "PNY/Datafab", | ||
| 1159 | "PNY/Datafab CF+SM Reader", | ||
| 1160 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
| 1161 | 0 ), | ||
| 1162 | |||
| 1163 | UNUSUAL_DEV( 0x07c4, 0xa006, 0x0000, 0xffff, | ||
| 1164 | "Simple Tech/Datafab", | ||
| 1165 | "Simple Tech/Datafab CF+SM Reader", | ||
| 1166 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
| 1167 | 0 ), | ||
| 1168 | #endif | ||
| 1169 | |||
| 1170 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
| 1171 | /* Contributed by Peter Waechtler */ | ||
| 1172 | UNUSUAL_DEV( 0x07c4, 0xa103, 0x0000, 0x9999, | ||
| 1173 | "Datafab", | ||
| 1174 | "MDSM-B reader", | ||
| 1175 | US_SC_SCSI, US_PR_SDDR55, NULL, | ||
| 1176 | US_FL_FIX_INQUIRY ), | ||
| 1177 | #endif | ||
| 1178 | |||
| 1179 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
| 1180 | /* Submitted by Olaf Hering <olh@suse.de> */ | ||
| 1181 | UNUSUAL_DEV( 0x07c4, 0xa109, 0x0000, 0xffff, | ||
| 1182 | "Datafab Systems, Inc.", | ||
| 1183 | "USB to CF + SM Combo (LC1)", | ||
| 1184 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
| 1185 | 0 ), | ||
| 1186 | #endif | ||
| 1187 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
| 1188 | /* SM part - aeb <Andries.Brouwer@cwi.nl> */ | ||
| 1189 | UNUSUAL_DEV( 0x07c4, 0xa109, 0x0000, 0xffff, | ||
| 1190 | "Datafab Systems, Inc.", | ||
| 1191 | "USB to CF + SM Combo (LC1)", | ||
| 1192 | US_SC_SCSI, US_PR_SDDR55, NULL, | ||
| 1193 | US_FL_SINGLE_LUN ), | ||
| 1194 | #endif | ||
| 1195 | |||
| 1196 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
| 1197 | /* Reported by Felix Moeller <felix@derklecks.de> | ||
| 1198 | * in Germany this is sold by Hama with the productnumber 46952 | ||
| 1199 | * as "DualSlot CompactFlash(TM) & MStick Drive USB" | ||
| 1200 | */ | ||
| 1201 | UNUSUAL_DEV( 0x07c4, 0xa10b, 0x0000, 0xffff, | ||
| 1202 | "DataFab Systems Inc.", | ||
| 1203 | "USB CF+MS", | ||
| 1204 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
| 1205 | 0 ), | ||
| 1206 | |||
| 1207 | #endif | ||
| 1208 | |||
| 1209 | /* Datafab KECF-USB / Sagatek DCS-CF / Simpletech Flashlink UCF-100 | 966 | /* Datafab KECF-USB / Sagatek DCS-CF / Simpletech Flashlink UCF-100 |
| 1210 | * Only revision 1.13 tested (same for all of the above devices, | 967 | * Only revision 1.13 tested (same for all of the above devices, |
| 1211 | * based on the Datafab DF-UG-07 chip). Needed for US_FL_FIX_INQUIRY. | 968 | * based on the Datafab DF-UG-07 chip). Needed for US_FL_FIX_INQUIRY. |
| @@ -1409,29 +1166,6 @@ UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000, | |||
| 1409 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1166 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
| 1410 | US_FL_SANE_SENSE ), | 1167 | US_FL_SANE_SENSE ), |
| 1411 | 1168 | ||
| 1412 | #ifdef CONFIG_USB_STORAGE_ISD200 | ||
| 1413 | UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110, | ||
| 1414 | "ATI", | ||
| 1415 | "USB Cable 205", | ||
| 1416 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
| 1417 | 0 ), | ||
| 1418 | #endif | ||
| 1419 | |||
| 1420 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
| 1421 | UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff, | ||
| 1422 | "Acomdata", | ||
| 1423 | "CF", | ||
| 1424 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
| 1425 | US_FL_SINGLE_LUN ), | ||
| 1426 | #endif | ||
| 1427 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
| 1428 | UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff, | ||
| 1429 | "Acomdata", | ||
| 1430 | "SM", | ||
| 1431 | US_SC_SCSI, US_PR_SDDR55, NULL, | ||
| 1432 | US_FL_SINGLE_LUN ), | ||
| 1433 | #endif | ||
| 1434 | |||
| 1435 | UNUSUAL_DEV( 0x0d49, 0x7310, 0x0000, 0x9999, | 1169 | UNUSUAL_DEV( 0x0d49, 0x7310, 0x0000, 0x9999, |
| 1436 | "Maxtor", | 1170 | "Maxtor", |
| 1437 | "USB to SATA", | 1171 | "USB to SATA", |
| @@ -1448,23 +1182,6 @@ UNUSUAL_DEV( 0x0c45, 0x1060, 0x0100, 0x0100, | |||
| 1448 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1182 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
| 1449 | US_FL_SINGLE_LUN ), | 1183 | US_FL_SINGLE_LUN ), |
| 1450 | 1184 | ||
| 1451 | /* Submitted by: Nick Sillik <n.sillik@temple.edu> | ||
| 1452 | * Needed for OneTouch extension to usb-storage | ||
| 1453 | * | ||
| 1454 | */ | ||
| 1455 | #ifdef CONFIG_USB_STORAGE_ONETOUCH | ||
| 1456 | UNUSUAL_DEV( 0x0d49, 0x7000, 0x0000, 0x9999, | ||
| 1457 | "Maxtor", | ||
| 1458 | "OneTouch External Harddrive", | ||
| 1459 | US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input, | ||
| 1460 | 0), | ||
| 1461 | UNUSUAL_DEV( 0x0d49, 0x7010, 0x0000, 0x9999, | ||
| 1462 | "Maxtor", | ||
| 1463 | "OneTouch External Harddrive", | ||
| 1464 | US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input, | ||
| 1465 | 0), | ||
| 1466 | #endif | ||
| 1467 | |||
| 1468 | /* Submitted by Joris Struyve <joris@struyve.be> */ | 1185 | /* Submitted by Joris Struyve <joris@struyve.be> */ |
| 1469 | UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff, | 1186 | UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff, |
| 1470 | "Medion", | 1187 | "Medion", |
| @@ -2117,14 +1834,6 @@ UNUSUAL_DEV( 0x4146, 0xba01, 0x0100, 0x0100, | |||
| 2117 | "Micro Mini 1GB", | 1834 | "Micro Mini 1GB", |
| 2118 | US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), | 1835 | US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), |
| 2119 | 1836 | ||
| 2120 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
| 2121 | UNUSUAL_DEV( 0x55aa, 0xa103, 0x0000, 0x9999, | ||
| 2122 | "Sandisk", | ||
| 2123 | "ImageMate SDDR55", | ||
| 2124 | US_SC_SCSI, US_PR_SDDR55, NULL, | ||
| 2125 | US_FL_SINGLE_LUN), | ||
| 2126 | #endif | ||
| 2127 | |||
| 2128 | /* Reported by Andrew Simmons <andrew.simmons@gmail.com> */ | 1837 | /* Reported by Andrew Simmons <andrew.simmons@gmail.com> */ |
| 2129 | UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001, | 1838 | UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001, |
| 2130 | "DataStor", | 1839 | "DataStor", |
diff --git a/drivers/usb/storage/cypress_atacb.h b/drivers/usb/storage/unusual_freecom.h index fbada898d56b..375867942391 100644 --- a/drivers/usb/storage/cypress_atacb.h +++ b/drivers/usb/storage/unusual_freecom.h | |||
| @@ -1,8 +1,4 @@ | |||
| 1 | /* | 1 | /* Unusual Devices File for the Freecom USB/IDE adaptor |
| 2 | * Support for emulating SAT (ata pass through) on devices based | ||
| 3 | * on the Cypress USB/ATA bridge supporting ATACB. | ||
| 4 | * | ||
| 5 | * Copyright (c) 2008 Matthieu Castet (castet.matthieu@free.fr) | ||
| 6 | * | 2 | * |
| 7 | * This program is free software; you can redistribute it and/or modify it | 3 | * This program is free software; you can redistribute it and/or modify it |
| 8 | * under the terms of the GNU General Public License as published by the | 4 | * under the terms of the GNU General Public License as published by the |
| @@ -19,7 +15,12 @@ | |||
| 19 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 15 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
| 20 | */ | 16 | */ |
| 21 | 17 | ||
| 22 | #ifndef _CYPRESS_ATACB_H_ | 18 | #if defined(CONFIG_USB_STORAGE_FREECOM) || \ |
| 23 | #define _CYPRESS_ATACB_H_ | 19 | defined(CONFIG_USB_STORAGE_FREECOM_MODULE) |
| 24 | extern void cypress_atacb_passthrough(struct scsi_cmnd*, struct us_data*); | 20 | |
| 25 | #endif | 21 | UNUSUAL_DEV( 0x07ab, 0xfc01, 0x0000, 0x9999, |
| 22 | "Freecom", | ||
| 23 | "USB-IDE", | ||
| 24 | US_SC_QIC, US_PR_FREECOM, init_freecom, 0), | ||
| 25 | |||
| 26 | #endif /* defined(CONFIG_USB_STORAGE_FREECOM) || ... */ | ||
diff --git a/drivers/usb/storage/unusual_isd200.h b/drivers/usb/storage/unusual_isd200.h new file mode 100644 index 000000000000..0d99dde3382a --- /dev/null +++ b/drivers/usb/storage/unusual_isd200.h | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | /* Unusual Devices File for In-System Design, Inc. ISD200 ASIC | ||
| 2 | * | ||
| 3 | * This program is free software; you can redistribute it and/or modify it | ||
| 4 | * under the terms of the GNU General Public License as published by the | ||
| 5 | * Free Software Foundation; either version 2, or (at your option) any | ||
| 6 | * later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, but | ||
| 9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 11 | * General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License along | ||
| 14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 15 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #if defined(CONFIG_USB_STORAGE_ISD200) || \ | ||
| 19 | defined(CONFIG_USB_STORAGE_ISD200_MODULE) | ||
| 20 | |||
| 21 | UNUSUAL_DEV( 0x054c, 0x002b, 0x0100, 0x0110, | ||
| 22 | "Sony", | ||
| 23 | "Portable USB Harddrive V2", | ||
| 24 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
| 25 | 0), | ||
| 26 | |||
| 27 | UNUSUAL_DEV( 0x05ab, 0x0031, 0x0100, 0x0110, | ||
| 28 | "In-System", | ||
| 29 | "USB/IDE Bridge (ATA/ATAPI)", | ||
| 30 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
| 31 | 0), | ||
| 32 | |||
| 33 | UNUSUAL_DEV( 0x05ab, 0x0301, 0x0100, 0x0110, | ||
| 34 | "In-System", | ||
| 35 | "Portable USB Harddrive V2", | ||
| 36 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
| 37 | 0), | ||
| 38 | |||
| 39 | UNUSUAL_DEV( 0x05ab, 0x0351, 0x0100, 0x0110, | ||
| 40 | "In-System", | ||
| 41 | "Portable USB Harddrive V2", | ||
| 42 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
| 43 | 0), | ||
| 44 | |||
| 45 | UNUSUAL_DEV( 0x05ab, 0x5701, 0x0100, 0x0110, | ||
| 46 | "In-System", | ||
| 47 | "USB Storage Adapter V2", | ||
| 48 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
| 49 | 0), | ||
| 50 | |||
| 51 | UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110, | ||
| 52 | "ATI", | ||
| 53 | "USB Cable 205", | ||
| 54 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
| 55 | 0), | ||
| 56 | |||
| 57 | #endif /* defined(CONFIG_USB_STORAGE_ISD200) || ... */ | ||
diff --git a/drivers/usb/storage/sddr55.h b/drivers/usb/storage/unusual_jumpshot.h index a815a0470c84..2e549b1c2c62 100644 --- a/drivers/usb/storage/sddr55.h +++ b/drivers/usb/storage/unusual_jumpshot.h | |||
| @@ -1,10 +1,4 @@ | |||
| 1 | /* Driver for SanDisk SDDR-55 SmartMedia reader | 1 | /* Unusual Devices File for the Lexar "Jumpshot" Compact Flash reader |
| 2 | * Header File | ||
| 3 | * | ||
| 4 | * Current development and maintenance by: | ||
| 5 | * (c) 2002 Simon Munton | ||
| 6 | * | ||
| 7 | * See sddr55.c for more explanation | ||
| 8 | * | 2 | * |
| 9 | * This program is free software; you can redistribute it and/or modify it | 3 | * This program is free software; you can redistribute it and/or modify it |
| 10 | * under the terms of the GNU General Public License as published by the | 4 | * under the terms of the GNU General Public License as published by the |
| @@ -21,12 +15,13 @@ | |||
| 21 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 15 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
| 22 | */ | 16 | */ |
| 23 | 17 | ||
| 24 | #ifndef _USB_SHUTTLE_EUSB_SDDR55_H | 18 | #if defined(CONFIG_USB_STORAGE_JUMPSHOT) || \ |
| 25 | #define _USB_SHUTTLE_EUSB_SDDR55_H | 19 | defined(CONFIG_USB_STORAGE_JUMPSHOT_MODULE) |
| 26 | |||
| 27 | /* Sandisk SDDR-55 stuff */ | ||
| 28 | 20 | ||
| 29 | extern int sddr55_transport(struct scsi_cmnd *srb, struct us_data *us); | 21 | UNUSUAL_DEV( 0x05dc, 0x0001, 0x0000, 0x0001, |
| 30 | extern int sddr55_reset(struct us_data *us); | 22 | "Lexar", |
| 23 | "Jumpshot USB CF Reader", | ||
| 24 | US_SC_SCSI, US_PR_JUMPSHOT, NULL, | ||
| 25 | US_FL_NEED_OVERRIDE), | ||
| 31 | 26 | ||
| 32 | #endif | 27 | #endif /* defined(CONFIG_USB_STORAGE_JUMPSHOT) || ... */ |
diff --git a/drivers/usb/storage/isd200.h b/drivers/usb/storage/unusual_karma.h index 0a35f4fa78f8..12ae3a03e802 100644 --- a/drivers/usb/storage/isd200.h +++ b/drivers/usb/storage/unusual_karma.h | |||
| @@ -1,11 +1,4 @@ | |||
| 1 | /* Header File for In-System Design, Inc. ISD200 ASIC | 1 | /* Unusual Devices File for the Rio Karma |
| 2 | * | ||
| 3 | * First release | ||
| 4 | * | ||
| 5 | * Current development and maintenance by: | ||
| 6 | * (c) 2000 In-System Design, Inc. (support@in-system.com) | ||
| 7 | * | ||
| 8 | * See isd200.c for more information. | ||
| 9 | * | 2 | * |
| 10 | * This program is free software; you can redistribute it and/or modify it | 3 | * This program is free software; you can redistribute it and/or modify it |
| 11 | * under the terms of the GNU General Public License as published by the | 4 | * under the terms of the GNU General Public License as published by the |
| @@ -22,10 +15,12 @@ | |||
| 22 | * 675 Mass Ave, Cambridge, MA 02139, USA. | 15 | * 675 Mass Ave, Cambridge, MA 02139, USA. |
| 23 | */ | 16 | */ |
| 24 | 17 | ||
| 25 | #ifndef _USB_ISD200_H | 18 | #if defined(CONFIG_USB_STORAGE_KARMA) || \ |
| 26 | #define _USB_ISD200_H | 19 | defined(CONFIG_USB_STORAGE_KARMA_MODULE) |
| 27 | 20 | ||
| 28 | extern void isd200_ata_command(struct scsi_cmnd *srb, struct us_data *us); | 21 | UNUSUAL_DEV( 0x045a, 0x5210, 0x0101, 0x0101, |
| 29 | extern int isd200_Initialization(struct us_data *us); | 22 | "Rio", |
| 23 | "Rio Karma", | ||
| 24 | US_SC_SCSI, US_PR_KARMA, rio_karma_init, 0), | ||
| 30 | 25 | ||
| 31 | #endif | 26 | #endif /* defined(CONFIG_USB_STORAGE_KARMA) || ... */ |
diff --git a/drivers/usb/storage/unusual_onetouch.h b/drivers/usb/storage/unusual_onetouch.h new file mode 100644 index 000000000000..bd9306b637df --- /dev/null +++ b/drivers/usb/storage/unusual_onetouch.h | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | /* Unusual Devices File for the Maxtor OneTouch USB hard drive's button | ||
| 2 | * | ||
| 3 | * This program is free software; you can redistribute it and/or modify it | ||
| 4 | * under the terms of the GNU General Public License as published by the | ||
| 5 | * Free Software Foundation; either version 2, or (at your option) any | ||
| 6 | * later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, but | ||
| 9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 11 | * General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License along | ||
| 14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 15 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #if defined(CONFIG_USB_STORAGE_ONETOUCH) || \ | ||
| 19 | defined(CONFIG_USB_STORAGE_ONETOUCH_MODULE) | ||
| 20 | |||
| 21 | /* Submitted by: Nick Sillik <n.sillik@temple.edu> | ||
| 22 | * Needed for OneTouch extension to usb-storage | ||
| 23 | */ | ||
| 24 | UNUSUAL_DEV( 0x0d49, 0x7000, 0x0000, 0x9999, | ||
| 25 | "Maxtor", | ||
| 26 | "OneTouch External Harddrive", | ||
| 27 | US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input, | ||
| 28 | 0), | ||
| 29 | |||
| 30 | UNUSUAL_DEV( 0x0d49, 0x7010, 0x0000, 0x9999, | ||
| 31 | "Maxtor", | ||
| 32 | "OneTouch External Harddrive", | ||
| 33 | US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input, | ||
| 34 | 0), | ||
| 35 | |||
| 36 | #endif /* defined(CONFIG_USB_STORAGE_ONETOUCH) || ... */ | ||
diff --git a/drivers/usb/storage/unusual_sddr09.h b/drivers/usb/storage/unusual_sddr09.h new file mode 100644 index 000000000000..50cab511a4d7 --- /dev/null +++ b/drivers/usb/storage/unusual_sddr09.h | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | /* Unusual Devices File for SanDisk SDDR-09 SmartMedia reader | ||
| 2 | * | ||
| 3 | * This program is free software; you can redistribute it and/or modify it | ||
| 4 | * under the terms of the GNU General Public License as published by the | ||
| 5 | * Free Software Foundation; either version 2, or (at your option) any | ||
| 6 | * later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, but | ||
| 9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 11 | * General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License along | ||
| 14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 15 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #if defined(CONFIG_USB_STORAGE_SDDR09) || \ | ||
| 19 | defined(CONFIG_USB_STORAGE_SDDR09_MODULE) | ||
| 20 | |||
| 21 | UNUSUAL_DEV( 0x0436, 0x0005, 0x0100, 0x0100, | ||
| 22 | "Microtech", | ||
| 23 | "CameraMate (DPCM_USB)", | ||
| 24 | US_SC_SCSI, US_PR_DPCM_USB, NULL, 0), | ||
| 25 | |||
| 26 | UNUSUAL_DEV( 0x04e6, 0x0003, 0x0000, 0x9999, | ||
| 27 | "Sandisk", | ||
| 28 | "ImageMate SDDR09", | ||
| 29 | US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init, | ||
| 30 | 0), | ||
| 31 | |||
| 32 | /* This entry is from Andries.Brouwer@cwi.nl */ | ||
| 33 | UNUSUAL_DEV( 0x04e6, 0x0005, 0x0100, 0x0208, | ||
| 34 | "SCM Microsystems", | ||
| 35 | "eUSB SmartMedia / CompactFlash Adapter", | ||
| 36 | US_SC_SCSI, US_PR_DPCM_USB, usb_stor_sddr09_dpcm_init, | ||
| 37 | 0), | ||
| 38 | |||
| 39 | UNUSUAL_DEV( 0x066b, 0x0105, 0x0100, 0x0100, | ||
| 40 | "Olympus", | ||
| 41 | "Camedia MAUSB-2", | ||
| 42 | US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init, | ||
| 43 | 0), | ||
| 44 | |||
| 45 | UNUSUAL_DEV( 0x0781, 0x0200, 0x0000, 0x9999, | ||
| 46 | "Sandisk", | ||
| 47 | "ImageMate SDDR-09", | ||
| 48 | US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init, | ||
| 49 | 0), | ||
| 50 | |||
| 51 | UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100, | ||
| 52 | "Microtech", | ||
| 53 | "CameraMate (DPCM_USB)", | ||
| 54 | US_SC_SCSI, US_PR_DPCM_USB, NULL, 0), | ||
| 55 | |||
| 56 | #endif /* defined(CONFIG_USB_STORAGE_SDDR09) || ... */ | ||
diff --git a/drivers/usb/storage/unusual_sddr55.h b/drivers/usb/storage/unusual_sddr55.h new file mode 100644 index 000000000000..ae81ef7a1cfd --- /dev/null +++ b/drivers/usb/storage/unusual_sddr55.h | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | /* Unusual Devices File for SanDisk SDDR-55 SmartMedia reader | ||
| 2 | * | ||
| 3 | * This program is free software; you can redistribute it and/or modify it | ||
| 4 | * under the terms of the GNU General Public License as published by the | ||
| 5 | * Free Software Foundation; either version 2, or (at your option) any | ||
| 6 | * later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, but | ||
| 9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 11 | * General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License along | ||
| 14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 15 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #if defined(CONFIG_USB_STORAGE_SDDR55) || \ | ||
| 19 | defined(CONFIG_USB_STORAGE_SDDR55_MODULE) | ||
| 20 | |||
| 21 | /* Contributed by Peter Waechtler */ | ||
| 22 | UNUSUAL_DEV( 0x07c4, 0xa103, 0x0000, 0x9999, | ||
| 23 | "Datafab", | ||
| 24 | "MDSM-B reader", | ||
| 25 | US_SC_SCSI, US_PR_SDDR55, NULL, | ||
| 26 | US_FL_FIX_INQUIRY), | ||
| 27 | |||
| 28 | /* SM part - aeb <Andries.Brouwer@cwi.nl> */ | ||
| 29 | UNUSUAL_DEV( 0x07c4, 0xa109, 0x0000, 0xffff, | ||
| 30 | "Datafab Systems, Inc.", | ||
| 31 | "USB to CF + SM Combo (LC1)", | ||
| 32 | US_SC_SCSI, US_PR_SDDR55, NULL, 0), | ||
| 33 | |||
| 34 | UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff, | ||
| 35 | "Acomdata", | ||
| 36 | "SM", | ||
| 37 | US_SC_SCSI, US_PR_SDDR55, NULL, 0), | ||
| 38 | |||
| 39 | UNUSUAL_DEV( 0x55aa, 0xa103, 0x0000, 0x9999, | ||
| 40 | "Sandisk", | ||
| 41 | "ImageMate SDDR55", | ||
| 42 | US_SC_SCSI, US_PR_SDDR55, NULL, 0), | ||
| 43 | |||
| 44 | #endif /* defined(CONFIG_USB_STORAGE_SDDR55) || ... */ | ||
diff --git a/drivers/usb/storage/unusual_usbat.h b/drivers/usb/storage/unusual_usbat.h new file mode 100644 index 000000000000..80e869f10180 --- /dev/null +++ b/drivers/usb/storage/unusual_usbat.h | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | /* Unusual Devices File for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable | ||
| 2 | * | ||
| 3 | * This program is free software; you can redistribute it and/or modify it | ||
| 4 | * under the terms of the GNU General Public License as published by the | ||
| 5 | * Free Software Foundation; either version 2, or (at your option) any | ||
| 6 | * later version. | ||
| 7 | * | ||
| 8 | * This program is distributed in the hope that it will be useful, but | ||
| 9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 11 | * General Public License for more details. | ||
| 12 | * | ||
| 13 | * You should have received a copy of the GNU General Public License along | ||
| 14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 15 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 16 | */ | ||
| 17 | |||
| 18 | #if defined(CONFIG_USB_STORAGE_USBAT) || \ | ||
| 19 | defined(CONFIG_USB_STORAGE_USBAT_MODULE) | ||
| 20 | |||
| 21 | UNUSUAL_DEV( 0x03f0, 0x0207, 0x0001, 0x0001, | ||
| 22 | "HP", | ||
| 23 | "CD-Writer+ 8200e", | ||
| 24 | US_SC_8070, US_PR_USBAT, init_usbat_cd, 0), | ||
| 25 | |||
| 26 | UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001, | ||
| 27 | "HP", | ||
| 28 | "CD-Writer+ CD-4e", | ||
| 29 | US_SC_8070, US_PR_USBAT, init_usbat_cd, 0), | ||
| 30 | |||
| 31 | UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999, | ||
| 32 | "Shuttle/SCM", | ||
| 33 | "USBAT-02", | ||
| 34 | US_SC_SCSI, US_PR_USBAT, init_usbat_flash, | ||
| 35 | US_FL_SINGLE_LUN), | ||
| 36 | |||
| 37 | UNUSUAL_DEV( 0x0781, 0x0005, 0x0005, 0x0005, | ||
| 38 | "Sandisk", | ||
| 39 | "ImageMate SDDR-05b", | ||
| 40 | US_SC_SCSI, US_PR_USBAT, init_usbat_flash, | ||
| 41 | US_FL_SINGLE_LUN), | ||
| 42 | |||
| 43 | #endif /* defined(CONFIG_USB_STORAGE_USBAT) || ... */ | ||
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 4becf495ca2d..8060b85fe1a3 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | * | 5 | * |
| 6 | * Developed with the assistance of: | 6 | * Developed with the assistance of: |
| 7 | * (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org) | 7 | * (c) 2000 David L. Brown, Jr. (usb-storage@davidb.org) |
| 8 | * (c) 2003 Alan Stern (stern@rowland.harvard.edu) | 8 | * (c) 2003-2009 Alan Stern (stern@rowland.harvard.edu) |
| 9 | * | 9 | * |
| 10 | * Initial work by: | 10 | * Initial work by: |
| 11 | * (c) 1999 Michael Gee (michael@linuxspecific.com) | 11 | * (c) 1999 Michael Gee (michael@linuxspecific.com) |
| @@ -66,39 +66,6 @@ | |||
| 66 | #include "debug.h" | 66 | #include "debug.h" |
| 67 | #include "initializers.h" | 67 | #include "initializers.h" |
| 68 | 68 | ||
| 69 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
| 70 | #include "shuttle_usbat.h" | ||
| 71 | #endif | ||
| 72 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
| 73 | #include "sddr09.h" | ||
| 74 | #endif | ||
| 75 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
| 76 | #include "sddr55.h" | ||
| 77 | #endif | ||
| 78 | #ifdef CONFIG_USB_STORAGE_FREECOM | ||
| 79 | #include "freecom.h" | ||
| 80 | #endif | ||
| 81 | #ifdef CONFIG_USB_STORAGE_ISD200 | ||
| 82 | #include "isd200.h" | ||
| 83 | #endif | ||
| 84 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
| 85 | #include "datafab.h" | ||
| 86 | #endif | ||
| 87 | #ifdef CONFIG_USB_STORAGE_JUMPSHOT | ||
| 88 | #include "jumpshot.h" | ||
| 89 | #endif | ||
| 90 | #ifdef CONFIG_USB_STORAGE_ONETOUCH | ||
| 91 | #include "onetouch.h" | ||
| 92 | #endif | ||
| 93 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
| 94 | #include "alauda.h" | ||
| 95 | #endif | ||
| 96 | #ifdef CONFIG_USB_STORAGE_KARMA | ||
| 97 | #include "karma.h" | ||
| 98 | #endif | ||
| 99 | #ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB | ||
| 100 | #include "cypress_atacb.h" | ||
| 101 | #endif | ||
| 102 | #include "sierra_ms.h" | 69 | #include "sierra_ms.h" |
| 103 | #include "option_ms.h" | 70 | #include "option_ms.h" |
| 104 | 71 | ||
| @@ -118,36 +85,8 @@ MODULE_PARM_DESC(quirks, "supplemental list of device IDs and their quirks"); | |||
| 118 | 85 | ||
| 119 | /* | 86 | /* |
| 120 | * The entries in this table correspond, line for line, | 87 | * The entries in this table correspond, line for line, |
| 121 | * with the entries of us_unusual_dev_list[]. | 88 | * with the entries in usb_storage_usb_ids[], defined in usual-tables.c. |
| 122 | */ | 89 | */ |
| 123 | #ifndef CONFIG_USB_LIBUSUAL | ||
| 124 | |||
| 125 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
| 126 | vendorName, productName,useProtocol, useTransport, \ | ||
| 127 | initFunction, flags) \ | ||
| 128 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin,bcdDeviceMax), \ | ||
| 129 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
| 130 | |||
| 131 | #define COMPLIANT_DEV UNUSUAL_DEV | ||
| 132 | |||
| 133 | #define USUAL_DEV(useProto, useTrans, useType) \ | ||
| 134 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ | ||
| 135 | .driver_info = (USB_US_TYPE_STOR<<24) } | ||
| 136 | |||
| 137 | static struct usb_device_id storage_usb_ids [] = { | ||
| 138 | |||
| 139 | # include "unusual_devs.h" | ||
| 140 | #undef UNUSUAL_DEV | ||
| 141 | #undef COMPLIANT_DEV | ||
| 142 | #undef USUAL_DEV | ||
| 143 | /* Terminating entry */ | ||
| 144 | { } | ||
| 145 | }; | ||
| 146 | |||
| 147 | MODULE_DEVICE_TABLE (usb, storage_usb_ids); | ||
| 148 | #endif /* CONFIG_USB_LIBUSUAL */ | ||
| 149 | |||
| 150 | /* This is the list of devices we recognize, along with their flag data */ | ||
| 151 | 90 | ||
| 152 | /* The vendor name should be kept at eight characters or less, and | 91 | /* The vendor name should be kept at eight characters or less, and |
| 153 | * the product name should be kept at 16 characters or less. If a device | 92 | * the product name should be kept at 16 characters or less. If a device |
| @@ -179,18 +118,17 @@ MODULE_DEVICE_TABLE (usb, storage_usb_ids); | |||
| 179 | 118 | ||
| 180 | static struct us_unusual_dev us_unusual_dev_list[] = { | 119 | static struct us_unusual_dev us_unusual_dev_list[] = { |
| 181 | # include "unusual_devs.h" | 120 | # include "unusual_devs.h" |
| 182 | # undef UNUSUAL_DEV | 121 | { } /* Terminating entry */ |
| 183 | # undef COMPLIANT_DEV | ||
| 184 | # undef USUAL_DEV | ||
| 185 | |||
| 186 | /* Terminating entry */ | ||
| 187 | { NULL } | ||
| 188 | }; | 122 | }; |
| 189 | 123 | ||
| 124 | #undef UNUSUAL_DEV | ||
| 125 | #undef COMPLIANT_DEV | ||
| 126 | #undef USUAL_DEV | ||
| 127 | |||
| 190 | 128 | ||
| 191 | #ifdef CONFIG_PM /* Minimal support for suspend and resume */ | 129 | #ifdef CONFIG_PM /* Minimal support for suspend and resume */ |
| 192 | 130 | ||
| 193 | static int storage_suspend(struct usb_interface *iface, pm_message_t message) | 131 | int usb_stor_suspend(struct usb_interface *iface, pm_message_t message) |
| 194 | { | 132 | { |
| 195 | struct us_data *us = usb_get_intfdata(iface); | 133 | struct us_data *us = usb_get_intfdata(iface); |
| 196 | 134 | ||
| @@ -207,8 +145,9 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message) | |||
| 207 | mutex_unlock(&us->dev_mutex); | 145 | mutex_unlock(&us->dev_mutex); |
| 208 | return 0; | 146 | return 0; |
| 209 | } | 147 | } |
| 148 | EXPORT_SYMBOL_GPL(usb_stor_suspend); | ||
| 210 | 149 | ||
| 211 | static int storage_resume(struct usb_interface *iface) | 150 | int usb_stor_resume(struct usb_interface *iface) |
| 212 | { | 151 | { |
| 213 | struct us_data *us = usb_get_intfdata(iface); | 152 | struct us_data *us = usb_get_intfdata(iface); |
| 214 | 153 | ||
| @@ -221,8 +160,9 @@ static int storage_resume(struct usb_interface *iface) | |||
| 221 | mutex_unlock(&us->dev_mutex); | 160 | mutex_unlock(&us->dev_mutex); |
| 222 | return 0; | 161 | return 0; |
| 223 | } | 162 | } |
| 163 | EXPORT_SYMBOL_GPL(usb_stor_resume); | ||
| 224 | 164 | ||
| 225 | static int storage_reset_resume(struct usb_interface *iface) | 165 | int usb_stor_reset_resume(struct usb_interface *iface) |
| 226 | { | 166 | { |
| 227 | struct us_data *us = usb_get_intfdata(iface); | 167 | struct us_data *us = usb_get_intfdata(iface); |
| 228 | 168 | ||
| @@ -235,6 +175,7 @@ static int storage_reset_resume(struct usb_interface *iface) | |||
| 235 | * the device */ | 175 | * the device */ |
| 236 | return 0; | 176 | return 0; |
| 237 | } | 177 | } |
| 178 | EXPORT_SYMBOL_GPL(usb_stor_reset_resume); | ||
| 238 | 179 | ||
| 239 | #endif /* CONFIG_PM */ | 180 | #endif /* CONFIG_PM */ |
| 240 | 181 | ||
| @@ -243,7 +184,7 @@ static int storage_reset_resume(struct usb_interface *iface) | |||
| 243 | * a USB port reset, whether from this driver or a different one. | 184 | * a USB port reset, whether from this driver or a different one. |
| 244 | */ | 185 | */ |
| 245 | 186 | ||
| 246 | static int storage_pre_reset(struct usb_interface *iface) | 187 | int usb_stor_pre_reset(struct usb_interface *iface) |
| 247 | { | 188 | { |
| 248 | struct us_data *us = usb_get_intfdata(iface); | 189 | struct us_data *us = usb_get_intfdata(iface); |
| 249 | 190 | ||
| @@ -253,8 +194,9 @@ static int storage_pre_reset(struct usb_interface *iface) | |||
| 253 | mutex_lock(&us->dev_mutex); | 194 | mutex_lock(&us->dev_mutex); |
| 254 | return 0; | 195 | return 0; |
| 255 | } | 196 | } |
| 197 | EXPORT_SYMBOL_GPL(usb_stor_pre_reset); | ||
| 256 | 198 | ||
| 257 | static int storage_post_reset(struct usb_interface *iface) | 199 | int usb_stor_post_reset(struct usb_interface *iface) |
| 258 | { | 200 | { |
| 259 | struct us_data *us = usb_get_intfdata(iface); | 201 | struct us_data *us = usb_get_intfdata(iface); |
| 260 | 202 | ||
| @@ -269,6 +211,7 @@ static int storage_post_reset(struct usb_interface *iface) | |||
| 269 | mutex_unlock(&us->dev_mutex); | 211 | mutex_unlock(&us->dev_mutex); |
| 270 | return 0; | 212 | return 0; |
| 271 | } | 213 | } |
| 214 | EXPORT_SYMBOL_GPL(usb_stor_post_reset); | ||
| 272 | 215 | ||
| 273 | /* | 216 | /* |
| 274 | * fill_inquiry_response takes an unsigned char array (which must | 217 | * fill_inquiry_response takes an unsigned char array (which must |
| @@ -311,6 +254,7 @@ void fill_inquiry_response(struct us_data *us, unsigned char *data, | |||
| 311 | 254 | ||
| 312 | usb_stor_set_xfer_buf(data, data_len, us->srb); | 255 | usb_stor_set_xfer_buf(data, data_len, us->srb); |
| 313 | } | 256 | } |
| 257 | EXPORT_SYMBOL_GPL(fill_inquiry_response); | ||
| 314 | 258 | ||
| 315 | static int usb_stor_control_thread(void * __us) | 259 | static int usb_stor_control_thread(void * __us) |
| 316 | { | 260 | { |
| @@ -551,20 +495,13 @@ static void adjust_quirks(struct us_data *us) | |||
| 551 | vid, pid, f); | 495 | vid, pid, f); |
| 552 | } | 496 | } |
| 553 | 497 | ||
| 554 | /* Find an unusual_dev descriptor (always succeeds in the current code) */ | ||
| 555 | static struct us_unusual_dev *find_unusual(const struct usb_device_id *id) | ||
| 556 | { | ||
| 557 | const int id_index = id - storage_usb_ids; | ||
| 558 | return &us_unusual_dev_list[id_index]; | ||
| 559 | } | ||
| 560 | |||
| 561 | /* Get the unusual_devs entries and the string descriptors */ | 498 | /* Get the unusual_devs entries and the string descriptors */ |
| 562 | static int get_device_info(struct us_data *us, const struct usb_device_id *id) | 499 | static int get_device_info(struct us_data *us, const struct usb_device_id *id, |
| 500 | struct us_unusual_dev *unusual_dev) | ||
| 563 | { | 501 | { |
| 564 | struct usb_device *dev = us->pusb_dev; | 502 | struct usb_device *dev = us->pusb_dev; |
| 565 | struct usb_interface_descriptor *idesc = | 503 | struct usb_interface_descriptor *idesc = |
| 566 | &us->pusb_intf->cur_altsetting->desc; | 504 | &us->pusb_intf->cur_altsetting->desc; |
| 567 | struct us_unusual_dev *unusual_dev = find_unusual(id); | ||
| 568 | 505 | ||
| 569 | /* Store the entries */ | 506 | /* Store the entries */ |
| 570 | us->unusual_dev = unusual_dev; | 507 | us->unusual_dev = unusual_dev; |
| @@ -629,7 +566,7 @@ static int get_device_info(struct us_data *us, const struct usb_device_id *id) | |||
| 629 | } | 566 | } |
| 630 | 567 | ||
| 631 | /* Get the transport settings */ | 568 | /* Get the transport settings */ |
| 632 | static int get_transport(struct us_data *us) | 569 | static void get_transport(struct us_data *us) |
| 633 | { | 570 | { |
| 634 | switch (us->protocol) { | 571 | switch (us->protocol) { |
| 635 | case US_PR_CB: | 572 | case US_PR_CB: |
| @@ -651,100 +588,11 @@ static int get_transport(struct us_data *us) | |||
| 651 | us->transport = usb_stor_Bulk_transport; | 588 | us->transport = usb_stor_Bulk_transport; |
| 652 | us->transport_reset = usb_stor_Bulk_reset; | 589 | us->transport_reset = usb_stor_Bulk_reset; |
| 653 | break; | 590 | break; |
| 654 | |||
| 655 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
| 656 | case US_PR_USBAT: | ||
| 657 | us->transport_name = "Shuttle USBAT"; | ||
| 658 | us->transport = usbat_transport; | ||
| 659 | us->transport_reset = usb_stor_CB_reset; | ||
| 660 | us->max_lun = 1; | ||
| 661 | break; | ||
| 662 | #endif | ||
| 663 | |||
| 664 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
| 665 | case US_PR_EUSB_SDDR09: | ||
| 666 | us->transport_name = "EUSB/SDDR09"; | ||
| 667 | us->transport = sddr09_transport; | ||
| 668 | us->transport_reset = usb_stor_CB_reset; | ||
| 669 | us->max_lun = 0; | ||
| 670 | break; | ||
| 671 | #endif | ||
| 672 | |||
| 673 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
| 674 | case US_PR_SDDR55: | ||
| 675 | us->transport_name = "SDDR55"; | ||
| 676 | us->transport = sddr55_transport; | ||
| 677 | us->transport_reset = sddr55_reset; | ||
| 678 | us->max_lun = 0; | ||
| 679 | break; | ||
| 680 | #endif | ||
| 681 | |||
| 682 | #ifdef CONFIG_USB_STORAGE_DPCM | ||
| 683 | case US_PR_DPCM_USB: | ||
| 684 | us->transport_name = "Control/Bulk-EUSB/SDDR09"; | ||
| 685 | us->transport = dpcm_transport; | ||
| 686 | us->transport_reset = usb_stor_CB_reset; | ||
| 687 | us->max_lun = 1; | ||
| 688 | break; | ||
| 689 | #endif | ||
| 690 | |||
| 691 | #ifdef CONFIG_USB_STORAGE_FREECOM | ||
| 692 | case US_PR_FREECOM: | ||
| 693 | us->transport_name = "Freecom"; | ||
| 694 | us->transport = freecom_transport; | ||
| 695 | us->transport_reset = usb_stor_freecom_reset; | ||
| 696 | us->max_lun = 0; | ||
| 697 | break; | ||
| 698 | #endif | ||
| 699 | |||
| 700 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
| 701 | case US_PR_DATAFAB: | ||
| 702 | us->transport_name = "Datafab Bulk-Only"; | ||
| 703 | us->transport = datafab_transport; | ||
| 704 | us->transport_reset = usb_stor_Bulk_reset; | ||
| 705 | us->max_lun = 1; | ||
| 706 | break; | ||
| 707 | #endif | ||
| 708 | |||
| 709 | #ifdef CONFIG_USB_STORAGE_JUMPSHOT | ||
| 710 | case US_PR_JUMPSHOT: | ||
| 711 | us->transport_name = "Lexar Jumpshot Control/Bulk"; | ||
| 712 | us->transport = jumpshot_transport; | ||
| 713 | us->transport_reset = usb_stor_Bulk_reset; | ||
| 714 | us->max_lun = 1; | ||
| 715 | break; | ||
| 716 | #endif | ||
| 717 | |||
| 718 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
| 719 | case US_PR_ALAUDA: | ||
| 720 | us->transport_name = "Alauda Control/Bulk"; | ||
| 721 | us->transport = alauda_transport; | ||
| 722 | us->transport_reset = usb_stor_Bulk_reset; | ||
| 723 | us->max_lun = 1; | ||
| 724 | break; | ||
| 725 | #endif | ||
| 726 | |||
| 727 | #ifdef CONFIG_USB_STORAGE_KARMA | ||
| 728 | case US_PR_KARMA: | ||
| 729 | us->transport_name = "Rio Karma/Bulk"; | ||
| 730 | us->transport = rio_karma_transport; | ||
| 731 | us->transport_reset = usb_stor_Bulk_reset; | ||
| 732 | break; | ||
| 733 | #endif | ||
| 734 | |||
| 735 | default: | ||
| 736 | return -EIO; | ||
| 737 | } | 591 | } |
| 738 | US_DEBUGP("Transport: %s\n", us->transport_name); | ||
| 739 | |||
| 740 | /* fix for single-lun devices */ | ||
| 741 | if (us->fflags & US_FL_SINGLE_LUN) | ||
| 742 | us->max_lun = 0; | ||
| 743 | return 0; | ||
| 744 | } | 592 | } |
| 745 | 593 | ||
| 746 | /* Get the protocol settings */ | 594 | /* Get the protocol settings */ |
| 747 | static int get_protocol(struct us_data *us) | 595 | static void get_protocol(struct us_data *us) |
| 748 | { | 596 | { |
| 749 | switch (us->subclass) { | 597 | switch (us->subclass) { |
| 750 | case US_SC_RBC: | 598 | case US_SC_RBC: |
| @@ -779,26 +627,7 @@ static int get_protocol(struct us_data *us) | |||
| 779 | us->protocol_name = "Uniform Floppy Interface (UFI)"; | 627 | us->protocol_name = "Uniform Floppy Interface (UFI)"; |
| 780 | us->proto_handler = usb_stor_ufi_command; | 628 | us->proto_handler = usb_stor_ufi_command; |
| 781 | break; | 629 | break; |
| 782 | |||
| 783 | #ifdef CONFIG_USB_STORAGE_ISD200 | ||
| 784 | case US_SC_ISD200: | ||
| 785 | us->protocol_name = "ISD200 ATA/ATAPI"; | ||
| 786 | us->proto_handler = isd200_ata_command; | ||
| 787 | break; | ||
| 788 | #endif | ||
| 789 | |||
| 790 | #ifdef CONFIG_USB_STORAGE_CYPRESS_ATACB | ||
| 791 | case US_SC_CYP_ATACB: | ||
| 792 | us->protocol_name = "Transparent SCSI with Cypress ATACB"; | ||
| 793 | us->proto_handler = cypress_atacb_passthrough; | ||
| 794 | break; | ||
| 795 | #endif | ||
| 796 | |||
| 797 | default: | ||
| 798 | return -EIO; | ||
| 799 | } | 630 | } |
| 800 | US_DEBUGP("Protocol: %s\n", us->protocol_name); | ||
| 801 | return 0; | ||
| 802 | } | 631 | } |
| 803 | 632 | ||
| 804 | /* Get the pipe settings */ | 633 | /* Get the pipe settings */ |
| @@ -846,12 +675,12 @@ static int get_pipes(struct us_data *us) | |||
| 846 | us->send_ctrl_pipe = usb_sndctrlpipe(us->pusb_dev, 0); | 675 | us->send_ctrl_pipe = usb_sndctrlpipe(us->pusb_dev, 0); |
| 847 | us->recv_ctrl_pipe = usb_rcvctrlpipe(us->pusb_dev, 0); | 676 | us->recv_ctrl_pipe = usb_rcvctrlpipe(us->pusb_dev, 0); |
| 848 | us->send_bulk_pipe = usb_sndbulkpipe(us->pusb_dev, | 677 | us->send_bulk_pipe = usb_sndbulkpipe(us->pusb_dev, |
| 849 | ep_out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); | 678 | usb_endpoint_num(ep_out)); |
| 850 | us->recv_bulk_pipe = usb_rcvbulkpipe(us->pusb_dev, | 679 | us->recv_bulk_pipe = usb_rcvbulkpipe(us->pusb_dev, |
| 851 | ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); | 680 | usb_endpoint_num(ep_in)); |
| 852 | if (ep_int) { | 681 | if (ep_int) { |
| 853 | us->recv_intr_pipe = usb_rcvintpipe(us->pusb_dev, | 682 | us->recv_intr_pipe = usb_rcvintpipe(us->pusb_dev, |
| 854 | ep_int->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); | 683 | usb_endpoint_num(ep_int)); |
| 855 | us->ep_bInterval = ep_int->bInterval; | 684 | us->ep_bInterval = ep_int->bInterval; |
| 856 | } | 685 | } |
| 857 | return 0; | 686 | return 0; |
| @@ -1012,17 +841,15 @@ static int usb_stor_scan_thread(void * __us) | |||
| 1012 | } | 841 | } |
| 1013 | 842 | ||
| 1014 | 843 | ||
| 1015 | /* Probe to see if we can drive a newly-connected USB device */ | 844 | /* First part of general USB mass-storage probing */ |
| 1016 | static int storage_probe(struct usb_interface *intf, | 845 | int usb_stor_probe1(struct us_data **pus, |
| 1017 | const struct usb_device_id *id) | 846 | struct usb_interface *intf, |
| 847 | const struct usb_device_id *id, | ||
| 848 | struct us_unusual_dev *unusual_dev) | ||
| 1018 | { | 849 | { |
| 1019 | struct Scsi_Host *host; | 850 | struct Scsi_Host *host; |
| 1020 | struct us_data *us; | 851 | struct us_data *us; |
| 1021 | int result; | 852 | int result; |
| 1022 | struct task_struct *th; | ||
| 1023 | |||
| 1024 | if (usb_usual_check_type(id, USB_US_TYPE_STOR)) | ||
| 1025 | return -ENXIO; | ||
| 1026 | 853 | ||
| 1027 | US_DEBUGP("USB Mass Storage device detected\n"); | 854 | US_DEBUGP("USB Mass Storage device detected\n"); |
| 1028 | 855 | ||
| @@ -1041,7 +868,7 @@ static int storage_probe(struct usb_interface *intf, | |||
| 1041 | * Allow 16-byte CDBs and thus > 2TB | 868 | * Allow 16-byte CDBs and thus > 2TB |
| 1042 | */ | 869 | */ |
| 1043 | host->max_cmd_len = 16; | 870 | host->max_cmd_len = 16; |
| 1044 | us = host_to_us(host); | 871 | *pus = us = host_to_us(host); |
| 1045 | memset(us, 0, sizeof(struct us_data)); | 872 | memset(us, 0, sizeof(struct us_data)); |
| 1046 | mutex_init(&(us->dev_mutex)); | 873 | mutex_init(&(us->dev_mutex)); |
| 1047 | init_completion(&us->cmnd_ready); | 874 | init_completion(&us->cmnd_ready); |
| @@ -1054,24 +881,46 @@ static int storage_probe(struct usb_interface *intf, | |||
| 1054 | if (result) | 881 | if (result) |
| 1055 | goto BadDevice; | 882 | goto BadDevice; |
| 1056 | 883 | ||
| 1057 | /* | 884 | /* Get the unusual_devs entries and the descriptors */ |
| 1058 | * Get the unusual_devs entries and the descriptors | 885 | result = get_device_info(us, id, unusual_dev); |
| 1059 | * | ||
| 1060 | * id_index is calculated in the declaration to be the index number | ||
| 1061 | * of the match from the usb_device_id table, so we can find the | ||
| 1062 | * corresponding entry in the private table. | ||
| 1063 | */ | ||
| 1064 | result = get_device_info(us, id); | ||
| 1065 | if (result) | 886 | if (result) |
| 1066 | goto BadDevice; | 887 | goto BadDevice; |
| 1067 | 888 | ||
| 1068 | /* Get the transport, protocol, and pipe settings */ | 889 | /* Get standard transport and protocol settings */ |
| 1069 | result = get_transport(us); | 890 | get_transport(us); |
| 1070 | if (result) | 891 | get_protocol(us); |
| 1071 | goto BadDevice; | 892 | |
| 1072 | result = get_protocol(us); | 893 | /* Give the caller a chance to fill in specialized transport |
| 1073 | if (result) | 894 | * or protocol settings. |
| 895 | */ | ||
| 896 | return 0; | ||
| 897 | |||
| 898 | BadDevice: | ||
| 899 | US_DEBUGP("storage_probe() failed\n"); | ||
| 900 | release_everything(us); | ||
| 901 | return result; | ||
| 902 | } | ||
| 903 | EXPORT_SYMBOL_GPL(usb_stor_probe1); | ||
| 904 | |||
| 905 | /* Second part of general USB mass-storage probing */ | ||
| 906 | int usb_stor_probe2(struct us_data *us) | ||
| 907 | { | ||
| 908 | struct task_struct *th; | ||
| 909 | int result; | ||
| 910 | |||
| 911 | /* Make sure the transport and protocol have both been set */ | ||
| 912 | if (!us->transport || !us->proto_handler) { | ||
| 913 | result = -ENXIO; | ||
| 1074 | goto BadDevice; | 914 | goto BadDevice; |
| 915 | } | ||
| 916 | US_DEBUGP("Transport: %s\n", us->transport_name); | ||
| 917 | US_DEBUGP("Protocol: %s\n", us->protocol_name); | ||
| 918 | |||
| 919 | /* fix for single-lun devices */ | ||
| 920 | if (us->fflags & US_FL_SINGLE_LUN) | ||
| 921 | us->max_lun = 0; | ||
| 922 | |||
| 923 | /* Find the endpoints and calculate pipe values */ | ||
| 1075 | result = get_pipes(us); | 924 | result = get_pipes(us); |
| 1076 | if (result) | 925 | if (result) |
| 1077 | goto BadDevice; | 926 | goto BadDevice; |
| @@ -1080,7 +929,7 @@ static int storage_probe(struct usb_interface *intf, | |||
| 1080 | result = usb_stor_acquire_resources(us); | 929 | result = usb_stor_acquire_resources(us); |
| 1081 | if (result) | 930 | if (result) |
| 1082 | goto BadDevice; | 931 | goto BadDevice; |
| 1083 | result = scsi_add_host(host, &intf->dev); | 932 | result = scsi_add_host(us_to_host(us), &us->pusb_intf->dev); |
| 1084 | if (result) { | 933 | if (result) { |
| 1085 | printk(KERN_WARNING USB_STORAGE | 934 | printk(KERN_WARNING USB_STORAGE |
| 1086 | "Unable to add the scsi host\n"); | 935 | "Unable to add the scsi host\n"); |
| @@ -1108,9 +957,10 @@ BadDevice: | |||
| 1108 | release_everything(us); | 957 | release_everything(us); |
| 1109 | return result; | 958 | return result; |
| 1110 | } | 959 | } |
| 960 | EXPORT_SYMBOL_GPL(usb_stor_probe2); | ||
| 1111 | 961 | ||
| 1112 | /* Handle a disconnect event from the USB core */ | 962 | /* Handle a USB mass-storage disconnect */ |
| 1113 | static void storage_disconnect(struct usb_interface *intf) | 963 | void usb_stor_disconnect(struct usb_interface *intf) |
| 1114 | { | 964 | { |
| 1115 | struct us_data *us = usb_get_intfdata(intf); | 965 | struct us_data *us = usb_get_intfdata(intf); |
| 1116 | 966 | ||
| @@ -1118,6 +968,42 @@ static void storage_disconnect(struct usb_interface *intf) | |||
| 1118 | quiesce_and_remove_host(us); | 968 | quiesce_and_remove_host(us); |
| 1119 | release_everything(us); | 969 | release_everything(us); |
| 1120 | } | 970 | } |
| 971 | EXPORT_SYMBOL_GPL(usb_stor_disconnect); | ||
| 972 | |||
| 973 | /* The main probe routine for standard devices */ | ||
| 974 | static int storage_probe(struct usb_interface *intf, | ||
| 975 | const struct usb_device_id *id) | ||
| 976 | { | ||
| 977 | struct us_data *us; | ||
| 978 | int result; | ||
| 979 | |||
| 980 | /* | ||
| 981 | * If libusual is configured, let it decide whether a standard | ||
| 982 | * device should be handled by usb-storage or by ub. | ||
| 983 | * If the device isn't standard (is handled by a subdriver | ||
| 984 | * module) then don't accept it. | ||
| 985 | */ | ||
| 986 | if (usb_usual_check_type(id, USB_US_TYPE_STOR) || | ||
| 987 | usb_usual_ignore_device(intf)) | ||
| 988 | return -ENXIO; | ||
| 989 | |||
| 990 | /* | ||
| 991 | * Call the general probe procedures. | ||
| 992 | * | ||
| 993 | * The unusual_dev_list array is parallel to the usb_storage_usb_ids | ||
| 994 | * table, so we use the index of the id entry to find the | ||
| 995 | * corresponding unusual_devs entry. | ||
| 996 | */ | ||
| 997 | result = usb_stor_probe1(&us, intf, id, | ||
| 998 | (id - usb_storage_usb_ids) + us_unusual_dev_list); | ||
| 999 | if (result) | ||
| 1000 | return result; | ||
| 1001 | |||
| 1002 | /* No special transport or protocol settings in the main module */ | ||
| 1003 | |||
| 1004 | result = usb_stor_probe2(us); | ||
| 1005 | return result; | ||
| 1006 | } | ||
| 1121 | 1007 | ||
| 1122 | /*********************************************************************** | 1008 | /*********************************************************************** |
| 1123 | * Initialization and registration | 1009 | * Initialization and registration |
| @@ -1126,15 +1012,13 @@ static void storage_disconnect(struct usb_interface *intf) | |||
| 1126 | static struct usb_driver usb_storage_driver = { | 1012 | static struct usb_driver usb_storage_driver = { |
| 1127 | .name = "usb-storage", | 1013 | .name = "usb-storage", |
| 1128 | .probe = storage_probe, | 1014 | .probe = storage_probe, |
| 1129 | .disconnect = storage_disconnect, | 1015 | .disconnect = usb_stor_disconnect, |
| 1130 | #ifdef CONFIG_PM | 1016 | .suspend = usb_stor_suspend, |
| 1131 | .suspend = storage_suspend, | 1017 | .resume = usb_stor_resume, |
| 1132 | .resume = storage_resume, | 1018 | .reset_resume = usb_stor_reset_resume, |
| 1133 | .reset_resume = storage_reset_resume, | 1019 | .pre_reset = usb_stor_pre_reset, |
| 1134 | #endif | 1020 | .post_reset = usb_stor_post_reset, |
| 1135 | .pre_reset = storage_pre_reset, | 1021 | .id_table = usb_storage_usb_ids, |
| 1136 | .post_reset = storage_post_reset, | ||
| 1137 | .id_table = storage_usb_ids, | ||
| 1138 | .soft_unbind = 1, | 1022 | .soft_unbind = 1, |
| 1139 | }; | 1023 | }; |
| 1140 | 1024 | ||
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 65e674e4be99..2609efb2bd7e 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h | |||
| @@ -177,4 +177,25 @@ extern void fill_inquiry_response(struct us_data *us, | |||
| 177 | #define scsi_unlock(host) spin_unlock_irq(host->host_lock) | 177 | #define scsi_unlock(host) spin_unlock_irq(host->host_lock) |
| 178 | #define scsi_lock(host) spin_lock_irq(host->host_lock) | 178 | #define scsi_lock(host) spin_lock_irq(host->host_lock) |
| 179 | 179 | ||
| 180 | /* General routines provided by the usb-storage standard core */ | ||
| 181 | #ifdef CONFIG_PM | ||
| 182 | extern int usb_stor_suspend(struct usb_interface *iface, pm_message_t message); | ||
| 183 | extern int usb_stor_resume(struct usb_interface *iface); | ||
| 184 | extern int usb_stor_reset_resume(struct usb_interface *iface); | ||
| 185 | #else | ||
| 186 | #define usb_stor_suspend NULL | ||
| 187 | #define usb_stor_resume NULL | ||
| 188 | #define usb_stor_reset_resume NULL | ||
| 189 | #endif | ||
| 190 | |||
| 191 | extern int usb_stor_pre_reset(struct usb_interface *iface); | ||
| 192 | extern int usb_stor_post_reset(struct usb_interface *iface); | ||
| 193 | |||
| 194 | extern int usb_stor_probe1(struct us_data **pus, | ||
| 195 | struct usb_interface *intf, | ||
| 196 | const struct usb_device_id *id, | ||
| 197 | struct us_unusual_dev *unusual_dev); | ||
| 198 | extern int usb_stor_probe2(struct us_data *us); | ||
| 199 | extern void usb_stor_disconnect(struct usb_interface *intf); | ||
| 200 | |||
| 180 | #endif | 201 | #endif |
diff --git a/drivers/usb/storage/usual-tables.c b/drivers/usb/storage/usual-tables.c new file mode 100644 index 000000000000..468bde7d1971 --- /dev/null +++ b/drivers/usb/storage/usual-tables.c | |||
| @@ -0,0 +1,116 @@ | |||
| 1 | /* Driver for USB Mass Storage devices | ||
| 2 | * Usual Tables File for usb-storage and libusual | ||
| 3 | * | ||
| 4 | * Copyright (C) 2009 Alan Stern (stern@rowland.harvard.edu) | ||
| 5 | * | ||
| 6 | * Please see http://www.one-eyed-alien.net/~mdharm/linux-usb for more | ||
| 7 | * information about this driver. | ||
| 8 | * | ||
| 9 | * This program is free software; you can redistribute it and/or modify it | ||
| 10 | * under the terms of the GNU General Public License as published by the | ||
| 11 | * Free Software Foundation; either version 2, or (at your option) any | ||
| 12 | * later version. | ||
| 13 | * | ||
| 14 | * This program is distributed in the hope that it will be useful, but | ||
| 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
| 17 | * General Public License for more details. | ||
| 18 | * | ||
| 19 | * You should have received a copy of the GNU General Public License along | ||
| 20 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
| 21 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 22 | */ | ||
| 23 | |||
| 24 | #include <linux/kernel.h> | ||
| 25 | #include <linux/module.h> | ||
| 26 | #include <linux/usb.h> | ||
| 27 | #include <linux/usb_usual.h> | ||
| 28 | |||
| 29 | |||
| 30 | /* | ||
| 31 | * The table of devices | ||
| 32 | */ | ||
| 33 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
| 34 | vendorName, productName, useProtocol, useTransport, \ | ||
| 35 | initFunction, flags) \ | ||
| 36 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
| 37 | .driver_info = (flags)|(USB_US_TYPE_STOR<<24) } | ||
| 38 | |||
| 39 | #define COMPLIANT_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
| 40 | vendorName, productName, useProtocol, useTransport, \ | ||
| 41 | initFunction, flags) \ | ||
| 42 | { USB_DEVICE_VER(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax), \ | ||
| 43 | .driver_info = (flags) } | ||
| 44 | |||
| 45 | #define USUAL_DEV(useProto, useTrans, useType) \ | ||
| 46 | { USB_INTERFACE_INFO(USB_CLASS_MASS_STORAGE, useProto, useTrans), \ | ||
| 47 | .driver_info = ((useType)<<24) } | ||
| 48 | |||
| 49 | struct usb_device_id usb_storage_usb_ids[] = { | ||
| 50 | # include "unusual_devs.h" | ||
| 51 | { } /* Terminating entry */ | ||
| 52 | }; | ||
| 53 | EXPORT_SYMBOL_GPL(usb_storage_usb_ids); | ||
| 54 | |||
| 55 | MODULE_DEVICE_TABLE(usb, usb_storage_usb_ids); | ||
| 56 | |||
| 57 | #undef UNUSUAL_DEV | ||
| 58 | #undef COMPLIANT_DEV | ||
| 59 | #undef USUAL_DEV | ||
| 60 | |||
| 61 | |||
| 62 | /* | ||
| 63 | * The table of devices to ignore | ||
| 64 | */ | ||
| 65 | struct ignore_entry { | ||
| 66 | u16 vid, pid, bcdmin, bcdmax; | ||
| 67 | }; | ||
| 68 | |||
| 69 | #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \ | ||
| 70 | vendorName, productName, useProtocol, useTransport, \ | ||
| 71 | initFunction, flags) \ | ||
| 72 | { \ | ||
| 73 | .vid = id_vendor, \ | ||
| 74 | .pid = id_product, \ | ||
| 75 | .bcdmin = bcdDeviceMin, \ | ||
| 76 | .bcdmax = bcdDeviceMax, \ | ||
| 77 | } | ||
| 78 | |||
| 79 | static struct ignore_entry ignore_ids[] = { | ||
| 80 | # include "unusual_alauda.h" | ||
| 81 | # include "unusual_cypress.h" | ||
| 82 | # include "unusual_datafab.h" | ||
| 83 | # include "unusual_freecom.h" | ||
| 84 | # include "unusual_isd200.h" | ||
| 85 | # include "unusual_jumpshot.h" | ||
| 86 | # include "unusual_karma.h" | ||
| 87 | # include "unusual_onetouch.h" | ||
| 88 | # include "unusual_sddr09.h" | ||
| 89 | # include "unusual_sddr55.h" | ||
| 90 | # include "unusual_usbat.h" | ||
| 91 | { } /* Terminating entry */ | ||
| 92 | }; | ||
| 93 | |||
| 94 | #undef UNUSUAL_DEV | ||
| 95 | |||
| 96 | |||
| 97 | /* Return an error if a device is in the ignore_ids list */ | ||
| 98 | int usb_usual_ignore_device(struct usb_interface *intf) | ||
| 99 | { | ||
| 100 | struct usb_device *udev; | ||
| 101 | unsigned vid, pid, bcd; | ||
| 102 | struct ignore_entry *p; | ||
| 103 | |||
| 104 | udev = interface_to_usbdev(intf); | ||
| 105 | vid = le16_to_cpu(udev->descriptor.idVendor); | ||
| 106 | pid = le16_to_cpu(udev->descriptor.idProduct); | ||
| 107 | bcd = le16_to_cpu(udev->descriptor.bcdDevice); | ||
| 108 | |||
| 109 | for (p = ignore_ids; p->vid; ++p) { | ||
| 110 | if (p->vid == vid && p->pid == pid && | ||
| 111 | p->bcdmin <= bcd && p->bcdmax >= bcd) | ||
| 112 | return -ENXIO; | ||
| 113 | } | ||
| 114 | return 0; | ||
| 115 | } | ||
| 116 | EXPORT_SYMBOL_GPL(usb_usual_ignore_device); | ||
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index be76084c8d7e..60ba631e99c2 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c | |||
| @@ -410,7 +410,9 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i | |||
| 410 | } | 410 | } |
| 411 | 411 | ||
| 412 | /* let the user know what node this device is now attached to */ | 412 | /* let the user know what node this device is now attached to */ |
| 413 | info("USB Skeleton device now attached to USBSkel-%d", interface->minor); | 413 | dev_info(&interface->dev, |
| 414 | "USB Skeleton device now attached to USBSkel-%d", | ||
| 415 | interface->minor); | ||
| 414 | return 0; | 416 | return 0; |
| 415 | 417 | ||
| 416 | error: | 418 | error: |
| @@ -441,7 +443,7 @@ static void skel_disconnect(struct usb_interface *interface) | |||
| 441 | /* decrement our usage count */ | 443 | /* decrement our usage count */ |
| 442 | kref_put(&dev->kref, skel_delete); | 444 | kref_put(&dev->kref, skel_delete); |
| 443 | 445 | ||
| 444 | info("USB Skeleton #%d now disconnected", minor); | 446 | dev_info(&interface->dev, "USB Skeleton #%d now disconnected", minor); |
| 445 | } | 447 | } |
| 446 | 448 | ||
| 447 | static void skel_draw_down(struct usb_skel *dev) | 449 | static void skel_draw_down(struct usb_skel *dev) |
diff --git a/drivers/usb/wusbcore/cbaf.c b/drivers/usb/wusbcore/cbaf.c index 1335cbe1191d..25eae405f622 100644 --- a/drivers/usb/wusbcore/cbaf.c +++ b/drivers/usb/wusbcore/cbaf.c | |||
| @@ -638,8 +638,7 @@ static void cbaf_disconnect(struct usb_interface *iface) | |||
| 638 | usb_put_intf(iface); | 638 | usb_put_intf(iface); |
| 639 | kfree(cbaf->buffer); | 639 | kfree(cbaf->buffer); |
| 640 | /* paranoia: clean up crypto keys */ | 640 | /* paranoia: clean up crypto keys */ |
| 641 | memset(cbaf, 0, sizeof(*cbaf)); | 641 | kzfree(cbaf); |
| 642 | kfree(cbaf); | ||
| 643 | } | 642 | } |
| 644 | 643 | ||
| 645 | static struct usb_device_id cbaf_id_table[] = { | 644 | static struct usb_device_id cbaf_id_table[] = { |
diff --git a/drivers/usb/wusbcore/devconnect.c b/drivers/usb/wusbcore/devconnect.c index 8e18141bb2e0..f0aac0cf315a 100644 --- a/drivers/usb/wusbcore/devconnect.c +++ b/drivers/usb/wusbcore/devconnect.c | |||
| @@ -889,6 +889,8 @@ static void wusb_dev_add_ncb(struct usb_device *usb_dev) | |||
| 889 | if (usb_dev->wusb == 0 || usb_dev->devnum == 1) | 889 | if (usb_dev->wusb == 0 || usb_dev->devnum == 1) |
| 890 | return; /* skip non wusb and wusb RHs */ | 890 | return; /* skip non wusb and wusb RHs */ |
| 891 | 891 | ||
| 892 | usb_set_device_state(usb_dev, USB_STATE_UNAUTHENTICATED); | ||
| 893 | |||
| 892 | wusbhc = wusbhc_get_by_usb_dev(usb_dev); | 894 | wusbhc = wusbhc_get_by_usb_dev(usb_dev); |
| 893 | if (wusbhc == NULL) | 895 | if (wusbhc == NULL) |
| 894 | goto error_nodev; | 896 | goto error_nodev; |
diff --git a/drivers/usb/wusbcore/security.c b/drivers/usb/wusbcore/security.c index f4aa28eca70d..8118db7f1d8d 100644 --- a/drivers/usb/wusbcore/security.c +++ b/drivers/usb/wusbcore/security.c | |||
| @@ -312,6 +312,7 @@ int wusb_dev_update_address(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev) | |||
| 312 | result = wusb_set_dev_addr(wusbhc, wusb_dev, 0); | 312 | result = wusb_set_dev_addr(wusbhc, wusb_dev, 0); |
| 313 | if (result < 0) | 313 | if (result < 0) |
| 314 | goto error_addr0; | 314 | goto error_addr0; |
| 315 | usb_set_device_state(usb_dev, USB_STATE_DEFAULT); | ||
| 315 | usb_ep0_reinit(usb_dev); | 316 | usb_ep0_reinit(usb_dev); |
| 316 | 317 | ||
| 317 | /* Set new (authenticated) address. */ | 318 | /* Set new (authenticated) address. */ |
| @@ -327,6 +328,7 @@ int wusb_dev_update_address(struct wusbhc *wusbhc, struct wusb_dev *wusb_dev) | |||
| 327 | result = wusb_set_dev_addr(wusbhc, wusb_dev, new_address); | 328 | result = wusb_set_dev_addr(wusbhc, wusb_dev, new_address); |
| 328 | if (result < 0) | 329 | if (result < 0) |
| 329 | goto error_addr; | 330 | goto error_addr; |
| 331 | usb_set_device_state(usb_dev, USB_STATE_ADDRESS); | ||
| 330 | usb_ep0_reinit(usb_dev); | 332 | usb_ep0_reinit(usb_dev); |
| 331 | usb_dev->authenticated = 1; | 333 | usb_dev->authenticated = 1; |
| 332 | error_addr: | 334 | error_addr: |
