diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-26 14:17:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-26 14:17:39 -0400 |
commit | 61a091827e273650b39eb87c799a6d260913fa0b (patch) | |
tree | 19f0a4840fc90da6ca3787ee7efacb5bb0c6c7a2 /drivers/usb | |
parent | 0c93ea4064a209cdc36de8a9a3003d43d08f46f7 (diff) | |
parent | fd8345f8dea93691b0ceba55146088d8c05415f6 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6: (97 commits)
USB: qcserial: add device id for HP devices
USB: isp1760: Add a delay before reading the SKIPMAP registers in isp1760-hcd.c
USB: allow malformed LANGID descriptors
USB: pxa27x_udc: typo fixes and code cleanups
USB: gadget: gadget zero uses new suspend/resume hooks
USB: gadget: composite device-level suspend/resume hooks
USB: r8a66597-hcd: suspend/resume support
USB: more u32 conversion after transfer_buffer_length and actual_length
USB: Fix cp2101 USB serial device driver termios functions for console use
USB: CP2101 New Device ID
USB: ipaq: handle 4 endpoint devices
USB: S3C: Move usb-control.h to platform include
USB: ohci-hcd: Add ARCH_S3C24XX to the ohci-s3c2410.c glue
USB: pedantic: spelling correction in comment for ch9.h
USB: host: fix sparse warning: Using plain integer as NULL pointer
USB: ohci-s3c2410: fix name of bus clock
USB: ohci-s3c2410: remove <mach/hardware.h> include
USB: serial: rename cp2101 driver to cp210x
USB: CP2101 Reduce Error Logging
USB: CP2101 Support AN205 baud rates
...
Diffstat (limited to 'drivers/usb')
145 files changed, 4984 insertions, 3606 deletions
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 7f4e5eb1dc80..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> |
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..d3c2464dee82 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 | ||
@@ -2646,7 +2646,7 @@ static int send_status(struct fsg_dev *fsg) | |||
2646 | struct bulk_cs_wrap *csw = bh->buf; | 2646 | struct bulk_cs_wrap *csw = bh->buf; |
2647 | 2647 | ||
2648 | /* Store and send the Bulk-only CSW */ | 2648 | /* Store and send the Bulk-only CSW */ |
2649 | csw->Signature = __constant_cpu_to_le32(USB_BULK_CS_SIG); | 2649 | csw->Signature = cpu_to_le32(USB_BULK_CS_SIG); |
2650 | csw->Tag = fsg->tag; | 2650 | csw->Tag = fsg->tag; |
2651 | csw->Residue = cpu_to_le32(fsg->residue); | 2651 | csw->Residue = cpu_to_le32(fsg->residue); |
2652 | csw->Status = status; | 2652 | csw->Status = status; |
@@ -3089,7 +3089,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
3089 | 3089 | ||
3090 | /* Is the CBW valid? */ | 3090 | /* Is the CBW valid? */ |
3091 | if (req->actual != USB_BULK_CB_WRAP_LEN || | 3091 | if (req->actual != USB_BULK_CB_WRAP_LEN || |
3092 | cbw->Signature != __constant_cpu_to_le32( | 3092 | cbw->Signature != cpu_to_le32( |
3093 | USB_BULK_CB_SIG)) { | 3093 | USB_BULK_CB_SIG)) { |
3094 | DBG(fsg, "invalid CBW: len %u sig 0x%x\n", | 3094 | DBG(fsg, "invalid CBW: len %u sig 0x%x\n", |
3095 | req->actual, | 3095 | 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 14e09abbddfc..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 | }; |
@@ -1226,7 +1226,7 @@ autoconf_fail: | |||
1226 | */ | 1226 | */ |
1227 | pr_warning("%s: controller '%s' not recognized\n", | 1227 | pr_warning("%s: controller '%s' not recognized\n", |
1228 | shortname, gadget->name); | 1228 | shortname, gadget->name); |
1229 | device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); | 1229 | device_desc.bcdDevice = cpu_to_le16(0x9999); |
1230 | } | 1230 | } |
1231 | 1231 | ||
1232 | 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 cd67ac75e624..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 | |||
1007 | if (intr & (INTR_WAKEUP | INTR_SUSPEND | INTR_RESUME | INTR_RESET_START | ||
1008 | | INTR_RESET_STOP | INTR_CFG_CHG)) { | ||
1009 | dump_intr(__func__, intr, imx_usb->dev); | ||
1010 | dump_usb_stat(__func__, imx_usb); | ||
1011 | } | ||
1012 | |||
1013 | if (!imx_usb->driver) { | ||
1014 | /*imx_udc_disable(imx_usb);*/ | ||
1015 | goto end_irq; | ||
1016 | } | ||
1017 | |||
1018 | if (intr & INTR_WAKEUP) { | ||
1019 | if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN | ||
1020 | && imx_usb->driver && imx_usb->driver->resume) | ||
1021 | imx_usb->driver->resume(&imx_usb->gadget); | ||
1022 | imx_usb->set_config = 0; | ||
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 | 1026 | ||
1034 | if (intr & INTR_RESET_START) { | 1027 | local_irq_disable(); |
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 | |||
1041 | if (intr & INTR_RESET_STOP) | ||
1042 | imx_usb->gadget.speed = USB_SPEED_FULL; | ||
1043 | 1028 | ||
1044 | if (intr & INTR_CFG_CHG) { | 1029 | temp = __raw_readl(imx_usb->base + USB_STAT); |
1045 | __raw_writel(INTR_CFG_CHG, imx_usb->base + USB_INTR); | 1030 | cfg = (temp & STAT_CFG) >> 5; |
1046 | temp = __raw_readl(imx_usb->base + USB_STAT); | 1031 | intf = (temp & STAT_INTF) >> 3; |
1047 | cfg = (temp & STAT_CFG) >> 5; | 1032 | alt = temp & STAT_ALTSET; |
1048 | intf = (temp & STAT_INTF) >> 3; | ||
1049 | alt = temp & STAT_ALTSET; | ||
1050 | 1033 | ||
1051 | D_REQ(imx_usb->dev, | 1034 | D_REQ(imx_usb->dev, |
1052 | "<%s> orig config C=%d, I=%d, A=%d / " | 1035 | "<%s> orig config C=%d, I=%d, A=%d / " |
1053 | "req config C=%d, I=%d, A=%d\n", | 1036 | "req config C=%d, I=%d, A=%d\n", |
1054 | __func__, imx_usb->cfg, imx_usb->intf, imx_usb->alt, | 1037 | __func__, imx_usb->cfg, imx_usb->intf, imx_usb->alt, |
1055 | cfg, intf, alt); | 1038 | cfg, intf, alt); |
1056 | 1039 | ||
1057 | if (cfg != 1 && cfg != 2) | 1040 | if (cfg == 1 || cfg == 2) { |
1058 | goto end_irq; | ||
1059 | 1041 | ||
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 | ||
@@ -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/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/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 7658589edb1c..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 |
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: |