diff options
author | Haavard Skinnemoen <haavard.skinnemoen@atmel.com> | 2009-03-27 11:14:38 -0400 |
---|---|---|
committer | Haavard Skinnemoen <haavard.skinnemoen@atmel.com> | 2009-03-27 11:14:38 -0400 |
commit | b92efa9abffc4a634cd2e7a0f81f8aa6310d67c9 (patch) | |
tree | 9847508d9b8d4e585f90db4a453bfbc3700c997e /drivers/usb | |
parent | a16fffdd8eb95ebab7dc22414896fe6493951e0e (diff) | |
parent | be0ea69674ed95e1e98cb3687a241badc756d228 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6 into avr32-arch
Diffstat (limited to 'drivers/usb')
187 files changed, 9527 insertions, 4086 deletions
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 83babb0a1df7..c6c816b7ecb5 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
@@ -47,6 +47,7 @@ config USB_ARCH_HAS_OHCI | |||
47 | default y if CPU_SUBTYPE_SH7720 | 47 | default y if CPU_SUBTYPE_SH7720 |
48 | default y if CPU_SUBTYPE_SH7721 | 48 | default y if CPU_SUBTYPE_SH7721 |
49 | default y if CPU_SUBTYPE_SH7763 | 49 | default y if CPU_SUBTYPE_SH7763 |
50 | default y if CPU_SUBTYPE_SH7786 | ||
50 | # more: | 51 | # more: |
51 | default PCI | 52 | default PCI |
52 | 53 | ||
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index 8b7c419b876e..89299a5ce168 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile | |||
@@ -11,12 +11,15 @@ obj-$(CONFIG_USB_MON) += mon/ | |||
11 | obj-$(CONFIG_PCI) += host/ | 11 | obj-$(CONFIG_PCI) += host/ |
12 | obj-$(CONFIG_USB_EHCI_HCD) += host/ | 12 | obj-$(CONFIG_USB_EHCI_HCD) += host/ |
13 | obj-$(CONFIG_USB_ISP116X_HCD) += host/ | 13 | obj-$(CONFIG_USB_ISP116X_HCD) += host/ |
14 | obj-$(CONFIG_USB_ISP1760_HCD) += host/ | ||
14 | obj-$(CONFIG_USB_OHCI_HCD) += host/ | 15 | obj-$(CONFIG_USB_OHCI_HCD) += host/ |
15 | obj-$(CONFIG_USB_UHCI_HCD) += host/ | 16 | obj-$(CONFIG_USB_UHCI_HCD) += host/ |
17 | obj-$(CONFIG_USB_FHCI_HCD) += host/ | ||
16 | obj-$(CONFIG_USB_SL811_HCD) += host/ | 18 | obj-$(CONFIG_USB_SL811_HCD) += host/ |
17 | obj-$(CONFIG_USB_U132_HCD) += host/ | 19 | obj-$(CONFIG_USB_U132_HCD) += host/ |
18 | obj-$(CONFIG_USB_R8A66597_HCD) += host/ | 20 | obj-$(CONFIG_USB_R8A66597_HCD) += host/ |
19 | obj-$(CONFIG_USB_HWA_HCD) += host/ | 21 | obj-$(CONFIG_USB_HWA_HCD) += host/ |
22 | obj-$(CONFIG_USB_ISP1760_HCD) += host/ | ||
20 | 23 | ||
21 | obj-$(CONFIG_USB_C67X00_HCD) += c67x00/ | 24 | obj-$(CONFIG_USB_C67X00_HCD) += c67x00/ |
22 | 25 | ||
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 5ed4ae07bac1..6789089e2461 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c | |||
@@ -485,7 +485,7 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, | |||
485 | usb_err(instance->usbatm, "requested transfer size too large (%d, %d)\n", | 485 | usb_err(instance->usbatm, "requested transfer size too large (%d, %d)\n", |
486 | wbuflen, rbuflen); | 486 | wbuflen, rbuflen); |
487 | ret = -ENOMEM; | 487 | ret = -ENOMEM; |
488 | goto fail; | 488 | goto err; |
489 | } | 489 | } |
490 | 490 | ||
491 | mutex_lock(&instance->cm_serialize); | 491 | mutex_lock(&instance->cm_serialize); |
@@ -565,6 +565,7 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, | |||
565 | dbg("cm %#x", cm); | 565 | dbg("cm %#x", cm); |
566 | fail: | 566 | fail: |
567 | mutex_unlock(&instance->cm_serialize); | 567 | mutex_unlock(&instance->cm_serialize); |
568 | err: | ||
568 | return ret; | 569 | return ret; |
569 | } | 570 | } |
570 | 571 | ||
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 00b47ea24f86..b3d5a23ab56f 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -1349,6 +1349,9 @@ static struct usb_device_id acm_ids[] = { | |||
1349 | { USB_DEVICE(0x0e8d, 0x0003), /* FIREFLY, MediaTek Inc; andrey.arapov@gmail.com */ | 1349 | { USB_DEVICE(0x0e8d, 0x0003), /* FIREFLY, MediaTek Inc; andrey.arapov@gmail.com */ |
1350 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ | 1350 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ |
1351 | }, | 1351 | }, |
1352 | { USB_DEVICE(0x0e8d, 0x3329), /* MediaTek Inc GPS */ | ||
1353 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ | ||
1354 | }, | ||
1352 | { USB_DEVICE(0x0482, 0x0203), /* KYOCERA AH-K3001V */ | 1355 | { USB_DEVICE(0x0482, 0x0203), /* KYOCERA AH-K3001V */ |
1353 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ | 1356 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ |
1354 | }, | 1357 | }, |
@@ -1370,6 +1373,18 @@ static struct usb_device_id acm_ids[] = { | |||
1370 | { USB_DEVICE(0x0572, 0x1321), /* Conexant USB MODEM CX93010 */ | 1373 | { USB_DEVICE(0x0572, 0x1321), /* Conexant USB MODEM CX93010 */ |
1371 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ | 1374 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ |
1372 | }, | 1375 | }, |
1376 | { USB_DEVICE(0x0572, 0x1324), /* Conexant USB MODEM RD02-D400 */ | ||
1377 | .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ | ||
1378 | }, | ||
1379 | { USB_DEVICE(0x22b8, 0x6425), /* Motorola MOTOMAGX phones */ | ||
1380 | }, | ||
1381 | { USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */ | ||
1382 | .driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on | ||
1383 | data interface instead of | ||
1384 | communications interface. | ||
1385 | Maybe we should define a new | ||
1386 | quirk for this. */ | ||
1387 | }, | ||
1373 | 1388 | ||
1374 | /* control interfaces with various AT-command sets */ | 1389 | /* control interfaces with various AT-command sets */ |
1375 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, | 1390 | { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, |
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index b5775af3ba26..d2747a49b974 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c | |||
@@ -226,6 +226,7 @@ static const struct quirk_printer_struct quirk_printers[] = { | |||
226 | { 0x0409, 0xf0be, USBLP_QUIRK_BIDIR }, /* NEC Picty920 (HP OEM) */ | 226 | { 0x0409, 0xf0be, USBLP_QUIRK_BIDIR }, /* NEC Picty920 (HP OEM) */ |
227 | { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */ | 227 | { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */ |
228 | { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */ | 228 | { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */ |
229 | { 0x04f9, 0x000d, USBLP_QUIRK_BIDIR }, /* Brother Industries, Ltd HL-1440 Laser Printer */ | ||
229 | { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */ | 230 | { 0x04b8, 0x0202, USBLP_QUIRK_BAD_CLASS }, /* Seiko Epson Receipt Printer M129C */ |
230 | { 0, 0 } | 231 | { 0, 0 } |
231 | }; | 232 | }; |
@@ -879,16 +880,19 @@ static int usblp_wwait(struct usblp *usblp, int nonblock) | |||
879 | if (rc <= 0) | 880 | if (rc <= 0) |
880 | break; | 881 | break; |
881 | 882 | ||
882 | if (usblp->flags & LP_ABORT) { | 883 | if (schedule_timeout(msecs_to_jiffies(1500)) == 0) { |
883 | if (schedule_timeout(msecs_to_jiffies(5000)) == 0) { | 884 | if (usblp->flags & LP_ABORT) { |
884 | err = usblp_check_status(usblp, err); | 885 | err = usblp_check_status(usblp, err); |
885 | if (err == 1) { /* Paper out */ | 886 | if (err == 1) { /* Paper out */ |
886 | rc = -ENOSPC; | 887 | rc = -ENOSPC; |
887 | break; | 888 | break; |
888 | } | 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); | ||
889 | } | 895 | } |
890 | } else { | ||
891 | schedule(); | ||
892 | } | 896 | } |
893 | } | 897 | } |
894 | set_current_state(TASK_RUNNING); | 898 | set_current_state(TASK_RUNNING); |
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c index 0f5c05f6f9df..c40a9b284cc9 100644 --- a/drivers/usb/class/usbtmc.c +++ b/drivers/usb/class/usbtmc.c | |||
@@ -50,6 +50,7 @@ | |||
50 | 50 | ||
51 | static struct usb_device_id usbtmc_devices[] = { | 51 | static struct usb_device_id usbtmc_devices[] = { |
52 | { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 0), }, | 52 | { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 0), }, |
53 | { USB_INTERFACE_INFO(USB_CLASS_APP_SPEC, 3, 1), }, | ||
53 | { 0, } /* terminating entry */ | 54 | { 0, } /* terminating entry */ |
54 | }; | 55 | }; |
55 | MODULE_DEVICE_TABLE(usb, usbtmc_devices); | 56 | MODULE_DEVICE_TABLE(usb, usbtmc_devices); |
@@ -106,12 +107,13 @@ static int usbtmc_open(struct inode *inode, struct file *filp) | |||
106 | { | 107 | { |
107 | struct usb_interface *intf; | 108 | struct usb_interface *intf; |
108 | struct usbtmc_device_data *data; | 109 | struct usbtmc_device_data *data; |
109 | int retval = -ENODEV; | 110 | int retval = 0; |
110 | 111 | ||
111 | intf = usb_find_interface(&usbtmc_driver, iminor(inode)); | 112 | intf = usb_find_interface(&usbtmc_driver, iminor(inode)); |
112 | if (!intf) { | 113 | if (!intf) { |
113 | printk(KERN_ERR KBUILD_MODNAME | 114 | printk(KERN_ERR KBUILD_MODNAME |
114 | ": can not find device for minor %d", iminor(inode)); | 115 | ": can not find device for minor %d", iminor(inode)); |
116 | retval = -ENODEV; | ||
115 | goto exit; | 117 | goto exit; |
116 | } | 118 | } |
117 | 119 | ||
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 26fece124e0e..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]); |
@@ -359,11 +359,6 @@ static void destroy_async(struct dev_state *ps, struct list_head *list) | |||
359 | spin_lock_irqsave(&ps->lock, flags); | 359 | spin_lock_irqsave(&ps->lock, flags); |
360 | } | 360 | } |
361 | spin_unlock_irqrestore(&ps->lock, flags); | 361 | spin_unlock_irqrestore(&ps->lock, flags); |
362 | as = async_getcompleted(ps); | ||
363 | while (as) { | ||
364 | free_async(as); | ||
365 | as = async_getcompleted(ps); | ||
366 | } | ||
367 | } | 362 | } |
368 | 363 | ||
369 | static void destroy_async_on_interface(struct dev_state *ps, | 364 | static void destroy_async_on_interface(struct dev_state *ps, |
@@ -381,7 +376,7 @@ static void destroy_async_on_interface(struct dev_state *ps, | |||
381 | destroy_async(ps, &hitlist); | 376 | destroy_async(ps, &hitlist); |
382 | } | 377 | } |
383 | 378 | ||
384 | static inline void destroy_all_async(struct dev_state *ps) | 379 | static void destroy_all_async(struct dev_state *ps) |
385 | { | 380 | { |
386 | destroy_async(ps, &ps->async_pending); | 381 | destroy_async(ps, &ps->async_pending); |
387 | } | 382 | } |
@@ -530,7 +525,8 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, | |||
530 | { | 525 | { |
531 | int ret = 0; | 526 | int ret = 0; |
532 | 527 | ||
533 | if (ps->dev->state != USB_STATE_ADDRESS | 528 | if (ps->dev->state != USB_STATE_UNAUTHENTICATED |
529 | && ps->dev->state != USB_STATE_ADDRESS | ||
534 | && ps->dev->state != USB_STATE_CONFIGURED) | 530 | && ps->dev->state != USB_STATE_CONFIGURED) |
535 | return -EHOSTUNREACH; | 531 | return -EHOSTUNREACH; |
536 | if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype)) | 532 | if (USB_TYPE_VENDOR == (USB_TYPE_MASK & requesttype)) |
@@ -643,6 +639,7 @@ static int usbdev_release(struct inode *inode, struct file *file) | |||
643 | struct dev_state *ps = file->private_data; | 639 | struct dev_state *ps = file->private_data; |
644 | struct usb_device *dev = ps->dev; | 640 | struct usb_device *dev = ps->dev; |
645 | unsigned int ifnum; | 641 | unsigned int ifnum; |
642 | struct async *as; | ||
646 | 643 | ||
647 | usb_lock_device(dev); | 644 | usb_lock_device(dev); |
648 | 645 | ||
@@ -661,6 +658,12 @@ static int usbdev_release(struct inode *inode, struct file *file) | |||
661 | usb_unlock_device(dev); | 658 | usb_unlock_device(dev); |
662 | usb_put_dev(dev); | 659 | usb_put_dev(dev); |
663 | put_pid(ps->disc_pid); | 660 | put_pid(ps->disc_pid); |
661 | |||
662 | as = async_getcompleted(ps); | ||
663 | while (as) { | ||
664 | free_async(as); | ||
665 | as = async_getcompleted(ps); | ||
666 | } | ||
664 | kfree(ps); | 667 | kfree(ps); |
665 | return 0; | 668 | return 0; |
666 | } | 669 | } |
@@ -1700,7 +1703,7 @@ const struct file_operations usbdev_file_operations = { | |||
1700 | .release = usbdev_release, | 1703 | .release = usbdev_release, |
1701 | }; | 1704 | }; |
1702 | 1705 | ||
1703 | void usb_fs_classdev_common_remove(struct usb_device *udev) | 1706 | static void usbdev_remove(struct usb_device *udev) |
1704 | { | 1707 | { |
1705 | struct dev_state *ps; | 1708 | struct dev_state *ps; |
1706 | struct siginfo sinfo; | 1709 | struct siginfo sinfo; |
@@ -1742,10 +1745,15 @@ static void usb_classdev_remove(struct usb_device *dev) | |||
1742 | { | 1745 | { |
1743 | if (dev->usb_classdev) | 1746 | if (dev->usb_classdev) |
1744 | device_unregister(dev->usb_classdev); | 1747 | device_unregister(dev->usb_classdev); |
1745 | usb_fs_classdev_common_remove(dev); | ||
1746 | } | 1748 | } |
1747 | 1749 | ||
1748 | static int usb_classdev_notify(struct notifier_block *self, | 1750 | #else |
1751 | #define usb_classdev_add(dev) 0 | ||
1752 | #define usb_classdev_remove(dev) do {} while (0) | ||
1753 | |||
1754 | #endif | ||
1755 | |||
1756 | static int usbdev_notify(struct notifier_block *self, | ||
1749 | unsigned long action, void *dev) | 1757 | unsigned long action, void *dev) |
1750 | { | 1758 | { |
1751 | switch (action) { | 1759 | switch (action) { |
@@ -1755,15 +1763,15 @@ static int usb_classdev_notify(struct notifier_block *self, | |||
1755 | break; | 1763 | break; |
1756 | case USB_DEVICE_REMOVE: | 1764 | case USB_DEVICE_REMOVE: |
1757 | usb_classdev_remove(dev); | 1765 | usb_classdev_remove(dev); |
1766 | usbdev_remove(dev); | ||
1758 | break; | 1767 | break; |
1759 | } | 1768 | } |
1760 | return NOTIFY_OK; | 1769 | return NOTIFY_OK; |
1761 | } | 1770 | } |
1762 | 1771 | ||
1763 | static struct notifier_block usbdev_nb = { | 1772 | static struct notifier_block usbdev_nb = { |
1764 | .notifier_call = usb_classdev_notify, | 1773 | .notifier_call = usbdev_notify, |
1765 | }; | 1774 | }; |
1766 | #endif | ||
1767 | 1775 | ||
1768 | static struct cdev usb_device_cdev; | 1776 | static struct cdev usb_device_cdev; |
1769 | 1777 | ||
@@ -1798,9 +1806,8 @@ int __init usb_devio_init(void) | |||
1798 | * to /sys/dev | 1806 | * to /sys/dev |
1799 | */ | 1807 | */ |
1800 | usb_classdev_class->dev_kobj = NULL; | 1808 | usb_classdev_class->dev_kobj = NULL; |
1801 | |||
1802 | usb_register_notify(&usbdev_nb); | ||
1803 | #endif | 1809 | #endif |
1810 | usb_register_notify(&usbdev_nb); | ||
1804 | out: | 1811 | out: |
1805 | return retval; | 1812 | return retval; |
1806 | 1813 | ||
@@ -1811,8 +1818,8 @@ error_cdev: | |||
1811 | 1818 | ||
1812 | void usb_devio_cleanup(void) | 1819 | void usb_devio_cleanup(void) |
1813 | { | 1820 | { |
1814 | #ifdef CONFIG_USB_DEVICE_CLASS | ||
1815 | usb_unregister_notify(&usbdev_nb); | 1821 | usb_unregister_notify(&usbdev_nb); |
1822 | #ifdef CONFIG_USB_DEVICE_CLASS | ||
1816 | class_destroy(usb_classdev_class); | 1823 | class_destroy(usb_classdev_class); |
1817 | #endif | 1824 | #endif |
1818 | cdev_del(&usb_device_cdev); | 1825 | cdev_del(&usb_device_cdev); |
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 98760553bc95..d0a21a5f8201 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -284,7 +284,7 @@ static int usb_unbind_interface(struct device *dev) | |||
284 | * supports "soft" unbinding. | 284 | * supports "soft" unbinding. |
285 | */ | 285 | */ |
286 | if (!driver->soft_unbind) | 286 | if (!driver->soft_unbind) |
287 | usb_disable_interface(udev, intf); | 287 | usb_disable_interface(udev, intf, false); |
288 | 288 | ||
289 | driver->disconnect(intf); | 289 | driver->disconnect(intf); |
290 | usb_cancel_queued_reset(intf); | 290 | usb_cancel_queued_reset(intf); |
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-pci.c b/drivers/usb/core/hcd-pci.c index 507741ed4482..a4301dc02d27 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c | |||
@@ -128,7 +128,6 @@ int usb_hcd_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) | |||
128 | } | 128 | } |
129 | 129 | ||
130 | pci_set_master(dev); | 130 | pci_set_master(dev); |
131 | device_set_wakeup_enable(&dev->dev, 1); | ||
132 | 131 | ||
133 | retval = usb_add_hcd(hcd, dev->irq, IRQF_DISABLED | IRQF_SHARED); | 132 | retval = usb_add_hcd(hcd, dev->irq, IRQF_DISABLED | IRQF_SHARED); |
134 | if (retval != 0) | 133 | if (retval != 0) |
@@ -201,6 +200,7 @@ int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t message) | |||
201 | struct usb_hcd *hcd = pci_get_drvdata(dev); | 200 | struct usb_hcd *hcd = pci_get_drvdata(dev); |
202 | int retval = 0; | 201 | int retval = 0; |
203 | int wake, w; | 202 | int wake, w; |
203 | int has_pci_pm; | ||
204 | 204 | ||
205 | /* Root hub suspend should have stopped all downstream traffic, | 205 | /* Root hub suspend should have stopped all downstream traffic, |
206 | * and all bus master traffic. And done so for both the interface | 206 | * and all bus master traffic. And done so for both the interface |
@@ -230,6 +230,15 @@ int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t message) | |||
230 | 230 | ||
231 | synchronize_irq(dev->irq); | 231 | synchronize_irq(dev->irq); |
232 | 232 | ||
233 | /* Downstream ports from this root hub should already be quiesced, so | ||
234 | * there will be no DMA activity. Now we can shut down the upstream | ||
235 | * link (except maybe for PME# resume signaling) and enter some PCI | ||
236 | * low power state, if the hardware allows. | ||
237 | */ | ||
238 | pci_disable_device(dev); | ||
239 | |||
240 | pci_save_state(dev); | ||
241 | |||
233 | /* Don't fail on error to enable wakeup. We rely on pci code | 242 | /* Don't fail on error to enable wakeup. We rely on pci code |
234 | * to reject requests the hardware can't implement, rather | 243 | * to reject requests the hardware can't implement, rather |
235 | * than coding the same thing. | 244 | * than coding the same thing. |
@@ -241,35 +250,6 @@ int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t message) | |||
241 | wake = w; | 250 | wake = w; |
242 | dev_dbg(&dev->dev, "wakeup: %d\n", wake); | 251 | dev_dbg(&dev->dev, "wakeup: %d\n", wake); |
243 | 252 | ||
244 | /* Downstream ports from this root hub should already be quiesced, so | ||
245 | * there will be no DMA activity. Now we can shut down the upstream | ||
246 | * link (except maybe for PME# resume signaling) and enter some PCI | ||
247 | * low power state, if the hardware allows. | ||
248 | */ | ||
249 | pci_disable_device(dev); | ||
250 | done: | ||
251 | return retval; | ||
252 | } | ||
253 | EXPORT_SYMBOL_GPL(usb_hcd_pci_suspend); | ||
254 | |||
255 | /** | ||
256 | * usb_hcd_pci_suspend_late - suspend a PCI-based HCD after IRQs are disabled | ||
257 | * @dev: USB Host Controller being suspended | ||
258 | * @message: Power Management message describing this state transition | ||
259 | * | ||
260 | * Store this function in the HCD's struct pci_driver as .suspend_late. | ||
261 | */ | ||
262 | int usb_hcd_pci_suspend_late(struct pci_dev *dev, pm_message_t message) | ||
263 | { | ||
264 | int retval = 0; | ||
265 | int has_pci_pm; | ||
266 | |||
267 | /* We might already be suspended (runtime PM -- not yet written) */ | ||
268 | if (dev->current_state != PCI_D0) | ||
269 | goto done; | ||
270 | |||
271 | pci_save_state(dev); | ||
272 | |||
273 | /* Don't change state if we don't need to */ | 253 | /* Don't change state if we don't need to */ |
274 | if (message.event == PM_EVENT_FREEZE || | 254 | if (message.event == PM_EVENT_FREEZE || |
275 | message.event == PM_EVENT_PRETHAW) { | 255 | message.event == PM_EVENT_PRETHAW) { |
@@ -315,18 +295,18 @@ int usb_hcd_pci_suspend_late(struct pci_dev *dev, pm_message_t message) | |||
315 | done: | 295 | done: |
316 | return retval; | 296 | return retval; |
317 | } | 297 | } |
318 | EXPORT_SYMBOL_GPL(usb_hcd_pci_suspend_late); | 298 | EXPORT_SYMBOL_GPL(usb_hcd_pci_suspend); |
319 | 299 | ||
320 | /** | 300 | /** |
321 | * usb_hcd_pci_resume_early - resume a PCI-based HCD before IRQs are enabled | 301 | * usb_hcd_pci_resume - power management resume of a PCI-based HCD |
322 | * @dev: USB Host Controller being resumed | 302 | * @dev: USB Host Controller being resumed |
323 | * | 303 | * |
324 | * Store this function in the HCD's struct pci_driver as .resume_early. | 304 | * Store this function in the HCD's struct pci_driver as .resume. |
325 | */ | 305 | */ |
326 | int usb_hcd_pci_resume_early(struct pci_dev *dev) | 306 | int usb_hcd_pci_resume(struct pci_dev *dev) |
327 | { | 307 | { |
328 | int retval = 0; | 308 | struct usb_hcd *hcd; |
329 | pci_power_t state = dev->current_state; | 309 | int retval; |
330 | 310 | ||
331 | #ifdef CONFIG_PPC_PMAC | 311 | #ifdef CONFIG_PPC_PMAC |
332 | /* Reenable ASIC clocks for USB */ | 312 | /* Reenable ASIC clocks for USB */ |
@@ -340,63 +320,7 @@ int usb_hcd_pci_resume_early(struct pci_dev *dev) | |||
340 | } | 320 | } |
341 | #endif | 321 | #endif |
342 | 322 | ||
343 | /* NOTE: chip docs cover clean "real suspend" cases (what Linux | 323 | pci_restore_state(dev); |
344 | * calls "standby", "suspend to RAM", and so on). There are also | ||
345 | * dirty cases when swsusp fakes a suspend in "shutdown" mode. | ||
346 | */ | ||
347 | if (state != PCI_D0) { | ||
348 | #ifdef DEBUG | ||
349 | int pci_pm; | ||
350 | u16 pmcr; | ||
351 | |||
352 | pci_pm = pci_find_capability(dev, PCI_CAP_ID_PM); | ||
353 | pci_read_config_word(dev, pci_pm + PCI_PM_CTRL, &pmcr); | ||
354 | pmcr &= PCI_PM_CTRL_STATE_MASK; | ||
355 | if (pmcr) { | ||
356 | /* Clean case: power to USB and to HC registers was | ||
357 | * maintained; remote wakeup is easy. | ||
358 | */ | ||
359 | dev_dbg(&dev->dev, "resume from PCI D%d\n", pmcr); | ||
360 | } else { | ||
361 | /* Clean: HC lost Vcc power, D0 uninitialized | ||
362 | * + Vaux may have preserved port and transceiver | ||
363 | * state ... for remote wakeup from D3cold | ||
364 | * + or not; HCD must reinit + re-enumerate | ||
365 | * | ||
366 | * Dirty: D0 semi-initialized cases with swsusp | ||
367 | * + after BIOS init | ||
368 | * + after Linux init (HCD statically linked) | ||
369 | */ | ||
370 | dev_dbg(&dev->dev, "resume from previous PCI D%d\n", | ||
371 | state); | ||
372 | } | ||
373 | #endif | ||
374 | |||
375 | retval = pci_set_power_state(dev, PCI_D0); | ||
376 | } else { | ||
377 | /* Same basic cases: clean (powered/not), dirty */ | ||
378 | dev_dbg(&dev->dev, "PCI legacy resume\n"); | ||
379 | } | ||
380 | |||
381 | if (retval < 0) | ||
382 | dev_err(&dev->dev, "can't resume: %d\n", retval); | ||
383 | else | ||
384 | pci_restore_state(dev); | ||
385 | |||
386 | return retval; | ||
387 | } | ||
388 | EXPORT_SYMBOL_GPL(usb_hcd_pci_resume_early); | ||
389 | |||
390 | /** | ||
391 | * usb_hcd_pci_resume - power management resume of a PCI-based HCD | ||
392 | * @dev: USB Host Controller being resumed | ||
393 | * | ||
394 | * Store this function in the HCD's struct pci_driver as .resume. | ||
395 | */ | ||
396 | int usb_hcd_pci_resume(struct pci_dev *dev) | ||
397 | { | ||
398 | struct usb_hcd *hcd; | ||
399 | int retval; | ||
400 | 324 | ||
401 | hcd = pci_get_drvdata(dev); | 325 | hcd = pci_get_drvdata(dev); |
402 | if (hcd->state != HC_STATE_SUSPENDED) { | 326 | if (hcd->state != HC_STATE_SUSPENDED) { |
@@ -405,6 +329,8 @@ int usb_hcd_pci_resume(struct pci_dev *dev) | |||
405 | return 0; | 329 | return 0; |
406 | } | 330 | } |
407 | 331 | ||
332 | pci_enable_wake(dev, PCI_D0, false); | ||
333 | |||
408 | retval = pci_enable_device(dev); | 334 | retval = pci_enable_device(dev); |
409 | if (retval < 0) { | 335 | if (retval < 0) { |
410 | dev_err(&dev->dev, "can't re-enable after resume, %d!\n", | 336 | dev_err(&dev->dev, "can't re-enable after resume, %d!\n", |
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/hcd.h b/drivers/usb/core/hcd.h index 572d2cf46e8d..f750eb1ab595 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -257,8 +257,6 @@ extern void usb_hcd_pci_remove(struct pci_dev *dev); | |||
257 | 257 | ||
258 | #ifdef CONFIG_PM | 258 | #ifdef CONFIG_PM |
259 | extern int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t msg); | 259 | extern int usb_hcd_pci_suspend(struct pci_dev *dev, pm_message_t msg); |
260 | extern int usb_hcd_pci_suspend_late(struct pci_dev *dev, pm_message_t msg); | ||
261 | extern int usb_hcd_pci_resume_early(struct pci_dev *dev); | ||
262 | extern int usb_hcd_pci_resume(struct pci_dev *dev); | 260 | extern int usb_hcd_pci_resume(struct pci_dev *dev); |
263 | #endif /* CONFIG_PM */ | 261 | #endif /* CONFIG_PM */ |
264 | 262 | ||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 94d5ee263c20..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 |
@@ -2382,8 +2383,8 @@ static int hub_port_debounce(struct usb_hub *hub, int port1) | |||
2382 | 2383 | ||
2383 | void usb_ep0_reinit(struct usb_device *udev) | 2384 | void usb_ep0_reinit(struct usb_device *udev) |
2384 | { | 2385 | { |
2385 | usb_disable_endpoint(udev, 0 + USB_DIR_IN); | 2386 | usb_disable_endpoint(udev, 0 + USB_DIR_IN, true); |
2386 | usb_disable_endpoint(udev, 0 + USB_DIR_OUT); | 2387 | usb_disable_endpoint(udev, 0 + USB_DIR_OUT, true); |
2387 | usb_enable_endpoint(udev, &udev->ep0, true); | 2388 | usb_enable_endpoint(udev, &udev->ep0, true); |
2388 | } | 2389 | } |
2389 | EXPORT_SYMBOL_GPL(usb_ep0_reinit); | 2390 | EXPORT_SYMBOL_GPL(usb_ep0_reinit); |
@@ -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/inode.c b/drivers/usb/core/inode.c index 2a129cb7bb56..dff5760a37f6 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c | |||
@@ -717,7 +717,6 @@ static void usbfs_remove_device(struct usb_device *dev) | |||
717 | fs_remove_file (dev->usbfs_dentry); | 717 | fs_remove_file (dev->usbfs_dentry); |
718 | dev->usbfs_dentry = NULL; | 718 | dev->usbfs_dentry = NULL; |
719 | } | 719 | } |
720 | usb_fs_classdev_common_remove(dev); | ||
721 | } | 720 | } |
722 | 721 | ||
723 | static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev) | 722 | static int usbfs_notify(struct notifier_block *self, unsigned long action, void *dev) |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index de51667dd64d..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", |
@@ -653,7 +653,7 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, | |||
653 | if (result <= 0 && result != -ETIMEDOUT) | 653 | if (result <= 0 && result != -ETIMEDOUT) |
654 | continue; | 654 | continue; |
655 | if (result > 1 && ((u8 *)buf)[1] != type) { | 655 | if (result > 1 && ((u8 *)buf)[1] != type) { |
656 | result = -EPROTO; | 656 | result = -ENODATA; |
657 | continue; | 657 | continue; |
658 | } | 658 | } |
659 | break; | 659 | break; |
@@ -696,8 +696,13 @@ static int usb_get_string(struct usb_device *dev, unsigned short langid, | |||
696 | USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, | 696 | USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, |
697 | (USB_DT_STRING << 8) + index, langid, buf, size, | 697 | (USB_DT_STRING << 8) + index, langid, buf, size, |
698 | USB_CTRL_GET_TIMEOUT); | 698 | USB_CTRL_GET_TIMEOUT); |
699 | if (!(result == 0 || result == -EPIPE)) | 699 | if (result == 0 || result == -EPIPE) |
700 | break; | 700 | continue; |
701 | if (result > 1 && ((u8 *) buf)[1] != USB_DT_STRING) { | ||
702 | result = -ENODATA; | ||
703 | continue; | ||
704 | } | ||
705 | break; | ||
701 | } | 706 | } |
702 | return result; | 707 | return result; |
703 | } | 708 | } |
@@ -799,18 +804,16 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size) | |||
799 | dev_err(&dev->dev, | 804 | dev_err(&dev->dev, |
800 | "string descriptor 0 read error: %d\n", | 805 | "string descriptor 0 read error: %d\n", |
801 | err); | 806 | err); |
802 | goto errout; | ||
803 | } else if (err < 4) { | 807 | } else if (err < 4) { |
804 | dev_err(&dev->dev, "string descriptor 0 too short\n"); | 808 | dev_err(&dev->dev, "string descriptor 0 too short\n"); |
805 | err = -EINVAL; | ||
806 | goto errout; | ||
807 | } else { | 809 | } else { |
808 | dev->have_langid = 1; | ||
809 | dev->string_langid = tbuf[2] | (tbuf[3] << 8); | 810 | dev->string_langid = tbuf[2] | (tbuf[3] << 8); |
810 | /* always use the first langid listed */ | 811 | /* always use the first langid listed */ |
811 | dev_dbg(&dev->dev, "default language 0x%04x\n", | 812 | dev_dbg(&dev->dev, "default language 0x%04x\n", |
812 | dev->string_langid); | 813 | dev->string_langid); |
813 | } | 814 | } |
815 | |||
816 | dev->have_langid = 1; | ||
814 | } | 817 | } |
815 | 818 | ||
816 | err = usb_string_sub(dev, dev->string_langid, index, tbuf); | 819 | err = usb_string_sub(dev, dev->string_langid, index, tbuf); |
@@ -1039,14 +1042,15 @@ static void remove_intf_ep_devs(struct usb_interface *intf) | |||
1039 | * @dev: the device whose endpoint is being disabled | 1042 | * @dev: the device whose endpoint is being disabled |
1040 | * @epaddr: the endpoint's address. Endpoint number for output, | 1043 | * @epaddr: the endpoint's address. Endpoint number for output, |
1041 | * endpoint number + USB_DIR_IN for input | 1044 | * endpoint number + USB_DIR_IN for input |
1045 | * @reset_hardware: flag to erase any endpoint state stored in the | ||
1046 | * controller hardware | ||
1042 | * | 1047 | * |
1043 | * Deallocates hcd/hardware state for this endpoint ... and nukes all | 1048 | * Disables the endpoint for URB submission and nukes all pending URBs. |
1044 | * pending urbs. | 1049 | * If @reset_hardware is set then also deallocates hcd/hardware state |
1045 | * | 1050 | * for the endpoint. |
1046 | * If the HCD hasn't registered a disable() function, this sets the | ||
1047 | * endpoint's maxpacket size to 0 to prevent further submissions. | ||
1048 | */ | 1051 | */ |
1049 | void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr) | 1052 | void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr, |
1053 | bool reset_hardware) | ||
1050 | { | 1054 | { |
1051 | unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK; | 1055 | unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK; |
1052 | struct usb_host_endpoint *ep; | 1056 | struct usb_host_endpoint *ep; |
@@ -1056,15 +1060,18 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr) | |||
1056 | 1060 | ||
1057 | if (usb_endpoint_out(epaddr)) { | 1061 | if (usb_endpoint_out(epaddr)) { |
1058 | ep = dev->ep_out[epnum]; | 1062 | ep = dev->ep_out[epnum]; |
1059 | dev->ep_out[epnum] = NULL; | 1063 | if (reset_hardware) |
1064 | dev->ep_out[epnum] = NULL; | ||
1060 | } else { | 1065 | } else { |
1061 | ep = dev->ep_in[epnum]; | 1066 | ep = dev->ep_in[epnum]; |
1062 | dev->ep_in[epnum] = NULL; | 1067 | if (reset_hardware) |
1068 | dev->ep_in[epnum] = NULL; | ||
1063 | } | 1069 | } |
1064 | if (ep) { | 1070 | if (ep) { |
1065 | ep->enabled = 0; | 1071 | ep->enabled = 0; |
1066 | usb_hcd_flush_endpoint(dev, ep); | 1072 | usb_hcd_flush_endpoint(dev, ep); |
1067 | usb_hcd_disable_endpoint(dev, ep); | 1073 | if (reset_hardware) |
1074 | usb_hcd_disable_endpoint(dev, ep); | ||
1068 | } | 1075 | } |
1069 | } | 1076 | } |
1070 | 1077 | ||
@@ -1072,17 +1079,21 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr) | |||
1072 | * usb_disable_interface -- Disable all endpoints for an interface | 1079 | * usb_disable_interface -- Disable all endpoints for an interface |
1073 | * @dev: the device whose interface is being disabled | 1080 | * @dev: the device whose interface is being disabled |
1074 | * @intf: pointer to the interface descriptor | 1081 | * @intf: pointer to the interface descriptor |
1082 | * @reset_hardware: flag to erase any endpoint state stored in the | ||
1083 | * controller hardware | ||
1075 | * | 1084 | * |
1076 | * Disables all the endpoints for the interface's current altsetting. | 1085 | * Disables all the endpoints for the interface's current altsetting. |
1077 | */ | 1086 | */ |
1078 | void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf) | 1087 | void usb_disable_interface(struct usb_device *dev, struct usb_interface *intf, |
1088 | bool reset_hardware) | ||
1079 | { | 1089 | { |
1080 | struct usb_host_interface *alt = intf->cur_altsetting; | 1090 | struct usb_host_interface *alt = intf->cur_altsetting; |
1081 | int i; | 1091 | int i; |
1082 | 1092 | ||
1083 | for (i = 0; i < alt->desc.bNumEndpoints; ++i) { | 1093 | for (i = 0; i < alt->desc.bNumEndpoints; ++i) { |
1084 | usb_disable_endpoint(dev, | 1094 | usb_disable_endpoint(dev, |
1085 | alt->endpoint[i].desc.bEndpointAddress); | 1095 | alt->endpoint[i].desc.bEndpointAddress, |
1096 | reset_hardware); | ||
1086 | } | 1097 | } |
1087 | } | 1098 | } |
1088 | 1099 | ||
@@ -1103,8 +1114,8 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) | |||
1103 | dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__, | 1114 | dev_dbg(&dev->dev, "%s nuking %s URBs\n", __func__, |
1104 | skip_ep0 ? "non-ep0" : "all"); | 1115 | skip_ep0 ? "non-ep0" : "all"); |
1105 | for (i = skip_ep0; i < 16; ++i) { | 1116 | for (i = skip_ep0; i < 16; ++i) { |
1106 | usb_disable_endpoint(dev, i); | 1117 | usb_disable_endpoint(dev, i, true); |
1107 | usb_disable_endpoint(dev, i + USB_DIR_IN); | 1118 | usb_disable_endpoint(dev, i + USB_DIR_IN, true); |
1108 | } | 1119 | } |
1109 | dev->toggle[0] = dev->toggle[1] = 0; | 1120 | dev->toggle[0] = dev->toggle[1] = 0; |
1110 | 1121 | ||
@@ -1274,7 +1285,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) | |||
1274 | remove_intf_ep_devs(iface); | 1285 | remove_intf_ep_devs(iface); |
1275 | usb_remove_sysfs_intf_files(iface); | 1286 | usb_remove_sysfs_intf_files(iface); |
1276 | } | 1287 | } |
1277 | usb_disable_interface(dev, iface); | 1288 | usb_disable_interface(dev, iface, true); |
1278 | 1289 | ||
1279 | iface->cur_altsetting = alt; | 1290 | iface->cur_altsetting = alt; |
1280 | 1291 | ||
@@ -1353,8 +1364,8 @@ int usb_reset_configuration(struct usb_device *dev) | |||
1353 | */ | 1364 | */ |
1354 | 1365 | ||
1355 | for (i = 1; i < 16; ++i) { | 1366 | for (i = 1; i < 16; ++i) { |
1356 | usb_disable_endpoint(dev, i); | 1367 | usb_disable_endpoint(dev, i, true); |
1357 | usb_disable_endpoint(dev, i + USB_DIR_IN); | 1368 | usb_disable_endpoint(dev, i + USB_DIR_IN, true); |
1358 | } | 1369 | } |
1359 | 1370 | ||
1360 | config = dev->actconfig; | 1371 | config = dev->actconfig; |
@@ -1706,7 +1717,8 @@ free_interfaces: | |||
1706 | } | 1717 | } |
1707 | kfree(new_interfaces); | 1718 | kfree(new_interfaces); |
1708 | 1719 | ||
1709 | if (cp->string == NULL) | 1720 | if (cp->string == NULL && |
1721 | !(dev->quirks & USB_QUIRK_CONFIG_INTF_STRINGS)) | ||
1710 | cp->string = usb_cache_string(dev, cp->desc.iConfiguration); | 1722 | cp->string = usb_cache_string(dev, cp->desc.iConfiguration); |
1711 | 1723 | ||
1712 | /* 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/core/usb.h b/drivers/usb/core/usb.h index 386177867a8a..79d8a9ea559b 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -15,9 +15,10 @@ extern void usb_enable_endpoint(struct usb_device *dev, | |||
15 | struct usb_host_endpoint *ep, bool reset_toggle); | 15 | struct usb_host_endpoint *ep, bool reset_toggle); |
16 | extern void usb_enable_interface(struct usb_device *dev, | 16 | extern void usb_enable_interface(struct usb_device *dev, |
17 | struct usb_interface *intf, bool reset_toggles); | 17 | struct usb_interface *intf, bool reset_toggles); |
18 | extern void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr); | 18 | extern void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr, |
19 | bool reset_hardware); | ||
19 | extern void usb_disable_interface(struct usb_device *dev, | 20 | extern void usb_disable_interface(struct usb_device *dev, |
20 | struct usb_interface *intf); | 21 | struct usb_interface *intf, bool reset_hardware); |
21 | extern void usb_release_interface_cache(struct kref *ref); | 22 | extern void usb_release_interface_cache(struct kref *ref); |
22 | extern void usb_disable_device(struct usb_device *dev, int skip_ep0); | 23 | extern void usb_disable_device(struct usb_device *dev, int skip_ep0); |
23 | extern int usb_deauthorize_device(struct usb_device *); | 24 | extern int usb_deauthorize_device(struct usb_device *); |
@@ -151,7 +152,6 @@ extern struct usb_driver usbfs_driver; | |||
151 | extern const struct file_operations usbfs_devices_fops; | 152 | extern const struct file_operations usbfs_devices_fops; |
152 | extern const struct file_operations usbdev_file_operations; | 153 | extern const struct file_operations usbdev_file_operations; |
153 | extern void usbfs_conn_disc_event(void); | 154 | extern void usbfs_conn_disc_event(void); |
154 | extern void usb_fs_classdev_common_remove(struct usb_device *udev); | ||
155 | 155 | ||
156 | extern int usb_devio_init(void); | 156 | extern int usb_devio_init(void); |
157 | extern void usb_devio_cleanup(void); | 157 | extern void usb_devio_cleanup(void); |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 3219d137340a..770b3eaa9184 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -191,6 +191,7 @@ config USB_GADGET_OMAP | |||
191 | boolean "OMAP USB Device Controller" | 191 | boolean "OMAP USB Device Controller" |
192 | depends on ARCH_OMAP | 192 | depends on ARCH_OMAP |
193 | select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4_OTG | 193 | select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 || MACH_OMAP_H4_OTG |
194 | select USB_OTG_UTILS if ARCH_OMAP | ||
194 | help | 195 | help |
195 | Many Texas Instruments OMAP processors have flexible full | 196 | Many Texas Instruments OMAP processors have flexible full |
196 | speed USB device controllers, with support for up to 30 | 197 | speed USB device controllers, with support for up to 30 |
@@ -253,6 +254,7 @@ config USB_PXA25X_SMALL | |||
253 | config USB_GADGET_PXA27X | 254 | config USB_GADGET_PXA27X |
254 | boolean "PXA 27x" | 255 | boolean "PXA 27x" |
255 | depends on ARCH_PXA && PXA27x | 256 | depends on ARCH_PXA && PXA27x |
257 | select USB_OTG_UTILS | ||
256 | help | 258 | help |
257 | Intel's PXA 27x series XScale ARM v5TE processors include | 259 | Intel's PXA 27x series XScale ARM v5TE processors include |
258 | 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 ee7ebb674416..563d57275448 100644 --- a/drivers/usb/gadget/atmel_usba_udc.c +++ b/drivers/usb/gadget/atmel_usba_udc.c | |||
@@ -1017,7 +1017,7 @@ static struct usb_endpoint_descriptor usba_ep0_desc = { | |||
1017 | .bDescriptorType = USB_DT_ENDPOINT, | 1017 | .bDescriptorType = USB_DT_ENDPOINT, |
1018 | .bEndpointAddress = 0, | 1018 | .bEndpointAddress = 0, |
1019 | .bmAttributes = USB_ENDPOINT_XFER_CONTROL, | 1019 | .bmAttributes = USB_ENDPOINT_XFER_CONTROL, |
1020 | .wMaxPacketSize = __constant_cpu_to_le16(64), | 1020 | .wMaxPacketSize = cpu_to_le16(64), |
1021 | /* FIXME: I have no idea what to put here */ | 1021 | /* FIXME: I have no idea what to put here */ |
1022 | .bInterval = 1, | 1022 | .bInterval = 1, |
1023 | }; | 1023 | }; |
@@ -1207,21 +1207,21 @@ static int do_test_mode(struct usba_udc *udc) | |||
1207 | /* Avoid overly long expressions */ | 1207 | /* Avoid overly long expressions */ |
1208 | static inline bool feature_is_dev_remote_wakeup(struct usb_ctrlrequest *crq) | 1208 | static inline bool feature_is_dev_remote_wakeup(struct usb_ctrlrequest *crq) |
1209 | { | 1209 | { |
1210 | if (crq->wValue == __constant_cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP)) | 1210 | if (crq->wValue == cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP)) |
1211 | return true; | 1211 | return true; |
1212 | return false; | 1212 | return false; |
1213 | } | 1213 | } |
1214 | 1214 | ||
1215 | static inline bool feature_is_dev_test_mode(struct usb_ctrlrequest *crq) | 1215 | static inline bool feature_is_dev_test_mode(struct usb_ctrlrequest *crq) |
1216 | { | 1216 | { |
1217 | if (crq->wValue == __constant_cpu_to_le16(USB_DEVICE_TEST_MODE)) | 1217 | if (crq->wValue == cpu_to_le16(USB_DEVICE_TEST_MODE)) |
1218 | return true; | 1218 | return true; |
1219 | return false; | 1219 | return false; |
1220 | } | 1220 | } |
1221 | 1221 | ||
1222 | static inline bool feature_is_ep_halt(struct usb_ctrlrequest *crq) | 1222 | static inline bool feature_is_ep_halt(struct usb_ctrlrequest *crq) |
1223 | { | 1223 | { |
1224 | if (crq->wValue == __constant_cpu_to_le16(USB_ENDPOINT_HALT)) | 1224 | if (crq->wValue == cpu_to_le16(USB_ENDPOINT_HALT)) |
1225 | return true; | 1225 | return true; |
1226 | return false; | 1226 | return false; |
1227 | } | 1227 | } |
@@ -1239,7 +1239,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep, | |||
1239 | status = cpu_to_le16(udc->devstatus); | 1239 | status = cpu_to_le16(udc->devstatus); |
1240 | } else if (crq->bRequestType | 1240 | } else if (crq->bRequestType |
1241 | == (USB_DIR_IN | USB_RECIP_INTERFACE)) { | 1241 | == (USB_DIR_IN | USB_RECIP_INTERFACE)) { |
1242 | status = __constant_cpu_to_le16(0); | 1242 | status = cpu_to_le16(0); |
1243 | } else if (crq->bRequestType | 1243 | } else if (crq->bRequestType |
1244 | == (USB_DIR_IN | USB_RECIP_ENDPOINT)) { | 1244 | == (USB_DIR_IN | USB_RECIP_ENDPOINT)) { |
1245 | struct usba_ep *target; | 1245 | struct usba_ep *target; |
@@ -1250,12 +1250,12 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep, | |||
1250 | 1250 | ||
1251 | status = 0; | 1251 | status = 0; |
1252 | if (is_stalled(udc, target)) | 1252 | if (is_stalled(udc, target)) |
1253 | status |= __constant_cpu_to_le16(1); | 1253 | status |= cpu_to_le16(1); |
1254 | } else | 1254 | } else |
1255 | goto delegate; | 1255 | goto delegate; |
1256 | 1256 | ||
1257 | /* Write directly to the FIFO. No queueing is done. */ | 1257 | /* Write directly to the FIFO. No queueing is done. */ |
1258 | if (crq->wLength != __constant_cpu_to_le16(sizeof(status))) | 1258 | if (crq->wLength != cpu_to_le16(sizeof(status))) |
1259 | goto stall; | 1259 | goto stall; |
1260 | ep->state = DATA_STAGE_IN; | 1260 | ep->state = DATA_STAGE_IN; |
1261 | __raw_writew(status, ep->fifo); | 1261 | __raw_writew(status, ep->fifo); |
@@ -1274,7 +1274,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep, | |||
1274 | } else if (crq->bRequestType == USB_RECIP_ENDPOINT) { | 1274 | } else if (crq->bRequestType == USB_RECIP_ENDPOINT) { |
1275 | struct usba_ep *target; | 1275 | struct usba_ep *target; |
1276 | 1276 | ||
1277 | if (crq->wLength != __constant_cpu_to_le16(0) | 1277 | if (crq->wLength != cpu_to_le16(0) |
1278 | || !feature_is_ep_halt(crq)) | 1278 | || !feature_is_ep_halt(crq)) |
1279 | goto stall; | 1279 | goto stall; |
1280 | target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex)); | 1280 | target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex)); |
@@ -1308,7 +1308,7 @@ static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep, | |||
1308 | } else if (crq->bRequestType == USB_RECIP_ENDPOINT) { | 1308 | } else if (crq->bRequestType == USB_RECIP_ENDPOINT) { |
1309 | struct usba_ep *target; | 1309 | struct usba_ep *target; |
1310 | 1310 | ||
1311 | if (crq->wLength != __constant_cpu_to_le16(0) | 1311 | if (crq->wLength != cpu_to_le16(0) |
1312 | || !feature_is_ep_halt(crq)) | 1312 | || !feature_is_ep_halt(crq)) |
1313 | goto stall; | 1313 | goto stall; |
1314 | 1314 | ||
@@ -1514,7 +1514,7 @@ restart: | |||
1514 | */ | 1514 | */ |
1515 | ep->state = DATA_STAGE_IN; | 1515 | ep->state = DATA_STAGE_IN; |
1516 | } else { | 1516 | } else { |
1517 | if (crq.crq.wLength != __constant_cpu_to_le16(0)) | 1517 | if (crq.crq.wLength != cpu_to_le16(0)) |
1518 | ep->state = DATA_STAGE_OUT; | 1518 | ep->state = DATA_STAGE_OUT; |
1519 | else | 1519 | else |
1520 | ep->state = STATUS_STAGE_IN; | 1520 | ep->state = STATUS_STAGE_IN; |
diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c index 5495b171cf29..928137d3dbdc 100644 --- a/drivers/usb/gadget/cdc2.c +++ b/drivers/usb/gadget/cdc2.c | |||
@@ -66,7 +66,7 @@ static struct usb_device_descriptor device_desc = { | |||
66 | .bLength = sizeof device_desc, | 66 | .bLength = sizeof device_desc, |
67 | .bDescriptorType = USB_DT_DEVICE, | 67 | .bDescriptorType = USB_DT_DEVICE, |
68 | 68 | ||
69 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 69 | .bcdUSB = cpu_to_le16(0x0200), |
70 | 70 | ||
71 | .bDeviceClass = USB_CLASS_COMM, | 71 | .bDeviceClass = USB_CLASS_COMM, |
72 | .bDeviceSubClass = 0, | 72 | .bDeviceSubClass = 0, |
@@ -74,8 +74,8 @@ static struct usb_device_descriptor device_desc = { | |||
74 | /* .bMaxPacketSize0 = f(hardware) */ | 74 | /* .bMaxPacketSize0 = f(hardware) */ |
75 | 75 | ||
76 | /* Vendor and product id can be overridden by module parameters. */ | 76 | /* Vendor and product id can be overridden by module parameters. */ |
77 | .idVendor = __constant_cpu_to_le16(CDC_VENDOR_NUM), | 77 | .idVendor = cpu_to_le16(CDC_VENDOR_NUM), |
78 | .idProduct = __constant_cpu_to_le16(CDC_PRODUCT_NUM), | 78 | .idProduct = cpu_to_le16(CDC_PRODUCT_NUM), |
79 | /* .bcdDevice = f(hardware) */ | 79 | /* .bcdDevice = f(hardware) */ |
80 | /* .iManufacturer = DYNAMIC */ | 80 | /* .iManufacturer = DYNAMIC */ |
81 | /* .iProduct = DYNAMIC */ | 81 | /* .iProduct = DYNAMIC */ |
@@ -193,7 +193,7 @@ static int __init cdc_bind(struct usb_composite_dev *cdev) | |||
193 | gadget->name, | 193 | gadget->name, |
194 | cdc_config_driver.label); | 194 | cdc_config_driver.label); |
195 | device_desc.bcdDevice = | 195 | device_desc.bcdDevice = |
196 | __constant_cpu_to_le16(0x0300 | 0x0099); | 196 | cpu_to_le16(0x0300 | 0x0099); |
197 | } | 197 | } |
198 | 198 | ||
199 | 199 | ||
diff --git a/drivers/usb/gadget/ci13xxx_udc.c b/drivers/usb/gadget/ci13xxx_udc.c index bebf911c7e5f..22c65960c429 100644 --- a/drivers/usb/gadget/ci13xxx_udc.c +++ b/drivers/usb/gadget/ci13xxx_udc.c | |||
@@ -56,7 +56,6 @@ | |||
56 | #include <linux/dma-mapping.h> | 56 | #include <linux/dma-mapping.h> |
57 | #include <linux/init.h> | 57 | #include <linux/init.h> |
58 | #include <linux/interrupt.h> | 58 | #include <linux/interrupt.h> |
59 | #include <linux/interrupt.h> | ||
60 | #include <linux/io.h> | 59 | #include <linux/io.h> |
61 | #include <linux/irq.h> | 60 | #include <linux/irq.h> |
62 | #include <linux/kernel.h> | 61 | #include <linux/kernel.h> |
@@ -2626,7 +2625,7 @@ static int udc_probe(struct device *dev, void __iomem *regs, const char *name) | |||
2626 | INIT_LIST_HEAD(&udc->gadget.ep_list); | 2625 | INIT_LIST_HEAD(&udc->gadget.ep_list); |
2627 | udc->gadget.ep0 = NULL; | 2626 | udc->gadget.ep0 = NULL; |
2628 | 2627 | ||
2629 | strcpy(udc->gadget.dev.bus_id, "gadget"); | 2628 | dev_set_name(&udc->gadget.dev, "gadget"); |
2630 | udc->gadget.dev.dma_mask = dev->dma_mask; | 2629 | udc->gadget.dev.dma_mask = dev->dma_mask; |
2631 | udc->gadget.dev.parent = dev; | 2630 | udc->gadget.dev.parent = dev; |
2632 | udc->gadget.dev.release = udc_release; | 2631 | udc->gadget.dev.release = udc_release; |
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c index f2da0269e1b1..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 | ||
@@ -683,6 +684,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
683 | struct usb_request *req = cdev->req; | 684 | struct usb_request *req = cdev->req; |
684 | int value = -EOPNOTSUPP; | 685 | int value = -EOPNOTSUPP; |
685 | u16 w_index = le16_to_cpu(ctrl->wIndex); | 686 | u16 w_index = le16_to_cpu(ctrl->wIndex); |
687 | u8 intf = w_index & 0xFF; | ||
686 | u16 w_value = le16_to_cpu(ctrl->wValue); | 688 | u16 w_value = le16_to_cpu(ctrl->wValue); |
687 | u16 w_length = le16_to_cpu(ctrl->wLength); | 689 | u16 w_length = le16_to_cpu(ctrl->wLength); |
688 | struct usb_function *f = NULL; | 690 | struct usb_function *f = NULL; |
@@ -769,10 +771,10 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
769 | goto unknown; | 771 | goto unknown; |
770 | if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES) | 772 | if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES) |
771 | break; | 773 | break; |
772 | f = cdev->config->interface[w_index]; | 774 | f = cdev->config->interface[intf]; |
773 | if (!f) | 775 | if (!f) |
774 | break; | 776 | break; |
775 | if (w_value && !f->get_alt) | 777 | if (w_value && !f->set_alt) |
776 | break; | 778 | break; |
777 | value = f->set_alt(f, w_index, w_value); | 779 | value = f->set_alt(f, w_index, w_value); |
778 | break; | 780 | break; |
@@ -781,7 +783,7 @@ composite_setup(struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
781 | goto unknown; | 783 | goto unknown; |
782 | if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES) | 784 | if (!cdev->config || w_index >= MAX_CONFIG_INTERFACES) |
783 | break; | 785 | break; |
784 | f = cdev->config->interface[w_index]; | 786 | f = cdev->config->interface[intf]; |
785 | if (!f) | 787 | if (!f) |
786 | break; | 788 | break; |
787 | /* lots of interfaces only need altsetting zero... */ | 789 | /* lots of interfaces only need altsetting zero... */ |
@@ -808,7 +810,7 @@ unknown: | |||
808 | */ | 810 | */ |
809 | if ((ctrl->bRequestType & USB_RECIP_MASK) | 811 | if ((ctrl->bRequestType & USB_RECIP_MASK) |
810 | == USB_RECIP_INTERFACE) { | 812 | == USB_RECIP_INTERFACE) { |
811 | f = cdev->config->interface[w_index]; | 813 | f = cdev->config->interface[intf]; |
812 | if (f && f->setup) | 814 | if (f && f->setup) |
813 | value = f->setup(f, ctrl); | 815 | value = f->setup(f, ctrl); |
814 | else | 816 | else |
@@ -1012,7 +1014,7 @@ composite_suspend(struct usb_gadget *gadget) | |||
1012 | struct usb_composite_dev *cdev = get_gadget_data(gadget); | 1014 | struct usb_composite_dev *cdev = get_gadget_data(gadget); |
1013 | struct usb_function *f; | 1015 | struct usb_function *f; |
1014 | 1016 | ||
1015 | /* REVISIT: should we have config and device level | 1017 | /* REVISIT: should we have config level |
1016 | * suspend/resume callbacks? | 1018 | * suspend/resume callbacks? |
1017 | */ | 1019 | */ |
1018 | DBG(cdev, "suspend\n"); | 1020 | DBG(cdev, "suspend\n"); |
@@ -1022,6 +1024,8 @@ composite_suspend(struct usb_gadget *gadget) | |||
1022 | f->suspend(f); | 1024 | f->suspend(f); |
1023 | } | 1025 | } |
1024 | } | 1026 | } |
1027 | if (composite->suspend) | ||
1028 | composite->suspend(cdev); | ||
1025 | } | 1029 | } |
1026 | 1030 | ||
1027 | static void | 1031 | static void |
@@ -1030,10 +1034,12 @@ composite_resume(struct usb_gadget *gadget) | |||
1030 | struct usb_composite_dev *cdev = get_gadget_data(gadget); | 1034 | struct usb_composite_dev *cdev = get_gadget_data(gadget); |
1031 | struct usb_function *f; | 1035 | struct usb_function *f; |
1032 | 1036 | ||
1033 | /* REVISIT: should we have config and device level | 1037 | /* REVISIT: should we have config level |
1034 | * suspend/resume callbacks? | 1038 | * suspend/resume callbacks? |
1035 | */ | 1039 | */ |
1036 | DBG(cdev, "resume\n"); | 1040 | DBG(cdev, "resume\n"); |
1041 | if (composite->resume) | ||
1042 | composite->resume(cdev); | ||
1037 | if (cdev->config) { | 1043 | if (cdev->config) { |
1038 | list_for_each_entry(f, &cdev->config->functions, list) { | 1044 | list_for_each_entry(f, &cdev->config->functions, list) { |
1039 | 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 80c2e7e9622f..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 = { |
@@ -366,9 +366,9 @@ obex_bind(struct usb_configuration *c, struct usb_function *f) | |||
366 | f->hs_descriptors = usb_copy_descriptors(hs_function); | 366 | f->hs_descriptors = usb_copy_descriptors(hs_function); |
367 | 367 | ||
368 | obex->hs.obex_in = usb_find_endpoint(hs_function, | 368 | obex->hs.obex_in = usb_find_endpoint(hs_function, |
369 | f->descriptors, &obex_hs_ep_in_desc); | 369 | f->hs_descriptors, &obex_hs_ep_in_desc); |
370 | obex->hs.obex_out = usb_find_endpoint(hs_function, | 370 | obex->hs.obex_out = usb_find_endpoint(hs_function, |
371 | f->descriptors, &obex_hs_ep_out_desc); | 371 | f->hs_descriptors, &obex_hs_ep_out_desc); |
372 | } | 372 | } |
373 | 373 | ||
374 | /* Avoid letting this gadget enumerate until the userspace | 374 | /* Avoid letting this gadget enumerate until the userspace |
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 b10fa31cc915..5c030b080d4c 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -847,13 +847,13 @@ device_desc = { | |||
847 | .bLength = sizeof device_desc, | 847 | .bLength = sizeof device_desc, |
848 | .bDescriptorType = USB_DT_DEVICE, | 848 | .bDescriptorType = USB_DT_DEVICE, |
849 | 849 | ||
850 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 850 | .bcdUSB = cpu_to_le16(0x0200), |
851 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | 851 | .bDeviceClass = USB_CLASS_PER_INTERFACE, |
852 | 852 | ||
853 | /* The next three values can be overridden by module parameters */ | 853 | /* The next three values can be overridden by module parameters */ |
854 | .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_ID), | 854 | .idVendor = cpu_to_le16(DRIVER_VENDOR_ID), |
855 | .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_ID), | 855 | .idProduct = cpu_to_le16(DRIVER_PRODUCT_ID), |
856 | .bcdDevice = __constant_cpu_to_le16(0xffff), | 856 | .bcdDevice = cpu_to_le16(0xffff), |
857 | 857 | ||
858 | .iManufacturer = STRING_MANUFACTURER, | 858 | .iManufacturer = STRING_MANUFACTURER, |
859 | .iProduct = STRING_PRODUCT, | 859 | .iProduct = STRING_PRODUCT, |
@@ -926,7 +926,7 @@ fs_intr_in_desc = { | |||
926 | 926 | ||
927 | .bEndpointAddress = USB_DIR_IN, | 927 | .bEndpointAddress = USB_DIR_IN, |
928 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 928 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
929 | .wMaxPacketSize = __constant_cpu_to_le16(2), | 929 | .wMaxPacketSize = cpu_to_le16(2), |
930 | .bInterval = 32, // frames -> 32 ms | 930 | .bInterval = 32, // frames -> 32 ms |
931 | }; | 931 | }; |
932 | 932 | ||
@@ -954,7 +954,7 @@ dev_qualifier = { | |||
954 | .bLength = sizeof dev_qualifier, | 954 | .bLength = sizeof dev_qualifier, |
955 | .bDescriptorType = USB_DT_DEVICE_QUALIFIER, | 955 | .bDescriptorType = USB_DT_DEVICE_QUALIFIER, |
956 | 956 | ||
957 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 957 | .bcdUSB = cpu_to_le16(0x0200), |
958 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | 958 | .bDeviceClass = USB_CLASS_PER_INTERFACE, |
959 | 959 | ||
960 | .bNumConfigurations = 1, | 960 | .bNumConfigurations = 1, |
@@ -967,7 +967,7 @@ hs_bulk_in_desc = { | |||
967 | 967 | ||
968 | /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */ | 968 | /* bEndpointAddress copied from fs_bulk_in_desc during fsg_bind() */ |
969 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 969 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
970 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 970 | .wMaxPacketSize = cpu_to_le16(512), |
971 | }; | 971 | }; |
972 | 972 | ||
973 | static struct usb_endpoint_descriptor | 973 | static struct usb_endpoint_descriptor |
@@ -977,7 +977,7 @@ hs_bulk_out_desc = { | |||
977 | 977 | ||
978 | /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */ | 978 | /* bEndpointAddress copied from fs_bulk_out_desc during fsg_bind() */ |
979 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 979 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
980 | .wMaxPacketSize = __constant_cpu_to_le16(512), | 980 | .wMaxPacketSize = cpu_to_le16(512), |
981 | .bInterval = 1, // NAK every 1 uframe | 981 | .bInterval = 1, // NAK every 1 uframe |
982 | }; | 982 | }; |
983 | 983 | ||
@@ -988,7 +988,7 @@ hs_intr_in_desc = { | |||
988 | 988 | ||
989 | /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */ | 989 | /* bEndpointAddress copied from fs_intr_in_desc during fsg_bind() */ |
990 | .bmAttributes = USB_ENDPOINT_XFER_INT, | 990 | .bmAttributes = USB_ENDPOINT_XFER_INT, |
991 | .wMaxPacketSize = __constant_cpu_to_le16(2), | 991 | .wMaxPacketSize = cpu_to_le16(2), |
992 | .bInterval = 9, // 2**(9-1) = 256 uframes -> 32 ms | 992 | .bInterval = 9, // 2**(9-1) = 256 uframes -> 32 ms |
993 | }; | 993 | }; |
994 | 994 | ||
@@ -1711,7 +1711,9 @@ static int do_write(struct fsg_dev *fsg) | |||
1711 | curlun->sense_data = SS_WRITE_PROTECTED; | 1711 | curlun->sense_data = SS_WRITE_PROTECTED; |
1712 | return -EINVAL; | 1712 | return -EINVAL; |
1713 | } | 1713 | } |
1714 | spin_lock(&curlun->filp->f_lock); | ||
1714 | curlun->filp->f_flags &= ~O_SYNC; // Default is not to wait | 1715 | curlun->filp->f_flags &= ~O_SYNC; // Default is not to wait |
1716 | spin_unlock(&curlun->filp->f_lock); | ||
1715 | 1717 | ||
1716 | /* Get the starting Logical Block Address and check that it's | 1718 | /* Get the starting Logical Block Address and check that it's |
1717 | * not too big */ | 1719 | * not too big */ |
@@ -1728,8 +1730,11 @@ static int do_write(struct fsg_dev *fsg) | |||
1728 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; | 1730 | curlun->sense_data = SS_INVALID_FIELD_IN_CDB; |
1729 | return -EINVAL; | 1731 | return -EINVAL; |
1730 | } | 1732 | } |
1731 | if (fsg->cmnd[1] & 0x08) // FUA | 1733 | if (fsg->cmnd[1] & 0x08) { // FUA |
1734 | spin_lock(&curlun->filp->f_lock); | ||
1732 | curlun->filp->f_flags |= O_SYNC; | 1735 | curlun->filp->f_flags |= O_SYNC; |
1736 | spin_unlock(&curlun->filp->f_lock); | ||
1737 | } | ||
1733 | } | 1738 | } |
1734 | if (lba >= curlun->num_sectors) { | 1739 | if (lba >= curlun->num_sectors) { |
1735 | curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; | 1740 | curlun->sense_data = SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE; |
@@ -2646,7 +2651,7 @@ static int send_status(struct fsg_dev *fsg) | |||
2646 | struct bulk_cs_wrap *csw = bh->buf; | 2651 | struct bulk_cs_wrap *csw = bh->buf; |
2647 | 2652 | ||
2648 | /* Store and send the Bulk-only CSW */ | 2653 | /* Store and send the Bulk-only CSW */ |
2649 | csw->Signature = __constant_cpu_to_le32(USB_BULK_CS_SIG); | 2654 | csw->Signature = cpu_to_le32(USB_BULK_CS_SIG); |
2650 | csw->Tag = fsg->tag; | 2655 | csw->Tag = fsg->tag; |
2651 | csw->Residue = cpu_to_le32(fsg->residue); | 2656 | csw->Residue = cpu_to_le32(fsg->residue); |
2652 | csw->Status = status; | 2657 | csw->Status = status; |
@@ -3089,7 +3094,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
3089 | 3094 | ||
3090 | /* Is the CBW valid? */ | 3095 | /* Is the CBW valid? */ |
3091 | if (req->actual != USB_BULK_CB_WRAP_LEN || | 3096 | if (req->actual != USB_BULK_CB_WRAP_LEN || |
3092 | cbw->Signature != __constant_cpu_to_le32( | 3097 | cbw->Signature != cpu_to_le32( |
3093 | USB_BULK_CB_SIG)) { | 3098 | USB_BULK_CB_SIG)) { |
3094 | DBG(fsg, "invalid CBW: len %u sig 0x%x\n", | 3099 | DBG(fsg, "invalid CBW: len %u sig 0x%x\n", |
3095 | req->actual, | 3100 | req->actual, |
@@ -3879,7 +3884,11 @@ static int __init check_parameters(struct fsg_dev *fsg) | |||
3879 | mod_data.protocol_type = USB_SC_SCSI; | 3884 | mod_data.protocol_type = USB_SC_SCSI; |
3880 | mod_data.protocol_name = "Transparent SCSI"; | 3885 | mod_data.protocol_name = "Transparent SCSI"; |
3881 | 3886 | ||
3882 | if (gadget_is_sh(fsg->gadget)) | 3887 | /* Some peripheral controllers are known not to be able to |
3888 | * halt bulk endpoints correctly. If one of them is present, | ||
3889 | * disable stalls. | ||
3890 | */ | ||
3891 | if (gadget_is_sh(fsg->gadget) || gadget_is_at91(fsg->gadget)) | ||
3883 | mod_data.can_stall = 0; | 3892 | mod_data.can_stall = 0; |
3884 | 3893 | ||
3885 | if (mod_data.release == 0xffff) { // Parameter wasn't set | 3894 | if (mod_data.release == 0xffff) { // Parameter wasn't set |
diff --git a/drivers/usb/gadget/fsl_qe_udc.c b/drivers/usb/gadget/fsl_qe_udc.c index d6c5bcd40064..d701bf4698d2 100644 --- a/drivers/usb/gadget/fsl_qe_udc.c +++ b/drivers/usb/gadget/fsl_qe_udc.c | |||
@@ -1622,6 +1622,8 @@ static int qe_ep_disable(struct usb_ep *_ep) | |||
1622 | nuke(ep, -ESHUTDOWN); | 1622 | nuke(ep, -ESHUTDOWN); |
1623 | ep->desc = NULL; | 1623 | ep->desc = NULL; |
1624 | ep->stopped = 1; | 1624 | ep->stopped = 1; |
1625 | ep->tx_req = NULL; | ||
1626 | qe_ep_reset(udc, ep->epnum); | ||
1625 | spin_unlock_irqrestore(&udc->lock, flags); | 1627 | spin_unlock_irqrestore(&udc->lock, flags); |
1626 | 1628 | ||
1627 | cpm_muram_free(cpm_muram_offset(ep->rxbase)); | 1629 | cpm_muram_free(cpm_muram_offset(ep->rxbase)); |
@@ -1681,14 +1683,11 @@ static void qe_free_request(struct usb_ep *_ep, struct usb_request *_req) | |||
1681 | kfree(req); | 1683 | kfree(req); |
1682 | } | 1684 | } |
1683 | 1685 | ||
1684 | /* queues (submits) an I/O request to an endpoint */ | 1686 | static int __qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req) |
1685 | static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req, | ||
1686 | gfp_t gfp_flags) | ||
1687 | { | 1687 | { |
1688 | struct qe_ep *ep = container_of(_ep, struct qe_ep, ep); | 1688 | struct qe_ep *ep = container_of(_ep, struct qe_ep, ep); |
1689 | struct qe_req *req = container_of(_req, struct qe_req, req); | 1689 | struct qe_req *req = container_of(_req, struct qe_req, req); |
1690 | struct qe_udc *udc; | 1690 | struct qe_udc *udc; |
1691 | unsigned long flags; | ||
1692 | int reval; | 1691 | int reval; |
1693 | 1692 | ||
1694 | udc = ep->udc; | 1693 | udc = ep->udc; |
@@ -1732,7 +1731,7 @@ static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req, | |||
1732 | list_add_tail(&req->queue, &ep->queue); | 1731 | list_add_tail(&req->queue, &ep->queue); |
1733 | dev_vdbg(udc->dev, "gadget have request in %s! %d\n", | 1732 | dev_vdbg(udc->dev, "gadget have request in %s! %d\n", |
1734 | ep->name, req->req.length); | 1733 | ep->name, req->req.length); |
1735 | spin_lock_irqsave(&udc->lock, flags); | 1734 | |
1736 | /* push the request to device */ | 1735 | /* push the request to device */ |
1737 | if (ep_is_in(ep)) | 1736 | if (ep_is_in(ep)) |
1738 | reval = ep_req_send(ep, req); | 1737 | reval = ep_req_send(ep, req); |
@@ -1748,11 +1747,24 @@ static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req, | |||
1748 | if (ep->dir == USB_DIR_OUT) | 1747 | if (ep->dir == USB_DIR_OUT) |
1749 | reval = ep_req_receive(ep, req); | 1748 | reval = ep_req_receive(ep, req); |
1750 | 1749 | ||
1751 | spin_unlock_irqrestore(&udc->lock, flags); | ||
1752 | |||
1753 | return 0; | 1750 | return 0; |
1754 | } | 1751 | } |
1755 | 1752 | ||
1753 | /* queues (submits) an I/O request to an endpoint */ | ||
1754 | static int qe_ep_queue(struct usb_ep *_ep, struct usb_request *_req, | ||
1755 | gfp_t gfp_flags) | ||
1756 | { | ||
1757 | struct qe_ep *ep = container_of(_ep, struct qe_ep, ep); | ||
1758 | struct qe_udc *udc = ep->udc; | ||
1759 | unsigned long flags; | ||
1760 | int ret; | ||
1761 | |||
1762 | spin_lock_irqsave(&udc->lock, flags); | ||
1763 | ret = __qe_ep_queue(_ep, _req); | ||
1764 | spin_unlock_irqrestore(&udc->lock, flags); | ||
1765 | return ret; | ||
1766 | } | ||
1767 | |||
1756 | /* dequeues (cancels, unlinks) an I/O request from an endpoint */ | 1768 | /* dequeues (cancels, unlinks) an I/O request from an endpoint */ |
1757 | static int qe_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | 1769 | static int qe_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) |
1758 | { | 1770 | { |
@@ -2008,7 +2020,7 @@ static void ch9getstatus(struct qe_udc *udc, u8 request_type, u16 value, | |||
2008 | udc->ep0_dir = USB_DIR_IN; | 2020 | udc->ep0_dir = USB_DIR_IN; |
2009 | 2021 | ||
2010 | /* data phase */ | 2022 | /* data phase */ |
2011 | status = qe_ep_queue(&ep->ep, &req->req, GFP_ATOMIC); | 2023 | status = __qe_ep_queue(&ep->ep, &req->req); |
2012 | 2024 | ||
2013 | if (status == 0) | 2025 | if (status == 0) |
2014 | return; | 2026 | return; |
@@ -2151,6 +2163,9 @@ static int reset_irq(struct qe_udc *udc) | |||
2151 | { | 2163 | { |
2152 | unsigned char i; | 2164 | unsigned char i; |
2153 | 2165 | ||
2166 | if (udc->usb_state == USB_STATE_DEFAULT) | ||
2167 | return 0; | ||
2168 | |||
2154 | qe_usb_disable(); | 2169 | qe_usb_disable(); |
2155 | out_8(&udc->usb_regs->usb_usadr, 0); | 2170 | out_8(&udc->usb_regs->usb_usadr, 0); |
2156 | 2171 | ||
@@ -2442,8 +2457,12 @@ static int __devinit qe_udc_reg_init(struct qe_udc *udc) | |||
2442 | struct usb_ctlr __iomem *qe_usbregs; | 2457 | struct usb_ctlr __iomem *qe_usbregs; |
2443 | qe_usbregs = udc->usb_regs; | 2458 | qe_usbregs = udc->usb_regs; |
2444 | 2459 | ||
2445 | /* Init the usb register */ | 2460 | /* Spec says that we must enable the USB controller to change mode. */ |
2446 | out_8(&qe_usbregs->usb_usmod, 0x01); | 2461 | out_8(&qe_usbregs->usb_usmod, 0x01); |
2462 | /* Mode changed, now disable it, since muram isn't initialized yet. */ | ||
2463 | out_8(&qe_usbregs->usb_usmod, 0x00); | ||
2464 | |||
2465 | /* Initialize the rest. */ | ||
2447 | out_be16(&qe_usbregs->usb_usbmr, 0); | 2466 | out_be16(&qe_usbregs->usb_usbmr, 0); |
2448 | out_8(&qe_usbregs->usb_uscom, 0); | 2467 | out_8(&qe_usbregs->usb_uscom, 0); |
2449 | out_be16(&qe_usbregs->usb_usber, USBER_ALL_CLEAR); | 2468 | out_be16(&qe_usbregs->usb_usber, USBER_ALL_CLEAR); |
@@ -2604,6 +2623,10 @@ static int __devinit qe_udc_probe(struct of_device *ofdev, | |||
2604 | (unsigned long)udc_controller); | 2623 | (unsigned long)udc_controller); |
2605 | /* request irq and disable DR */ | 2624 | /* request irq and disable DR */ |
2606 | udc_controller->usb_irq = irq_of_parse_and_map(np, 0); | 2625 | udc_controller->usb_irq = irq_of_parse_and_map(np, 0); |
2626 | if (!udc_controller->usb_irq) { | ||
2627 | ret = -EINVAL; | ||
2628 | goto err_noirq; | ||
2629 | } | ||
2607 | 2630 | ||
2608 | ret = request_irq(udc_controller->usb_irq, qe_udc_irq, 0, | 2631 | ret = request_irq(udc_controller->usb_irq, qe_udc_irq, 0, |
2609 | driver_name, udc_controller); | 2632 | driver_name, udc_controller); |
@@ -2625,6 +2648,8 @@ static int __devinit qe_udc_probe(struct of_device *ofdev, | |||
2625 | err6: | 2648 | err6: |
2626 | free_irq(udc_controller->usb_irq, udc_controller); | 2649 | free_irq(udc_controller->usb_irq, udc_controller); |
2627 | err5: | 2650 | err5: |
2651 | irq_dispose_mapping(udc_controller->usb_irq); | ||
2652 | err_noirq: | ||
2628 | if (udc_controller->nullmap) { | 2653 | if (udc_controller->nullmap) { |
2629 | dma_unmap_single(udc_controller->gadget.dev.parent, | 2654 | dma_unmap_single(udc_controller->gadget.dev.parent, |
2630 | udc_controller->nullp, 256, | 2655 | udc_controller->nullp, 256, |
@@ -2648,7 +2673,7 @@ err2: | |||
2648 | iounmap(udc_controller->usb_regs); | 2673 | iounmap(udc_controller->usb_regs); |
2649 | err1: | 2674 | err1: |
2650 | kfree(udc_controller); | 2675 | kfree(udc_controller); |
2651 | 2676 | udc_controller = NULL; | |
2652 | return ret; | 2677 | return ret; |
2653 | } | 2678 | } |
2654 | 2679 | ||
@@ -2710,6 +2735,7 @@ static int __devexit qe_udc_remove(struct of_device *ofdev) | |||
2710 | kfree(ep->txframe); | 2735 | kfree(ep->txframe); |
2711 | 2736 | ||
2712 | free_irq(udc_controller->usb_irq, udc_controller); | 2737 | free_irq(udc_controller->usb_irq, udc_controller); |
2738 | irq_dispose_mapping(udc_controller->usb_irq); | ||
2713 | 2739 | ||
2714 | tasklet_kill(&udc_controller->rx_tasklet); | 2740 | tasklet_kill(&udc_controller->rx_tasklet); |
2715 | 2741 | ||
diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index f3c6703cffda..9d7b95d4e3d2 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c | |||
@@ -404,7 +404,10 @@ static void struct_ep_qh_setup(struct fsl_udc *udc, unsigned char ep_num, | |||
404 | } | 404 | } |
405 | if (zlt) | 405 | if (zlt) |
406 | tmp |= EP_QUEUE_HEAD_ZLT_SEL; | 406 | tmp |= EP_QUEUE_HEAD_ZLT_SEL; |
407 | |||
407 | p_QH->max_pkt_length = cpu_to_le32(tmp); | 408 | p_QH->max_pkt_length = cpu_to_le32(tmp); |
409 | p_QH->next_dtd_ptr = 1; | ||
410 | p_QH->size_ioc_int_sts = 0; | ||
408 | 411 | ||
409 | return; | 412 | return; |
410 | } | 413 | } |
@@ -1799,7 +1802,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1799 | 1802 | ||
1800 | out: | 1803 | out: |
1801 | if (retval) | 1804 | if (retval) |
1802 | printk("gadget driver register failed %d\n", retval); | 1805 | printk(KERN_WARNING "gadget driver register failed %d\n", |
1806 | retval); | ||
1803 | return retval; | 1807 | return retval; |
1804 | } | 1808 | } |
1805 | EXPORT_SYMBOL(usb_gadget_register_driver); | 1809 | EXPORT_SYMBOL(usb_gadget_register_driver); |
@@ -1844,7 +1848,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1844 | udc_controller->gadget.dev.driver = NULL; | 1848 | udc_controller->gadget.dev.driver = NULL; |
1845 | udc_controller->driver = NULL; | 1849 | udc_controller->driver = NULL; |
1846 | 1850 | ||
1847 | printk("unregistered gadget driver '%s'\n", driver->driver.name); | 1851 | printk(KERN_WARNING "unregistered gadget driver '%s'\n", |
1852 | driver->driver.name); | ||
1848 | return 0; | 1853 | return 0; |
1849 | } | 1854 | } |
1850 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | 1855 | EXPORT_SYMBOL(usb_gadget_unregister_driver); |
@@ -2452,7 +2457,7 @@ module_init(udc_init); | |||
2452 | static void __exit udc_exit(void) | 2457 | static void __exit udc_exit(void) |
2453 | { | 2458 | { |
2454 | platform_driver_unregister(&udc_driver); | 2459 | platform_driver_unregister(&udc_driver); |
2455 | printk("%s unregistered\n", driver_desc); | 2460 | printk(KERN_WARNING "%s unregistered\n", driver_desc); |
2456 | } | 2461 | } |
2457 | 2462 | ||
2458 | module_exit(udc_exit); | 2463 | module_exit(udc_exit); |
diff --git a/drivers/usb/gadget/g_zero.h b/drivers/usb/gadget/g_zero.h index dd2f16ad5a88..e84b3c47ed3c 100644 --- a/drivers/usb/gadget/g_zero.h +++ b/drivers/usb/gadget/g_zero.h | |||
@@ -19,7 +19,7 @@ void disable_endpoints(struct usb_composite_dev *cdev, | |||
19 | struct usb_ep *in, struct usb_ep *out); | 19 | struct usb_ep *in, struct usb_ep *out); |
20 | 20 | ||
21 | /* configuration-specific linkup */ | 21 | /* configuration-specific linkup */ |
22 | int sourcesink_add(struct usb_composite_dev *cdev); | 22 | int sourcesink_add(struct usb_composite_dev *cdev, bool autoresume); |
23 | int loopback_add(struct usb_composite_dev *cdev); | 23 | int loopback_add(struct usb_composite_dev *cdev, bool autoresume); |
24 | 24 | ||
25 | #endif /* __G_ZERO_H */ | 25 | #endif /* __G_ZERO_H */ |
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 60d3f9e9b51f..b9312dc6e041 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c | |||
@@ -199,10 +199,10 @@ DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(1); | |||
199 | static struct usb_device_descriptor device_desc = { | 199 | static struct usb_device_descriptor device_desc = { |
200 | .bLength = USB_DT_DEVICE_SIZE, | 200 | .bLength = USB_DT_DEVICE_SIZE, |
201 | .bDescriptorType = USB_DT_DEVICE, | 201 | .bDescriptorType = USB_DT_DEVICE, |
202 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 202 | .bcdUSB = cpu_to_le16(0x0200), |
203 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | 203 | .bDeviceClass = USB_CLASS_PER_INTERFACE, |
204 | .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_NUM), | 204 | .idVendor = cpu_to_le16(DRIVER_VENDOR_NUM), |
205 | .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_NUM), | 205 | .idProduct = cpu_to_le16(DRIVER_PRODUCT_NUM), |
206 | .iManufacturer = STRING_MANUFACTURER, | 206 | .iManufacturer = STRING_MANUFACTURER, |
207 | .iProduct = STRING_PRODUCT, | 207 | .iProduct = STRING_PRODUCT, |
208 | .bNumConfigurations = 1, | 208 | .bNumConfigurations = 1, |
@@ -241,8 +241,8 @@ static const struct usb_ac_header_descriptor_1 ac_header_desc = { | |||
241 | .bLength = USB_DT_AC_HEADER_SIZE(1), | 241 | .bLength = USB_DT_AC_HEADER_SIZE(1), |
242 | .bDescriptorType = USB_DT_CS_INTERFACE, | 242 | .bDescriptorType = USB_DT_CS_INTERFACE, |
243 | .bDescriptorSubtype = USB_MS_HEADER, | 243 | .bDescriptorSubtype = USB_MS_HEADER, |
244 | .bcdADC = __constant_cpu_to_le16(0x0100), | 244 | .bcdADC = cpu_to_le16(0x0100), |
245 | .wTotalLength = __constant_cpu_to_le16(USB_DT_AC_HEADER_SIZE(1)), | 245 | .wTotalLength = cpu_to_le16(USB_DT_AC_HEADER_SIZE(1)), |
246 | .bInCollection = 1, | 246 | .bInCollection = 1, |
247 | .baInterfaceNr = { | 247 | .baInterfaceNr = { |
248 | [0] = GMIDI_MS_INTERFACE, | 248 | [0] = GMIDI_MS_INTERFACE, |
@@ -265,8 +265,8 @@ static const struct usb_ms_header_descriptor ms_header_desc = { | |||
265 | .bLength = USB_DT_MS_HEADER_SIZE, | 265 | .bLength = USB_DT_MS_HEADER_SIZE, |
266 | .bDescriptorType = USB_DT_CS_INTERFACE, | 266 | .bDescriptorType = USB_DT_CS_INTERFACE, |
267 | .bDescriptorSubtype = USB_MS_HEADER, | 267 | .bDescriptorSubtype = USB_MS_HEADER, |
268 | .bcdMSC = __constant_cpu_to_le16(0x0100), | 268 | .bcdMSC = cpu_to_le16(0x0100), |
269 | .wTotalLength = __constant_cpu_to_le16(USB_DT_MS_HEADER_SIZE | 269 | .wTotalLength = cpu_to_le16(USB_DT_MS_HEADER_SIZE |
270 | + 2*USB_DT_MIDI_IN_SIZE | 270 | + 2*USB_DT_MIDI_IN_SIZE |
271 | + 2*USB_DT_MIDI_OUT_SIZE(1)), | 271 | + 2*USB_DT_MIDI_OUT_SIZE(1)), |
272 | }; | 272 | }; |
@@ -1099,10 +1099,9 @@ static int gmidi_register_card(struct gmidi_device *dev) | |||
1099 | .dev_free = gmidi_snd_free, | 1099 | .dev_free = gmidi_snd_free, |
1100 | }; | 1100 | }; |
1101 | 1101 | ||
1102 | card = snd_card_new(index, id, THIS_MODULE, 0); | 1102 | err = snd_card_create(index, id, THIS_MODULE, 0, &card); |
1103 | if (!card) { | 1103 | if (err < 0) { |
1104 | ERROR(dev, "snd_card_new failed\n"); | 1104 | ERROR(dev, "snd_card_create failed\n"); |
1105 | err = -ENOMEM; | ||
1106 | goto fail; | 1105 | goto fail; |
1107 | } | 1106 | } |
1108 | dev->card = card; | 1107 | dev->card = card; |
@@ -1227,7 +1226,7 @@ autoconf_fail: | |||
1227 | */ | 1226 | */ |
1228 | pr_warning("%s: controller '%s' not recognized\n", | 1227 | pr_warning("%s: controller '%s' not recognized\n", |
1229 | shortname, gadget->name); | 1228 | shortname, gadget->name); |
1230 | device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); | 1229 | device_desc.bcdDevice = cpu_to_le16(0x9999); |
1231 | } | 1230 | } |
1232 | 1231 | ||
1233 | 1232 | ||
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 63419c4d503c..de010c939dbb 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -1472,7 +1472,7 @@ static void ep0_setup(struct goku_udc *dev) | |||
1472 | /* active endpoint */ | 1472 | /* active endpoint */ |
1473 | if (tmp > 3 || (!dev->ep[tmp].desc && tmp != 0)) | 1473 | if (tmp > 3 || (!dev->ep[tmp].desc && tmp != 0)) |
1474 | goto stall; | 1474 | goto stall; |
1475 | if (ctrl.wIndex & __constant_cpu_to_le16( | 1475 | if (ctrl.wIndex & cpu_to_le16( |
1476 | USB_DIR_IN)) { | 1476 | USB_DIR_IN)) { |
1477 | if (!dev->ep[tmp].is_in) | 1477 | if (!dev->ep[tmp].is_in) |
1478 | goto stall; | 1478 | goto stall; |
@@ -1480,7 +1480,7 @@ static void ep0_setup(struct goku_udc *dev) | |||
1480 | if (dev->ep[tmp].is_in) | 1480 | if (dev->ep[tmp].is_in) |
1481 | goto stall; | 1481 | goto stall; |
1482 | } | 1482 | } |
1483 | if (ctrl.wValue != __constant_cpu_to_le16( | 1483 | if (ctrl.wValue != cpu_to_le16( |
1484 | USB_ENDPOINT_HALT)) | 1484 | USB_ENDPOINT_HALT)) |
1485 | goto stall; | 1485 | goto stall; |
1486 | if (tmp) | 1486 | if (tmp) |
@@ -1493,7 +1493,7 @@ succeed: | |||
1493 | return; | 1493 | return; |
1494 | case USB_RECIP_DEVICE: | 1494 | case USB_RECIP_DEVICE: |
1495 | /* device remote wakeup: always clear */ | 1495 | /* device remote wakeup: always clear */ |
1496 | if (ctrl.wValue != __constant_cpu_to_le16(1)) | 1496 | if (ctrl.wValue != cpu_to_le16(1)) |
1497 | goto stall; | 1497 | goto stall; |
1498 | VDBG(dev, "clear dev remote wakeup\n"); | 1498 | VDBG(dev, "clear dev remote wakeup\n"); |
1499 | goto succeed; | 1499 | goto succeed; |
@@ -1519,7 +1519,7 @@ succeed: | |||
1519 | dev->req_config = (ctrl.bRequest == USB_REQ_SET_CONFIGURATION | 1519 | dev->req_config = (ctrl.bRequest == USB_REQ_SET_CONFIGURATION |
1520 | && ctrl.bRequestType == USB_RECIP_DEVICE); | 1520 | && ctrl.bRequestType == USB_RECIP_DEVICE); |
1521 | if (unlikely(dev->req_config)) | 1521 | if (unlikely(dev->req_config)) |
1522 | dev->configured = (ctrl.wValue != __constant_cpu_to_le16(0)); | 1522 | dev->configured = (ctrl.wValue != cpu_to_le16(0)); |
1523 | 1523 | ||
1524 | /* delegate everything to the gadget driver. | 1524 | /* delegate everything to the gadget driver. |
1525 | * it may respond after this irq handler returns. | 1525 | * it may respond after this irq handler returns. |
diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c index cde8fdf15d5b..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 |
300 | if (!temp & EPSTAT_STALL) | 307 | + USB_EP_STAT(EP_NO(imx_ep))); |
308 | if (!(temp & EPSTAT_STALL)) | ||
301 | break; | 309 | break; |
302 | udelay(20); | 310 | udelay(20); |
303 | } | 311 | } |
304 | if (i == 50) | 312 | if (i == 100) |
305 | D_ERR(imx_usb->dev, "<%s> Non finished stall on %s\n", | 313 | D_ERR(imx_usb->dev, "<%s> Non finished stall on %s\n", |
306 | __func__, imx_ep->ep.name); | 314 | __func__, imx_ep->ep.name); |
307 | } | 315 | } |
@@ -325,7 +333,8 @@ static int imx_udc_wakeup(struct usb_gadget *_gadget) | |||
325 | ******************************************************************************* | 333 | ******************************************************************************* |
326 | */ | 334 | */ |
327 | 335 | ||
328 | static void ep_add_request(struct imx_ep_struct *imx_ep, struct imx_request *req) | 336 | static void ep_add_request(struct imx_ep_struct *imx_ep, |
337 | struct imx_request *req) | ||
329 | { | 338 | { |
330 | if (unlikely(!req)) | 339 | if (unlikely(!req)) |
331 | return; | 340 | return; |
@@ -334,7 +343,8 @@ static void ep_add_request(struct imx_ep_struct *imx_ep, struct imx_request *req | |||
334 | list_add_tail(&req->queue, &imx_ep->queue); | 343 | list_add_tail(&req->queue, &imx_ep->queue); |
335 | } | 344 | } |
336 | 345 | ||
337 | static void ep_del_request(struct imx_ep_struct *imx_ep, struct imx_request *req) | 346 | static void ep_del_request(struct imx_ep_struct *imx_ep, |
347 | struct imx_request *req) | ||
338 | { | 348 | { |
339 | if (unlikely(!req)) | 349 | if (unlikely(!req)) |
340 | return; | 350 | return; |
@@ -343,7 +353,8 @@ static void ep_del_request(struct imx_ep_struct *imx_ep, struct imx_request *req | |||
343 | req->in_use = 0; | 353 | req->in_use = 0; |
344 | } | 354 | } |
345 | 355 | ||
346 | static void done(struct imx_ep_struct *imx_ep, struct imx_request *req, int status) | 356 | static void done(struct imx_ep_struct *imx_ep, |
357 | struct imx_request *req, int status) | ||
347 | { | 358 | { |
348 | ep_del_request(imx_ep, req); | 359 | ep_del_request(imx_ep, req); |
349 | 360 | ||
@@ -494,7 +505,8 @@ static int write_fifo(struct imx_ep_struct *imx_ep, struct imx_request *req) | |||
494 | __func__, imx_ep->ep.name, req, | 505 | __func__, imx_ep->ep.name, req, |
495 | completed ? "completed" : "not completed"); | 506 | completed ? "completed" : "not completed"); |
496 | if (!EP_NO(imx_ep)) | 507 | if (!EP_NO(imx_ep)) |
497 | ep0_chg_stat(__func__, imx_ep->imx_usb, EP0_IDLE); | 508 | ep0_chg_stat(__func__, |
509 | imx_ep->imx_usb, EP0_IDLE); | ||
498 | } | 510 | } |
499 | } | 511 | } |
500 | 512 | ||
@@ -539,10 +551,9 @@ static int handle_ep0(struct imx_ep_struct *imx_ep) | |||
539 | struct imx_request *req = NULL; | 551 | struct imx_request *req = NULL; |
540 | int ret = 0; | 552 | int ret = 0; |
541 | 553 | ||
542 | if (!list_empty(&imx_ep->queue)) | 554 | if (!list_empty(&imx_ep->queue)) { |
543 | req = list_entry(imx_ep->queue.next, struct imx_request, queue); | 555 | req = list_entry(imx_ep->queue.next, struct imx_request, queue); |
544 | 556 | ||
545 | if (req) { | ||
546 | switch (imx_ep->imx_usb->ep0state) { | 557 | switch (imx_ep->imx_usb->ep0state) { |
547 | 558 | ||
548 | case EP0_IN_DATA_PHASE: /* GET_DESCRIPTOR */ | 559 | case EP0_IN_DATA_PHASE: /* GET_DESCRIPTOR */ |
@@ -561,6 +572,10 @@ static int handle_ep0(struct imx_ep_struct *imx_ep) | |||
561 | } | 572 | } |
562 | } | 573 | } |
563 | 574 | ||
575 | else | ||
576 | D_ERR(imx_ep->imx_usb->dev, "<%s> no request on %s\n", | ||
577 | __func__, imx_ep->ep.name); | ||
578 | |||
564 | return ret; | 579 | return ret; |
565 | } | 580 | } |
566 | 581 | ||
@@ -583,7 +598,8 @@ static void handle_ep0_devreq(struct imx_udc_struct *imx_usb) | |||
583 | "<%s> no setup packet received\n", __func__); | 598 | "<%s> no setup packet received\n", __func__); |
584 | goto stall; | 599 | goto stall; |
585 | } | 600 | } |
586 | u.word[i] = __raw_readl(imx_usb->base + USB_EP_FDAT(EP_NO(imx_ep))); | 601 | u.word[i] = __raw_readl(imx_usb->base |
602 | + USB_EP_FDAT(EP_NO(imx_ep))); | ||
587 | } | 603 | } |
588 | 604 | ||
589 | temp = imx_ep_empty(imx_ep); | 605 | temp = imx_ep_empty(imx_ep); |
@@ -759,7 +775,7 @@ static int imx_ep_queue | |||
759 | */ | 775 | */ |
760 | if (imx_usb->set_config && !EP_NO(imx_ep)) { | 776 | if (imx_usb->set_config && !EP_NO(imx_ep)) { |
761 | imx_usb->set_config = 0; | 777 | imx_usb->set_config = 0; |
762 | D_EPX(imx_usb->dev, | 778 | D_ERR(imx_usb->dev, |
763 | "<%s> gadget reply set config\n", __func__); | 779 | "<%s> gadget reply set config\n", __func__); |
764 | return 0; | 780 | return 0; |
765 | } | 781 | } |
@@ -779,28 +795,29 @@ static int imx_ep_queue | |||
779 | return -ESHUTDOWN; | 795 | return -ESHUTDOWN; |
780 | } | 796 | } |
781 | 797 | ||
782 | local_irq_save(flags); | ||
783 | |||
784 | /* Debug */ | 798 | /* Debug */ |
785 | D_REQ(imx_usb->dev, "<%s> ep%d %s request for [%d] bytes\n", | 799 | D_REQ(imx_usb->dev, "<%s> ep%d %s request for [%d] bytes\n", |
786 | __func__, EP_NO(imx_ep), | 800 | __func__, EP_NO(imx_ep), |
787 | ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state == EP0_IN_DATA_PHASE) | 801 | ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state |
788 | || (EP_NO(imx_ep) && EP_DIR(imx_ep))) ? "IN" : "OUT", usb_req->length); | 802 | == EP0_IN_DATA_PHASE) |
803 | || (EP_NO(imx_ep) && EP_DIR(imx_ep))) | ||
804 | ? "IN" : "OUT", usb_req->length); | ||
789 | dump_req(__func__, imx_ep, usb_req); | 805 | dump_req(__func__, imx_ep, usb_req); |
790 | 806 | ||
791 | if (imx_ep->stopped) { | 807 | if (imx_ep->stopped) { |
792 | usb_req->status = -ESHUTDOWN; | 808 | usb_req->status = -ESHUTDOWN; |
793 | ret = -ESHUTDOWN; | 809 | return -ESHUTDOWN; |
794 | goto out; | ||
795 | } | 810 | } |
796 | 811 | ||
797 | if (req->in_use) { | 812 | if (req->in_use) { |
798 | D_ERR(imx_usb->dev, | 813 | D_ERR(imx_usb->dev, |
799 | "<%s> refusing to queue req %p (already queued)\n", | 814 | "<%s> refusing to queue req %p (already queued)\n", |
800 | __func__, req); | 815 | __func__, req); |
801 | goto out; | 816 | return 0; |
802 | } | 817 | } |
803 | 818 | ||
819 | local_irq_save(flags); | ||
820 | |||
804 | usb_req->status = -EINPROGRESS; | 821 | usb_req->status = -EINPROGRESS; |
805 | usb_req->actual = 0; | 822 | usb_req->actual = 0; |
806 | 823 | ||
@@ -810,7 +827,7 @@ static int imx_ep_queue | |||
810 | ret = handle_ep0(imx_ep); | 827 | ret = handle_ep0(imx_ep); |
811 | else | 828 | else |
812 | ret = handle_ep(imx_ep); | 829 | ret = handle_ep(imx_ep); |
813 | out: | 830 | |
814 | local_irq_restore(flags); | 831 | local_irq_restore(flags); |
815 | return ret; | 832 | return ret; |
816 | } | 833 | } |
@@ -997,71 +1014,32 @@ static void udc_stop_activity(struct imx_udc_struct *imx_usb, | |||
997 | ******************************************************************************* | 1014 | ******************************************************************************* |
998 | */ | 1015 | */ |
999 | 1016 | ||
1000 | static irqreturn_t imx_udc_irq(int irq, void *dev) | 1017 | /* |
1018 | * Called when timer expires. | ||
1019 | * Timer is started when CFG_CHG is received. | ||
1020 | */ | ||
1021 | static void handle_config(unsigned long data) | ||
1001 | { | 1022 | { |
1002 | struct imx_udc_struct *imx_usb = dev; | 1023 | struct imx_udc_struct *imx_usb = (void *)data; |
1003 | struct usb_ctrlrequest u; | 1024 | struct usb_ctrlrequest u; |
1004 | int temp, cfg, intf, alt; | 1025 | int temp, cfg, intf, alt; |
1005 | int intr = __raw_readl(imx_usb->base + USB_INTR); | ||
1006 | 1026 | ||
1007 | if (intr & (INTR_WAKEUP | INTR_SUSPEND | INTR_RESUME | INTR_RESET_START | 1027 | local_irq_disable(); |
1008 | | INTR_RESET_STOP | INTR_CFG_CHG)) { | ||
1009 | dump_intr(__func__, intr, imx_usb->dev); | ||
1010 | dump_usb_stat(__func__, imx_usb); | ||
1011 | } | ||
1012 | 1028 | ||
1013 | if (!imx_usb->driver) { | 1029 | temp = __raw_readl(imx_usb->base + USB_STAT); |
1014 | /*imx_udc_disable(imx_usb);*/ | 1030 | cfg = (temp & STAT_CFG) >> 5; |
1015 | goto end_irq; | 1031 | intf = (temp & STAT_INTF) >> 3; |
1016 | } | 1032 | alt = temp & STAT_ALTSET; |
1017 | 1033 | ||
1018 | if (intr & INTR_WAKEUP) { | 1034 | D_REQ(imx_usb->dev, |
1019 | if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN | 1035 | "<%s> orig config C=%d, I=%d, A=%d / " |
1020 | && imx_usb->driver && imx_usb->driver->resume) | 1036 | "req config C=%d, I=%d, A=%d\n", |
1021 | imx_usb->driver->resume(&imx_usb->gadget); | 1037 | __func__, imx_usb->cfg, imx_usb->intf, imx_usb->alt, |
1022 | imx_usb->set_config = 0; | 1038 | cfg, intf, alt); |
1023 | imx_usb->gadget.speed = USB_SPEED_FULL; | ||
1024 | } | ||
1025 | |||
1026 | if (intr & INTR_SUSPEND) { | ||
1027 | if (imx_usb->gadget.speed != USB_SPEED_UNKNOWN | ||
1028 | && imx_usb->driver && imx_usb->driver->suspend) | ||
1029 | imx_usb->driver->suspend(&imx_usb->gadget); | ||
1030 | imx_usb->set_config = 0; | ||
1031 | imx_usb->gadget.speed = USB_SPEED_UNKNOWN; | ||
1032 | } | ||
1033 | |||
1034 | if (intr & INTR_RESET_START) { | ||
1035 | __raw_writel(intr, imx_usb->base + USB_INTR); | ||
1036 | udc_stop_activity(imx_usb, imx_usb->driver); | ||
1037 | imx_usb->set_config = 0; | ||
1038 | imx_usb->gadget.speed = USB_SPEED_UNKNOWN; | ||
1039 | } | ||
1040 | 1039 | ||
1041 | if (intr & INTR_RESET_STOP) | 1040 | if (cfg == 1 || cfg == 2) { |
1042 | imx_usb->gadget.speed = USB_SPEED_FULL; | ||
1043 | 1041 | ||
1044 | if (intr & INTR_CFG_CHG) { | ||
1045 | __raw_writel(INTR_CFG_CHG, imx_usb->base + USB_INTR); | ||
1046 | temp = __raw_readl(imx_usb->base + USB_STAT); | ||
1047 | cfg = (temp & STAT_CFG) >> 5; | ||
1048 | intf = (temp & STAT_INTF) >> 3; | ||
1049 | alt = temp & STAT_ALTSET; | ||
1050 | |||
1051 | D_REQ(imx_usb->dev, | ||
1052 | "<%s> orig config C=%d, I=%d, A=%d / " | ||
1053 | "req config C=%d, I=%d, A=%d\n", | ||
1054 | __func__, imx_usb->cfg, imx_usb->intf, imx_usb->alt, | ||
1055 | cfg, intf, alt); | ||
1056 | |||
1057 | if (cfg != 1 && cfg != 2) | ||
1058 | goto end_irq; | ||
1059 | |||
1060 | imx_usb->set_config = 0; | ||
1061 | |||
1062 | /* Config setup */ | ||
1063 | if (imx_usb->cfg != cfg) { | 1042 | if (imx_usb->cfg != cfg) { |
1064 | D_REQ(imx_usb->dev, "<%s> Change config start\n",__func__); | ||
1065 | u.bRequest = USB_REQ_SET_CONFIGURATION; | 1043 | u.bRequest = USB_REQ_SET_CONFIGURATION; |
1066 | u.bRequestType = USB_DIR_OUT | | 1044 | u.bRequestType = USB_DIR_OUT | |
1067 | USB_TYPE_STANDARD | | 1045 | USB_TYPE_STANDARD | |
@@ -1070,14 +1048,10 @@ static irqreturn_t imx_udc_irq(int irq, void *dev) | |||
1070 | u.wIndex = 0; | 1048 | u.wIndex = 0; |
1071 | u.wLength = 0; | 1049 | u.wLength = 0; |
1072 | imx_usb->cfg = cfg; | 1050 | imx_usb->cfg = cfg; |
1073 | imx_usb->set_config = 1; | ||
1074 | imx_usb->driver->setup(&imx_usb->gadget, &u); | 1051 | imx_usb->driver->setup(&imx_usb->gadget, &u); |
1075 | imx_usb->set_config = 0; | ||
1076 | D_REQ(imx_usb->dev, "<%s> Change config done\n",__func__); | ||
1077 | 1052 | ||
1078 | } | 1053 | } |
1079 | if (imx_usb->intf != intf || imx_usb->alt != alt) { | 1054 | if (imx_usb->intf != intf || imx_usb->alt != alt) { |
1080 | D_REQ(imx_usb->dev, "<%s> Change interface start\n",__func__); | ||
1081 | u.bRequest = USB_REQ_SET_INTERFACE; | 1055 | u.bRequest = USB_REQ_SET_INTERFACE; |
1082 | u.bRequestType = USB_DIR_OUT | | 1056 | u.bRequestType = USB_DIR_OUT | |
1083 | USB_TYPE_STANDARD | | 1057 | USB_TYPE_STANDARD | |
@@ -1087,20 +1061,92 @@ static irqreturn_t imx_udc_irq(int irq, void *dev) | |||
1087 | u.wLength = 0; | 1061 | u.wLength = 0; |
1088 | imx_usb->intf = intf; | 1062 | imx_usb->intf = intf; |
1089 | imx_usb->alt = alt; | 1063 | imx_usb->alt = alt; |
1090 | imx_usb->set_config = 1; | ||
1091 | imx_usb->driver->setup(&imx_usb->gadget, &u); | 1064 | imx_usb->driver->setup(&imx_usb->gadget, &u); |
1092 | imx_usb->set_config = 0; | ||
1093 | D_REQ(imx_usb->dev, "<%s> Change interface done\n",__func__); | ||
1094 | } | 1065 | } |
1095 | } | 1066 | } |
1096 | 1067 | ||
1068 | imx_usb->set_config = 0; | ||
1069 | |||
1070 | local_irq_enable(); | ||
1071 | } | ||
1072 | |||
1073 | static irqreturn_t imx_udc_irq(int irq, void *dev) | ||
1074 | { | ||
1075 | struct imx_udc_struct *imx_usb = dev; | ||
1076 | int intr = __raw_readl(imx_usb->base + USB_INTR); | ||
1077 | int temp; | ||
1078 | |||
1079 | if (intr & (INTR_WAKEUP | INTR_SUSPEND | INTR_RESUME | INTR_RESET_START | ||
1080 | | INTR_RESET_STOP | INTR_CFG_CHG)) { | ||
1081 | dump_intr(__func__, intr, imx_usb->dev); | ||
1082 | dump_usb_stat(__func__, imx_usb); | ||
1083 | } | ||
1084 | |||
1085 | if (!imx_usb->driver) | ||
1086 | goto end_irq; | ||
1087 | |||
1097 | if (intr & INTR_SOF) { | 1088 | if (intr & INTR_SOF) { |
1089 | /* Copy from Freescale BSP. | ||
1090 | We must enable SOF intr and set CMDOVER. | ||
1091 | Datasheet don't specifiy this action, but it | ||
1092 | is done in Freescale BSP, so just copy it. | ||
1093 | */ | ||
1098 | if (imx_usb->ep0state == EP0_IDLE) { | 1094 | if (imx_usb->ep0state == EP0_IDLE) { |
1099 | temp = __raw_readl(imx_usb->base + USB_CTRL); | 1095 | temp = __raw_readl(imx_usb->base + USB_CTRL); |
1100 | __raw_writel(temp | CTRL_CMDOVER, imx_usb->base + USB_CTRL); | 1096 | __raw_writel(temp | CTRL_CMDOVER, |
1097 | imx_usb->base + USB_CTRL); | ||
1101 | } | 1098 | } |
1102 | } | 1099 | } |
1103 | 1100 | ||
1101 | if (intr & INTR_CFG_CHG) { | ||
1102 | /* A workaround of serious IMX UDC bug. | ||
1103 | Handling of CFG_CHG should be delayed for some time, because | ||
1104 | IMX does not NACK the host when CFG_CHG interrupt is pending. | ||
1105 | There is no time to handle current CFG_CHG | ||
1106 | if next CFG_CHG or SETUP packed is send immediately. | ||
1107 | We have to clear CFG_CHG, start the timer and | ||
1108 | NACK the host by setting CTRL_CMDOVER | ||
1109 | if it sends any SETUP packet. | ||
1110 | When timer expires, handler is called to handle configuration | ||
1111 | changes. While CFG_CHG is not handled (set_config=1), | ||
1112 | we must NACK the host to every SETUP packed. | ||
1113 | This delay prevents from going out of sync with host. | ||
1114 | */ | ||
1115 | __raw_writel(INTR_CFG_CHG, imx_usb->base + USB_INTR); | ||
1116 | imx_usb->set_config = 1; | ||
1117 | mod_timer(&imx_usb->timer, jiffies + 5); | ||
1118 | goto end_irq; | ||
1119 | } | ||
1120 | |||
1121 | if (intr & INTR_WAKEUP) { | ||
1122 | if (imx_usb->gadget.speed == USB_SPEED_UNKNOWN | ||
1123 | && imx_usb->driver && imx_usb->driver->resume) | ||
1124 | imx_usb->driver->resume(&imx_usb->gadget); | ||
1125 | imx_usb->set_config = 0; | ||
1126 | del_timer(&imx_usb->timer); | ||
1127 | imx_usb->gadget.speed = USB_SPEED_FULL; | ||
1128 | } | ||
1129 | |||
1130 | if (intr & INTR_SUSPEND) { | ||
1131 | if (imx_usb->gadget.speed != USB_SPEED_UNKNOWN | ||
1132 | && imx_usb->driver && imx_usb->driver->suspend) | ||
1133 | imx_usb->driver->suspend(&imx_usb->gadget); | ||
1134 | imx_usb->set_config = 0; | ||
1135 | del_timer(&imx_usb->timer); | ||
1136 | imx_usb->gadget.speed = USB_SPEED_UNKNOWN; | ||
1137 | } | ||
1138 | |||
1139 | if (intr & INTR_RESET_START) { | ||
1140 | __raw_writel(intr, imx_usb->base + USB_INTR); | ||
1141 | udc_stop_activity(imx_usb, imx_usb->driver); | ||
1142 | imx_usb->set_config = 0; | ||
1143 | del_timer(&imx_usb->timer); | ||
1144 | imx_usb->gadget.speed = USB_SPEED_UNKNOWN; | ||
1145 | } | ||
1146 | |||
1147 | if (intr & INTR_RESET_STOP) | ||
1148 | imx_usb->gadget.speed = USB_SPEED_FULL; | ||
1149 | |||
1104 | end_irq: | 1150 | end_irq: |
1105 | __raw_writel(intr, imx_usb->base + USB_INTR); | 1151 | __raw_writel(intr, imx_usb->base + USB_INTR); |
1106 | return IRQ_HANDLED; | 1152 | return IRQ_HANDLED; |
@@ -1109,6 +1155,7 @@ end_irq: | |||
1109 | static irqreturn_t imx_udc_ctrl_irq(int irq, void *dev) | 1155 | static irqreturn_t imx_udc_ctrl_irq(int irq, void *dev) |
1110 | { | 1156 | { |
1111 | struct imx_udc_struct *imx_usb = dev; | 1157 | struct imx_udc_struct *imx_usb = dev; |
1158 | struct imx_ep_struct *imx_ep = &imx_usb->imx_ep[0]; | ||
1112 | int intr = __raw_readl(imx_usb->base + USB_EP_INTR(0)); | 1159 | int intr = __raw_readl(imx_usb->base + USB_EP_INTR(0)); |
1113 | 1160 | ||
1114 | dump_ep_intr(__func__, 0, intr, imx_usb->dev); | 1161 | dump_ep_intr(__func__, 0, intr, imx_usb->dev); |
@@ -1118,16 +1165,15 @@ static irqreturn_t imx_udc_ctrl_irq(int irq, void *dev) | |||
1118 | return IRQ_HANDLED; | 1165 | return IRQ_HANDLED; |
1119 | } | 1166 | } |
1120 | 1167 | ||
1121 | /* DEVREQ IRQ has highest priority */ | 1168 | /* DEVREQ has highest priority */ |
1122 | if (intr & (EPINTR_DEVREQ | EPINTR_MDEVREQ)) | 1169 | if (intr & (EPINTR_DEVREQ | EPINTR_MDEVREQ)) |
1123 | handle_ep0_devreq(imx_usb); | 1170 | handle_ep0_devreq(imx_usb); |
1124 | /* Seem i.MX is missing EOF interrupt sometimes. | 1171 | /* Seem i.MX is missing EOF interrupt sometimes. |
1125 | * Therefore we monitor both EOF and FIFO_EMPTY interrups | 1172 | * Therefore we don't monitor EOF. |
1126 | * when transmiting, and both EOF and FIFO_FULL when | 1173 | * We call handle_ep0() only if a request is queued for ep0. |
1127 | * receiving data. | ||
1128 | */ | 1174 | */ |
1129 | else if (intr & (EPINTR_EOF | EPINTR_FIFO_EMPTY | EPINTR_FIFO_FULL)) | 1175 | else if (!list_empty(&imx_ep->queue)) |
1130 | handle_ep0(&imx_usb->imx_ep[0]); | 1176 | handle_ep0(imx_ep); |
1131 | 1177 | ||
1132 | __raw_writel(intr, imx_usb->base + USB_EP_INTR(0)); | 1178 | __raw_writel(intr, imx_usb->base + USB_EP_INTR(0)); |
1133 | 1179 | ||
@@ -1186,8 +1232,8 @@ static struct imx_udc_struct controller = { | |||
1186 | .ep0 = &controller.imx_ep[0].ep, | 1232 | .ep0 = &controller.imx_ep[0].ep, |
1187 | .name = driver_name, | 1233 | .name = driver_name, |
1188 | .dev = { | 1234 | .dev = { |
1189 | .bus_id = "gadget", | 1235 | .init_name = "gadget", |
1190 | }, | 1236 | }, |
1191 | }, | 1237 | }, |
1192 | 1238 | ||
1193 | .imx_ep[0] = { | 1239 | .imx_ep[0] = { |
@@ -1318,6 +1364,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1318 | 1364 | ||
1319 | udc_stop_activity(imx_usb, driver); | 1365 | udc_stop_activity(imx_usb, driver); |
1320 | imx_udc_disable(imx_usb); | 1366 | imx_udc_disable(imx_usb); |
1367 | del_timer(&imx_usb->timer); | ||
1321 | 1368 | ||
1322 | driver->unbind(&imx_usb->gadget); | 1369 | driver->unbind(&imx_usb->gadget); |
1323 | imx_usb->gadget.dev.driver = NULL; | 1370 | imx_usb->gadget.dev.driver = NULL; |
@@ -1435,6 +1482,10 @@ static int __init imx_udc_probe(struct platform_device *pdev) | |||
1435 | usb_init_data(imx_usb); | 1482 | usb_init_data(imx_usb); |
1436 | imx_udc_init(imx_usb); | 1483 | imx_udc_init(imx_usb); |
1437 | 1484 | ||
1485 | init_timer(&imx_usb->timer); | ||
1486 | imx_usb->timer.function = handle_config; | ||
1487 | imx_usb->timer.data = (unsigned long)imx_usb; | ||
1488 | |||
1438 | return 0; | 1489 | return 0; |
1439 | 1490 | ||
1440 | fail3: | 1491 | fail3: |
@@ -1457,6 +1508,7 @@ static int __exit imx_udc_remove(struct platform_device *pdev) | |||
1457 | int i; | 1508 | int i; |
1458 | 1509 | ||
1459 | imx_udc_disable(imx_usb); | 1510 | imx_udc_disable(imx_usb); |
1511 | del_timer(&imx_usb->timer); | ||
1460 | 1512 | ||
1461 | for (i = 0; i < IMX_USB_NB_EP + 1; i++) | 1513 | for (i = 0; i < IMX_USB_NB_EP + 1; i++) |
1462 | free_irq(imx_usb->usbd_int[i], imx_usb); | 1514 | free_irq(imx_usb->usbd_int[i], imx_usb); |
diff --git a/drivers/usb/gadget/imx_udc.h b/drivers/usb/gadget/imx_udc.h index 850076937d8d..b48ad59603d1 100644 --- a/drivers/usb/gadget/imx_udc.h +++ b/drivers/usb/gadget/imx_udc.h | |||
@@ -23,7 +23,8 @@ | |||
23 | /* Helper macros */ | 23 | /* Helper macros */ |
24 | #define EP_NO(ep) ((ep->bEndpointAddress) & ~USB_DIR_IN) /* IN:1, OUT:0 */ | 24 | #define EP_NO(ep) ((ep->bEndpointAddress) & ~USB_DIR_IN) /* IN:1, OUT:0 */ |
25 | #define EP_DIR(ep) ((ep->bEndpointAddress) & USB_DIR_IN ? 1 : 0) | 25 | #define EP_DIR(ep) ((ep->bEndpointAddress) & USB_DIR_IN ? 1 : 0) |
26 | #define irq_to_ep(irq) (((irq) >= USBD_INT0) || ((irq) <= USBD_INT6) ? ((irq) - USBD_INT0) : (USBD_INT6)) /*should not happen*/ | 26 | #define irq_to_ep(irq) (((irq) >= USBD_INT0) || ((irq) <= USBD_INT6) \ |
27 | ? ((irq) - USBD_INT0) : (USBD_INT6)) /*should not happen*/ | ||
27 | #define ep_to_irq(ep) (EP_NO((ep)) + USBD_INT0) | 28 | #define ep_to_irq(ep) (EP_NO((ep)) + USBD_INT0) |
28 | #define IMX_USB_NB_EP 6 | 29 | #define IMX_USB_NB_EP 6 |
29 | 30 | ||
@@ -58,6 +59,7 @@ struct imx_udc_struct { | |||
58 | struct device *dev; | 59 | struct device *dev; |
59 | struct imx_ep_struct imx_ep[IMX_USB_NB_EP]; | 60 | struct imx_ep_struct imx_ep[IMX_USB_NB_EP]; |
60 | struct clk *clk; | 61 | struct clk *clk; |
62 | struct timer_list timer; | ||
61 | enum ep0_state ep0state; | 63 | enum ep0_state ep0state; |
62 | struct resource *res; | 64 | struct resource *res; |
63 | void __iomem *base; | 65 | void __iomem *base; |
@@ -88,8 +90,8 @@ struct imx_udc_struct { | |||
88 | #define USB_EP_FDAT3(x) (0x3F + (x*0x30)) /* USB FIFO data */ | 90 | #define USB_EP_FDAT3(x) (0x3F + (x*0x30)) /* USB FIFO data */ |
89 | #define USB_EP_FSTAT(x) (0x40 + (x*0x30)) /* USB FIFO status */ | 91 | #define USB_EP_FSTAT(x) (0x40 + (x*0x30)) /* USB FIFO status */ |
90 | #define USB_EP_FCTRL(x) (0x44 + (x*0x30)) /* USB FIFO control */ | 92 | #define USB_EP_FCTRL(x) (0x44 + (x*0x30)) /* USB FIFO control */ |
91 | #define USB_EP_LRFP(x) (0x48 + (x*0x30)) /* USB last read frame pointer */ | 93 | #define USB_EP_LRFP(x) (0x48 + (x*0x30)) /* USB last rd f. pointer */ |
92 | #define USB_EP_LWFP(x) (0x4C + (x*0x30)) /* USB last write frame pointer */ | 94 | #define USB_EP_LWFP(x) (0x4C + (x*0x30)) /* USB last wr f. pointer */ |
93 | #define USB_EP_FALRM(x) (0x50 + (x*0x30)) /* USB FIFO alarm */ | 95 | #define USB_EP_FALRM(x) (0x50 + (x*0x30)) /* USB FIFO alarm */ |
94 | #define USB_EP_FRDP(x) (0x54 + (x*0x30)) /* USB FIFO read pointer */ | 96 | #define USB_EP_FRDP(x) (0x54 + (x*0x30)) /* USB FIFO read pointer */ |
95 | #define USB_EP_FWRP(x) (0x58 + (x*0x30)) /* USB FIFO write pointer */ | 97 | #define USB_EP_FWRP(x) (0x58 + (x*0x30)) /* USB FIFO write pointer */ |
@@ -170,7 +172,7 @@ struct imx_udc_struct { | |||
170 | /* #define DEBUG_IRQ */ | 172 | /* #define DEBUG_IRQ */ |
171 | /* #define DEBUG_EPIRQ */ | 173 | /* #define DEBUG_EPIRQ */ |
172 | /* #define DEBUG_DUMP */ | 174 | /* #define DEBUG_DUMP */ |
173 | #define DEBUG_ERR | 175 | /* #define DEBUG_ERR */ |
174 | 176 | ||
175 | #ifdef DEBUG_REQ | 177 | #ifdef DEBUG_REQ |
176 | #define D_REQ(dev, args...) dev_dbg(dev, ## args) | 178 | #define D_REQ(dev, args...) dev_dbg(dev, ## args) |
@@ -228,7 +230,8 @@ struct imx_udc_struct { | |||
228 | #endif /* DEBUG_IRQ */ | 230 | #endif /* DEBUG_IRQ */ |
229 | 231 | ||
230 | #ifdef DEBUG_EPIRQ | 232 | #ifdef DEBUG_EPIRQ |
231 | static void dump_ep_intr(const char *label, int nr, int irqreg, struct device *dev) | 233 | static void dump_ep_intr(const char *label, int nr, int irqreg, |
234 | struct device *dev) | ||
232 | { | 235 | { |
233 | dev_dbg(dev, "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, nr, | 236 | dev_dbg(dev, "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, nr, |
234 | (irqreg & EPINTR_FIFO_FULL) ? " full" : "", | 237 | (irqreg & EPINTR_FIFO_FULL) ? " full" : "", |
@@ -246,7 +249,8 @@ struct imx_udc_struct { | |||
246 | #endif /* DEBUG_IRQ */ | 249 | #endif /* DEBUG_IRQ */ |
247 | 250 | ||
248 | #ifdef DEBUG_DUMP | 251 | #ifdef DEBUG_DUMP |
249 | static void dump_usb_stat(const char *label, struct imx_udc_struct *imx_usb) | 252 | static void dump_usb_stat(const char *label, |
253 | struct imx_udc_struct *imx_usb) | ||
250 | { | 254 | { |
251 | int temp = __raw_readl(imx_usb->base + USB_STAT); | 255 | int temp = __raw_readl(imx_usb->base + USB_STAT); |
252 | 256 | ||
@@ -259,12 +263,15 @@ struct imx_udc_struct { | |||
259 | (temp & STAT_ALTSET)); | 263 | (temp & STAT_ALTSET)); |
260 | } | 264 | } |
261 | 265 | ||
262 | static void dump_ep_stat(const char *label, struct imx_ep_struct *imx_ep) | 266 | static void dump_ep_stat(const char *label, |
267 | struct imx_ep_struct *imx_ep) | ||
263 | { | 268 | { |
264 | int temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_INTR(EP_NO(imx_ep))); | 269 | int temp = __raw_readl(imx_ep->imx_usb->base |
270 | + USB_EP_INTR(EP_NO(imx_ep))); | ||
265 | 271 | ||
266 | dev_dbg(imx_ep->imx_usb->dev, | 272 | dev_dbg(imx_ep->imx_usb->dev, |
267 | "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", label, EP_NO(imx_ep), | 273 | "<%s> EP%d_INTR=[%s%s%s%s%s%s%s%s%s]\n", |
274 | label, EP_NO(imx_ep), | ||
268 | (temp & EPINTR_FIFO_FULL) ? " full" : "", | 275 | (temp & EPINTR_FIFO_FULL) ? " full" : "", |
269 | (temp & EPINTR_FIFO_EMPTY) ? " fempty" : "", | 276 | (temp & EPINTR_FIFO_EMPTY) ? " fempty" : "", |
270 | (temp & EPINTR_FIFO_ERROR) ? " ferr" : "", | 277 | (temp & EPINTR_FIFO_ERROR) ? " ferr" : "", |
@@ -275,18 +282,22 @@ struct imx_udc_struct { | |||
275 | (temp & EPINTR_DEVREQ) ? " devreq" : "", | 282 | (temp & EPINTR_DEVREQ) ? " devreq" : "", |
276 | (temp & EPINTR_EOT) ? " eot" : ""); | 283 | (temp & EPINTR_EOT) ? " eot" : ""); |
277 | 284 | ||
278 | temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_STAT(EP_NO(imx_ep))); | 285 | temp = __raw_readl(imx_ep->imx_usb->base |
286 | + USB_EP_STAT(EP_NO(imx_ep))); | ||
279 | 287 | ||
280 | dev_dbg(imx_ep->imx_usb->dev, | 288 | dev_dbg(imx_ep->imx_usb->dev, |
281 | "<%s> EP%d_STAT=[%s%s bcount=%d]\n", label, EP_NO(imx_ep), | 289 | "<%s> EP%d_STAT=[%s%s bcount=%d]\n", |
290 | label, EP_NO(imx_ep), | ||
282 | (temp & EPSTAT_SIP) ? " sip" : "", | 291 | (temp & EPSTAT_SIP) ? " sip" : "", |
283 | (temp & EPSTAT_STALL) ? " stall" : "", | 292 | (temp & EPSTAT_STALL) ? " stall" : "", |
284 | (temp & EPSTAT_BCOUNT) >> 16); | 293 | (temp & EPSTAT_BCOUNT) >> 16); |
285 | 294 | ||
286 | temp = __raw_readl(imx_ep->imx_usb->base + USB_EP_FSTAT(EP_NO(imx_ep))); | 295 | temp = __raw_readl(imx_ep->imx_usb->base |
296 | + USB_EP_FSTAT(EP_NO(imx_ep))); | ||
287 | 297 | ||
288 | dev_dbg(imx_ep->imx_usb->dev, | 298 | dev_dbg(imx_ep->imx_usb->dev, |
289 | "<%s> EP%d_FSTAT=[%s%s%s%s%s%s%s]\n", label, EP_NO(imx_ep), | 299 | "<%s> EP%d_FSTAT=[%s%s%s%s%s%s%s]\n", |
300 | label, EP_NO(imx_ep), | ||
290 | (temp & FSTAT_ERR) ? " ferr" : "", | 301 | (temp & FSTAT_ERR) ? " ferr" : "", |
291 | (temp & FSTAT_UF) ? " funder" : "", | 302 | (temp & FSTAT_UF) ? " funder" : "", |
292 | (temp & FSTAT_OF) ? " fover" : "", | 303 | (temp & FSTAT_OF) ? " fover" : "", |
@@ -296,19 +307,23 @@ struct imx_udc_struct { | |||
296 | (temp & FSTAT_EMPTY) ? " fempty" : ""); | 307 | (temp & FSTAT_EMPTY) ? " fempty" : ""); |
297 | } | 308 | } |
298 | 309 | ||
299 | static void dump_req(const char *label, struct imx_ep_struct *imx_ep, struct usb_request *req) | 310 | static void dump_req(const char *label, struct imx_ep_struct *imx_ep, |
311 | struct usb_request *req) | ||
300 | { | 312 | { |
301 | int i; | 313 | int i; |
302 | 314 | ||
303 | if (!req || !req->buf) { | 315 | if (!req || !req->buf) { |
304 | dev_dbg(imx_ep->imx_usb->dev, "<%s> req or req buf is free\n", label); | 316 | dev_dbg(imx_ep->imx_usb->dev, |
317 | "<%s> req or req buf is free\n", label); | ||
305 | return; | 318 | return; |
306 | } | 319 | } |
307 | 320 | ||
308 | if ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state == EP0_IN_DATA_PHASE) | 321 | if ((!EP_NO(imx_ep) && imx_ep->imx_usb->ep0state |
322 | == EP0_IN_DATA_PHASE) | ||
309 | || (EP_NO(imx_ep) && EP_DIR(imx_ep))) { | 323 | || (EP_NO(imx_ep) && EP_DIR(imx_ep))) { |
310 | 324 | ||
311 | dev_dbg(imx_ep->imx_usb->dev, "<%s> request dump <", label); | 325 | dev_dbg(imx_ep->imx_usb->dev, |
326 | "<%s> request dump <", label); | ||
312 | for (i = 0; i < req->length; i++) | 327 | for (i = 0; i < req->length; i++) |
313 | printk("%02x-", *((u8 *)req->buf + i)); | 328 | printk("%02x-", *((u8 *)req->buf + i)); |
314 | printk(">\n"); | 329 | printk(">\n"); |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 317b48fdbf01..d20937f28a19 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
@@ -1334,7 +1334,7 @@ static void make_qualifier (struct dev_data *dev) | |||
1334 | 1334 | ||
1335 | qual.bLength = sizeof qual; | 1335 | qual.bLength = sizeof qual; |
1336 | qual.bDescriptorType = USB_DT_DEVICE_QUALIFIER; | 1336 | qual.bDescriptorType = USB_DT_DEVICE_QUALIFIER; |
1337 | qual.bcdUSB = __constant_cpu_to_le16 (0x0200); | 1337 | qual.bcdUSB = cpu_to_le16 (0x0200); |
1338 | 1338 | ||
1339 | desc = dev->dev; | 1339 | desc = dev->dev; |
1340 | qual.bDeviceClass = desc->bDeviceClass; | 1340 | qual.bDeviceClass = desc->bDeviceClass; |
@@ -1908,7 +1908,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
1908 | || dev->dev->bNumConfigurations != 1) | 1908 | || dev->dev->bNumConfigurations != 1) |
1909 | goto fail; | 1909 | goto fail; |
1910 | dev->dev->bNumConfigurations = 1; | 1910 | dev->dev->bNumConfigurations = 1; |
1911 | dev->dev->bcdUSB = __constant_cpu_to_le16 (0x0200); | 1911 | dev->dev->bcdUSB = cpu_to_le16 (0x0200); |
1912 | 1912 | ||
1913 | /* triggers gadgetfs_bind(); then we can enumerate. */ | 1913 | /* triggers gadgetfs_bind(); then we can enumerate. */ |
1914 | spin_unlock_irq (&dev->lock); | 1914 | spin_unlock_irq (&dev->lock); |
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c index d554b0895603..6cd3d54f5640 100644 --- a/drivers/usb/gadget/lh7a40x_udc.c +++ b/drivers/usb/gadget/lh7a40x_udc.c | |||
@@ -432,8 +432,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
432 | device_add(&dev->gadget.dev); | 432 | device_add(&dev->gadget.dev); |
433 | retval = driver->bind(&dev->gadget); | 433 | retval = driver->bind(&dev->gadget); |
434 | if (retval) { | 434 | if (retval) { |
435 | printk("%s: bind to driver %s --> error %d\n", dev->gadget.name, | 435 | printk(KERN_WARNING "%s: bind to driver %s --> error %d\n", |
436 | driver->driver.name, retval); | 436 | dev->gadget.name, driver->driver.name, retval); |
437 | device_del(&dev->gadget.dev); | 437 | device_del(&dev->gadget.dev); |
438 | 438 | ||
439 | dev->driver = 0; | 439 | dev->driver = 0; |
@@ -445,8 +445,8 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
445 | * for set_configuration as well as eventual disconnect. | 445 | * for set_configuration as well as eventual disconnect. |
446 | * NOTE: this shouldn't power up until later. | 446 | * NOTE: this shouldn't power up until later. |
447 | */ | 447 | */ |
448 | printk("%s: registered gadget driver '%s'\n", dev->gadget.name, | 448 | printk(KERN_WARNING "%s: registered gadget driver '%s'\n", |
449 | driver->driver.name); | 449 | dev->gadget.name, driver->driver.name); |
450 | 450 | ||
451 | udc_enable(dev); | 451 | udc_enable(dev); |
452 | 452 | ||
@@ -581,7 +581,8 @@ static int read_fifo(struct lh7a40x_ep *ep, struct lh7a40x_request *req) | |||
581 | * discard the extra data. | 581 | * discard the extra data. |
582 | */ | 582 | */ |
583 | if (req->req.status != -EOVERFLOW) | 583 | if (req->req.status != -EOVERFLOW) |
584 | printk("%s overflow %d\n", ep->ep.name, count); | 584 | printk(KERN_WARNING "%s overflow %d\n", |
585 | ep->ep.name, count); | ||
585 | req->req.status = -EOVERFLOW; | 586 | req->req.status = -EOVERFLOW; |
586 | } else { | 587 | } else { |
587 | *buf++ = byte; | 588 | *buf++ = byte; |
@@ -831,7 +832,8 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr) | |||
831 | queue); | 832 | queue); |
832 | 833 | ||
833 | if (!req) { | 834 | if (!req) { |
834 | printk("%s: NULL REQ %d\n", | 835 | printk(KERN_WARNING |
836 | "%s: NULL REQ %d\n", | ||
835 | __func__, ep_idx); | 837 | __func__, ep_idx); |
836 | flush(ep); | 838 | flush(ep); |
837 | break; | 839 | break; |
@@ -844,7 +846,7 @@ static void lh7a40x_out_epn(struct lh7a40x_udc *dev, u32 ep_idx, u32 intr) | |||
844 | 846 | ||
845 | } else { | 847 | } else { |
846 | /* Throw packet away.. */ | 848 | /* Throw packet away.. */ |
847 | printk("%s: No descriptor?!?\n", __func__); | 849 | printk(KERN_WARNING "%s: No descriptor?!?\n", __func__); |
848 | flush(ep); | 850 | flush(ep); |
849 | } | 851 | } |
850 | } | 852 | } |
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 12c6d83b218c..9498be87a724 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -142,8 +142,8 @@ static char *type_string (u8 bmAttributes) | |||
142 | 142 | ||
143 | #include "net2280.h" | 143 | #include "net2280.h" |
144 | 144 | ||
145 | #define valid_bit __constant_cpu_to_le32 (1 << VALID_BIT) | 145 | #define valid_bit cpu_to_le32 (1 << VALID_BIT) |
146 | #define dma_done_ie __constant_cpu_to_le32 (1 << DMA_DONE_INTERRUPT_ENABLE) | 146 | #define dma_done_ie cpu_to_le32 (1 << DMA_DONE_INTERRUPT_ENABLE) |
147 | 147 | ||
148 | /*-------------------------------------------------------------------------*/ | 148 | /*-------------------------------------------------------------------------*/ |
149 | 149 | ||
@@ -425,7 +425,7 @@ net2280_alloc_request (struct usb_ep *_ep, gfp_t gfp_flags) | |||
425 | return NULL; | 425 | return NULL; |
426 | } | 426 | } |
427 | td->dmacount = 0; /* not VALID */ | 427 | td->dmacount = 0; /* not VALID */ |
428 | td->dmaaddr = __constant_cpu_to_le32 (DMA_ADDR_INVALID); | 428 | td->dmaaddr = cpu_to_le32 (DMA_ADDR_INVALID); |
429 | td->dmadesc = td->dmaaddr; | 429 | td->dmadesc = td->dmaaddr; |
430 | req->td = td; | 430 | req->td = td; |
431 | } | 431 | } |
@@ -775,7 +775,7 @@ static void start_dma (struct net2280_ep *ep, struct net2280_request *req) | |||
775 | fill_dma_desc (ep, req, 1); | 775 | fill_dma_desc (ep, req, 1); |
776 | 776 | ||
777 | if (!use_dma_chaining) | 777 | if (!use_dma_chaining) |
778 | req->td->dmacount |= __constant_cpu_to_le32 (1 << END_OF_CHAIN); | 778 | req->td->dmacount |= cpu_to_le32 (1 << END_OF_CHAIN); |
779 | 779 | ||
780 | start_queue (ep, tmp, req->td_dma); | 780 | start_queue (ep, tmp, req->td_dma); |
781 | } | 781 | } |
@@ -2407,9 +2407,9 @@ static void handle_stat0_irqs (struct net2280 *dev, u32 stat) | |||
2407 | 2407 | ||
2408 | if (readl (&e->regs->ep_rsp) | 2408 | if (readl (&e->regs->ep_rsp) |
2409 | & (1 << SET_ENDPOINT_HALT)) | 2409 | & (1 << SET_ENDPOINT_HALT)) |
2410 | status = __constant_cpu_to_le32 (1); | 2410 | status = cpu_to_le32 (1); |
2411 | else | 2411 | else |
2412 | status = __constant_cpu_to_le32 (0); | 2412 | status = cpu_to_le32 (0); |
2413 | 2413 | ||
2414 | /* don't bother with a request object! */ | 2414 | /* don't bother with a request object! */ |
2415 | writel (0, &dev->epregs [0].ep_irqenb); | 2415 | writel (0, &dev->epregs [0].ep_irqenb); |
@@ -2667,7 +2667,7 @@ static void handle_stat1_irqs (struct net2280 *dev, u32 stat) | |||
2667 | req = list_entry (ep->queue.next, | 2667 | req = list_entry (ep->queue.next, |
2668 | struct net2280_request, queue); | 2668 | struct net2280_request, queue); |
2669 | dmacount = req->td->dmacount; | 2669 | dmacount = req->td->dmacount; |
2670 | dmacount &= __constant_cpu_to_le32 ( | 2670 | dmacount &= cpu_to_le32 ( |
2671 | (1 << VALID_BIT) | 2671 | (1 << VALID_BIT) |
2672 | | DMA_BYTE_COUNT_MASK); | 2672 | | DMA_BYTE_COUNT_MASK); |
2673 | if (dmacount && (dmacount & valid_bit) == 0) | 2673 | if (dmacount && (dmacount & valid_bit) == 0) |
@@ -2881,7 +2881,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) | |||
2881 | goto done; | 2881 | goto done; |
2882 | } | 2882 | } |
2883 | td->dmacount = 0; /* not VALID */ | 2883 | td->dmacount = 0; /* not VALID */ |
2884 | td->dmaaddr = __constant_cpu_to_le32 (DMA_ADDR_INVALID); | 2884 | td->dmaaddr = cpu_to_le32 (DMA_ADDR_INVALID); |
2885 | td->dmadesc = td->dmaaddr; | 2885 | td->dmadesc = td->dmaaddr; |
2886 | dev->ep [i].dummy = td; | 2886 | dev->ep [i].dummy = td; |
2887 | } | 2887 | } |
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c index 5a3034fdfe47..29500154d00c 100644 --- a/drivers/usb/gadget/printer.c +++ b/drivers/usb/gadget/printer.c | |||
@@ -225,12 +225,12 @@ module_param(qlen, uint, S_IRUGO|S_IWUSR); | |||
225 | static struct usb_device_descriptor device_desc = { | 225 | static struct usb_device_descriptor device_desc = { |
226 | .bLength = sizeof device_desc, | 226 | .bLength = sizeof device_desc, |
227 | .bDescriptorType = USB_DT_DEVICE, | 227 | .bDescriptorType = USB_DT_DEVICE, |
228 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 228 | .bcdUSB = cpu_to_le16(0x0200), |
229 | .bDeviceClass = USB_CLASS_PER_INTERFACE, | 229 | .bDeviceClass = USB_CLASS_PER_INTERFACE, |
230 | .bDeviceSubClass = 0, | 230 | .bDeviceSubClass = 0, |
231 | .bDeviceProtocol = 0, | 231 | .bDeviceProtocol = 0, |
232 | .idVendor = __constant_cpu_to_le16(PRINTER_VENDOR_NUM), | 232 | .idVendor = cpu_to_le16(PRINTER_VENDOR_NUM), |
233 | .idProduct = __constant_cpu_to_le16(PRINTER_PRODUCT_NUM), | 233 | .idProduct = cpu_to_le16(PRINTER_PRODUCT_NUM), |
234 | .iManufacturer = STRING_MANUFACTURER, | 234 | .iManufacturer = STRING_MANUFACTURER, |
235 | .iProduct = STRING_PRODUCT, | 235 | .iProduct = STRING_PRODUCT, |
236 | .iSerialNumber = STRING_SERIALNUM, | 236 | .iSerialNumber = STRING_SERIALNUM, |
@@ -299,20 +299,20 @@ static struct usb_endpoint_descriptor hs_ep_in_desc = { | |||
299 | .bLength = USB_DT_ENDPOINT_SIZE, | 299 | .bLength = USB_DT_ENDPOINT_SIZE, |
300 | .bDescriptorType = USB_DT_ENDPOINT, | 300 | .bDescriptorType = USB_DT_ENDPOINT, |
301 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 301 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
302 | .wMaxPacketSize = __constant_cpu_to_le16(512) | 302 | .wMaxPacketSize = cpu_to_le16(512) |
303 | }; | 303 | }; |
304 | 304 | ||
305 | static struct usb_endpoint_descriptor hs_ep_out_desc = { | 305 | static struct usb_endpoint_descriptor hs_ep_out_desc = { |
306 | .bLength = USB_DT_ENDPOINT_SIZE, | 306 | .bLength = USB_DT_ENDPOINT_SIZE, |
307 | .bDescriptorType = USB_DT_ENDPOINT, | 307 | .bDescriptorType = USB_DT_ENDPOINT, |
308 | .bmAttributes = USB_ENDPOINT_XFER_BULK, | 308 | .bmAttributes = USB_ENDPOINT_XFER_BULK, |
309 | .wMaxPacketSize = __constant_cpu_to_le16(512) | 309 | .wMaxPacketSize = cpu_to_le16(512) |
310 | }; | 310 | }; |
311 | 311 | ||
312 | static struct usb_qualifier_descriptor dev_qualifier = { | 312 | static struct usb_qualifier_descriptor dev_qualifier = { |
313 | .bLength = sizeof dev_qualifier, | 313 | .bLength = sizeof dev_qualifier, |
314 | .bDescriptorType = USB_DT_DEVICE_QUALIFIER, | 314 | .bDescriptorType = USB_DT_DEVICE_QUALIFIER, |
315 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 315 | .bcdUSB = cpu_to_le16(0x0200), |
316 | .bDeviceClass = USB_CLASS_PRINTER, | 316 | .bDeviceClass = USB_CLASS_PRINTER, |
317 | .bNumConfigurations = 1 | 317 | .bNumConfigurations = 1 |
318 | }; | 318 | }; |
@@ -1406,16 +1406,16 @@ printer_bind(struct usb_gadget *gadget) | |||
1406 | gadget->name); | 1406 | gadget->name); |
1407 | /* unrecognized, but safe unless bulk is REALLY quirky */ | 1407 | /* unrecognized, but safe unless bulk is REALLY quirky */ |
1408 | device_desc.bcdDevice = | 1408 | device_desc.bcdDevice = |
1409 | __constant_cpu_to_le16(0xFFFF); | 1409 | cpu_to_le16(0xFFFF); |
1410 | } | 1410 | } |
1411 | snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s", | 1411 | snprintf(manufacturer, sizeof(manufacturer), "%s %s with %s", |
1412 | init_utsname()->sysname, init_utsname()->release, | 1412 | init_utsname()->sysname, init_utsname()->release, |
1413 | gadget->name); | 1413 | gadget->name); |
1414 | 1414 | ||
1415 | device_desc.idVendor = | 1415 | device_desc.idVendor = |
1416 | __constant_cpu_to_le16(PRINTER_VENDOR_NUM); | 1416 | cpu_to_le16(PRINTER_VENDOR_NUM); |
1417 | device_desc.idProduct = | 1417 | device_desc.idProduct = |
1418 | __constant_cpu_to_le16(PRINTER_PRODUCT_NUM); | 1418 | cpu_to_le16(PRINTER_PRODUCT_NUM); |
1419 | 1419 | ||
1420 | /* support optional vendor/distro customization */ | 1420 | /* support optional vendor/distro customization */ |
1421 | if (idVendor) { | 1421 | if (idVendor) { |
diff --git a/drivers/usb/gadget/pxa25x_udc.c b/drivers/usb/gadget/pxa25x_udc.c index 9b36205c5759..0ce4e2819847 100644 --- a/drivers/usb/gadget/pxa25x_udc.c +++ b/drivers/usb/gadget/pxa25x_udc.c | |||
@@ -904,8 +904,8 @@ static void pxa25x_ep_fifo_flush(struct usb_ep *_ep) | |||
904 | 904 | ||
905 | /* most IN status is the same, but ISO can't stall */ | 905 | /* most IN status is the same, but ISO can't stall */ |
906 | *ep->reg_udccs = UDCCS_BI_TPC|UDCCS_BI_FTF|UDCCS_BI_TUR | 906 | *ep->reg_udccs = UDCCS_BI_TPC|UDCCS_BI_FTF|UDCCS_BI_TUR |
907 | | (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC) | 907 | | (ep->bmAttributes == USB_ENDPOINT_XFER_ISOC |
908 | ? 0 : UDCCS_BI_SST; | 908 | ? 0 : UDCCS_BI_SST); |
909 | } | 909 | } |
910 | 910 | ||
911 | 911 | ||
diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 990f40f988d4..8cc676ecbb23 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/proc_fs.h> | 30 | #include <linux/proc_fs.h> |
31 | #include <linux/clk.h> | 31 | #include <linux/clk.h> |
32 | #include <linux/irq.h> | 32 | #include <linux/irq.h> |
33 | #include <linux/gpio.h> | ||
33 | 34 | ||
34 | #include <asm/byteorder.h> | 35 | #include <asm/byteorder.h> |
35 | #include <mach/hardware.h> | 36 | #include <mach/hardware.h> |
@@ -278,7 +279,7 @@ static void pxa_init_debugfs(struct pxa_udc *udc) | |||
278 | goto err_queues; | 279 | goto err_queues; |
279 | eps = debugfs_create_file("epstate", 0400, root, udc, | 280 | eps = debugfs_create_file("epstate", 0400, root, udc, |
280 | &eps_dbg_fops); | 281 | &eps_dbg_fops); |
281 | if (!queues) | 282 | if (!eps) |
282 | goto err_eps; | 283 | goto err_eps; |
283 | 284 | ||
284 | udc->debugfs_root = root; | 285 | udc->debugfs_root = root; |
@@ -747,13 +748,13 @@ static void req_done(struct pxa_ep *ep, struct pxa27x_request *req, int status) | |||
747 | } | 748 | } |
748 | 749 | ||
749 | /** | 750 | /** |
750 | * ep_end_out_req - Ends control endpoint in request | 751 | * ep_end_out_req - Ends endpoint OUT request |
751 | * @ep: physical endpoint | 752 | * @ep: physical endpoint |
752 | * @req: pxa request | 753 | * @req: pxa request |
753 | * | 754 | * |
754 | * Context: ep->lock held | 755 | * Context: ep->lock held |
755 | * | 756 | * |
756 | * Ends endpoint in request (completes usb request). | 757 | * Ends endpoint OUT request (completes usb request). |
757 | */ | 758 | */ |
758 | static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) | 759 | static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) |
759 | { | 760 | { |
@@ -762,13 +763,13 @@ static void ep_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) | |||
762 | } | 763 | } |
763 | 764 | ||
764 | /** | 765 | /** |
765 | * ep0_end_out_req - Ends control endpoint in request (ends data stage) | 766 | * ep0_end_out_req - Ends control endpoint OUT request (ends data stage) |
766 | * @ep: physical endpoint | 767 | * @ep: physical endpoint |
767 | * @req: pxa request | 768 | * @req: pxa request |
768 | * | 769 | * |
769 | * Context: ep->lock held | 770 | * Context: ep->lock held |
770 | * | 771 | * |
771 | * Ends control endpoint in request (completes usb request), and puts | 772 | * Ends control endpoint OUT request (completes usb request), and puts |
772 | * control endpoint into idle state | 773 | * control endpoint into idle state |
773 | */ | 774 | */ |
774 | static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) | 775 | static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) |
@@ -779,13 +780,13 @@ static void ep0_end_out_req(struct pxa_ep *ep, struct pxa27x_request *req) | |||
779 | } | 780 | } |
780 | 781 | ||
781 | /** | 782 | /** |
782 | * ep_end_in_req - Ends endpoint out request | 783 | * ep_end_in_req - Ends endpoint IN request |
783 | * @ep: physical endpoint | 784 | * @ep: physical endpoint |
784 | * @req: pxa request | 785 | * @req: pxa request |
785 | * | 786 | * |
786 | * Context: ep->lock held | 787 | * Context: ep->lock held |
787 | * | 788 | * |
788 | * Ends endpoint out request (completes usb request). | 789 | * Ends endpoint IN request (completes usb request). |
789 | */ | 790 | */ |
790 | static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) | 791 | static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) |
791 | { | 792 | { |
@@ -794,20 +795,18 @@ static void ep_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) | |||
794 | } | 795 | } |
795 | 796 | ||
796 | /** | 797 | /** |
797 | * ep0_end_in_req - Ends control endpoint out request (ends data stage) | 798 | * ep0_end_in_req - Ends control endpoint IN request (ends data stage) |
798 | * @ep: physical endpoint | 799 | * @ep: physical endpoint |
799 | * @req: pxa request | 800 | * @req: pxa request |
800 | * | 801 | * |
801 | * Context: ep->lock held | 802 | * Context: ep->lock held |
802 | * | 803 | * |
803 | * Ends control endpoint out request (completes usb request), and puts | 804 | * Ends control endpoint IN request (completes usb request), and puts |
804 | * control endpoint into status state | 805 | * control endpoint into status state |
805 | */ | 806 | */ |
806 | static void ep0_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) | 807 | static void ep0_end_in_req(struct pxa_ep *ep, struct pxa27x_request *req) |
807 | { | 808 | { |
808 | struct pxa_udc *udc = ep->dev; | 809 | set_ep0state(ep->dev, IN_STATUS_STAGE); |
809 | |||
810 | set_ep0state(udc, IN_STATUS_STAGE); | ||
811 | ep_end_in_req(ep, req); | 810 | ep_end_in_req(ep, req); |
812 | } | 811 | } |
813 | 812 | ||
@@ -1167,7 +1166,7 @@ static int pxa_ep_queue(struct usb_ep *_ep, struct usb_request *_req, | |||
1167 | ep_end_in_req(ep, req); | 1166 | ep_end_in_req(ep, req); |
1168 | } else { | 1167 | } else { |
1169 | ep_err(ep, "got a request of %d bytes while" | 1168 | ep_err(ep, "got a request of %d bytes while" |
1170 | "in state WATI_ACK_SET_CONF_INTERF\n", | 1169 | "in state WAIT_ACK_SET_CONF_INTERF\n", |
1171 | length); | 1170 | length); |
1172 | ep_del_request(ep, req); | 1171 | ep_del_request(ep, req); |
1173 | rc = -EL2HLT; | 1172 | rc = -EL2HLT; |
@@ -1213,30 +1212,26 @@ static int pxa_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | |||
1213 | struct udc_usb_ep *udc_usb_ep; | 1212 | struct udc_usb_ep *udc_usb_ep; |
1214 | struct pxa27x_request *req; | 1213 | struct pxa27x_request *req; |
1215 | unsigned long flags; | 1214 | unsigned long flags; |
1216 | int rc; | 1215 | int rc = -EINVAL; |
1217 | 1216 | ||
1218 | if (!_ep) | 1217 | if (!_ep) |
1219 | return -EINVAL; | 1218 | return rc; |
1220 | udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); | 1219 | udc_usb_ep = container_of(_ep, struct udc_usb_ep, usb_ep); |
1221 | ep = udc_usb_ep->pxa_ep; | 1220 | ep = udc_usb_ep->pxa_ep; |
1222 | if (!ep || is_ep0(ep)) | 1221 | if (!ep || is_ep0(ep)) |
1223 | return -EINVAL; | 1222 | return rc; |
1224 | 1223 | ||
1225 | spin_lock_irqsave(&ep->lock, flags); | 1224 | spin_lock_irqsave(&ep->lock, flags); |
1226 | 1225 | ||
1227 | /* make sure it's actually queued on this endpoint */ | 1226 | /* make sure it's actually queued on this endpoint */ |
1228 | list_for_each_entry(req, &ep->queue, queue) { | 1227 | list_for_each_entry(req, &ep->queue, queue) { |
1229 | if (&req->req == _req) | 1228 | if (&req->req == _req) { |
1229 | req_done(ep, req, -ECONNRESET); | ||
1230 | rc = 0; | ||
1230 | break; | 1231 | break; |
1232 | } | ||
1231 | } | 1233 | } |
1232 | 1234 | ||
1233 | rc = -EINVAL; | ||
1234 | if (&req->req != _req) | ||
1235 | goto out; | ||
1236 | |||
1237 | rc = 0; | ||
1238 | req_done(ep, req, -ECONNRESET); | ||
1239 | out: | ||
1240 | spin_unlock_irqrestore(&ep->lock, flags); | 1235 | spin_unlock_irqrestore(&ep->lock, flags); |
1241 | return rc; | 1236 | return rc; |
1242 | } | 1237 | } |
@@ -1471,6 +1466,32 @@ static struct usb_ep_ops pxa_ep_ops = { | |||
1471 | .fifo_flush = pxa_ep_fifo_flush, | 1466 | .fifo_flush = pxa_ep_fifo_flush, |
1472 | }; | 1467 | }; |
1473 | 1468 | ||
1469 | /** | ||
1470 | * dplus_pullup - Connect or disconnect pullup resistor to D+ pin | ||
1471 | * @udc: udc device | ||
1472 | * @on: 0 if disconnect pullup resistor, 1 otherwise | ||
1473 | * Context: any | ||
1474 | * | ||
1475 | * Handle D+ pullup resistor, make the device visible to the usb bus, and | ||
1476 | * declare it as a full speed usb device | ||
1477 | */ | ||
1478 | static void dplus_pullup(struct pxa_udc *udc, int on) | ||
1479 | { | ||
1480 | if (on) { | ||
1481 | if (gpio_is_valid(udc->mach->gpio_pullup)) | ||
1482 | gpio_set_value(udc->mach->gpio_pullup, | ||
1483 | !udc->mach->gpio_pullup_inverted); | ||
1484 | if (udc->mach->udc_command) | ||
1485 | udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT); | ||
1486 | } else { | ||
1487 | if (gpio_is_valid(udc->mach->gpio_pullup)) | ||
1488 | gpio_set_value(udc->mach->gpio_pullup, | ||
1489 | udc->mach->gpio_pullup_inverted); | ||
1490 | if (udc->mach->udc_command) | ||
1491 | udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); | ||
1492 | } | ||
1493 | udc->pullup_on = on; | ||
1494 | } | ||
1474 | 1495 | ||
1475 | /** | 1496 | /** |
1476 | * pxa_udc_get_frame - Returns usb frame number | 1497 | * pxa_udc_get_frame - Returns usb frame number |
@@ -1500,21 +1521,145 @@ static int pxa_udc_wakeup(struct usb_gadget *_gadget) | |||
1500 | return 0; | 1521 | return 0; |
1501 | } | 1522 | } |
1502 | 1523 | ||
1524 | static void udc_enable(struct pxa_udc *udc); | ||
1525 | static void udc_disable(struct pxa_udc *udc); | ||
1526 | |||
1527 | /** | ||
1528 | * should_enable_udc - Tells if UDC should be enabled | ||
1529 | * @udc: udc device | ||
1530 | * Context: any | ||
1531 | * | ||
1532 | * The UDC should be enabled if : | ||
1533 | |||
1534 | * - the pullup resistor is connected | ||
1535 | * - and a gadget driver is bound | ||
1536 | * - and vbus is sensed (or no vbus sense is available) | ||
1537 | * | ||
1538 | * Returns 1 if UDC should be enabled, 0 otherwise | ||
1539 | */ | ||
1540 | static int should_enable_udc(struct pxa_udc *udc) | ||
1541 | { | ||
1542 | int put_on; | ||
1543 | |||
1544 | put_on = ((udc->pullup_on) && (udc->driver)); | ||
1545 | put_on &= ((udc->vbus_sensed) || (!udc->transceiver)); | ||
1546 | return put_on; | ||
1547 | } | ||
1548 | |||
1549 | /** | ||
1550 | * should_disable_udc - Tells if UDC should be disabled | ||
1551 | * @udc: udc device | ||
1552 | * Context: any | ||
1553 | * | ||
1554 | * The UDC should be disabled if : | ||
1555 | * - the pullup resistor is not connected | ||
1556 | * - or no gadget driver is bound | ||
1557 | * - or no vbus is sensed (when vbus sesing is available) | ||
1558 | * | ||
1559 | * Returns 1 if UDC should be disabled | ||
1560 | */ | ||
1561 | static int should_disable_udc(struct pxa_udc *udc) | ||
1562 | { | ||
1563 | int put_off; | ||
1564 | |||
1565 | put_off = ((!udc->pullup_on) || (!udc->driver)); | ||
1566 | put_off |= ((!udc->vbus_sensed) && (udc->transceiver)); | ||
1567 | return put_off; | ||
1568 | } | ||
1569 | |||
1570 | /** | ||
1571 | * pxa_udc_pullup - Offer manual D+ pullup control | ||
1572 | * @_gadget: usb gadget using the control | ||
1573 | * @is_active: 0 if disconnect, else connect D+ pullup resistor | ||
1574 | * Context: !in_interrupt() | ||
1575 | * | ||
1576 | * Returns 0 if OK, -EOPNOTSUPP if udc driver doesn't handle D+ pullup | ||
1577 | */ | ||
1578 | static int pxa_udc_pullup(struct usb_gadget *_gadget, int is_active) | ||
1579 | { | ||
1580 | struct pxa_udc *udc = to_gadget_udc(_gadget); | ||
1581 | |||
1582 | if (!gpio_is_valid(udc->mach->gpio_pullup) && !udc->mach->udc_command) | ||
1583 | return -EOPNOTSUPP; | ||
1584 | |||
1585 | dplus_pullup(udc, is_active); | ||
1586 | |||
1587 | if (should_enable_udc(udc)) | ||
1588 | udc_enable(udc); | ||
1589 | if (should_disable_udc(udc)) | ||
1590 | udc_disable(udc); | ||
1591 | return 0; | ||
1592 | } | ||
1593 | |||
1594 | static void udc_enable(struct pxa_udc *udc); | ||
1595 | static void udc_disable(struct pxa_udc *udc); | ||
1596 | |||
1597 | /** | ||
1598 | * pxa_udc_vbus_session - Called by external transceiver to enable/disable udc | ||
1599 | * @_gadget: usb gadget | ||
1600 | * @is_active: 0 if should disable the udc, 1 if should enable | ||
1601 | * | ||
1602 | * Enables the udc, and optionnaly activates D+ pullup resistor. Or disables the | ||
1603 | * udc, and deactivates D+ pullup resistor. | ||
1604 | * | ||
1605 | * Returns 0 | ||
1606 | */ | ||
1607 | static int pxa_udc_vbus_session(struct usb_gadget *_gadget, int is_active) | ||
1608 | { | ||
1609 | struct pxa_udc *udc = to_gadget_udc(_gadget); | ||
1610 | |||
1611 | udc->vbus_sensed = is_active; | ||
1612 | if (should_enable_udc(udc)) | ||
1613 | udc_enable(udc); | ||
1614 | if (should_disable_udc(udc)) | ||
1615 | udc_disable(udc); | ||
1616 | |||
1617 | return 0; | ||
1618 | } | ||
1619 | |||
1620 | /** | ||
1621 | * pxa_udc_vbus_draw - Called by gadget driver after SET_CONFIGURATION completed | ||
1622 | * @_gadget: usb gadget | ||
1623 | * @mA: current drawn | ||
1624 | * | ||
1625 | * Context: !in_interrupt() | ||
1626 | * | ||
1627 | * Called after a configuration was chosen by a USB host, to inform how much | ||
1628 | * current can be drawn by the device from VBus line. | ||
1629 | * | ||
1630 | * Returns 0 or -EOPNOTSUPP if no transceiver is handling the udc | ||
1631 | */ | ||
1632 | static int pxa_udc_vbus_draw(struct usb_gadget *_gadget, unsigned mA) | ||
1633 | { | ||
1634 | struct pxa_udc *udc; | ||
1635 | |||
1636 | udc = to_gadget_udc(_gadget); | ||
1637 | if (udc->transceiver) | ||
1638 | return otg_set_power(udc->transceiver, mA); | ||
1639 | return -EOPNOTSUPP; | ||
1640 | } | ||
1641 | |||
1503 | static const struct usb_gadget_ops pxa_udc_ops = { | 1642 | static const struct usb_gadget_ops pxa_udc_ops = { |
1504 | .get_frame = pxa_udc_get_frame, | 1643 | .get_frame = pxa_udc_get_frame, |
1505 | .wakeup = pxa_udc_wakeup, | 1644 | .wakeup = pxa_udc_wakeup, |
1506 | /* current versions must always be self-powered */ | 1645 | .pullup = pxa_udc_pullup, |
1646 | .vbus_session = pxa_udc_vbus_session, | ||
1647 | .vbus_draw = pxa_udc_vbus_draw, | ||
1507 | }; | 1648 | }; |
1508 | 1649 | ||
1509 | /** | 1650 | /** |
1510 | * udc_disable - disable udc device controller | 1651 | * udc_disable - disable udc device controller |
1511 | * @udc: udc device | 1652 | * @udc: udc device |
1653 | * Context: any | ||
1512 | * | 1654 | * |
1513 | * Disables the udc device : disables clocks, udc interrupts, control endpoint | 1655 | * Disables the udc device : disables clocks, udc interrupts, control endpoint |
1514 | * interrupts. | 1656 | * interrupts. |
1515 | */ | 1657 | */ |
1516 | static void udc_disable(struct pxa_udc *udc) | 1658 | static void udc_disable(struct pxa_udc *udc) |
1517 | { | 1659 | { |
1660 | if (!udc->enabled) | ||
1661 | return; | ||
1662 | |||
1518 | udc_writel(udc, UDCICR0, 0); | 1663 | udc_writel(udc, UDCICR0, 0); |
1519 | udc_writel(udc, UDCICR1, 0); | 1664 | udc_writel(udc, UDCICR1, 0); |
1520 | 1665 | ||
@@ -1523,8 +1668,8 @@ static void udc_disable(struct pxa_udc *udc) | |||
1523 | 1668 | ||
1524 | ep0_idle(udc); | 1669 | ep0_idle(udc); |
1525 | udc->gadget.speed = USB_SPEED_UNKNOWN; | 1670 | udc->gadget.speed = USB_SPEED_UNKNOWN; |
1526 | if (udc->mach->udc_command) | 1671 | |
1527 | udc->mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); | 1672 | udc->enabled = 0; |
1528 | } | 1673 | } |
1529 | 1674 | ||
1530 | /** | 1675 | /** |
@@ -1555,10 +1700,9 @@ static __init void udc_init_data(struct pxa_udc *dev) | |||
1555 | } | 1700 | } |
1556 | 1701 | ||
1557 | /* USB endpoints init */ | 1702 | /* USB endpoints init */ |
1558 | for (i = 0; i < NR_USB_ENDPOINTS; i++) | 1703 | for (i = 1; i < NR_USB_ENDPOINTS; i++) |
1559 | if (i != 0) | 1704 | list_add_tail(&dev->udc_usb_ep[i].usb_ep.ep_list, |
1560 | list_add_tail(&dev->udc_usb_ep[i].usb_ep.ep_list, | 1705 | &dev->gadget.ep_list); |
1561 | &dev->gadget.ep_list); | ||
1562 | } | 1706 | } |
1563 | 1707 | ||
1564 | /** | 1708 | /** |
@@ -1570,6 +1714,9 @@ static __init void udc_init_data(struct pxa_udc *dev) | |||
1570 | */ | 1714 | */ |
1571 | static void udc_enable(struct pxa_udc *udc) | 1715 | static void udc_enable(struct pxa_udc *udc) |
1572 | { | 1716 | { |
1717 | if (udc->enabled) | ||
1718 | return; | ||
1719 | |||
1573 | udc_writel(udc, UDCICR0, 0); | 1720 | udc_writel(udc, UDCICR0, 0); |
1574 | udc_writel(udc, UDCICR1, 0); | 1721 | udc_writel(udc, UDCICR1, 0); |
1575 | udc_clear_mask_UDCCR(udc, UDCCR_UDE); | 1722 | udc_clear_mask_UDCCR(udc, UDCCR_UDE); |
@@ -1598,9 +1745,7 @@ static void udc_enable(struct pxa_udc *udc) | |||
1598 | /* enable ep0 irqs */ | 1745 | /* enable ep0 irqs */ |
1599 | pio_irq_enable(&udc->pxa_ep[0]); | 1746 | pio_irq_enable(&udc->pxa_ep[0]); |
1600 | 1747 | ||
1601 | dev_info(udc->dev, "UDC connecting\n"); | 1748 | udc->enabled = 1; |
1602 | if (udc->mach->udc_command) | ||
1603 | udc->mach->udc_command(PXA2XX_UDC_CMD_CONNECT); | ||
1604 | } | 1749 | } |
1605 | 1750 | ||
1606 | /** | 1751 | /** |
@@ -1612,6 +1757,9 @@ static void udc_enable(struct pxa_udc *udc) | |||
1612 | * usb traffic follows until a disconnect is reported. Then a host may connect | 1757 | * usb traffic follows until a disconnect is reported. Then a host may connect |
1613 | * again, or the driver might get unbound. | 1758 | * again, or the driver might get unbound. |
1614 | * | 1759 | * |
1760 | * Note that the udc is not automatically enabled. Check function | ||
1761 | * should_enable_udc(). | ||
1762 | * | ||
1615 | * Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise | 1763 | * Returns 0 if no error, -EINVAL, -ENODEV, -EBUSY otherwise |
1616 | */ | 1764 | */ |
1617 | int usb_gadget_register_driver(struct usb_gadget_driver *driver) | 1765 | int usb_gadget_register_driver(struct usb_gadget_driver *driver) |
@@ -1630,6 +1778,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1630 | /* first hook up the driver ... */ | 1778 | /* first hook up the driver ... */ |
1631 | udc->driver = driver; | 1779 | udc->driver = driver; |
1632 | udc->gadget.dev.driver = &driver->driver; | 1780 | udc->gadget.dev.driver = &driver->driver; |
1781 | dplus_pullup(udc, 1); | ||
1633 | 1782 | ||
1634 | retval = device_add(&udc->gadget.dev); | 1783 | retval = device_add(&udc->gadget.dev); |
1635 | if (retval) { | 1784 | if (retval) { |
@@ -1645,9 +1794,21 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1645 | dev_dbg(udc->dev, "registered gadget driver '%s'\n", | 1794 | dev_dbg(udc->dev, "registered gadget driver '%s'\n", |
1646 | driver->driver.name); | 1795 | driver->driver.name); |
1647 | 1796 | ||
1648 | udc_enable(udc); | 1797 | if (udc->transceiver) { |
1798 | retval = otg_set_peripheral(udc->transceiver, &udc->gadget); | ||
1799 | if (retval) { | ||
1800 | dev_err(udc->dev, "can't bind to transceiver\n"); | ||
1801 | goto transceiver_fail; | ||
1802 | } | ||
1803 | } | ||
1804 | |||
1805 | if (should_enable_udc(udc)) | ||
1806 | udc_enable(udc); | ||
1649 | return 0; | 1807 | return 0; |
1650 | 1808 | ||
1809 | transceiver_fail: | ||
1810 | if (driver->unbind) | ||
1811 | driver->unbind(&udc->gadget); | ||
1651 | bind_fail: | 1812 | bind_fail: |
1652 | device_del(&udc->gadget.dev); | 1813 | device_del(&udc->gadget.dev); |
1653 | add_fail: | 1814 | add_fail: |
@@ -1699,14 +1860,17 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1699 | 1860 | ||
1700 | stop_activity(udc, driver); | 1861 | stop_activity(udc, driver); |
1701 | udc_disable(udc); | 1862 | udc_disable(udc); |
1863 | dplus_pullup(udc, 0); | ||
1702 | 1864 | ||
1703 | driver->unbind(&udc->gadget); | 1865 | driver->unbind(&udc->gadget); |
1704 | udc->driver = NULL; | 1866 | udc->driver = NULL; |
1705 | 1867 | ||
1706 | device_del(&udc->gadget.dev); | 1868 | device_del(&udc->gadget.dev); |
1707 | |||
1708 | dev_info(udc->dev, "unregistered gadget driver '%s'\n", | 1869 | dev_info(udc->dev, "unregistered gadget driver '%s'\n", |
1709 | driver->driver.name); | 1870 | driver->driver.name); |
1871 | |||
1872 | if (udc->transceiver) | ||
1873 | return otg_set_peripheral(udc->transceiver, NULL); | ||
1710 | return 0; | 1874 | return 0; |
1711 | } | 1875 | } |
1712 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | 1876 | EXPORT_SYMBOL(usb_gadget_unregister_driver); |
@@ -1823,14 +1987,14 @@ static void handle_ep0(struct pxa_udc *udc, int fifo_irq, int opc_irq) | |||
1823 | struct pxa27x_request *req = NULL; | 1987 | struct pxa27x_request *req = NULL; |
1824 | int completed = 0; | 1988 | int completed = 0; |
1825 | 1989 | ||
1990 | if (!list_empty(&ep->queue)) | ||
1991 | req = list_entry(ep->queue.next, struct pxa27x_request, queue); | ||
1992 | |||
1826 | udccsr0 = udc_ep_readl(ep, UDCCSR); | 1993 | udccsr0 = udc_ep_readl(ep, UDCCSR); |
1827 | ep_dbg(ep, "state=%s, req=%p, udccsr0=0x%03x, udcbcr=%d, irq_msk=%x\n", | 1994 | ep_dbg(ep, "state=%s, req=%p, udccsr0=0x%03x, udcbcr=%d, irq_msk=%x\n", |
1828 | EP0_STNAME(udc), req, udccsr0, udc_ep_readl(ep, UDCBCR), | 1995 | EP0_STNAME(udc), req, udccsr0, udc_ep_readl(ep, UDCBCR), |
1829 | (fifo_irq << 1 | opc_irq)); | 1996 | (fifo_irq << 1 | opc_irq)); |
1830 | 1997 | ||
1831 | if (!list_empty(&ep->queue)) | ||
1832 | req = list_entry(ep->queue.next, struct pxa27x_request, queue); | ||
1833 | |||
1834 | if (udccsr0 & UDCCSR0_SST) { | 1998 | if (udccsr0 & UDCCSR0_SST) { |
1835 | ep_dbg(ep, "clearing stall status\n"); | 1999 | ep_dbg(ep, "clearing stall status\n"); |
1836 | nuke(ep, -EPIPE); | 2000 | nuke(ep, -EPIPE); |
@@ -2212,7 +2376,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev) | |||
2212 | { | 2376 | { |
2213 | struct resource *regs; | 2377 | struct resource *regs; |
2214 | struct pxa_udc *udc = &memory; | 2378 | struct pxa_udc *udc = &memory; |
2215 | int retval; | 2379 | int retval = 0, gpio; |
2216 | 2380 | ||
2217 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 2381 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
2218 | if (!regs) | 2382 | if (!regs) |
@@ -2223,6 +2387,20 @@ static int __init pxa_udc_probe(struct platform_device *pdev) | |||
2223 | 2387 | ||
2224 | udc->dev = &pdev->dev; | 2388 | udc->dev = &pdev->dev; |
2225 | udc->mach = pdev->dev.platform_data; | 2389 | udc->mach = pdev->dev.platform_data; |
2390 | udc->transceiver = otg_get_transceiver(); | ||
2391 | |||
2392 | gpio = udc->mach->gpio_pullup; | ||
2393 | if (gpio_is_valid(gpio)) { | ||
2394 | retval = gpio_request(gpio, "USB D+ pullup"); | ||
2395 | if (retval == 0) | ||
2396 | gpio_direction_output(gpio, | ||
2397 | udc->mach->gpio_pullup_inverted); | ||
2398 | } | ||
2399 | if (retval) { | ||
2400 | dev_err(&pdev->dev, "Couldn't request gpio %d : %d\n", | ||
2401 | gpio, retval); | ||
2402 | return retval; | ||
2403 | } | ||
2226 | 2404 | ||
2227 | udc->clk = clk_get(&pdev->dev, NULL); | 2405 | udc->clk = clk_get(&pdev->dev, NULL); |
2228 | if (IS_ERR(udc->clk)) { | 2406 | if (IS_ERR(udc->clk)) { |
@@ -2240,6 +2418,7 @@ static int __init pxa_udc_probe(struct platform_device *pdev) | |||
2240 | device_initialize(&udc->gadget.dev); | 2418 | device_initialize(&udc->gadget.dev); |
2241 | udc->gadget.dev.parent = &pdev->dev; | 2419 | udc->gadget.dev.parent = &pdev->dev; |
2242 | udc->gadget.dev.dma_mask = NULL; | 2420 | udc->gadget.dev.dma_mask = NULL; |
2421 | udc->vbus_sensed = 0; | ||
2243 | 2422 | ||
2244 | the_controller = udc; | 2423 | the_controller = udc; |
2245 | platform_set_drvdata(pdev, udc); | 2424 | platform_set_drvdata(pdev, udc); |
@@ -2273,14 +2452,21 @@ err_clk: | |||
2273 | static int __exit pxa_udc_remove(struct platform_device *_dev) | 2452 | static int __exit pxa_udc_remove(struct platform_device *_dev) |
2274 | { | 2453 | { |
2275 | struct pxa_udc *udc = platform_get_drvdata(_dev); | 2454 | struct pxa_udc *udc = platform_get_drvdata(_dev); |
2455 | int gpio = udc->mach->gpio_pullup; | ||
2276 | 2456 | ||
2277 | usb_gadget_unregister_driver(udc->driver); | 2457 | usb_gadget_unregister_driver(udc->driver); |
2278 | free_irq(udc->irq, udc); | 2458 | free_irq(udc->irq, udc); |
2279 | pxa_cleanup_debugfs(udc); | 2459 | pxa_cleanup_debugfs(udc); |
2460 | if (gpio_is_valid(gpio)) | ||
2461 | gpio_free(gpio); | ||
2462 | |||
2463 | otg_put_transceiver(udc->transceiver); | ||
2280 | 2464 | ||
2465 | udc->transceiver = NULL; | ||
2281 | platform_set_drvdata(_dev, NULL); | 2466 | platform_set_drvdata(_dev, NULL); |
2282 | the_controller = NULL; | 2467 | the_controller = NULL; |
2283 | clk_put(udc->clk); | 2468 | clk_put(udc->clk); |
2469 | iounmap(udc->regs); | ||
2284 | 2470 | ||
2285 | return 0; | 2471 | return 0; |
2286 | } | 2472 | } |
@@ -2319,6 +2505,8 @@ static int pxa_udc_suspend(struct platform_device *_dev, pm_message_t state) | |||
2319 | } | 2505 | } |
2320 | 2506 | ||
2321 | udc_disable(udc); | 2507 | udc_disable(udc); |
2508 | udc->pullup_resume = udc->pullup_on; | ||
2509 | dplus_pullup(udc, 0); | ||
2322 | 2510 | ||
2323 | return 0; | 2511 | return 0; |
2324 | } | 2512 | } |
@@ -2346,7 +2534,9 @@ static int pxa_udc_resume(struct platform_device *_dev) | |||
2346 | ep->udccsr_value, ep->udccr_value); | 2534 | ep->udccsr_value, ep->udccr_value); |
2347 | } | 2535 | } |
2348 | 2536 | ||
2349 | udc_enable(udc); | 2537 | dplus_pullup(udc, udc->pullup_resume); |
2538 | if (should_enable_udc(udc)) | ||
2539 | udc_enable(udc); | ||
2350 | /* | 2540 | /* |
2351 | * We do not handle OTG yet. | 2541 | * We do not handle OTG yet. |
2352 | * | 2542 | * |
diff --git a/drivers/usb/gadget/pxa27x_udc.h b/drivers/usb/gadget/pxa27x_udc.h index 1d1b7936ee11..db58125331da 100644 --- a/drivers/usb/gadget/pxa27x_udc.h +++ b/drivers/usb/gadget/pxa27x_udc.h | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/types.h> | 26 | #include <linux/types.h> |
27 | #include <linux/spinlock.h> | 27 | #include <linux/spinlock.h> |
28 | #include <linux/io.h> | 28 | #include <linux/io.h> |
29 | #include <linux/usb/otg.h> | ||
29 | 30 | ||
30 | /* | 31 | /* |
31 | * Register definitions | 32 | * Register definitions |
@@ -421,10 +422,14 @@ struct udc_stats { | |||
421 | * @driver: bound gadget (zero, g_ether, g_file_storage, ...) | 422 | * @driver: bound gadget (zero, g_ether, g_file_storage, ...) |
422 | * @dev: device | 423 | * @dev: device |
423 | * @mach: machine info, used to activate specific GPIO | 424 | * @mach: machine info, used to activate specific GPIO |
425 | * @transceiver: external transceiver to handle vbus sense and D+ pullup | ||
424 | * @ep0state: control endpoint state machine state | 426 | * @ep0state: control endpoint state machine state |
425 | * @stats: statistics on udc usage | 427 | * @stats: statistics on udc usage |
426 | * @udc_usb_ep: array of usb endpoints offered by the gadget | 428 | * @udc_usb_ep: array of usb endpoints offered by the gadget |
427 | * @pxa_ep: array of pxa available endpoints | 429 | * @pxa_ep: array of pxa available endpoints |
430 | * @enabled: UDC was enabled by a previous udc_enable() | ||
431 | * @pullup_on: if pullup resistor connected to D+ pin | ||
432 | * @pullup_resume: if pullup resistor should be connected to D+ pin on resume | ||
428 | * @config: UDC active configuration | 433 | * @config: UDC active configuration |
429 | * @last_interface: UDC interface of the last SET_INTERFACE host request | 434 | * @last_interface: UDC interface of the last SET_INTERFACE host request |
430 | * @last_alternate: UDC altsetting of the last SET_INTERFACE host request | 435 | * @last_alternate: UDC altsetting of the last SET_INTERFACE host request |
@@ -443,6 +448,7 @@ struct pxa_udc { | |||
443 | struct usb_gadget_driver *driver; | 448 | struct usb_gadget_driver *driver; |
444 | struct device *dev; | 449 | struct device *dev; |
445 | struct pxa2xx_udc_mach_info *mach; | 450 | struct pxa2xx_udc_mach_info *mach; |
451 | struct otg_transceiver *transceiver; | ||
446 | 452 | ||
447 | enum ep0_state ep0state; | 453 | enum ep0_state ep0state; |
448 | struct udc_stats stats; | 454 | struct udc_stats stats; |
@@ -450,6 +456,10 @@ struct pxa_udc { | |||
450 | struct udc_usb_ep udc_usb_ep[NR_USB_ENDPOINTS]; | 456 | struct udc_usb_ep udc_usb_ep[NR_USB_ENDPOINTS]; |
451 | struct pxa_ep pxa_ep[NR_PXA_ENDPOINTS]; | 457 | struct pxa_ep pxa_ep[NR_PXA_ENDPOINTS]; |
452 | 458 | ||
459 | unsigned enabled:1; | ||
460 | unsigned pullup_on:1; | ||
461 | unsigned pullup_resume:1; | ||
462 | unsigned vbus_sensed:1; | ||
453 | unsigned config:2; | 463 | unsigned config:2; |
454 | unsigned last_interface:3; | 464 | unsigned last_interface:3; |
455 | unsigned last_alternate:3; | 465 | unsigned last_alternate:3; |
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c index 8c26f5ea2b83..2b4660e08c4d 100644 --- a/drivers/usb/gadget/rndis.c +++ b/drivers/usb/gadget/rndis.c | |||
@@ -63,7 +63,7 @@ MODULE_PARM_DESC (rndis_debug, "enable debugging"); | |||
63 | static rndis_params rndis_per_dev_params [RNDIS_MAX_CONFIGS]; | 63 | static rndis_params rndis_per_dev_params [RNDIS_MAX_CONFIGS]; |
64 | 64 | ||
65 | /* Driver Version */ | 65 | /* Driver Version */ |
66 | static const __le32 rndis_driver_version = __constant_cpu_to_le32 (1); | 66 | static const __le32 rndis_driver_version = cpu_to_le32 (1); |
67 | 67 | ||
68 | /* Function Prototypes */ | 68 | /* Function Prototypes */ |
69 | static rndis_resp_t *rndis_add_response (int configNr, u32 length); | 69 | static rndis_resp_t *rndis_add_response (int configNr, u32 length); |
@@ -170,7 +170,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
170 | int i, count; | 170 | int i, count; |
171 | rndis_query_cmplt_type *resp; | 171 | rndis_query_cmplt_type *resp; |
172 | struct net_device *net; | 172 | struct net_device *net; |
173 | struct net_device_stats *stats; | 173 | const struct net_device_stats *stats; |
174 | 174 | ||
175 | if (!r) return -ENOMEM; | 175 | if (!r) return -ENOMEM; |
176 | resp = (rndis_query_cmplt_type *) r->buf; | 176 | resp = (rndis_query_cmplt_type *) r->buf; |
@@ -190,13 +190,10 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
190 | 190 | ||
191 | /* response goes here, right after the header */ | 191 | /* response goes here, right after the header */ |
192 | outbuf = (__le32 *) &resp[1]; | 192 | outbuf = (__le32 *) &resp[1]; |
193 | resp->InformationBufferOffset = __constant_cpu_to_le32 (16); | 193 | resp->InformationBufferOffset = cpu_to_le32 (16); |
194 | 194 | ||
195 | net = rndis_per_dev_params[configNr].dev; | 195 | net = rndis_per_dev_params[configNr].dev; |
196 | if (net->get_stats) | 196 | stats = dev_get_stats(net); |
197 | stats = net->get_stats(net); | ||
198 | else | ||
199 | stats = NULL; | ||
200 | 197 | ||
201 | switch (OID) { | 198 | switch (OID) { |
202 | 199 | ||
@@ -221,7 +218,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
221 | * reddite ergo quae sunt Caesaris Caesari | 218 | * reddite ergo quae sunt Caesaris Caesari |
222 | * et quae sunt Dei Deo! | 219 | * et quae sunt Dei Deo! |
223 | */ | 220 | */ |
224 | *outbuf = __constant_cpu_to_le32 (0); | 221 | *outbuf = cpu_to_le32 (0); |
225 | retval = 0; | 222 | retval = 0; |
226 | break; | 223 | break; |
227 | 224 | ||
@@ -256,7 +253,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
256 | pr_debug("%s: OID_GEN_LINK_SPEED\n", __func__); | 253 | pr_debug("%s: OID_GEN_LINK_SPEED\n", __func__); |
257 | if (rndis_per_dev_params [configNr].media_state | 254 | if (rndis_per_dev_params [configNr].media_state |
258 | == NDIS_MEDIA_STATE_DISCONNECTED) | 255 | == NDIS_MEDIA_STATE_DISCONNECTED) |
259 | *outbuf = __constant_cpu_to_le32 (0); | 256 | *outbuf = cpu_to_le32 (0); |
260 | else | 257 | else |
261 | *outbuf = cpu_to_le32 ( | 258 | *outbuf = cpu_to_le32 ( |
262 | rndis_per_dev_params [configNr].speed); | 259 | rndis_per_dev_params [configNr].speed); |
@@ -317,7 +314,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
317 | /* mandatory */ | 314 | /* mandatory */ |
318 | case OID_GEN_MAXIMUM_TOTAL_SIZE: | 315 | case OID_GEN_MAXIMUM_TOTAL_SIZE: |
319 | pr_debug("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__); | 316 | pr_debug("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__); |
320 | *outbuf = __constant_cpu_to_le32(RNDIS_MAX_TOTAL_SIZE); | 317 | *outbuf = cpu_to_le32(RNDIS_MAX_TOTAL_SIZE); |
321 | retval = 0; | 318 | retval = 0; |
322 | break; | 319 | break; |
323 | 320 | ||
@@ -332,7 +329,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
332 | 329 | ||
333 | case OID_GEN_PHYSICAL_MEDIUM: | 330 | case OID_GEN_PHYSICAL_MEDIUM: |
334 | pr_debug("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__); | 331 | pr_debug("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__); |
335 | *outbuf = __constant_cpu_to_le32 (0); | 332 | *outbuf = cpu_to_le32 (0); |
336 | retval = 0; | 333 | retval = 0; |
337 | break; | 334 | break; |
338 | 335 | ||
@@ -342,7 +339,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
342 | */ | 339 | */ |
343 | case OID_GEN_MAC_OPTIONS: /* from WinME */ | 340 | case OID_GEN_MAC_OPTIONS: /* from WinME */ |
344 | pr_debug("%s: OID_GEN_MAC_OPTIONS\n", __func__); | 341 | pr_debug("%s: OID_GEN_MAC_OPTIONS\n", __func__); |
345 | *outbuf = __constant_cpu_to_le32( | 342 | *outbuf = cpu_to_le32( |
346 | NDIS_MAC_OPTION_RECEIVE_SERIALIZED | 343 | NDIS_MAC_OPTION_RECEIVE_SERIALIZED |
347 | | NDIS_MAC_OPTION_FULL_DUPLEX); | 344 | | NDIS_MAC_OPTION_FULL_DUPLEX); |
348 | retval = 0; | 345 | retval = 0; |
@@ -431,7 +428,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
431 | case OID_802_3_MULTICAST_LIST: | 428 | case OID_802_3_MULTICAST_LIST: |
432 | pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__); | 429 | pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__); |
433 | /* Multicast base address only */ | 430 | /* Multicast base address only */ |
434 | *outbuf = __constant_cpu_to_le32 (0xE0000000); | 431 | *outbuf = cpu_to_le32 (0xE0000000); |
435 | retval = 0; | 432 | retval = 0; |
436 | break; | 433 | break; |
437 | 434 | ||
@@ -439,7 +436,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
439 | case OID_802_3_MAXIMUM_LIST_SIZE: | 436 | case OID_802_3_MAXIMUM_LIST_SIZE: |
440 | pr_debug("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__); | 437 | pr_debug("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__); |
441 | /* Multicast base address only */ | 438 | /* Multicast base address only */ |
442 | *outbuf = __constant_cpu_to_le32 (1); | 439 | *outbuf = cpu_to_le32 (1); |
443 | retval = 0; | 440 | retval = 0; |
444 | break; | 441 | break; |
445 | 442 | ||
@@ -461,14 +458,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len, | |||
461 | /* mandatory */ | 458 | /* mandatory */ |
462 | case OID_802_3_XMIT_ONE_COLLISION: | 459 | case OID_802_3_XMIT_ONE_COLLISION: |
463 | pr_debug("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__); | 460 | pr_debug("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__); |
464 | *outbuf = __constant_cpu_to_le32 (0); | 461 | *outbuf = cpu_to_le32 (0); |
465 | retval = 0; | 462 | retval = 0; |
466 | break; | 463 | break; |
467 | 464 | ||
468 | /* mandatory */ | 465 | /* mandatory */ |
469 | case OID_802_3_XMIT_MORE_COLLISIONS: | 466 | case OID_802_3_XMIT_MORE_COLLISIONS: |
470 | pr_debug("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__); | 467 | pr_debug("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__); |
471 | *outbuf = __constant_cpu_to_le32 (0); | 468 | *outbuf = cpu_to_le32 (0); |
472 | retval = 0; | 469 | retval = 0; |
473 | break; | 470 | break; |
474 | 471 | ||
@@ -572,24 +569,24 @@ static int rndis_init_response (int configNr, rndis_init_msg_type *buf) | |||
572 | return -ENOMEM; | 569 | return -ENOMEM; |
573 | resp = (rndis_init_cmplt_type *) r->buf; | 570 | resp = (rndis_init_cmplt_type *) r->buf; |
574 | 571 | ||
575 | resp->MessageType = __constant_cpu_to_le32 ( | 572 | resp->MessageType = cpu_to_le32 ( |
576 | REMOTE_NDIS_INITIALIZE_CMPLT); | 573 | REMOTE_NDIS_INITIALIZE_CMPLT); |
577 | resp->MessageLength = __constant_cpu_to_le32 (52); | 574 | resp->MessageLength = cpu_to_le32 (52); |
578 | resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ | 575 | resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ |
579 | resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); | 576 | resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS); |
580 | resp->MajorVersion = __constant_cpu_to_le32 (RNDIS_MAJOR_VERSION); | 577 | resp->MajorVersion = cpu_to_le32 (RNDIS_MAJOR_VERSION); |
581 | resp->MinorVersion = __constant_cpu_to_le32 (RNDIS_MINOR_VERSION); | 578 | resp->MinorVersion = cpu_to_le32 (RNDIS_MINOR_VERSION); |
582 | resp->DeviceFlags = __constant_cpu_to_le32 (RNDIS_DF_CONNECTIONLESS); | 579 | resp->DeviceFlags = cpu_to_le32 (RNDIS_DF_CONNECTIONLESS); |
583 | resp->Medium = __constant_cpu_to_le32 (RNDIS_MEDIUM_802_3); | 580 | resp->Medium = cpu_to_le32 (RNDIS_MEDIUM_802_3); |
584 | resp->MaxPacketsPerTransfer = __constant_cpu_to_le32 (1); | 581 | resp->MaxPacketsPerTransfer = cpu_to_le32 (1); |
585 | resp->MaxTransferSize = cpu_to_le32 ( | 582 | resp->MaxTransferSize = cpu_to_le32 ( |
586 | params->dev->mtu | 583 | params->dev->mtu |
587 | + sizeof (struct ethhdr) | 584 | + sizeof (struct ethhdr) |
588 | + sizeof (struct rndis_packet_msg_type) | 585 | + sizeof (struct rndis_packet_msg_type) |
589 | + 22); | 586 | + 22); |
590 | resp->PacketAlignmentFactor = __constant_cpu_to_le32 (0); | 587 | resp->PacketAlignmentFactor = cpu_to_le32 (0); |
591 | resp->AFListOffset = __constant_cpu_to_le32 (0); | 588 | resp->AFListOffset = cpu_to_le32 (0); |
592 | resp->AFListSize = __constant_cpu_to_le32 (0); | 589 | resp->AFListSize = cpu_to_le32 (0); |
593 | 590 | ||
594 | params->resp_avail(params->v); | 591 | params->resp_avail(params->v); |
595 | return 0; | 592 | return 0; |
@@ -617,7 +614,7 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf) | |||
617 | return -ENOMEM; | 614 | return -ENOMEM; |
618 | resp = (rndis_query_cmplt_type *) r->buf; | 615 | resp = (rndis_query_cmplt_type *) r->buf; |
619 | 616 | ||
620 | resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT); | 617 | resp->MessageType = cpu_to_le32 (REMOTE_NDIS_QUERY_CMPLT); |
621 | resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ | 618 | resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ |
622 | 619 | ||
623 | if (gen_ndis_query_resp (configNr, le32_to_cpu (buf->OID), | 620 | if (gen_ndis_query_resp (configNr, le32_to_cpu (buf->OID), |
@@ -626,13 +623,13 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf) | |||
626 | le32_to_cpu(buf->InformationBufferLength), | 623 | le32_to_cpu(buf->InformationBufferLength), |
627 | r)) { | 624 | r)) { |
628 | /* OID not supported */ | 625 | /* OID not supported */ |
629 | resp->Status = __constant_cpu_to_le32 ( | 626 | resp->Status = cpu_to_le32 ( |
630 | RNDIS_STATUS_NOT_SUPPORTED); | 627 | RNDIS_STATUS_NOT_SUPPORTED); |
631 | resp->MessageLength = __constant_cpu_to_le32 (sizeof *resp); | 628 | resp->MessageLength = cpu_to_le32 (sizeof *resp); |
632 | resp->InformationBufferLength = __constant_cpu_to_le32 (0); | 629 | resp->InformationBufferLength = cpu_to_le32 (0); |
633 | resp->InformationBufferOffset = __constant_cpu_to_le32 (0); | 630 | resp->InformationBufferOffset = cpu_to_le32 (0); |
634 | } else | 631 | } else |
635 | resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); | 632 | resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS); |
636 | 633 | ||
637 | params->resp_avail(params->v); | 634 | params->resp_avail(params->v); |
638 | return 0; | 635 | return 0; |
@@ -665,14 +662,14 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf) | |||
665 | pr_debug("\n"); | 662 | pr_debug("\n"); |
666 | #endif | 663 | #endif |
667 | 664 | ||
668 | resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT); | 665 | resp->MessageType = cpu_to_le32 (REMOTE_NDIS_SET_CMPLT); |
669 | resp->MessageLength = __constant_cpu_to_le32 (16); | 666 | resp->MessageLength = cpu_to_le32 (16); |
670 | resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ | 667 | resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ |
671 | if (gen_ndis_set_resp (configNr, le32_to_cpu (buf->OID), | 668 | if (gen_ndis_set_resp (configNr, le32_to_cpu (buf->OID), |
672 | ((u8 *) buf) + 8 + BufOffset, BufLength, r)) | 669 | ((u8 *) buf) + 8 + BufOffset, BufLength, r)) |
673 | resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED); | 670 | resp->Status = cpu_to_le32 (RNDIS_STATUS_NOT_SUPPORTED); |
674 | else | 671 | else |
675 | resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); | 672 | resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS); |
676 | 673 | ||
677 | params->resp_avail(params->v); | 674 | params->resp_avail(params->v); |
678 | return 0; | 675 | return 0; |
@@ -689,11 +686,11 @@ static int rndis_reset_response (int configNr, rndis_reset_msg_type *buf) | |||
689 | return -ENOMEM; | 686 | return -ENOMEM; |
690 | resp = (rndis_reset_cmplt_type *) r->buf; | 687 | resp = (rndis_reset_cmplt_type *) r->buf; |
691 | 688 | ||
692 | resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT); | 689 | resp->MessageType = cpu_to_le32 (REMOTE_NDIS_RESET_CMPLT); |
693 | resp->MessageLength = __constant_cpu_to_le32 (16); | 690 | resp->MessageLength = cpu_to_le32 (16); |
694 | resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); | 691 | resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS); |
695 | /* resent information */ | 692 | /* resent information */ |
696 | resp->AddressingReset = __constant_cpu_to_le32 (1); | 693 | resp->AddressingReset = cpu_to_le32 (1); |
697 | 694 | ||
698 | params->resp_avail(params->v); | 695 | params->resp_avail(params->v); |
699 | return 0; | 696 | return 0; |
@@ -713,11 +710,11 @@ static int rndis_keepalive_response (int configNr, | |||
713 | return -ENOMEM; | 710 | return -ENOMEM; |
714 | resp = (rndis_keepalive_cmplt_type *) r->buf; | 711 | resp = (rndis_keepalive_cmplt_type *) r->buf; |
715 | 712 | ||
716 | resp->MessageType = __constant_cpu_to_le32 ( | 713 | resp->MessageType = cpu_to_le32 ( |
717 | REMOTE_NDIS_KEEPALIVE_CMPLT); | 714 | REMOTE_NDIS_KEEPALIVE_CMPLT); |
718 | resp->MessageLength = __constant_cpu_to_le32 (16); | 715 | resp->MessageLength = cpu_to_le32 (16); |
719 | resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ | 716 | resp->RequestID = buf->RequestID; /* Still LE in msg buffer */ |
720 | resp->Status = __constant_cpu_to_le32 (RNDIS_STATUS_SUCCESS); | 717 | resp->Status = cpu_to_le32 (RNDIS_STATUS_SUCCESS); |
721 | 718 | ||
722 | params->resp_avail(params->v); | 719 | params->resp_avail(params->v); |
723 | return 0; | 720 | return 0; |
@@ -742,12 +739,12 @@ static int rndis_indicate_status_msg (int configNr, u32 status) | |||
742 | return -ENOMEM; | 739 | return -ENOMEM; |
743 | resp = (rndis_indicate_status_msg_type *) r->buf; | 740 | resp = (rndis_indicate_status_msg_type *) r->buf; |
744 | 741 | ||
745 | resp->MessageType = __constant_cpu_to_le32 ( | 742 | resp->MessageType = cpu_to_le32 ( |
746 | REMOTE_NDIS_INDICATE_STATUS_MSG); | 743 | REMOTE_NDIS_INDICATE_STATUS_MSG); |
747 | resp->MessageLength = __constant_cpu_to_le32 (20); | 744 | resp->MessageLength = cpu_to_le32 (20); |
748 | resp->Status = cpu_to_le32 (status); | 745 | resp->Status = cpu_to_le32 (status); |
749 | resp->StatusBufferLength = __constant_cpu_to_le32 (0); | 746 | resp->StatusBufferLength = cpu_to_le32 (0); |
750 | resp->StatusBufferOffset = __constant_cpu_to_le32 (0); | 747 | resp->StatusBufferOffset = cpu_to_le32 (0); |
751 | 748 | ||
752 | params->resp_avail(params->v); | 749 | params->resp_avail(params->v); |
753 | return 0; | 750 | return 0; |
@@ -963,9 +960,9 @@ void rndis_add_hdr (struct sk_buff *skb) | |||
963 | return; | 960 | return; |
964 | header = (void *) skb_push (skb, sizeof *header); | 961 | header = (void *) skb_push (skb, sizeof *header); |
965 | memset (header, 0, sizeof *header); | 962 | memset (header, 0, sizeof *header); |
966 | header->MessageType = __constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG); | 963 | header->MessageType = cpu_to_le32(REMOTE_NDIS_PACKET_MSG); |
967 | header->MessageLength = cpu_to_le32(skb->len); | 964 | header->MessageLength = cpu_to_le32(skb->len); |
968 | header->DataOffset = __constant_cpu_to_le32 (36); | 965 | header->DataOffset = cpu_to_le32 (36); |
969 | header->DataLength = cpu_to_le32(skb->len - sizeof *header); | 966 | header->DataLength = cpu_to_le32(skb->len - sizeof *header); |
970 | } | 967 | } |
971 | 968 | ||
@@ -1029,7 +1026,7 @@ int rndis_rm_hdr(struct sk_buff *skb) | |||
1029 | __le32 *tmp = (void *) skb->data; | 1026 | __le32 *tmp = (void *) skb->data; |
1030 | 1027 | ||
1031 | /* MessageType, MessageLength */ | 1028 | /* MessageType, MessageLength */ |
1032 | if (__constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG) | 1029 | if (cpu_to_le32(REMOTE_NDIS_PACKET_MSG) |
1033 | != get_unaligned(tmp++)) | 1030 | != get_unaligned(tmp++)) |
1034 | return -EINVAL; | 1031 | return -EINVAL; |
1035 | tmp++; | 1032 | tmp++; |
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 37879af1c433..f46a60962dab 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -87,12 +87,12 @@ static struct usb_gadget_strings *dev_strings[] = { | |||
87 | static struct usb_device_descriptor device_desc = { | 87 | static struct usb_device_descriptor device_desc = { |
88 | .bLength = USB_DT_DEVICE_SIZE, | 88 | .bLength = USB_DT_DEVICE_SIZE, |
89 | .bDescriptorType = USB_DT_DEVICE, | 89 | .bDescriptorType = USB_DT_DEVICE, |
90 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 90 | .bcdUSB = cpu_to_le16(0x0200), |
91 | /* .bDeviceClass = f(use_acm) */ | 91 | /* .bDeviceClass = f(use_acm) */ |
92 | .bDeviceSubClass = 0, | 92 | .bDeviceSubClass = 0, |
93 | .bDeviceProtocol = 0, | 93 | .bDeviceProtocol = 0, |
94 | /* .bMaxPacketSize0 = f(hardware) */ | 94 | /* .bMaxPacketSize0 = f(hardware) */ |
95 | .idVendor = __constant_cpu_to_le16(GS_VENDOR_ID), | 95 | .idVendor = cpu_to_le16(GS_VENDOR_ID), |
96 | /* .idProduct = f(use_acm) */ | 96 | /* .idProduct = f(use_acm) */ |
97 | /* .bcdDevice = f(hardware) */ | 97 | /* .bcdDevice = f(hardware) */ |
98 | /* .iManufacturer = DYNAMIC */ | 98 | /* .iManufacturer = DYNAMIC */ |
@@ -216,7 +216,7 @@ static int __init gs_bind(struct usb_composite_dev *cdev) | |||
216 | pr_warning("gs_bind: controller '%s' not recognized\n", | 216 | pr_warning("gs_bind: controller '%s' not recognized\n", |
217 | gadget->name); | 217 | gadget->name); |
218 | device_desc.bcdDevice = | 218 | device_desc.bcdDevice = |
219 | __constant_cpu_to_le16(GS_VERSION_NUM | 0x0099); | 219 | cpu_to_le16(GS_VERSION_NUM | 0x0099); |
220 | } | 220 | } |
221 | 221 | ||
222 | if (gadget_is_otg(cdev->gadget)) { | 222 | if (gadget_is_otg(cdev->gadget)) { |
@@ -255,19 +255,19 @@ static int __init init(void) | |||
255 | serial_config_driver.bConfigurationValue = 2; | 255 | serial_config_driver.bConfigurationValue = 2; |
256 | device_desc.bDeviceClass = USB_CLASS_COMM; | 256 | device_desc.bDeviceClass = USB_CLASS_COMM; |
257 | device_desc.idProduct = | 257 | device_desc.idProduct = |
258 | __constant_cpu_to_le16(GS_CDC_PRODUCT_ID); | 258 | cpu_to_le16(GS_CDC_PRODUCT_ID); |
259 | } else if (use_obex) { | 259 | } else if (use_obex) { |
260 | serial_config_driver.label = "CDC OBEX config"; | 260 | serial_config_driver.label = "CDC OBEX config"; |
261 | serial_config_driver.bConfigurationValue = 3; | 261 | serial_config_driver.bConfigurationValue = 3; |
262 | device_desc.bDeviceClass = USB_CLASS_COMM; | 262 | device_desc.bDeviceClass = USB_CLASS_COMM; |
263 | device_desc.idProduct = | 263 | device_desc.idProduct = |
264 | __constant_cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID); | 264 | cpu_to_le16(GS_CDC_OBEX_PRODUCT_ID); |
265 | } else { | 265 | } else { |
266 | serial_config_driver.label = "Generic Serial config"; | 266 | serial_config_driver.label = "Generic Serial config"; |
267 | serial_config_driver.bConfigurationValue = 1; | 267 | serial_config_driver.bConfigurationValue = 1; |
268 | device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; | 268 | device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; |
269 | device_desc.idProduct = | 269 | device_desc.idProduct = |
270 | __constant_cpu_to_le16(GS_PRODUCT_ID); | 270 | cpu_to_le16(GS_PRODUCT_ID); |
271 | } | 271 | } |
272 | strings_dev[STRING_DESCRIPTION_IDX].s = serial_config_driver.label; | 272 | strings_dev[STRING_DESCRIPTION_IDX].s = serial_config_driver.label; |
273 | 273 | ||
diff --git a/drivers/usb/gadget/u_serial.c b/drivers/usb/gadget/u_serial.c index 53d59287f2bc..0a4d99ab40d8 100644 --- a/drivers/usb/gadget/u_serial.c +++ b/drivers/usb/gadget/u_serial.c | |||
@@ -1092,7 +1092,7 @@ int __init gserial_setup(struct usb_gadget *g, unsigned count) | |||
1092 | gs_tty_driver->init_termios.c_ispeed = 9600; | 1092 | gs_tty_driver->init_termios.c_ispeed = 9600; |
1093 | gs_tty_driver->init_termios.c_ospeed = 9600; | 1093 | gs_tty_driver->init_termios.c_ospeed = 9600; |
1094 | 1094 | ||
1095 | coding.dwDTERate = __constant_cpu_to_le32(9600); | 1095 | coding.dwDTERate = cpu_to_le32(9600); |
1096 | coding.bCharFormat = 8; | 1096 | coding.bCharFormat = 8; |
1097 | coding.bParityType = USB_CDC_NO_PARITY; | 1097 | coding.bParityType = USB_CDC_NO_PARITY; |
1098 | coding.bDataBits = USB_CDC_1_STOP_BITS; | 1098 | coding.bDataBits = USB_CDC_1_STOP_BITS; |
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 361d9659ac48..2d772401b7ad 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c | |||
@@ -102,22 +102,32 @@ module_param(loopdefault, bool, S_IRUGO|S_IWUSR); | |||
102 | #ifndef CONFIG_USB_ZERO_HNPTEST | 102 | #ifndef CONFIG_USB_ZERO_HNPTEST |
103 | #define DRIVER_VENDOR_NUM 0x0525 /* NetChip */ | 103 | #define DRIVER_VENDOR_NUM 0x0525 /* NetChip */ |
104 | #define DRIVER_PRODUCT_NUM 0xa4a0 /* Linux-USB "Gadget Zero" */ | 104 | #define DRIVER_PRODUCT_NUM 0xa4a0 /* Linux-USB "Gadget Zero" */ |
105 | #define DEFAULT_AUTORESUME 0 | ||
105 | #else | 106 | #else |
106 | #define DRIVER_VENDOR_NUM 0x1a0a /* OTG test device IDs */ | 107 | #define DRIVER_VENDOR_NUM 0x1a0a /* OTG test device IDs */ |
107 | #define DRIVER_PRODUCT_NUM 0xbadd | 108 | #define DRIVER_PRODUCT_NUM 0xbadd |
109 | #define DEFAULT_AUTORESUME 5 | ||
108 | #endif | 110 | #endif |
109 | 111 | ||
112 | /* If the optional "autoresume" mode is enabled, it provides good | ||
113 | * functional coverage for the "USBCV" test harness from USB-IF. | ||
114 | * It's always set if OTG mode is enabled. | ||
115 | */ | ||
116 | unsigned autoresume = DEFAULT_AUTORESUME; | ||
117 | module_param(autoresume, uint, S_IRUGO); | ||
118 | MODULE_PARM_DESC(autoresume, "zero, or seconds before remote wakeup"); | ||
119 | |||
110 | /*-------------------------------------------------------------------------*/ | 120 | /*-------------------------------------------------------------------------*/ |
111 | 121 | ||
112 | static struct usb_device_descriptor device_desc = { | 122 | static struct usb_device_descriptor device_desc = { |
113 | .bLength = sizeof device_desc, | 123 | .bLength = sizeof device_desc, |
114 | .bDescriptorType = USB_DT_DEVICE, | 124 | .bDescriptorType = USB_DT_DEVICE, |
115 | 125 | ||
116 | .bcdUSB = __constant_cpu_to_le16(0x0200), | 126 | .bcdUSB = cpu_to_le16(0x0200), |
117 | .bDeviceClass = USB_CLASS_VENDOR_SPEC, | 127 | .bDeviceClass = USB_CLASS_VENDOR_SPEC, |
118 | 128 | ||
119 | .idVendor = __constant_cpu_to_le16(DRIVER_VENDOR_NUM), | 129 | .idVendor = cpu_to_le16(DRIVER_VENDOR_NUM), |
120 | .idProduct = __constant_cpu_to_le16(DRIVER_PRODUCT_NUM), | 130 | .idProduct = cpu_to_le16(DRIVER_PRODUCT_NUM), |
121 | .bNumConfigurations = 2, | 131 | .bNumConfigurations = 2, |
122 | }; | 132 | }; |
123 | 133 | ||
@@ -212,6 +222,47 @@ void disable_endpoints(struct usb_composite_dev *cdev, | |||
212 | 222 | ||
213 | /*-------------------------------------------------------------------------*/ | 223 | /*-------------------------------------------------------------------------*/ |
214 | 224 | ||
225 | static struct timer_list autoresume_timer; | ||
226 | |||
227 | static void zero_autoresume(unsigned long _c) | ||
228 | { | ||
229 | struct usb_composite_dev *cdev = (void *)_c; | ||
230 | struct usb_gadget *g = cdev->gadget; | ||
231 | |||
232 | /* unconfigured devices can't issue wakeups */ | ||
233 | if (!cdev->config) | ||
234 | return; | ||
235 | |||
236 | /* Normally the host would be woken up for something | ||
237 | * more significant than just a timer firing; likely | ||
238 | * because of some direct user request. | ||
239 | */ | ||
240 | if (g->speed != USB_SPEED_UNKNOWN) { | ||
241 | int status = usb_gadget_wakeup(g); | ||
242 | INFO(cdev, "%s --> %d\n", __func__, status); | ||
243 | } | ||
244 | } | ||
245 | |||
246 | static void zero_suspend(struct usb_composite_dev *cdev) | ||
247 | { | ||
248 | if (cdev->gadget->speed == USB_SPEED_UNKNOWN) | ||
249 | return; | ||
250 | |||
251 | if (autoresume) { | ||
252 | mod_timer(&autoresume_timer, jiffies + (HZ * autoresume)); | ||
253 | DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume); | ||
254 | } else | ||
255 | DBG(cdev, "%s\n", __func__); | ||
256 | } | ||
257 | |||
258 | static void zero_resume(struct usb_composite_dev *cdev) | ||
259 | { | ||
260 | DBG(cdev, "%s\n", __func__); | ||
261 | del_timer(&autoresume_timer); | ||
262 | } | ||
263 | |||
264 | /*-------------------------------------------------------------------------*/ | ||
265 | |||
215 | static int __init zero_bind(struct usb_composite_dev *cdev) | 266 | static int __init zero_bind(struct usb_composite_dev *cdev) |
216 | { | 267 | { |
217 | int gcnum; | 268 | int gcnum; |
@@ -239,17 +290,19 @@ static int __init zero_bind(struct usb_composite_dev *cdev) | |||
239 | strings_dev[STRING_SERIAL_IDX].id = id; | 290 | strings_dev[STRING_SERIAL_IDX].id = id; |
240 | device_desc.iSerialNumber = id; | 291 | device_desc.iSerialNumber = id; |
241 | 292 | ||
293 | setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev); | ||
294 | |||
242 | /* Register primary, then secondary configuration. Note that | 295 | /* Register primary, then secondary configuration. Note that |
243 | * SH3 only allows one config... | 296 | * SH3 only allows one config... |
244 | */ | 297 | */ |
245 | if (loopdefault) { | 298 | if (loopdefault) { |
246 | loopback_add(cdev); | 299 | loopback_add(cdev, autoresume != 0); |
247 | if (!gadget_is_sh(gadget)) | 300 | if (!gadget_is_sh(gadget)) |
248 | sourcesink_add(cdev); | 301 | sourcesink_add(cdev, autoresume != 0); |
249 | } else { | 302 | } else { |
250 | sourcesink_add(cdev); | 303 | sourcesink_add(cdev, autoresume != 0); |
251 | if (!gadget_is_sh(gadget)) | 304 | if (!gadget_is_sh(gadget)) |
252 | loopback_add(cdev); | 305 | loopback_add(cdev, autoresume != 0); |
253 | } | 306 | } |
254 | 307 | ||
255 | gcnum = usb_gadget_controller_number(gadget); | 308 | gcnum = usb_gadget_controller_number(gadget); |
@@ -265,7 +318,7 @@ static int __init zero_bind(struct usb_composite_dev *cdev) | |||
265 | */ | 318 | */ |
266 | pr_warning("%s: controller '%s' not recognized\n", | 319 | pr_warning("%s: controller '%s' not recognized\n", |
267 | longname, gadget->name); | 320 | longname, gadget->name); |
268 | device_desc.bcdDevice = __constant_cpu_to_le16(0x9999); | 321 | device_desc.bcdDevice = cpu_to_le16(0x9999); |
269 | } | 322 | } |
270 | 323 | ||
271 | 324 | ||
@@ -278,11 +331,20 @@ static int __init zero_bind(struct usb_composite_dev *cdev) | |||
278 | return 0; | 331 | return 0; |
279 | } | 332 | } |
280 | 333 | ||
334 | static int zero_unbind(struct usb_composite_dev *cdev) | ||
335 | { | ||
336 | del_timer_sync(&autoresume_timer); | ||
337 | return 0; | ||
338 | } | ||
339 | |||
281 | static struct usb_composite_driver zero_driver = { | 340 | static struct usb_composite_driver zero_driver = { |
282 | .name = "zero", | 341 | .name = "zero", |
283 | .dev = &device_desc, | 342 | .dev = &device_desc, |
284 | .strings = dev_strings, | 343 | .strings = dev_strings, |
285 | .bind = zero_bind, | 344 | .bind = zero_bind, |
345 | .unbind = zero_unbind, | ||
346 | .suspend = zero_suspend, | ||
347 | .resume = zero_resume, | ||
286 | }; | 348 | }; |
287 | 349 | ||
288 | MODULE_AUTHOR("David Brownell"); | 350 | MODULE_AUTHOR("David Brownell"); |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 2b476b6b3d4d..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 | ||
@@ -140,6 +137,7 @@ config USB_OHCI_HCD | |||
140 | tristate "OHCI HCD support" | 137 | tristate "OHCI HCD support" |
141 | depends on USB && USB_ARCH_HAS_OHCI | 138 | depends on USB && USB_ARCH_HAS_OHCI |
142 | select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 | 139 | select ISP1301_OMAP if MACH_OMAP_H2 || MACH_OMAP_H3 |
140 | select USB_OTG_UTILS if ARCH_OMAP | ||
143 | ---help--- | 141 | ---help--- |
144 | The Open Host Controller Interface (OHCI) is a standard for accessing | 142 | The Open Host Controller Interface (OHCI) is a standard for accessing |
145 | USB 1.1 host controller hardware. It does more in hardware than Intel's | 143 | USB 1.1 host controller hardware. It does more in hardware than Intel's |
@@ -238,6 +236,23 @@ config USB_UHCI_HCD | |||
238 | To compile this driver as a module, choose M here: the | 236 | To compile this driver as a module, choose M here: the |
239 | module will be called uhci-hcd. | 237 | module will be called uhci-hcd. |
240 | 238 | ||
239 | config USB_FHCI_HCD | ||
240 | tristate "Freescale QE USB Host Controller support" | ||
241 | depends on USB && OF_GPIO && QE_GPIO && QUICC_ENGINE | ||
242 | select FSL_GTM | ||
243 | select QE_USB | ||
244 | help | ||
245 | This driver enables support for Freescale QE USB Host Controller | ||
246 | (as found on MPC8360 and MPC8323 processors), the driver supports | ||
247 | Full and Low Speed USB. | ||
248 | |||
249 | config FHCI_DEBUG | ||
250 | bool "Freescale QE USB Host Controller debug support" | ||
251 | depends on USB_FHCI_HCD && DEBUG_FS | ||
252 | help | ||
253 | Say "y" to see some FHCI debug information and statistics | ||
254 | throught debugfs. | ||
255 | |||
241 | config USB_U132_HCD | 256 | config USB_U132_HCD |
242 | tristate "Elan U132 Adapter Host Controller" | 257 | tristate "Elan U132 Adapter Host Controller" |
243 | depends on USB && USB_FTDI_ELAN | 258 | depends on USB && USB_FTDI_ELAN |
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index e5f3f20787e4..f163571e33d8 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile | |||
@@ -7,6 +7,11 @@ ifeq ($(CONFIG_USB_DEBUG),y) | |||
7 | endif | 7 | endif |
8 | 8 | ||
9 | isp1760-objs := isp1760-hcd.o isp1760-if.o | 9 | isp1760-objs := isp1760-hcd.o isp1760-if.o |
10 | fhci-objs := fhci-hcd.o fhci-hub.o fhci-q.o fhci-mem.o \ | ||
11 | fhci-tds.o fhci-sched.o | ||
12 | ifeq ($(CONFIG_FHCI_DEBUG),y) | ||
13 | fhci-objs += fhci-dbg.o | ||
14 | endif | ||
10 | 15 | ||
11 | obj-$(CONFIG_USB_WHCI_HCD) += whci/ | 16 | obj-$(CONFIG_USB_WHCI_HCD) += whci/ |
12 | 17 | ||
@@ -17,6 +22,7 @@ obj-$(CONFIG_USB_OXU210HP_HCD) += oxu210hp-hcd.o | |||
17 | obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o | 22 | obj-$(CONFIG_USB_ISP116X_HCD) += isp116x-hcd.o |
18 | obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o | 23 | obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o |
19 | obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o | 24 | obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o |
25 | obj-$(CONFIG_USB_FHCI_HCD) += fhci.o | ||
20 | obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o | 26 | obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o |
21 | obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o | 27 | obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o |
22 | obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o | 28 | obj-$(CONFIG_USB_U132_HCD) += u132-hcd.o |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 4725d15d096f..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 |
@@ -485,6 +521,7 @@ static int ehci_init(struct usb_hcd *hcd) | |||
485 | * periodic_size can shrink by USBCMD update if hcc_params allows. | 521 | * periodic_size can shrink by USBCMD update if hcc_params allows. |
486 | */ | 522 | */ |
487 | ehci->periodic_size = DEFAULT_I_TDPS; | 523 | ehci->periodic_size = DEFAULT_I_TDPS; |
524 | INIT_LIST_HEAD(&ehci->cached_itd_list); | ||
488 | if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0) | 525 | if ((retval = ehci_mem_init(ehci, GFP_KERNEL)) < 0) |
489 | return retval; | 526 | return retval; |
490 | 527 | ||
@@ -497,6 +534,7 @@ static int ehci_init(struct usb_hcd *hcd) | |||
497 | 534 | ||
498 | ehci->reclaim = NULL; | 535 | ehci->reclaim = NULL; |
499 | ehci->next_uframe = -1; | 536 | ehci->next_uframe = -1; |
537 | ehci->clock_frame = -1; | ||
500 | 538 | ||
501 | /* | 539 | /* |
502 | * dedicate a qh for the async ring head, since we couldn't unlink | 540 | * dedicate a qh for the async ring head, since we couldn't unlink |
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c index 0431397836f6..10d52919abbb 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c | |||
@@ -128,6 +128,7 @@ static inline void qh_put (struct ehci_qh *qh) | |||
128 | 128 | ||
129 | static void ehci_mem_cleanup (struct ehci_hcd *ehci) | 129 | static void ehci_mem_cleanup (struct ehci_hcd *ehci) |
130 | { | 130 | { |
131 | free_cached_itd_list(ehci); | ||
131 | if (ehci->async) | 132 | if (ehci->async) |
132 | qh_put (ehci->async); | 133 | qh_put (ehci->async); |
133 | ehci->async = NULL; | 134 | ehci->async = NULL; |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index bdc6e86e1f8b..abb9a7706ec7 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -230,7 +230,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd) | |||
230 | pci_read_config_word(pdev, 0x62, &port_wake); | 230 | pci_read_config_word(pdev, 0x62, &port_wake); |
231 | if (port_wake & 0x0001) { | 231 | if (port_wake & 0x0001) { |
232 | dev_warn(&pdev->dev, "Enabling legacy PCI PM\n"); | 232 | dev_warn(&pdev->dev, "Enabling legacy PCI PM\n"); |
233 | device_init_wakeup(&pdev->dev, 1); | 233 | device_set_wakeup_capable(&pdev->dev, 1); |
234 | } | 234 | } |
235 | } | 235 | } |
236 | 236 | ||
@@ -432,8 +432,6 @@ static struct pci_driver ehci_pci_driver = { | |||
432 | 432 | ||
433 | #ifdef CONFIG_PM | 433 | #ifdef CONFIG_PM |
434 | .suspend = usb_hcd_pci_suspend, | 434 | .suspend = usb_hcd_pci_suspend, |
435 | .suspend_late = usb_hcd_pci_suspend_late, | ||
436 | .resume_early = usb_hcd_pci_resume_early, | ||
437 | .resume = usb_hcd_pci_resume, | 435 | .resume = usb_hcd_pci_resume, |
438 | #endif | 436 | #endif |
439 | .shutdown = usb_hcd_pci_shutdown, | 437 | .shutdown = usb_hcd_pci_shutdown, |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 3712b925b315..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 | } |
@@ -1095,7 +1127,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
1095 | prev->qh_next = qh->qh_next; | 1127 | prev->qh_next = qh->qh_next; |
1096 | wmb (); | 1128 | wmb (); |
1097 | 1129 | ||
1098 | if (unlikely (ehci_to_hcd(ehci)->state == HC_STATE_HALT)) { | 1130 | /* If the controller isn't running, we don't have to wait for it */ |
1131 | if (unlikely(!HC_IS_RUNNING(ehci_to_hcd(ehci)->state))) { | ||
1099 | /* if (unlikely (qh->reclaim != 0)) | 1132 | /* if (unlikely (qh->reclaim != 0)) |
1100 | * this will recurse, probably not much | 1133 | * this will recurse, probably not much |
1101 | */ | 1134 | */ |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index a081ee65bde6..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) |
@@ -1004,7 +1004,8 @@ iso_stream_put(struct ehci_hcd *ehci, struct ehci_iso_stream *stream) | |||
1004 | 1004 | ||
1005 | is_in = (stream->bEndpointAddress & USB_DIR_IN) ? 0x10 : 0; | 1005 | is_in = (stream->bEndpointAddress & USB_DIR_IN) ? 0x10 : 0; |
1006 | stream->bEndpointAddress &= 0x0f; | 1006 | stream->bEndpointAddress &= 0x0f; |
1007 | stream->ep->hcpriv = NULL; | 1007 | if (stream->ep) |
1008 | stream->ep->hcpriv = NULL; | ||
1008 | 1009 | ||
1009 | if (stream->rescheduled) { | 1010 | if (stream->rescheduled) { |
1010 | ehci_info (ehci, "ep%d%s-iso rescheduled " | 1011 | ehci_info (ehci, "ep%d%s-iso rescheduled " |
@@ -1535,7 +1536,7 @@ itd_link_urb ( | |||
1535 | struct ehci_itd, itd_list); | 1536 | struct ehci_itd, itd_list); |
1536 | list_move_tail (&itd->itd_list, &stream->td_list); | 1537 | list_move_tail (&itd->itd_list, &stream->td_list); |
1537 | itd->stream = iso_stream_get (stream); | 1538 | itd->stream = iso_stream_get (stream); |
1538 | itd->urb = usb_get_urb (urb); | 1539 | itd->urb = urb; |
1539 | itd_init (ehci, stream, itd); | 1540 | itd_init (ehci, stream, itd); |
1540 | } | 1541 | } |
1541 | 1542 | ||
@@ -1644,7 +1645,7 @@ itd_complete ( | |||
1644 | (void) disable_periodic(ehci); | 1645 | (void) disable_periodic(ehci); |
1645 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; | 1646 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; |
1646 | 1647 | ||
1647 | if (unlikely (list_empty (&stream->td_list))) { | 1648 | if (unlikely(list_is_singular(&stream->td_list))) { |
1648 | ehci_to_hcd(ehci)->self.bandwidth_allocated | 1649 | ehci_to_hcd(ehci)->self.bandwidth_allocated |
1649 | -= stream->bandwidth; | 1650 | -= stream->bandwidth; |
1650 | ehci_vdbg (ehci, | 1651 | ehci_vdbg (ehci, |
@@ -1653,14 +1654,27 @@ itd_complete ( | |||
1653 | (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); | 1654 | (stream->bEndpointAddress & USB_DIR_IN) ? "in" : "out"); |
1654 | } | 1655 | } |
1655 | iso_stream_put (ehci, stream); | 1656 | iso_stream_put (ehci, stream); |
1656 | /* OK to recycle this ITD now that its completion callback ran. */ | 1657 | |
1657 | done: | 1658 | done: |
1658 | usb_put_urb(urb); | ||
1659 | itd->urb = NULL; | 1659 | itd->urb = NULL; |
1660 | itd->stream = NULL; | 1660 | if (ehci->clock_frame != itd->frame || itd->index[7] != -1) { |
1661 | list_move(&itd->itd_list, &stream->free_list); | 1661 | /* OK to recycle this ITD now. */ |
1662 | iso_stream_put(ehci, stream); | 1662 | itd->stream = NULL; |
1663 | 1663 | list_move(&itd->itd_list, &stream->free_list); | |
1664 | iso_stream_put(ehci, stream); | ||
1665 | } else { | ||
1666 | /* HW might remember this ITD, so we can't recycle it yet. | ||
1667 | * Move it to a safe place until a new frame starts. | ||
1668 | */ | ||
1669 | list_move(&itd->itd_list, &ehci->cached_itd_list); | ||
1670 | if (stream->refcount == 2) { | ||
1671 | /* If iso_stream_put() were called here, stream | ||
1672 | * would be freed. Instead, just prevent reuse. | ||
1673 | */ | ||
1674 | stream->ep->hcpriv = NULL; | ||
1675 | stream->ep = NULL; | ||
1676 | } | ||
1677 | } | ||
1664 | return retval; | 1678 | return retval; |
1665 | } | 1679 | } |
1666 | 1680 | ||
@@ -1934,7 +1948,7 @@ sitd_link_urb ( | |||
1934 | struct ehci_sitd, sitd_list); | 1948 | struct ehci_sitd, sitd_list); |
1935 | list_move_tail (&sitd->sitd_list, &stream->td_list); | 1949 | list_move_tail (&sitd->sitd_list, &stream->td_list); |
1936 | sitd->stream = iso_stream_get (stream); | 1950 | sitd->stream = iso_stream_get (stream); |
1937 | sitd->urb = usb_get_urb (urb); | 1951 | sitd->urb = urb; |
1938 | 1952 | ||
1939 | sitd_patch(ehci, stream, sitd, sched, packet); | 1953 | sitd_patch(ehci, stream, sitd, sched, packet); |
1940 | sitd_link (ehci, (next_uframe >> 3) % ehci->periodic_size, | 1954 | sitd_link (ehci, (next_uframe >> 3) % ehci->periodic_size, |
@@ -2019,7 +2033,7 @@ sitd_complete ( | |||
2019 | (void) disable_periodic(ehci); | 2033 | (void) disable_periodic(ehci); |
2020 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; | 2034 | ehci_to_hcd(ehci)->self.bandwidth_isoc_reqs--; |
2021 | 2035 | ||
2022 | if (list_empty (&stream->td_list)) { | 2036 | if (list_is_singular(&stream->td_list)) { |
2023 | ehci_to_hcd(ehci)->self.bandwidth_allocated | 2037 | ehci_to_hcd(ehci)->self.bandwidth_allocated |
2024 | -= stream->bandwidth; | 2038 | -= stream->bandwidth; |
2025 | ehci_vdbg (ehci, | 2039 | ehci_vdbg (ehci, |
@@ -2030,7 +2044,6 @@ sitd_complete ( | |||
2030 | iso_stream_put (ehci, stream); | 2044 | iso_stream_put (ehci, stream); |
2031 | /* OK to recycle this SITD now that its completion callback ran. */ | 2045 | /* OK to recycle this SITD now that its completion callback ran. */ |
2032 | done: | 2046 | done: |
2033 | usb_put_urb(urb); | ||
2034 | sitd->urb = NULL; | 2047 | sitd->urb = NULL; |
2035 | sitd->stream = NULL; | 2048 | sitd->stream = NULL; |
2036 | list_move(&sitd->sitd_list, &stream->free_list); | 2049 | list_move(&sitd->sitd_list, &stream->free_list); |
@@ -2101,6 +2114,20 @@ done: | |||
2101 | 2114 | ||
2102 | /*-------------------------------------------------------------------------*/ | 2115 | /*-------------------------------------------------------------------------*/ |
2103 | 2116 | ||
2117 | static void free_cached_itd_list(struct ehci_hcd *ehci) | ||
2118 | { | ||
2119 | struct ehci_itd *itd, *n; | ||
2120 | |||
2121 | list_for_each_entry_safe(itd, n, &ehci->cached_itd_list, itd_list) { | ||
2122 | struct ehci_iso_stream *stream = itd->stream; | ||
2123 | itd->stream = NULL; | ||
2124 | list_move(&itd->itd_list, &stream->free_list); | ||
2125 | iso_stream_put(ehci, stream); | ||
2126 | } | ||
2127 | } | ||
2128 | |||
2129 | /*-------------------------------------------------------------------------*/ | ||
2130 | |||
2104 | static void | 2131 | static void |
2105 | scan_periodic (struct ehci_hcd *ehci) | 2132 | scan_periodic (struct ehci_hcd *ehci) |
2106 | { | 2133 | { |
@@ -2115,10 +2142,17 @@ scan_periodic (struct ehci_hcd *ehci) | |||
2115 | * Touches as few pages as possible: cache-friendly. | 2142 | * Touches as few pages as possible: cache-friendly. |
2116 | */ | 2143 | */ |
2117 | now_uframe = ehci->next_uframe; | 2144 | now_uframe = ehci->next_uframe; |
2118 | if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) | 2145 | if (HC_IS_RUNNING(ehci_to_hcd(ehci)->state)) { |
2119 | clock = ehci_readl(ehci, &ehci->regs->frame_index); | 2146 | clock = ehci_readl(ehci, &ehci->regs->frame_index); |
2120 | else | 2147 | clock_frame = (clock >> 3) % ehci->periodic_size; |
2148 | } else { | ||
2121 | clock = now_uframe + mod - 1; | 2149 | clock = now_uframe + mod - 1; |
2150 | clock_frame = -1; | ||
2151 | } | ||
2152 | if (ehci->clock_frame != clock_frame) { | ||
2153 | free_cached_itd_list(ehci); | ||
2154 | ehci->clock_frame = clock_frame; | ||
2155 | } | ||
2122 | clock %= mod; | 2156 | clock %= mod; |
2123 | clock_frame = clock >> 3; | 2157 | clock_frame = clock >> 3; |
2124 | 2158 | ||
@@ -2277,6 +2311,10 @@ restart: | |||
2277 | /* rescan the rest of this frame, then ... */ | 2311 | /* rescan the rest of this frame, then ... */ |
2278 | clock = now; | 2312 | clock = now; |
2279 | clock_frame = clock >> 3; | 2313 | clock_frame = clock >> 3; |
2314 | if (ehci->clock_frame != clock_frame) { | ||
2315 | free_cached_itd_list(ehci); | ||
2316 | ehci->clock_frame = clock_frame; | ||
2317 | } | ||
2280 | } else { | 2318 | } else { |
2281 | now_uframe++; | 2319 | now_uframe++; |
2282 | now_uframe %= mod; | 2320 | now_uframe %= mod; |
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index fb7054ccf4fc..6cff195e1a36 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -87,6 +87,10 @@ struct ehci_hcd { /* one per controller */ | |||
87 | int next_uframe; /* scan periodic, start here */ | 87 | int next_uframe; /* scan periodic, start here */ |
88 | unsigned periodic_sched; /* periodic activity count */ | 88 | unsigned periodic_sched; /* periodic activity count */ |
89 | 89 | ||
90 | /* list of itds completed while clock_frame was still active */ | ||
91 | struct list_head cached_itd_list; | ||
92 | unsigned clock_frame; | ||
93 | |||
90 | /* per root hub port */ | 94 | /* per root hub port */ |
91 | unsigned long reset_done [EHCI_MAX_ROOT_PORTS]; | 95 | unsigned long reset_done [EHCI_MAX_ROOT_PORTS]; |
92 | 96 | ||
@@ -186,39 +190,7 @@ timer_action_done (struct ehci_hcd *ehci, enum ehci_timer_action action) | |||
186 | clear_bit (action, &ehci->actions); | 190 | clear_bit (action, &ehci->actions); |
187 | } | 191 | } |
188 | 192 | ||
189 | static inline void | 193 | static void free_cached_itd_list(struct ehci_hcd *ehci); |
190 | timer_action (struct ehci_hcd *ehci, enum ehci_timer_action action) | ||
191 | { | ||
192 | /* Don't override timeouts which shrink or (later) disable | ||
193 | * the async ring; just the I/O watchdog. Note that if a | ||
194 | * SHRINK were pending, OFF would never be requested. | ||
195 | */ | ||
196 | if (timer_pending(&ehci->watchdog) | ||
197 | && ((BIT(TIMER_ASYNC_SHRINK) | BIT(TIMER_ASYNC_OFF)) | ||
198 | & ehci->actions)) | ||
199 | return; | ||
200 | |||
201 | if (!test_and_set_bit (action, &ehci->actions)) { | ||
202 | unsigned long t; | ||
203 | |||
204 | switch (action) { | ||
205 | case TIMER_IO_WATCHDOG: | ||
206 | t = EHCI_IO_JIFFIES; | ||
207 | break; | ||
208 | case TIMER_ASYNC_OFF: | ||
209 | t = EHCI_ASYNC_JIFFIES; | ||
210 | break; | ||
211 | // case TIMER_ASYNC_SHRINK: | ||
212 | default: | ||
213 | /* add a jiffie since we synch against the | ||
214 | * 8 KHz uframe counter. | ||
215 | */ | ||
216 | t = DIV_ROUND_UP(EHCI_SHRINK_FRAMES * HZ, 1000) + 1; | ||
217 | break; | ||
218 | } | ||
219 | mod_timer(&ehci->watchdog, t + jiffies); | ||
220 | } | ||
221 | } | ||
222 | 194 | ||
223 | /*-------------------------------------------------------------------------*/ | 195 | /*-------------------------------------------------------------------------*/ |
224 | 196 | ||
@@ -281,7 +253,7 @@ struct ehci_qtd { | |||
281 | 253 | ||
282 | /* | 254 | /* |
283 | * Now the following defines are not converted using the | 255 | * Now the following defines are not converted using the |
284 | * __constant_cpu_to_le32() macro anymore, since we have to support | 256 | * cpu_to_le32() macro anymore, since we have to support |
285 | * "dynamic" switching between be and le support, so that the driver | 257 | * "dynamic" switching between be and le support, so that the driver |
286 | * 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 |
287 | * descriptors as well as a normal little-endian PCI EHCI controller. | 259 | * descriptors as well as a normal little-endian PCI EHCI controller. |
@@ -370,6 +342,9 @@ struct ehci_qh { | |||
370 | #define QH_STATE_UNLINK_WAIT 4 /* LINKED and on reclaim q */ | 342 | #define QH_STATE_UNLINK_WAIT 4 /* LINKED and on reclaim q */ |
371 | #define QH_STATE_COMPLETING 5 /* don't touch token.HALT */ | 343 | #define QH_STATE_COMPLETING 5 /* don't touch token.HALT */ |
372 | 344 | ||
345 | u8 xacterrs; /* XactErr retry counter */ | ||
346 | #define QH_XACTERR_MAX 32 /* XactErr retry limit */ | ||
347 | |||
373 | /* periodic schedule info */ | 348 | /* periodic schedule info */ |
374 | u8 usecs; /* intr bandwidth */ | 349 | u8 usecs; /* intr bandwidth */ |
375 | u8 gap_uf; /* uframes split/csplit gap */ | 350 | u8 gap_uf; /* uframes split/csplit gap */ |
diff --git a/drivers/usb/host/fhci-dbg.c b/drivers/usb/host/fhci-dbg.c new file mode 100644 index 000000000000..ea8a4255c5da --- /dev/null +++ b/drivers/usb/host/fhci-dbg.c | |||
@@ -0,0 +1,139 @@ | |||
1 | /* | ||
2 | * Freescale QUICC Engine USB Host Controller Driver | ||
3 | * | ||
4 | * Copyright (c) Freescale Semicondutor, Inc. 2006. | ||
5 | * Shlomi Gridish <gridish@freescale.com> | ||
6 | * Jerry Huang <Chang-Ming.Huang@freescale.com> | ||
7 | * Copyright (c) Logic Product Development, Inc. 2007 | ||
8 | * Peter Barada <peterb@logicpd.com> | ||
9 | * Copyright (c) MontaVista Software, Inc. 2008. | ||
10 | * Anton Vorontsov <avorontsov@ru.mvista.com> | ||
11 | * | ||
12 | * 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 | ||
14 | * Free Software Foundation; either version 2 of the License, or (at your | ||
15 | * option) any later version. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/errno.h> | ||
20 | #include <linux/debugfs.h> | ||
21 | #include <linux/seq_file.h> | ||
22 | #include <linux/usb.h> | ||
23 | #include "../core/hcd.h" | ||
24 | #include "fhci.h" | ||
25 | |||
26 | void fhci_dbg_isr(struct fhci_hcd *fhci, int usb_er) | ||
27 | { | ||
28 | int i; | ||
29 | |||
30 | if (usb_er == -1) { | ||
31 | fhci->usb_irq_stat[12]++; | ||
32 | return; | ||
33 | } | ||
34 | |||
35 | for (i = 0; i < 12; ++i) { | ||
36 | if (usb_er & (1 << i)) | ||
37 | fhci->usb_irq_stat[i]++; | ||
38 | } | ||
39 | } | ||
40 | |||
41 | static int fhci_dfs_regs_show(struct seq_file *s, void *v) | ||
42 | { | ||
43 | struct fhci_hcd *fhci = s->private; | ||
44 | struct fhci_regs __iomem *regs = fhci->regs; | ||
45 | |||
46 | seq_printf(s, | ||
47 | "mode: 0x%x\n" "addr: 0x%x\n" | ||
48 | "command: 0x%x\n" "ep0: 0x%x\n" | ||
49 | "event: 0x%x\n" "mask: 0x%x\n" | ||
50 | "status: 0x%x\n" "SOF timer: %d\n" | ||
51 | "frame number: %d\n" | ||
52 | "lines status: 0x%x\n", | ||
53 | in_8(®s->usb_mod), in_8(®s->usb_addr), | ||
54 | in_8(®s->usb_comm), in_be16(®s->usb_ep[0]), | ||
55 | in_be16(®s->usb_event), in_be16(®s->usb_mask), | ||
56 | in_8(®s->usb_status), in_be16(®s->usb_sof_tmr), | ||
57 | in_be16(®s->usb_frame_num), | ||
58 | fhci_ioports_check_bus_state(fhci)); | ||
59 | |||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | static int fhci_dfs_irq_stat_show(struct seq_file *s, void *v) | ||
64 | { | ||
65 | struct fhci_hcd *fhci = s->private; | ||
66 | int *usb_irq_stat = fhci->usb_irq_stat; | ||
67 | |||
68 | seq_printf(s, | ||
69 | "RXB: %d\n" "TXB: %d\n" "BSY: %d\n" | ||
70 | "SOF: %d\n" "TXE0: %d\n" "TXE1: %d\n" | ||
71 | "TXE2: %d\n" "TXE3: %d\n" "IDLE: %d\n" | ||
72 | "RESET: %d\n" "SFT: %d\n" "MSF: %d\n" | ||
73 | "IDLE_ONLY: %d\n", | ||
74 | usb_irq_stat[0], usb_irq_stat[1], usb_irq_stat[2], | ||
75 | usb_irq_stat[3], usb_irq_stat[4], usb_irq_stat[5], | ||
76 | usb_irq_stat[6], usb_irq_stat[7], usb_irq_stat[8], | ||
77 | usb_irq_stat[9], usb_irq_stat[10], usb_irq_stat[11], | ||
78 | usb_irq_stat[12]); | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static int fhci_dfs_regs_open(struct inode *inode, struct file *file) | ||
84 | { | ||
85 | return single_open(file, fhci_dfs_regs_show, inode->i_private); | ||
86 | } | ||
87 | |||
88 | static int fhci_dfs_irq_stat_open(struct inode *inode, struct file *file) | ||
89 | { | ||
90 | return single_open(file, fhci_dfs_irq_stat_show, inode->i_private); | ||
91 | } | ||
92 | |||
93 | static const struct file_operations fhci_dfs_regs_fops = { | ||
94 | .open = fhci_dfs_regs_open, | ||
95 | .read = seq_read, | ||
96 | .llseek = seq_lseek, | ||
97 | .release = single_release, | ||
98 | }; | ||
99 | |||
100 | static const struct file_operations fhci_dfs_irq_stat_fops = { | ||
101 | .open = fhci_dfs_irq_stat_open, | ||
102 | .read = seq_read, | ||
103 | .llseek = seq_lseek, | ||
104 | .release = single_release, | ||
105 | }; | ||
106 | |||
107 | void fhci_dfs_create(struct fhci_hcd *fhci) | ||
108 | { | ||
109 | struct device *dev = fhci_to_hcd(fhci)->self.controller; | ||
110 | |||
111 | fhci->dfs_root = debugfs_create_dir(dev_name(dev), NULL); | ||
112 | if (!fhci->dfs_root) { | ||
113 | WARN_ON(1); | ||
114 | return; | ||
115 | } | ||
116 | |||
117 | fhci->dfs_regs = debugfs_create_file("regs", S_IFREG | S_IRUGO, | ||
118 | fhci->dfs_root, fhci, &fhci_dfs_regs_fops); | ||
119 | |||
120 | fhci->dfs_irq_stat = debugfs_create_file("irq_stat", | ||
121 | S_IFREG | S_IRUGO, fhci->dfs_root, fhci, | ||
122 | &fhci_dfs_irq_stat_fops); | ||
123 | |||
124 | WARN_ON(!fhci->dfs_regs || !fhci->dfs_irq_stat); | ||
125 | } | ||
126 | |||
127 | void fhci_dfs_destroy(struct fhci_hcd *fhci) | ||
128 | { | ||
129 | if (!fhci->dfs_root) | ||
130 | return; | ||
131 | |||
132 | if (fhci->dfs_irq_stat) | ||
133 | debugfs_remove(fhci->dfs_irq_stat); | ||
134 | |||
135 | if (fhci->dfs_regs) | ||
136 | debugfs_remove(fhci->dfs_regs); | ||
137 | |||
138 | debugfs_remove(fhci->dfs_root); | ||
139 | } | ||
diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c new file mode 100644 index 000000000000..0951818ef93b --- /dev/null +++ b/drivers/usb/host/fhci-hcd.c | |||
@@ -0,0 +1,836 @@ | |||
1 | /* | ||
2 | * Freescale QUICC Engine USB Host Controller Driver | ||
3 | * | ||
4 | * Copyright (c) Freescale Semicondutor, Inc. 2006. | ||
5 | * Shlomi Gridish <gridish@freescale.com> | ||
6 | * Jerry Huang <Chang-Ming.Huang@freescale.com> | ||
7 | * Copyright (c) Logic Product Development, Inc. 2007 | ||
8 | * Peter Barada <peterb@logicpd.com> | ||
9 | * Copyright (c) MontaVista Software, Inc. 2008. | ||
10 | * Anton Vorontsov <avorontsov@ru.mvista.com> | ||
11 | * | ||
12 | * 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 | ||
14 | * Free Software Foundation; either version 2 of the License, or (at your | ||
15 | * option) any later version. | ||
16 | */ | ||
17 | |||
18 | #include <linux/module.h> | ||
19 | #include <linux/types.h> | ||
20 | #include <linux/spinlock.h> | ||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/delay.h> | ||
23 | #include <linux/errno.h> | ||
24 | #include <linux/list.h> | ||
25 | #include <linux/interrupt.h> | ||
26 | #include <linux/io.h> | ||
27 | #include <linux/usb.h> | ||
28 | #include <linux/of_platform.h> | ||
29 | #include <linux/of_gpio.h> | ||
30 | #include <asm/qe.h> | ||
31 | #include <asm/fsl_gtm.h> | ||
32 | #include "../core/hcd.h" | ||
33 | #include "fhci.h" | ||
34 | |||
35 | void fhci_start_sof_timer(struct fhci_hcd *fhci) | ||
36 | { | ||
37 | fhci_dbg(fhci, "-> %s\n", __func__); | ||
38 | |||
39 | /* clear frame_n */ | ||
40 | out_be16(&fhci->pram->frame_num, 0); | ||
41 | |||
42 | out_be16(&fhci->regs->usb_sof_tmr, 0); | ||
43 | setbits8(&fhci->regs->usb_mod, USB_MODE_SFTE); | ||
44 | |||
45 | fhci_dbg(fhci, "<- %s\n", __func__); | ||
46 | } | ||
47 | |||
48 | void fhci_stop_sof_timer(struct fhci_hcd *fhci) | ||
49 | { | ||
50 | fhci_dbg(fhci, "-> %s\n", __func__); | ||
51 | |||
52 | clrbits8(&fhci->regs->usb_mod, USB_MODE_SFTE); | ||
53 | gtm_stop_timer16(fhci->timer); | ||
54 | |||
55 | fhci_dbg(fhci, "<- %s\n", __func__); | ||
56 | } | ||
57 | |||
58 | u16 fhci_get_sof_timer_count(struct fhci_usb *usb) | ||
59 | { | ||
60 | return be16_to_cpu(in_be16(&usb->fhci->regs->usb_sof_tmr) / 12); | ||
61 | } | ||
62 | |||
63 | /* initialize the endpoint zero */ | ||
64 | static u32 endpoint_zero_init(struct fhci_usb *usb, | ||
65 | enum fhci_mem_alloc data_mem, | ||
66 | u32 ring_len) | ||
67 | { | ||
68 | u32 rc; | ||
69 | |||
70 | rc = fhci_create_ep(usb, data_mem, ring_len); | ||
71 | if (rc) | ||
72 | return rc; | ||
73 | |||
74 | /* inilialize endpoint registers */ | ||
75 | fhci_init_ep_registers(usb, usb->ep0, data_mem); | ||
76 | |||
77 | return 0; | ||
78 | } | ||
79 | |||
80 | /* enable the USB interrupts */ | ||
81 | void fhci_usb_enable_interrupt(struct fhci_usb *usb) | ||
82 | { | ||
83 | struct fhci_hcd *fhci = usb->fhci; | ||
84 | |||
85 | if (usb->intr_nesting_cnt == 1) { | ||
86 | /* initialize the USB interrupt */ | ||
87 | enable_irq(fhci_to_hcd(fhci)->irq); | ||
88 | |||
89 | /* initialize the event register and mask register */ | ||
90 | out_be16(&usb->fhci->regs->usb_event, 0xffff); | ||
91 | out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk); | ||
92 | |||
93 | /* enable the timer interrupts */ | ||
94 | enable_irq(fhci->timer->irq); | ||
95 | } else if (usb->intr_nesting_cnt > 1) | ||
96 | fhci_info(fhci, "unbalanced USB interrupts nesting\n"); | ||
97 | usb->intr_nesting_cnt--; | ||
98 | } | ||
99 | |||
100 | /* diable the usb interrupt */ | ||
101 | void fhci_usb_disable_interrupt(struct fhci_usb *usb) | ||
102 | { | ||
103 | struct fhci_hcd *fhci = usb->fhci; | ||
104 | |||
105 | if (usb->intr_nesting_cnt == 0) { | ||
106 | /* diable the timer interrupt */ | ||
107 | disable_irq_nosync(fhci->timer->irq); | ||
108 | |||
109 | /* disable the usb interrupt */ | ||
110 | disable_irq_nosync(fhci_to_hcd(fhci)->irq); | ||
111 | out_be16(&usb->fhci->regs->usb_mask, 0); | ||
112 | } | ||
113 | usb->intr_nesting_cnt++; | ||
114 | } | ||
115 | |||
116 | /* enable the USB controller */ | ||
117 | static u32 fhci_usb_enable(struct fhci_hcd *fhci) | ||
118 | { | ||
119 | struct fhci_usb *usb = fhci->usb_lld; | ||
120 | |||
121 | out_be16(&usb->fhci->regs->usb_event, 0xffff); | ||
122 | out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk); | ||
123 | setbits8(&usb->fhci->regs->usb_mod, USB_MODE_EN); | ||
124 | |||
125 | mdelay(100); | ||
126 | |||
127 | return 0; | ||
128 | } | ||
129 | |||
130 | /* disable the USB controller */ | ||
131 | static u32 fhci_usb_disable(struct fhci_hcd *fhci) | ||
132 | { | ||
133 | struct fhci_usb *usb = fhci->usb_lld; | ||
134 | |||
135 | fhci_usb_disable_interrupt(usb); | ||
136 | fhci_port_disable(fhci); | ||
137 | |||
138 | /* disable the usb controller */ | ||
139 | if (usb->port_status == FHCI_PORT_FULL || | ||
140 | usb->port_status == FHCI_PORT_LOW) | ||
141 | fhci_device_disconnected_interrupt(fhci); | ||
142 | |||
143 | clrbits8(&usb->fhci->regs->usb_mod, USB_MODE_EN); | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | /* check the bus state by polling the QE bit on the IO ports */ | ||
149 | int fhci_ioports_check_bus_state(struct fhci_hcd *fhci) | ||
150 | { | ||
151 | u8 bits = 0; | ||
152 | |||
153 | /* check USBOE,if transmitting,exit */ | ||
154 | if (!gpio_get_value(fhci->gpios[GPIO_USBOE])) | ||
155 | return -1; | ||
156 | |||
157 | /* check USBRP */ | ||
158 | if (gpio_get_value(fhci->gpios[GPIO_USBRP])) | ||
159 | bits |= 0x2; | ||
160 | |||
161 | /* check USBRN */ | ||
162 | if (gpio_get_value(fhci->gpios[GPIO_USBRN])) | ||
163 | bits |= 0x1; | ||
164 | |||
165 | return bits; | ||
166 | } | ||
167 | |||
168 | static void fhci_mem_free(struct fhci_hcd *fhci) | ||
169 | { | ||
170 | struct ed *ed; | ||
171 | struct ed *next_ed; | ||
172 | struct td *td; | ||
173 | struct td *next_td; | ||
174 | |||
175 | list_for_each_entry_safe(ed, next_ed, &fhci->empty_eds, node) { | ||
176 | list_del(&ed->node); | ||
177 | kfree(ed); | ||
178 | } | ||
179 | |||
180 | list_for_each_entry_safe(td, next_td, &fhci->empty_tds, node) { | ||
181 | list_del(&td->node); | ||
182 | kfree(td); | ||
183 | } | ||
184 | |||
185 | kfree(fhci->vroot_hub); | ||
186 | fhci->vroot_hub = NULL; | ||
187 | |||
188 | kfree(fhci->hc_list); | ||
189 | fhci->hc_list = NULL; | ||
190 | } | ||
191 | |||
192 | static int fhci_mem_init(struct fhci_hcd *fhci) | ||
193 | { | ||
194 | int i; | ||
195 | |||
196 | fhci->hc_list = kzalloc(sizeof(*fhci->hc_list), GFP_KERNEL); | ||
197 | if (!fhci->hc_list) | ||
198 | goto err; | ||
199 | |||
200 | INIT_LIST_HEAD(&fhci->hc_list->ctrl_list); | ||
201 | INIT_LIST_HEAD(&fhci->hc_list->bulk_list); | ||
202 | INIT_LIST_HEAD(&fhci->hc_list->iso_list); | ||
203 | INIT_LIST_HEAD(&fhci->hc_list->intr_list); | ||
204 | INIT_LIST_HEAD(&fhci->hc_list->done_list); | ||
205 | |||
206 | fhci->vroot_hub = kzalloc(sizeof(*fhci->vroot_hub), GFP_KERNEL); | ||
207 | if (!fhci->vroot_hub) | ||
208 | goto err; | ||
209 | |||
210 | INIT_LIST_HEAD(&fhci->empty_eds); | ||
211 | INIT_LIST_HEAD(&fhci->empty_tds); | ||
212 | |||
213 | /* initialize work queue to handle done list */ | ||
214 | fhci_tasklet.data = (unsigned long)fhci; | ||
215 | fhci->process_done_task = &fhci_tasklet; | ||
216 | |||
217 | for (i = 0; i < MAX_TDS; i++) { | ||
218 | struct td *td; | ||
219 | |||
220 | td = kmalloc(sizeof(*td), GFP_KERNEL); | ||
221 | if (!td) | ||
222 | goto err; | ||
223 | fhci_recycle_empty_td(fhci, td); | ||
224 | } | ||
225 | for (i = 0; i < MAX_EDS; i++) { | ||
226 | struct ed *ed; | ||
227 | |||
228 | ed = kmalloc(sizeof(*ed), GFP_KERNEL); | ||
229 | if (!ed) | ||
230 | goto err; | ||
231 | fhci_recycle_empty_ed(fhci, ed); | ||
232 | } | ||
233 | |||
234 | fhci->active_urbs = 0; | ||
235 | return 0; | ||
236 | err: | ||
237 | fhci_mem_free(fhci); | ||
238 | return -ENOMEM; | ||
239 | } | ||
240 | |||
241 | /* destroy the fhci_usb structure */ | ||
242 | static void fhci_usb_free(void *lld) | ||
243 | { | ||
244 | struct fhci_usb *usb = lld; | ||
245 | struct fhci_hcd *fhci = usb->fhci; | ||
246 | |||
247 | if (usb) { | ||
248 | fhci_config_transceiver(fhci, FHCI_PORT_POWER_OFF); | ||
249 | fhci_ep0_free(usb); | ||
250 | kfree(usb->actual_frame); | ||
251 | kfree(usb); | ||
252 | } | ||
253 | } | ||
254 | |||
255 | /* initialize the USB */ | ||
256 | static int fhci_usb_init(struct fhci_hcd *fhci) | ||
257 | { | ||
258 | struct fhci_usb *usb = fhci->usb_lld; | ||
259 | |||
260 | memset_io(usb->fhci->pram, 0, FHCI_PRAM_SIZE); | ||
261 | |||
262 | usb->port_status = FHCI_PORT_DISABLED; | ||
263 | usb->max_frame_usage = FRAME_TIME_USAGE; | ||
264 | usb->sw_transaction_time = SW_FIX_TIME_BETWEEN_TRANSACTION; | ||
265 | |||
266 | usb->actual_frame = kzalloc(sizeof(*usb->actual_frame), GFP_KERNEL); | ||
267 | if (!usb->actual_frame) { | ||
268 | fhci_usb_free(usb); | ||
269 | return -ENOMEM; | ||
270 | } | ||
271 | |||
272 | INIT_LIST_HEAD(&usb->actual_frame->tds_list); | ||
273 | |||
274 | /* initializing registers on chip, clear frame number */ | ||
275 | out_be16(&fhci->pram->frame_num, 0); | ||
276 | |||
277 | /* clear rx state */ | ||
278 | out_be32(&fhci->pram->rx_state, 0); | ||
279 | |||
280 | /* set mask register */ | ||
281 | usb->saved_msk = (USB_E_TXB_MASK | | ||
282 | USB_E_TXE1_MASK | | ||
283 | USB_E_IDLE_MASK | | ||
284 | USB_E_RESET_MASK | USB_E_SFT_MASK | USB_E_MSF_MASK); | ||
285 | |||
286 | out_8(&usb->fhci->regs->usb_mod, USB_MODE_HOST | USB_MODE_EN); | ||
287 | |||
288 | /* clearing the mask register */ | ||
289 | out_be16(&usb->fhci->regs->usb_mask, 0); | ||
290 | |||
291 | /* initialing the event register */ | ||
292 | out_be16(&usb->fhci->regs->usb_event, 0xffff); | ||
293 | |||
294 | if (endpoint_zero_init(usb, DEFAULT_DATA_MEM, DEFAULT_RING_LEN) != 0) { | ||
295 | fhci_usb_free(usb); | ||
296 | return -EINVAL; | ||
297 | } | ||
298 | |||
299 | return 0; | ||
300 | } | ||
301 | |||
302 | /* initialize the fhci_usb struct and the corresponding data staruct */ | ||
303 | static struct fhci_usb *fhci_create_lld(struct fhci_hcd *fhci) | ||
304 | { | ||
305 | struct fhci_usb *usb; | ||
306 | |||
307 | /* allocate memory for SCC data structure */ | ||
308 | usb = kzalloc(sizeof(*usb), GFP_KERNEL); | ||
309 | if (!usb) { | ||
310 | fhci_err(fhci, "no memory for SCC data struct\n"); | ||
311 | return NULL; | ||
312 | } | ||
313 | |||
314 | usb->fhci = fhci; | ||
315 | usb->hc_list = fhci->hc_list; | ||
316 | usb->vroot_hub = fhci->vroot_hub; | ||
317 | |||
318 | usb->transfer_confirm = fhci_transfer_confirm_callback; | ||
319 | |||
320 | return usb; | ||
321 | } | ||
322 | |||
323 | static int fhci_start(struct usb_hcd *hcd) | ||
324 | { | ||
325 | int ret; | ||
326 | struct fhci_hcd *fhci = hcd_to_fhci(hcd); | ||
327 | |||
328 | ret = fhci_mem_init(fhci); | ||
329 | if (ret) { | ||
330 | fhci_err(fhci, "failed to allocate memory\n"); | ||
331 | goto err; | ||
332 | } | ||
333 | |||
334 | fhci->usb_lld = fhci_create_lld(fhci); | ||
335 | if (!fhci->usb_lld) { | ||
336 | fhci_err(fhci, "low level driver config failed\n"); | ||
337 | ret = -ENOMEM; | ||
338 | goto err; | ||
339 | } | ||
340 | |||
341 | ret = fhci_usb_init(fhci); | ||
342 | if (ret) { | ||
343 | fhci_err(fhci, "low level driver initialize failed\n"); | ||
344 | goto err; | ||
345 | } | ||
346 | |||
347 | spin_lock_init(&fhci->lock); | ||
348 | |||
349 | /* connect the virtual root hub */ | ||
350 | fhci->vroot_hub->dev_num = 1; /* this field may be needed to fix */ | ||
351 | fhci->vroot_hub->hub.wHubStatus = 0; | ||
352 | fhci->vroot_hub->hub.wHubChange = 0; | ||
353 | fhci->vroot_hub->port.wPortStatus = 0; | ||
354 | fhci->vroot_hub->port.wPortChange = 0; | ||
355 | |||
356 | hcd->state = HC_STATE_RUNNING; | ||
357 | |||
358 | /* | ||
359 | * From here on, khubd concurrently accesses the root | ||
360 | * hub; drivers will be talking to enumerated devices. | ||
361 | * (On restart paths, khubd already knows about the root | ||
362 | * hub and could find work as soon as we wrote FLAG_CF.) | ||
363 | * | ||
364 | * Before this point the HC was idle/ready. After, khubd | ||
365 | * and device drivers may start it running. | ||
366 | */ | ||
367 | fhci_usb_enable(fhci); | ||
368 | return 0; | ||
369 | err: | ||
370 | fhci_mem_free(fhci); | ||
371 | return ret; | ||
372 | } | ||
373 | |||
374 | static void fhci_stop(struct usb_hcd *hcd) | ||
375 | { | ||
376 | struct fhci_hcd *fhci = hcd_to_fhci(hcd); | ||
377 | |||
378 | fhci_usb_disable_interrupt(fhci->usb_lld); | ||
379 | fhci_usb_disable(fhci); | ||
380 | |||
381 | fhci_usb_free(fhci->usb_lld); | ||
382 | fhci->usb_lld = NULL; | ||
383 | fhci_mem_free(fhci); | ||
384 | } | ||
385 | |||
386 | static int fhci_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, | ||
387 | gfp_t mem_flags) | ||
388 | { | ||
389 | struct fhci_hcd *fhci = hcd_to_fhci(hcd); | ||
390 | u32 pipe = urb->pipe; | ||
391 | int ret; | ||
392 | int i; | ||
393 | int size = 0; | ||
394 | struct urb_priv *urb_priv; | ||
395 | unsigned long flags; | ||
396 | |||
397 | switch (usb_pipetype(pipe)) { | ||
398 | case PIPE_CONTROL: | ||
399 | /* 1 td fro setup,1 for ack */ | ||
400 | size = 2; | ||
401 | case PIPE_BULK: | ||
402 | /* one td for every 4096 bytes(can be upto 8k) */ | ||
403 | size += urb->transfer_buffer_length / 4096; | ||
404 | /* ...add for any remaining bytes... */ | ||
405 | if ((urb->transfer_buffer_length % 4096) != 0) | ||
406 | size++; | ||
407 | /* ..and maybe a zero length packet to wrap it up */ | ||
408 | if (size == 0) | ||
409 | size++; | ||
410 | else if ((urb->transfer_flags & URB_ZERO_PACKET) != 0 | ||
411 | && (urb->transfer_buffer_length | ||
412 | % usb_maxpacket(urb->dev, pipe, | ||
413 | usb_pipeout(pipe))) != 0) | ||
414 | size++; | ||
415 | break; | ||
416 | case PIPE_ISOCHRONOUS: | ||
417 | size = urb->number_of_packets; | ||
418 | if (size <= 0) | ||
419 | return -EINVAL; | ||
420 | for (i = 0; i < urb->number_of_packets; i++) { | ||
421 | urb->iso_frame_desc[i].actual_length = 0; | ||
422 | urb->iso_frame_desc[i].status = (u32) (-EXDEV); | ||
423 | } | ||
424 | break; | ||
425 | case PIPE_INTERRUPT: | ||
426 | size = 1; | ||
427 | } | ||
428 | |||
429 | /* allocate the private part of the URB */ | ||
430 | urb_priv = kzalloc(sizeof(*urb_priv), mem_flags); | ||
431 | if (!urb_priv) | ||
432 | return -ENOMEM; | ||
433 | |||
434 | /* allocate the private part of the URB */ | ||
435 | urb_priv->tds = kzalloc(size * sizeof(struct td), mem_flags); | ||
436 | if (!urb_priv->tds) { | ||
437 | kfree(urb_priv); | ||
438 | return -ENOMEM; | ||
439 | } | ||
440 | |||
441 | spin_lock_irqsave(&fhci->lock, flags); | ||
442 | |||
443 | ret = usb_hcd_link_urb_to_ep(hcd, urb); | ||
444 | if (ret) | ||
445 | goto err; | ||
446 | |||
447 | /* fill the private part of the URB */ | ||
448 | urb_priv->num_of_tds = size; | ||
449 | |||
450 | urb->status = -EINPROGRESS; | ||
451 | urb->actual_length = 0; | ||
452 | urb->error_count = 0; | ||
453 | urb->hcpriv = urb_priv; | ||
454 | |||
455 | fhci_queue_urb(fhci, urb); | ||
456 | err: | ||
457 | if (ret) { | ||
458 | kfree(urb_priv->tds); | ||
459 | kfree(urb_priv); | ||
460 | } | ||
461 | spin_unlock_irqrestore(&fhci->lock, flags); | ||
462 | return ret; | ||
463 | } | ||
464 | |||
465 | /* dequeue FHCI URB */ | ||
466 | static int fhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | ||
467 | { | ||
468 | struct fhci_hcd *fhci = hcd_to_fhci(hcd); | ||
469 | struct fhci_usb *usb = fhci->usb_lld; | ||
470 | int ret = -EINVAL; | ||
471 | unsigned long flags; | ||
472 | |||
473 | if (!urb || !urb->dev || !urb->dev->bus) | ||
474 | goto out; | ||
475 | |||
476 | spin_lock_irqsave(&fhci->lock, flags); | ||
477 | |||
478 | ret = usb_hcd_check_unlink_urb(hcd, urb, status); | ||
479 | if (ret) | ||
480 | goto out2; | ||
481 | |||
482 | if (usb->port_status != FHCI_PORT_DISABLED) { | ||
483 | struct urb_priv *urb_priv; | ||
484 | |||
485 | /* | ||
486 | * flag the urb's data for deletion in some upcoming | ||
487 | * SF interrupt's delete list processing | ||
488 | */ | ||
489 | urb_priv = urb->hcpriv; | ||
490 | |||
491 | if (!urb_priv || (urb_priv->state == URB_DEL)) | ||
492 | goto out2; | ||
493 | |||
494 | urb_priv->state = URB_DEL; | ||
495 | |||
496 | /* already pending? */ | ||
497 | urb_priv->ed->state = FHCI_ED_URB_DEL; | ||
498 | } else { | ||
499 | fhci_urb_complete_free(fhci, urb); | ||
500 | } | ||
501 | |||
502 | out2: | ||
503 | spin_unlock_irqrestore(&fhci->lock, flags); | ||
504 | out: | ||
505 | return ret; | ||
506 | } | ||
507 | |||
508 | static void fhci_endpoint_disable(struct usb_hcd *hcd, | ||
509 | struct usb_host_endpoint *ep) | ||
510 | { | ||
511 | struct fhci_hcd *fhci; | ||
512 | struct ed *ed; | ||
513 | unsigned long flags; | ||
514 | |||
515 | fhci = hcd_to_fhci(hcd); | ||
516 | spin_lock_irqsave(&fhci->lock, flags); | ||
517 | ed = ep->hcpriv; | ||
518 | if (ed) { | ||
519 | while (ed->td_head != NULL) { | ||
520 | struct td *td = fhci_remove_td_from_ed(ed); | ||
521 | fhci_urb_complete_free(fhci, td->urb); | ||
522 | } | ||
523 | fhci_recycle_empty_ed(fhci, ed); | ||
524 | ep->hcpriv = NULL; | ||
525 | } | ||
526 | spin_unlock_irqrestore(&fhci->lock, flags); | ||
527 | } | ||
528 | |||
529 | static int fhci_get_frame_number(struct usb_hcd *hcd) | ||
530 | { | ||
531 | struct fhci_hcd *fhci = hcd_to_fhci(hcd); | ||
532 | |||
533 | return get_frame_num(fhci); | ||
534 | } | ||
535 | |||
536 | static const struct hc_driver fhci_driver = { | ||
537 | .description = "fsl,usb-fhci", | ||
538 | .product_desc = "FHCI HOST Controller", | ||
539 | .hcd_priv_size = sizeof(struct fhci_hcd), | ||
540 | |||
541 | /* generic hardware linkage */ | ||
542 | .irq = fhci_irq, | ||
543 | .flags = HCD_USB11 | HCD_MEMORY, | ||
544 | |||
545 | /* basic lifecycle operation */ | ||
546 | .start = fhci_start, | ||
547 | .stop = fhci_stop, | ||
548 | |||
549 | /* managing i/o requests and associated device resources */ | ||
550 | .urb_enqueue = fhci_urb_enqueue, | ||
551 | .urb_dequeue = fhci_urb_dequeue, | ||
552 | .endpoint_disable = fhci_endpoint_disable, | ||
553 | |||
554 | /* scheduling support */ | ||
555 | .get_frame_number = fhci_get_frame_number, | ||
556 | |||
557 | /* root hub support */ | ||
558 | .hub_status_data = fhci_hub_status_data, | ||
559 | .hub_control = fhci_hub_control, | ||
560 | }; | ||
561 | |||
562 | static int __devinit of_fhci_probe(struct of_device *ofdev, | ||
563 | const struct of_device_id *ofid) | ||
564 | { | ||
565 | struct device *dev = &ofdev->dev; | ||
566 | struct device_node *node = ofdev->node; | ||
567 | struct usb_hcd *hcd; | ||
568 | struct fhci_hcd *fhci; | ||
569 | struct resource usb_regs; | ||
570 | unsigned long pram_addr; | ||
571 | unsigned int usb_irq; | ||
572 | const char *sprop; | ||
573 | const u32 *iprop; | ||
574 | int size; | ||
575 | int ret; | ||
576 | int i; | ||
577 | int j; | ||
578 | |||
579 | if (usb_disabled()) | ||
580 | return -ENODEV; | ||
581 | |||
582 | sprop = of_get_property(node, "mode", NULL); | ||
583 | if (sprop && strcmp(sprop, "host")) | ||
584 | return -ENODEV; | ||
585 | |||
586 | hcd = usb_create_hcd(&fhci_driver, dev, dev_name(dev)); | ||
587 | if (!hcd) { | ||
588 | dev_err(dev, "could not create hcd\n"); | ||
589 | return -ENOMEM; | ||
590 | } | ||
591 | |||
592 | fhci = hcd_to_fhci(hcd); | ||
593 | hcd->self.controller = dev; | ||
594 | dev_set_drvdata(dev, hcd); | ||
595 | |||
596 | iprop = of_get_property(node, "hub-power-budget", &size); | ||
597 | if (iprop && size == sizeof(*iprop)) | ||
598 | hcd->power_budget = *iprop; | ||
599 | |||
600 | /* FHCI registers. */ | ||
601 | ret = of_address_to_resource(node, 0, &usb_regs); | ||
602 | if (ret) { | ||
603 | dev_err(dev, "could not get regs\n"); | ||
604 | goto err_regs; | ||
605 | } | ||
606 | |||
607 | hcd->regs = ioremap(usb_regs.start, usb_regs.end - usb_regs.start + 1); | ||
608 | if (!hcd->regs) { | ||
609 | dev_err(dev, "could not ioremap regs\n"); | ||
610 | ret = -ENOMEM; | ||
611 | goto err_regs; | ||
612 | } | ||
613 | fhci->regs = hcd->regs; | ||
614 | |||
615 | /* Parameter RAM. */ | ||
616 | iprop = of_get_property(node, "reg", &size); | ||
617 | if (!iprop || size < sizeof(*iprop) * 4) { | ||
618 | dev_err(dev, "can't get pram offset\n"); | ||
619 | ret = -EINVAL; | ||
620 | goto err_pram; | ||
621 | } | ||
622 | |||
623 | pram_addr = cpm_muram_alloc_fixed(iprop[2], FHCI_PRAM_SIZE); | ||
624 | if (IS_ERR_VALUE(pram_addr)) { | ||
625 | dev_err(dev, "failed to allocate usb pram\n"); | ||
626 | ret = -ENOMEM; | ||
627 | goto err_pram; | ||
628 | } | ||
629 | fhci->pram = cpm_muram_addr(pram_addr); | ||
630 | |||
631 | /* GPIOs and pins */ | ||
632 | for (i = 0; i < NUM_GPIOS; i++) { | ||
633 | int gpio; | ||
634 | enum of_gpio_flags flags; | ||
635 | |||
636 | gpio = of_get_gpio_flags(node, i, &flags); | ||
637 | fhci->gpios[i] = gpio; | ||
638 | fhci->alow_gpios[i] = flags & OF_GPIO_ACTIVE_LOW; | ||
639 | |||
640 | if (!gpio_is_valid(gpio)) { | ||
641 | if (i < GPIO_SPEED) { | ||
642 | dev_err(dev, "incorrect GPIO%d: %d\n", | ||
643 | i, gpio); | ||
644 | goto err_gpios; | ||
645 | } else { | ||
646 | dev_info(dev, "assuming board doesn't have " | ||
647 | "%s gpio\n", i == GPIO_SPEED ? | ||
648 | "speed" : "power"); | ||
649 | continue; | ||
650 | } | ||
651 | } | ||
652 | |||
653 | ret = gpio_request(gpio, dev_name(dev)); | ||
654 | if (ret) { | ||
655 | dev_err(dev, "failed to request gpio %d", i); | ||
656 | goto err_gpios; | ||
657 | } | ||
658 | |||
659 | if (i >= GPIO_SPEED) { | ||
660 | ret = gpio_direction_output(gpio, 0); | ||
661 | if (ret) { | ||
662 | dev_err(dev, "failed to set gpio %d as " | ||
663 | "an output\n", i); | ||
664 | i++; | ||
665 | goto err_gpios; | ||
666 | } | ||
667 | } | ||
668 | } | ||
669 | |||
670 | for (j = 0; j < NUM_PINS; j++) { | ||
671 | fhci->pins[j] = qe_pin_request(ofdev->node, j); | ||
672 | if (IS_ERR(fhci->pins[j])) { | ||
673 | ret = PTR_ERR(fhci->pins[j]); | ||
674 | dev_err(dev, "can't get pin %d: %d\n", j, ret); | ||
675 | goto err_pins; | ||
676 | } | ||
677 | } | ||
678 | |||
679 | /* Frame limit timer and its interrupt. */ | ||
680 | fhci->timer = gtm_get_timer16(); | ||
681 | if (IS_ERR(fhci->timer)) { | ||
682 | ret = PTR_ERR(fhci->timer); | ||
683 | dev_err(dev, "failed to request qe timer: %i", ret); | ||
684 | goto err_get_timer; | ||
685 | } | ||
686 | |||
687 | ret = request_irq(fhci->timer->irq, fhci_frame_limit_timer_irq, | ||
688 | IRQF_DISABLED, "qe timer (usb)", hcd); | ||
689 | if (ret) { | ||
690 | dev_err(dev, "failed to request timer irq"); | ||
691 | goto err_timer_irq; | ||
692 | } | ||
693 | |||
694 | /* USB Host interrupt. */ | ||
695 | usb_irq = irq_of_parse_and_map(node, 0); | ||
696 | if (usb_irq == NO_IRQ) { | ||
697 | dev_err(dev, "could not get usb irq\n"); | ||
698 | ret = -EINVAL; | ||
699 | goto err_usb_irq; | ||
700 | } | ||
701 | |||
702 | /* Clocks. */ | ||
703 | sprop = of_get_property(node, "fsl,fullspeed-clock", NULL); | ||
704 | if (sprop) { | ||
705 | fhci->fullspeed_clk = qe_clock_source(sprop); | ||
706 | if (fhci->fullspeed_clk == QE_CLK_DUMMY) { | ||
707 | dev_err(dev, "wrong fullspeed-clock\n"); | ||
708 | ret = -EINVAL; | ||
709 | goto err_clocks; | ||
710 | } | ||
711 | } | ||
712 | |||
713 | sprop = of_get_property(node, "fsl,lowspeed-clock", NULL); | ||
714 | if (sprop) { | ||
715 | fhci->lowspeed_clk = qe_clock_source(sprop); | ||
716 | if (fhci->lowspeed_clk == QE_CLK_DUMMY) { | ||
717 | dev_err(dev, "wrong lowspeed-clock\n"); | ||
718 | ret = -EINVAL; | ||
719 | goto err_clocks; | ||
720 | } | ||
721 | } | ||
722 | |||
723 | if (fhci->fullspeed_clk == QE_CLK_NONE && | ||
724 | fhci->lowspeed_clk == QE_CLK_NONE) { | ||
725 | dev_err(dev, "no clocks specified\n"); | ||
726 | ret = -EINVAL; | ||
727 | goto err_clocks; | ||
728 | } | ||
729 | |||
730 | dev_info(dev, "at 0x%p, irq %d\n", hcd->regs, usb_irq); | ||
731 | |||
732 | fhci_config_transceiver(fhci, FHCI_PORT_POWER_OFF); | ||
733 | |||
734 | /* Start with full-speed, if possible. */ | ||
735 | if (fhci->fullspeed_clk != QE_CLK_NONE) { | ||
736 | fhci_config_transceiver(fhci, FHCI_PORT_FULL); | ||
737 | qe_usb_clock_set(fhci->fullspeed_clk, USB_CLOCK); | ||
738 | } else { | ||
739 | fhci_config_transceiver(fhci, FHCI_PORT_LOW); | ||
740 | qe_usb_clock_set(fhci->lowspeed_clk, USB_CLOCK >> 3); | ||
741 | } | ||
742 | |||
743 | /* Clear and disable any pending interrupts. */ | ||
744 | out_be16(&fhci->regs->usb_event, 0xffff); | ||
745 | out_be16(&fhci->regs->usb_mask, 0); | ||
746 | |||
747 | ret = usb_add_hcd(hcd, usb_irq, IRQF_DISABLED); | ||
748 | if (ret < 0) | ||
749 | goto err_add_hcd; | ||
750 | |||
751 | fhci_dfs_create(fhci); | ||
752 | |||
753 | return 0; | ||
754 | |||
755 | err_add_hcd: | ||
756 | err_clocks: | ||
757 | irq_dispose_mapping(usb_irq); | ||
758 | err_usb_irq: | ||
759 | free_irq(fhci->timer->irq, hcd); | ||
760 | err_timer_irq: | ||
761 | gtm_put_timer16(fhci->timer); | ||
762 | err_get_timer: | ||
763 | err_pins: | ||
764 | while (--j >= 0) | ||
765 | qe_pin_free(fhci->pins[j]); | ||
766 | err_gpios: | ||
767 | while (--i >= 0) { | ||
768 | if (gpio_is_valid(fhci->gpios[i])) | ||
769 | gpio_free(fhci->gpios[i]); | ||
770 | } | ||
771 | cpm_muram_free(pram_addr); | ||
772 | err_pram: | ||
773 | iounmap(hcd->regs); | ||
774 | err_regs: | ||
775 | usb_put_hcd(hcd); | ||
776 | return ret; | ||
777 | } | ||
778 | |||
779 | static int __devexit fhci_remove(struct device *dev) | ||
780 | { | ||
781 | struct usb_hcd *hcd = dev_get_drvdata(dev); | ||
782 | struct fhci_hcd *fhci = hcd_to_fhci(hcd); | ||
783 | int i; | ||
784 | int j; | ||
785 | |||
786 | usb_remove_hcd(hcd); | ||
787 | free_irq(fhci->timer->irq, hcd); | ||
788 | gtm_put_timer16(fhci->timer); | ||
789 | cpm_muram_free(cpm_muram_offset(fhci->pram)); | ||
790 | for (i = 0; i < NUM_GPIOS; i++) { | ||
791 | if (!gpio_is_valid(fhci->gpios[i])) | ||
792 | continue; | ||
793 | gpio_free(fhci->gpios[i]); | ||
794 | } | ||
795 | for (j = 0; j < NUM_PINS; j++) | ||
796 | qe_pin_free(fhci->pins[j]); | ||
797 | fhci_dfs_destroy(fhci); | ||
798 | usb_put_hcd(hcd); | ||
799 | return 0; | ||
800 | } | ||
801 | |||
802 | static int __devexit of_fhci_remove(struct of_device *ofdev) | ||
803 | { | ||
804 | return fhci_remove(&ofdev->dev); | ||
805 | } | ||
806 | |||
807 | static struct of_device_id of_fhci_match[] = { | ||
808 | { .compatible = "fsl,mpc8323-qe-usb", }, | ||
809 | {}, | ||
810 | }; | ||
811 | MODULE_DEVICE_TABLE(of, of_fhci_match); | ||
812 | |||
813 | static struct of_platform_driver of_fhci_driver = { | ||
814 | .name = "fsl,usb-fhci", | ||
815 | .match_table = of_fhci_match, | ||
816 | .probe = of_fhci_probe, | ||
817 | .remove = __devexit_p(of_fhci_remove), | ||
818 | }; | ||
819 | |||
820 | static int __init fhci_module_init(void) | ||
821 | { | ||
822 | return of_register_platform_driver(&of_fhci_driver); | ||
823 | } | ||
824 | module_init(fhci_module_init); | ||
825 | |||
826 | static void __exit fhci_module_exit(void) | ||
827 | { | ||
828 | of_unregister_platform_driver(&of_fhci_driver); | ||
829 | } | ||
830 | module_exit(fhci_module_exit); | ||
831 | |||
832 | MODULE_DESCRIPTION("USB Freescale Host Controller Interface Driver"); | ||
833 | MODULE_AUTHOR("Shlomi Gridish <gridish@freescale.com>, " | ||
834 | "Jerry Huang <Chang-Ming.Huang@freescale.com>, " | ||
835 | "Anton Vorontsov <avorontsov@ru.mvista.com>"); | ||
836 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/host/fhci-hub.c b/drivers/usb/host/fhci-hub.c new file mode 100644 index 000000000000..0cfaedc3e124 --- /dev/null +++ b/drivers/usb/host/fhci-hub.c | |||
@@ -0,0 +1,345 @@ | |||
1 | /* | ||
2 | * Freescale QUICC Engine USB Host Controller Driver | ||
3 | * | ||
4 | * Copyright (c) Freescale Semicondutor, Inc. 2006. | ||
5 | * Shlomi Gridish <gridish@freescale.com> | ||
6 | * Jerry Huang <Chang-Ming.Huang@freescale.com> | ||
7 | * Copyright (c) Logic Product Development, Inc. 2007 | ||
8 | * Peter Barada <peterb@logicpd.com> | ||
9 | * Copyright (c) MontaVista Software, Inc. 2008. | ||
10 | * Anton Vorontsov <avorontsov@ru.mvista.com> | ||
11 | * | ||
12 | * 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 | ||
14 | * Free Software Foundation; either version 2 of the License, or (at your | ||
15 | * option) any later version. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/types.h> | ||
20 | #include <linux/spinlock.h> | ||
21 | #include <linux/delay.h> | ||
22 | #include <linux/errno.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <linux/usb.h> | ||
25 | #include <linux/gpio.h> | ||
26 | #include <asm/qe.h> | ||
27 | #include "../core/hcd.h" | ||
28 | #include "fhci.h" | ||
29 | |||
30 | /* virtual root hub specific descriptor */ | ||
31 | static u8 root_hub_des[] = { | ||
32 | 0x09, /* blength */ | ||
33 | 0x29, /* bDescriptorType;hub-descriptor */ | ||
34 | 0x01, /* bNbrPorts */ | ||
35 | 0x00, /* wHubCharacteristics */ | ||
36 | 0x00, | ||
37 | 0x01, /* bPwrOn2pwrGood;2ms */ | ||
38 | 0x00, /* bHubContrCurrent;0mA */ | ||
39 | 0x00, /* DeviceRemoveable */ | ||
40 | 0xff, /* PortPwrCtrlMask */ | ||
41 | }; | ||
42 | |||
43 | static void fhci_gpio_set_value(struct fhci_hcd *fhci, int gpio_nr, bool on) | ||
44 | { | ||
45 | int gpio = fhci->gpios[gpio_nr]; | ||
46 | bool alow = fhci->alow_gpios[gpio_nr]; | ||
47 | |||
48 | if (!gpio_is_valid(gpio)) | ||
49 | return; | ||
50 | |||
51 | gpio_set_value(gpio, on ^ alow); | ||
52 | mdelay(5); | ||
53 | } | ||
54 | |||
55 | void fhci_config_transceiver(struct fhci_hcd *fhci, | ||
56 | enum fhci_port_status status) | ||
57 | { | ||
58 | fhci_dbg(fhci, "-> %s: %d\n", __func__, status); | ||
59 | |||
60 | switch (status) { | ||
61 | case FHCI_PORT_POWER_OFF: | ||
62 | fhci_gpio_set_value(fhci, GPIO_POWER, false); | ||
63 | break; | ||
64 | case FHCI_PORT_DISABLED: | ||
65 | case FHCI_PORT_WAITING: | ||
66 | fhci_gpio_set_value(fhci, GPIO_POWER, true); | ||
67 | break; | ||
68 | case FHCI_PORT_LOW: | ||
69 | fhci_gpio_set_value(fhci, GPIO_SPEED, false); | ||
70 | break; | ||
71 | case FHCI_PORT_FULL: | ||
72 | fhci_gpio_set_value(fhci, GPIO_SPEED, true); | ||
73 | break; | ||
74 | default: | ||
75 | WARN_ON(1); | ||
76 | break; | ||
77 | } | ||
78 | |||
79 | fhci_dbg(fhci, "<- %s: %d\n", __func__, status); | ||
80 | } | ||
81 | |||
82 | /* disable the USB port by clearing the EN bit in the USBMOD register */ | ||
83 | void fhci_port_disable(struct fhci_hcd *fhci) | ||
84 | { | ||
85 | struct fhci_usb *usb = (struct fhci_usb *)fhci->usb_lld; | ||
86 | enum fhci_port_status port_status; | ||
87 | |||
88 | fhci_dbg(fhci, "-> %s\n", __func__); | ||
89 | |||
90 | fhci_stop_sof_timer(fhci); | ||
91 | |||
92 | fhci_flush_all_transmissions(usb); | ||
93 | |||
94 | fhci_usb_disable_interrupt((struct fhci_usb *)fhci->usb_lld); | ||
95 | port_status = usb->port_status; | ||
96 | usb->port_status = FHCI_PORT_DISABLED; | ||
97 | |||
98 | /* Enable IDLE since we want to know if something comes along */ | ||
99 | usb->saved_msk |= USB_E_IDLE_MASK; | ||
100 | out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk); | ||
101 | |||
102 | /* check if during the disconnection process attached new device */ | ||
103 | if (port_status == FHCI_PORT_WAITING) | ||
104 | fhci_device_connected_interrupt(fhci); | ||
105 | usb->vroot_hub->port.wPortStatus &= ~USB_PORT_STAT_ENABLE; | ||
106 | usb->vroot_hub->port.wPortChange |= USB_PORT_STAT_C_ENABLE; | ||
107 | fhci_usb_enable_interrupt((struct fhci_usb *)fhci->usb_lld); | ||
108 | |||
109 | fhci_dbg(fhci, "<- %s\n", __func__); | ||
110 | } | ||
111 | |||
112 | /* enable the USB port by setting the EN bit in the USBMOD register */ | ||
113 | void fhci_port_enable(void *lld) | ||
114 | { | ||
115 | struct fhci_usb *usb = (struct fhci_usb *)lld; | ||
116 | struct fhci_hcd *fhci = usb->fhci; | ||
117 | |||
118 | fhci_dbg(fhci, "-> %s\n", __func__); | ||
119 | |||
120 | fhci_config_transceiver(fhci, usb->port_status); | ||
121 | |||
122 | if ((usb->port_status != FHCI_PORT_FULL) && | ||
123 | (usb->port_status != FHCI_PORT_LOW)) | ||
124 | fhci_start_sof_timer(fhci); | ||
125 | |||
126 | usb->vroot_hub->port.wPortStatus |= USB_PORT_STAT_ENABLE; | ||
127 | usb->vroot_hub->port.wPortChange |= USB_PORT_STAT_C_ENABLE; | ||
128 | |||
129 | fhci_dbg(fhci, "<- %s\n", __func__); | ||
130 | } | ||
131 | |||
132 | void fhci_io_port_generate_reset(struct fhci_hcd *fhci) | ||
133 | { | ||
134 | fhci_dbg(fhci, "-> %s\n", __func__); | ||
135 | |||
136 | gpio_direction_output(fhci->gpios[GPIO_USBOE], 0); | ||
137 | gpio_direction_output(fhci->gpios[GPIO_USBTP], 0); | ||
138 | gpio_direction_output(fhci->gpios[GPIO_USBTN], 0); | ||
139 | |||
140 | mdelay(5); | ||
141 | |||
142 | qe_pin_set_dedicated(fhci->pins[PIN_USBOE]); | ||
143 | qe_pin_set_dedicated(fhci->pins[PIN_USBTP]); | ||
144 | qe_pin_set_dedicated(fhci->pins[PIN_USBTN]); | ||
145 | |||
146 | fhci_dbg(fhci, "<- %s\n", __func__); | ||
147 | } | ||
148 | |||
149 | /* generate the RESET condition on the bus */ | ||
150 | void fhci_port_reset(void *lld) | ||
151 | { | ||
152 | struct fhci_usb *usb = (struct fhci_usb *)lld; | ||
153 | struct fhci_hcd *fhci = usb->fhci; | ||
154 | u8 mode; | ||
155 | u16 mask; | ||
156 | |||
157 | fhci_dbg(fhci, "-> %s\n", __func__); | ||
158 | |||
159 | fhci_stop_sof_timer(fhci); | ||
160 | /* disable the USB controller */ | ||
161 | mode = in_8(&fhci->regs->usb_mod); | ||
162 | out_8(&fhci->regs->usb_mod, mode & (~USB_MODE_EN)); | ||
163 | |||
164 | /* disable idle interrupts */ | ||
165 | mask = in_be16(&fhci->regs->usb_mask); | ||
166 | out_be16(&fhci->regs->usb_mask, mask & (~USB_E_IDLE_MASK)); | ||
167 | |||
168 | fhci_io_port_generate_reset(fhci); | ||
169 | |||
170 | /* enable interrupt on this endpoint */ | ||
171 | out_be16(&fhci->regs->usb_mask, mask); | ||
172 | |||
173 | /* enable the USB controller */ | ||
174 | mode = in_8(&fhci->regs->usb_mod); | ||
175 | out_8(&fhci->regs->usb_mod, mode | USB_MODE_EN); | ||
176 | fhci_start_sof_timer(fhci); | ||
177 | |||
178 | fhci_dbg(fhci, "<- %s\n", __func__); | ||
179 | } | ||
180 | |||
181 | int fhci_hub_status_data(struct usb_hcd *hcd, char *buf) | ||
182 | { | ||
183 | struct fhci_hcd *fhci = hcd_to_fhci(hcd); | ||
184 | int ret = 0; | ||
185 | unsigned long flags; | ||
186 | |||
187 | fhci_dbg(fhci, "-> %s\n", __func__); | ||
188 | |||
189 | spin_lock_irqsave(&fhci->lock, flags); | ||
190 | |||
191 | if (fhci->vroot_hub->port.wPortChange & (USB_PORT_STAT_C_CONNECTION | | ||
192 | USB_PORT_STAT_C_ENABLE | USB_PORT_STAT_C_SUSPEND | | ||
193 | USB_PORT_STAT_C_RESET | USB_PORT_STAT_C_OVERCURRENT)) { | ||
194 | *buf = 1 << 1; | ||
195 | ret = 1; | ||
196 | fhci_dbg(fhci, "-- %s\n", __func__); | ||
197 | } | ||
198 | |||
199 | spin_unlock_irqrestore(&fhci->lock, flags); | ||
200 | |||
201 | fhci_dbg(fhci, "<- %s\n", __func__); | ||
202 | |||
203 | return ret; | ||
204 | } | ||
205 | |||
206 | int fhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | ||
207 | u16 wIndex, char *buf, u16 wLength) | ||
208 | { | ||
209 | struct fhci_hcd *fhci = hcd_to_fhci(hcd); | ||
210 | int retval = 0; | ||
211 | int len = 0; | ||
212 | struct usb_hub_status *hub_status; | ||
213 | struct usb_port_status *port_status; | ||
214 | unsigned long flags; | ||
215 | |||
216 | spin_lock_irqsave(&fhci->lock, flags); | ||
217 | |||
218 | fhci_dbg(fhci, "-> %s\n", __func__); | ||
219 | |||
220 | switch (typeReq) { | ||
221 | case ClearHubFeature: | ||
222 | switch (wValue) { | ||
223 | case C_HUB_LOCAL_POWER: | ||
224 | case C_HUB_OVER_CURRENT: | ||
225 | break; | ||
226 | default: | ||
227 | goto error; | ||
228 | } | ||
229 | break; | ||
230 | case ClearPortFeature: | ||
231 | fhci->vroot_hub->feature &= (1 << wValue); | ||
232 | |||
233 | switch (wValue) { | ||
234 | case USB_PORT_FEAT_ENABLE: | ||
235 | fhci->vroot_hub->port.wPortStatus &= | ||
236 | ~USB_PORT_STAT_ENABLE; | ||
237 | fhci_port_disable(fhci); | ||
238 | break; | ||
239 | case USB_PORT_FEAT_C_ENABLE: | ||
240 | fhci->vroot_hub->port.wPortChange &= | ||
241 | ~USB_PORT_STAT_C_ENABLE; | ||
242 | break; | ||
243 | case USB_PORT_FEAT_SUSPEND: | ||
244 | fhci->vroot_hub->port.wPortStatus &= | ||
245 | ~USB_PORT_STAT_SUSPEND; | ||
246 | fhci_stop_sof_timer(fhci); | ||
247 | break; | ||
248 | case USB_PORT_FEAT_C_SUSPEND: | ||
249 | fhci->vroot_hub->port.wPortChange &= | ||
250 | ~USB_PORT_STAT_C_SUSPEND; | ||
251 | break; | ||
252 | case USB_PORT_FEAT_POWER: | ||
253 | fhci->vroot_hub->port.wPortStatus &= | ||
254 | ~USB_PORT_STAT_POWER; | ||
255 | fhci_config_transceiver(fhci, FHCI_PORT_POWER_OFF); | ||
256 | break; | ||
257 | case USB_PORT_FEAT_C_CONNECTION: | ||
258 | fhci->vroot_hub->port.wPortChange &= | ||
259 | ~USB_PORT_STAT_C_CONNECTION; | ||
260 | break; | ||
261 | case USB_PORT_FEAT_C_OVER_CURRENT: | ||
262 | fhci->vroot_hub->port.wPortChange &= | ||
263 | ~USB_PORT_STAT_C_OVERCURRENT; | ||
264 | break; | ||
265 | case USB_PORT_FEAT_C_RESET: | ||
266 | fhci->vroot_hub->port.wPortChange &= | ||
267 | ~USB_PORT_STAT_C_RESET; | ||
268 | break; | ||
269 | default: | ||
270 | goto error; | ||
271 | } | ||
272 | break; | ||
273 | case GetHubDescriptor: | ||
274 | memcpy(buf, root_hub_des, sizeof(root_hub_des)); | ||
275 | buf[3] = 0x11; /* per-port power, no ovrcrnt */ | ||
276 | len = (buf[0] < wLength) ? buf[0] : wLength; | ||
277 | break; | ||
278 | case GetHubStatus: | ||
279 | hub_status = (struct usb_hub_status *)buf; | ||
280 | hub_status->wHubStatus = | ||
281 | cpu_to_le16(fhci->vroot_hub->hub.wHubStatus); | ||
282 | hub_status->wHubChange = | ||
283 | cpu_to_le16(fhci->vroot_hub->hub.wHubChange); | ||
284 | len = 4; | ||
285 | break; | ||
286 | case GetPortStatus: | ||
287 | port_status = (struct usb_port_status *)buf; | ||
288 | port_status->wPortStatus = | ||
289 | cpu_to_le16(fhci->vroot_hub->port.wPortStatus); | ||
290 | port_status->wPortChange = | ||
291 | cpu_to_le16(fhci->vroot_hub->port.wPortChange); | ||
292 | len = 4; | ||
293 | break; | ||
294 | case SetHubFeature: | ||
295 | switch (wValue) { | ||
296 | case C_HUB_OVER_CURRENT: | ||
297 | case C_HUB_LOCAL_POWER: | ||
298 | break; | ||
299 | default: | ||
300 | goto error; | ||
301 | } | ||
302 | break; | ||
303 | case SetPortFeature: | ||
304 | fhci->vroot_hub->feature |= (1 << wValue); | ||
305 | |||
306 | switch (wValue) { | ||
307 | case USB_PORT_FEAT_ENABLE: | ||
308 | fhci->vroot_hub->port.wPortStatus |= | ||
309 | USB_PORT_STAT_ENABLE; | ||
310 | fhci_port_enable(fhci->usb_lld); | ||
311 | break; | ||
312 | case USB_PORT_FEAT_SUSPEND: | ||
313 | fhci->vroot_hub->port.wPortStatus |= | ||
314 | USB_PORT_STAT_SUSPEND; | ||
315 | fhci_stop_sof_timer(fhci); | ||
316 | break; | ||
317 | case USB_PORT_FEAT_RESET: | ||
318 | fhci->vroot_hub->port.wPortStatus |= | ||
319 | USB_PORT_STAT_RESET; | ||
320 | fhci_port_reset(fhci->usb_lld); | ||
321 | fhci->vroot_hub->port.wPortStatus |= | ||
322 | USB_PORT_STAT_ENABLE; | ||
323 | fhci->vroot_hub->port.wPortStatus &= | ||
324 | ~USB_PORT_STAT_RESET; | ||
325 | break; | ||
326 | case USB_PORT_FEAT_POWER: | ||
327 | fhci->vroot_hub->port.wPortStatus |= | ||
328 | USB_PORT_STAT_POWER; | ||
329 | fhci_config_transceiver(fhci, FHCI_PORT_WAITING); | ||
330 | break; | ||
331 | default: | ||
332 | goto error; | ||
333 | } | ||
334 | break; | ||
335 | default: | ||
336 | error: | ||
337 | retval = -EPIPE; | ||
338 | } | ||
339 | |||
340 | fhci_dbg(fhci, "<- %s\n", __func__); | ||
341 | |||
342 | spin_unlock_irqrestore(&fhci->lock, flags); | ||
343 | |||
344 | return retval; | ||
345 | } | ||
diff --git a/drivers/usb/host/fhci-mem.c b/drivers/usb/host/fhci-mem.c new file mode 100644 index 000000000000..2c0736c99712 --- /dev/null +++ b/drivers/usb/host/fhci-mem.c | |||
@@ -0,0 +1,113 @@ | |||
1 | /* | ||
2 | * Freescale QUICC Engine USB Host Controller Driver | ||
3 | * | ||
4 | * Copyright (c) Freescale Semicondutor, Inc. 2006. | ||
5 | * Shlomi Gridish <gridish@freescale.com> | ||
6 | * Jerry Huang <Chang-Ming.Huang@freescale.com> | ||
7 | * Copyright (c) Logic Product Development, Inc. 2007 | ||
8 | * Peter Barada <peterb@logicpd.com> | ||
9 | * Copyright (c) MontaVista Software, Inc. 2008. | ||
10 | * Anton Vorontsov <avorontsov@ru.mvista.com> | ||
11 | * | ||
12 | * 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 | ||
14 | * Free Software Foundation; either version 2 of the License, or (at your | ||
15 | * option) any later version. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/types.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/list.h> | ||
22 | #include <linux/usb.h> | ||
23 | #include "../core/hcd.h" | ||
24 | #include "fhci.h" | ||
25 | |||
26 | static void init_td(struct td *td) | ||
27 | { | ||
28 | memset(td, 0, sizeof(*td)); | ||
29 | INIT_LIST_HEAD(&td->node); | ||
30 | INIT_LIST_HEAD(&td->frame_lh); | ||
31 | } | ||
32 | |||
33 | static void init_ed(struct ed *ed) | ||
34 | { | ||
35 | memset(ed, 0, sizeof(*ed)); | ||
36 | INIT_LIST_HEAD(&ed->td_list); | ||
37 | INIT_LIST_HEAD(&ed->node); | ||
38 | } | ||
39 | |||
40 | static struct td *get_empty_td(struct fhci_hcd *fhci) | ||
41 | { | ||
42 | struct td *td; | ||
43 | |||
44 | if (!list_empty(&fhci->empty_tds)) { | ||
45 | td = list_entry(fhci->empty_tds.next, struct td, node); | ||
46 | list_del(fhci->empty_tds.next); | ||
47 | } else { | ||
48 | td = kmalloc(sizeof(*td), GFP_ATOMIC); | ||
49 | if (!td) | ||
50 | fhci_err(fhci, "No memory to allocate to TD\n"); | ||
51 | else | ||
52 | init_td(td); | ||
53 | } | ||
54 | |||
55 | return td; | ||
56 | } | ||
57 | |||
58 | void fhci_recycle_empty_td(struct fhci_hcd *fhci, struct td *td) | ||
59 | { | ||
60 | init_td(td); | ||
61 | list_add(&td->node, &fhci->empty_tds); | ||
62 | } | ||
63 | |||
64 | struct ed *fhci_get_empty_ed(struct fhci_hcd *fhci) | ||
65 | { | ||
66 | struct ed *ed; | ||
67 | |||
68 | if (!list_empty(&fhci->empty_eds)) { | ||
69 | ed = list_entry(fhci->empty_eds.next, struct ed, node); | ||
70 | list_del(fhci->empty_eds.next); | ||
71 | } else { | ||
72 | ed = kmalloc(sizeof(*ed), GFP_ATOMIC); | ||
73 | if (!ed) | ||
74 | fhci_err(fhci, "No memory to allocate to ED\n"); | ||
75 | else | ||
76 | init_ed(ed); | ||
77 | } | ||
78 | |||
79 | return ed; | ||
80 | } | ||
81 | |||
82 | void fhci_recycle_empty_ed(struct fhci_hcd *fhci, struct ed *ed) | ||
83 | { | ||
84 | init_ed(ed); | ||
85 | list_add(&ed->node, &fhci->empty_eds); | ||
86 | } | ||
87 | |||
88 | struct td *fhci_td_fill(struct fhci_hcd *fhci, struct urb *urb, | ||
89 | struct urb_priv *urb_priv, struct ed *ed, u16 index, | ||
90 | enum fhci_ta_type type, int toggle, u8 *data, u32 len, | ||
91 | u16 interval, u16 start_frame, bool ioc) | ||
92 | { | ||
93 | struct td *td = get_empty_td(fhci); | ||
94 | |||
95 | if (!td) | ||
96 | return NULL; | ||
97 | |||
98 | td->urb = urb; | ||
99 | td->ed = ed; | ||
100 | td->type = type; | ||
101 | td->toggle = toggle; | ||
102 | td->data = data; | ||
103 | td->len = len; | ||
104 | td->iso_index = index; | ||
105 | td->interval = interval; | ||
106 | td->start_frame = start_frame; | ||
107 | td->ioc = ioc; | ||
108 | td->status = USB_TD_OK; | ||
109 | |||
110 | urb_priv->tds[index] = td; | ||
111 | |||
112 | return td; | ||
113 | } | ||
diff --git a/drivers/usb/host/fhci-q.c b/drivers/usb/host/fhci-q.c new file mode 100644 index 000000000000..b0a1446ba292 --- /dev/null +++ b/drivers/usb/host/fhci-q.c | |||
@@ -0,0 +1,284 @@ | |||
1 | /* | ||
2 | * Freescale QUICC Engine USB Host Controller Driver | ||
3 | * | ||
4 | * Copyright (c) Freescale Semicondutor, Inc. 2006. | ||
5 | * Shlomi Gridish <gridish@freescale.com> | ||
6 | * Jerry Huang <Chang-Ming.Huang@freescale.com> | ||
7 | * Copyright (c) Logic Product Development, Inc. 2007 | ||
8 | * Peter Barada <peterb@logicpd.com> | ||
9 | * Copyright (c) MontaVista Software, Inc. 2008. | ||
10 | * Anton Vorontsov <avorontsov@ru.mvista.com> | ||
11 | * | ||
12 | * 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 | ||
14 | * Free Software Foundation; either version 2 of the License, or (at your | ||
15 | * option) any later version. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/types.h> | ||
20 | #include <linux/spinlock.h> | ||
21 | #include <linux/errno.h> | ||
22 | #include <linux/list.h> | ||
23 | #include <linux/usb.h> | ||
24 | #include "../core/hcd.h" | ||
25 | #include "fhci.h" | ||
26 | |||
27 | /* maps the hardware error code to the USB error code */ | ||
28 | static int status_to_error(u32 status) | ||
29 | { | ||
30 | if (status == USB_TD_OK) | ||
31 | return 0; | ||
32 | else if (status & USB_TD_RX_ER_CRC) | ||
33 | return -EILSEQ; | ||
34 | else if (status & USB_TD_RX_ER_NONOCT) | ||
35 | return -EPROTO; | ||
36 | else if (status & USB_TD_RX_ER_OVERUN) | ||
37 | return -ECOMM; | ||
38 | else if (status & USB_TD_RX_ER_BITSTUFF) | ||
39 | return -EPROTO; | ||
40 | else if (status & USB_TD_RX_ER_PID) | ||
41 | return -EILSEQ; | ||
42 | else if (status & (USB_TD_TX_ER_NAK | USB_TD_TX_ER_TIMEOUT)) | ||
43 | return -ETIMEDOUT; | ||
44 | else if (status & USB_TD_TX_ER_STALL) | ||
45 | return -EPIPE; | ||
46 | else if (status & USB_TD_TX_ER_UNDERUN) | ||
47 | return -ENOSR; | ||
48 | else if (status & USB_TD_RX_DATA_UNDERUN) | ||
49 | return -EREMOTEIO; | ||
50 | else if (status & USB_TD_RX_DATA_OVERUN) | ||
51 | return -EOVERFLOW; | ||
52 | else | ||
53 | return -EINVAL; | ||
54 | } | ||
55 | |||
56 | void fhci_add_td_to_frame(struct fhci_time_frame *frame, struct td *td) | ||
57 | { | ||
58 | list_add_tail(&td->frame_lh, &frame->tds_list); | ||
59 | } | ||
60 | |||
61 | void fhci_add_tds_to_ed(struct ed *ed, struct td **td_list, int number) | ||
62 | { | ||
63 | int i; | ||
64 | |||
65 | for (i = 0; i < number; i++) { | ||
66 | struct td *td = td_list[i]; | ||
67 | list_add_tail(&td->node, &ed->td_list); | ||
68 | } | ||
69 | if (ed->td_head == NULL) | ||
70 | ed->td_head = td_list[0]; | ||
71 | } | ||
72 | |||
73 | static struct td *peek_td_from_ed(struct ed *ed) | ||
74 | { | ||
75 | struct td *td; | ||
76 | |||
77 | if (!list_empty(&ed->td_list)) | ||
78 | td = list_entry(ed->td_list.next, struct td, node); | ||
79 | else | ||
80 | td = NULL; | ||
81 | |||
82 | return td; | ||
83 | } | ||
84 | |||
85 | struct td *fhci_remove_td_from_frame(struct fhci_time_frame *frame) | ||
86 | { | ||
87 | struct td *td; | ||
88 | |||
89 | if (!list_empty(&frame->tds_list)) { | ||
90 | td = list_entry(frame->tds_list.next, struct td, frame_lh); | ||
91 | list_del_init(frame->tds_list.next); | ||
92 | } else | ||
93 | td = NULL; | ||
94 | |||
95 | return td; | ||
96 | } | ||
97 | |||
98 | struct td *fhci_peek_td_from_frame(struct fhci_time_frame *frame) | ||
99 | { | ||
100 | struct td *td; | ||
101 | |||
102 | if (!list_empty(&frame->tds_list)) | ||
103 | td = list_entry(frame->tds_list.next, struct td, frame_lh); | ||
104 | else | ||
105 | td = NULL; | ||
106 | |||
107 | return td; | ||
108 | } | ||
109 | |||
110 | struct td *fhci_remove_td_from_ed(struct ed *ed) | ||
111 | { | ||
112 | struct td *td; | ||
113 | |||
114 | if (!list_empty(&ed->td_list)) { | ||
115 | td = list_entry(ed->td_list.next, struct td, node); | ||
116 | list_del_init(ed->td_list.next); | ||
117 | |||
118 | /* if this TD was the ED's head, find next TD */ | ||
119 | if (!list_empty(&ed->td_list)) | ||
120 | ed->td_head = list_entry(ed->td_list.next, struct td, | ||
121 | node); | ||
122 | else | ||
123 | ed->td_head = NULL; | ||
124 | } else | ||
125 | td = NULL; | ||
126 | |||
127 | return td; | ||
128 | } | ||
129 | |||
130 | struct td *fhci_remove_td_from_done_list(struct fhci_controller_list *p_list) | ||
131 | { | ||
132 | struct td *td; | ||
133 | |||
134 | if (!list_empty(&p_list->done_list)) { | ||
135 | td = list_entry(p_list->done_list.next, struct td, node); | ||
136 | list_del_init(p_list->done_list.next); | ||
137 | } else | ||
138 | td = NULL; | ||
139 | |||
140 | return td; | ||
141 | } | ||
142 | |||
143 | void fhci_move_td_from_ed_to_done_list(struct fhci_usb *usb, struct ed *ed) | ||
144 | { | ||
145 | struct td *td; | ||
146 | |||
147 | td = ed->td_head; | ||
148 | list_del_init(&td->node); | ||
149 | |||
150 | /* If this TD was the ED's head,find next TD */ | ||
151 | if (!list_empty(&ed->td_list)) | ||
152 | ed->td_head = list_entry(ed->td_list.next, struct td, node); | ||
153 | else { | ||
154 | ed->td_head = NULL; | ||
155 | ed->state = FHCI_ED_SKIP; | ||
156 | } | ||
157 | ed->toggle_carry = td->toggle; | ||
158 | list_add_tail(&td->node, &usb->hc_list->done_list); | ||
159 | if (td->ioc) | ||
160 | usb->transfer_confirm(usb->fhci); | ||
161 | } | ||
162 | |||
163 | /* free done FHCI URB resource such as ED and TD */ | ||
164 | static void free_urb_priv(struct fhci_hcd *fhci, struct urb *urb) | ||
165 | { | ||
166 | int i; | ||
167 | struct urb_priv *urb_priv = urb->hcpriv; | ||
168 | struct ed *ed = urb_priv->ed; | ||
169 | |||
170 | for (i = 0; i < urb_priv->num_of_tds; i++) { | ||
171 | list_del_init(&urb_priv->tds[i]->node); | ||
172 | fhci_recycle_empty_td(fhci, urb_priv->tds[i]); | ||
173 | } | ||
174 | |||
175 | /* if this TD was the ED's head,find the next TD */ | ||
176 | if (!list_empty(&ed->td_list)) | ||
177 | ed->td_head = list_entry(ed->td_list.next, struct td, node); | ||
178 | else | ||
179 | ed->td_head = NULL; | ||
180 | |||
181 | kfree(urb_priv->tds); | ||
182 | kfree(urb_priv); | ||
183 | urb->hcpriv = NULL; | ||
184 | |||
185 | /* if this TD was the ED's head,find next TD */ | ||
186 | if (ed->td_head == NULL) | ||
187 | list_del_init(&ed->node); | ||
188 | fhci->active_urbs--; | ||
189 | } | ||
190 | |||
191 | /* this routine called to complete and free done URB */ | ||
192 | void fhci_urb_complete_free(struct fhci_hcd *fhci, struct urb *urb) | ||
193 | { | ||
194 | free_urb_priv(fhci, urb); | ||
195 | |||
196 | if (urb->status == -EINPROGRESS) { | ||
197 | if (urb->actual_length != urb->transfer_buffer_length && | ||
198 | urb->transfer_flags & URB_SHORT_NOT_OK) | ||
199 | urb->status = -EREMOTEIO; | ||
200 | else | ||
201 | urb->status = 0; | ||
202 | } | ||
203 | |||
204 | usb_hcd_unlink_urb_from_ep(fhci_to_hcd(fhci), urb); | ||
205 | |||
206 | spin_unlock(&fhci->lock); | ||
207 | |||
208 | usb_hcd_giveback_urb(fhci_to_hcd(fhci), urb, urb->status); | ||
209 | |||
210 | spin_lock(&fhci->lock); | ||
211 | } | ||
212 | |||
213 | /* | ||
214 | * caculate transfer length/stats and update the urb | ||
215 | * Precondition: irqsafe(only for urb-?status locking) | ||
216 | */ | ||
217 | void fhci_done_td(struct urb *urb, struct td *td) | ||
218 | { | ||
219 | struct ed *ed = td->ed; | ||
220 | u32 cc = td->status; | ||
221 | |||
222 | /* ISO...drivers see per-TD length/status */ | ||
223 | if (ed->mode == FHCI_TF_ISO) { | ||
224 | u32 len; | ||
225 | if (!(urb->transfer_flags & URB_SHORT_NOT_OK && | ||
226 | cc == USB_TD_RX_DATA_UNDERUN)) | ||
227 | cc = USB_TD_OK; | ||
228 | |||
229 | if (usb_pipeout(urb->pipe)) | ||
230 | len = urb->iso_frame_desc[td->iso_index].length; | ||
231 | else | ||
232 | len = td->actual_len; | ||
233 | |||
234 | urb->actual_length += len; | ||
235 | urb->iso_frame_desc[td->iso_index].actual_length = len; | ||
236 | urb->iso_frame_desc[td->iso_index].status = | ||
237 | status_to_error(cc); | ||
238 | } | ||
239 | |||
240 | /* BULK,INT,CONTROL... drivers see aggregate length/status, | ||
241 | * except that "setup" bytes aren't counted and "short" transfers | ||
242 | * might not be reported as errors. | ||
243 | */ | ||
244 | else { | ||
245 | if (td->error_cnt >= 3) | ||
246 | urb->error_count = 3; | ||
247 | |||
248 | /* control endpoint only have soft stalls */ | ||
249 | |||
250 | /* update packet status if needed(short may be ok) */ | ||
251 | if (!(urb->transfer_flags & URB_SHORT_NOT_OK) && | ||
252 | cc == USB_TD_RX_DATA_UNDERUN) { | ||
253 | ed->state = FHCI_ED_OPER; | ||
254 | cc = USB_TD_OK; | ||
255 | } | ||
256 | if (cc != USB_TD_OK) { | ||
257 | if (urb->status == -EINPROGRESS) | ||
258 | urb->status = status_to_error(cc); | ||
259 | } | ||
260 | |||
261 | /* count all non-empty packets except control SETUP packet */ | ||
262 | if (td->type != FHCI_TA_SETUP || td->iso_index != 0) | ||
263 | urb->actual_length += td->actual_len; | ||
264 | } | ||
265 | } | ||
266 | |||
267 | /* there are some pedning request to unlink */ | ||
268 | void fhci_del_ed_list(struct fhci_hcd *fhci, struct ed *ed) | ||
269 | { | ||
270 | struct td *td = peek_td_from_ed(ed); | ||
271 | struct urb *urb = td->urb; | ||
272 | struct urb_priv *urb_priv = urb->hcpriv; | ||
273 | |||
274 | if (urb_priv->state == URB_DEL) { | ||
275 | td = fhci_remove_td_from_ed(ed); | ||
276 | /* HC may have partly processed this TD */ | ||
277 | if (td->status != USB_TD_INPROGRESS) | ||
278 | fhci_done_td(urb, td); | ||
279 | |||
280 | /* URB is done;clean up */ | ||
281 | if (++(urb_priv->tds_cnt) == urb_priv->num_of_tds) | ||
282 | fhci_urb_complete_free(fhci, urb); | ||
283 | } | ||
284 | } | ||
diff --git a/drivers/usb/host/fhci-sched.c b/drivers/usb/host/fhci-sched.c new file mode 100644 index 000000000000..bb63b68ddb77 --- /dev/null +++ b/drivers/usb/host/fhci-sched.c | |||
@@ -0,0 +1,888 @@ | |||
1 | /* | ||
2 | * Freescale QUICC Engine USB Host Controller Driver | ||
3 | * | ||
4 | * Copyright (c) Freescale Semicondutor, Inc. 2006. | ||
5 | * Shlomi Gridish <gridish@freescale.com> | ||
6 | * Jerry Huang <Chang-Ming.Huang@freescale.com> | ||
7 | * Copyright (c) Logic Product Development, Inc. 2007 | ||
8 | * Peter Barada <peterb@logicpd.com> | ||
9 | * Copyright (c) MontaVista Software, Inc. 2008. | ||
10 | * Anton Vorontsov <avorontsov@ru.mvista.com> | ||
11 | * | ||
12 | * 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 | ||
14 | * Free Software Foundation; either version 2 of the License, or (at your | ||
15 | * option) any later version. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/types.h> | ||
20 | #include <linux/spinlock.h> | ||
21 | #include <linux/delay.h> | ||
22 | #include <linux/errno.h> | ||
23 | #include <linux/list.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/io.h> | ||
26 | #include <linux/usb.h> | ||
27 | #include <asm/qe.h> | ||
28 | #include <asm/fsl_gtm.h> | ||
29 | #include "../core/hcd.h" | ||
30 | #include "fhci.h" | ||
31 | |||
32 | static void recycle_frame(struct fhci_usb *usb, struct packet *pkt) | ||
33 | { | ||
34 | pkt->data = NULL; | ||
35 | pkt->len = 0; | ||
36 | pkt->status = USB_TD_OK; | ||
37 | pkt->info = 0; | ||
38 | pkt->priv_data = NULL; | ||
39 | |||
40 | cq_put(usb->ep0->empty_frame_Q, pkt); | ||
41 | } | ||
42 | |||
43 | /* confirm submitted packet */ | ||
44 | void fhci_transaction_confirm(struct fhci_usb *usb, struct packet *pkt) | ||
45 | { | ||
46 | struct td *td; | ||
47 | struct packet *td_pkt; | ||
48 | struct ed *ed; | ||
49 | u32 trans_len; | ||
50 | bool td_done = false; | ||
51 | |||
52 | td = fhci_remove_td_from_frame(usb->actual_frame); | ||
53 | td_pkt = td->pkt; | ||
54 | trans_len = pkt->len; | ||
55 | td->status = pkt->status; | ||
56 | if (td->type == FHCI_TA_IN && td_pkt->info & PKT_DUMMY_PACKET) { | ||
57 | if ((td->data + td->actual_len) && trans_len) | ||
58 | memcpy(td->data + td->actual_len, pkt->data, | ||
59 | trans_len); | ||
60 | cq_put(usb->ep0->dummy_packets_Q, pkt->data); | ||
61 | } | ||
62 | |||
63 | recycle_frame(usb, pkt); | ||
64 | |||
65 | ed = td->ed; | ||
66 | if (ed->mode == FHCI_TF_ISO) { | ||
67 | if (ed->td_list.next->next != &ed->td_list) { | ||
68 | struct td *td_next = | ||
69 | list_entry(ed->td_list.next->next, struct td, | ||
70 | node); | ||
71 | |||
72 | td_next->start_frame = usb->actual_frame->frame_num; | ||
73 | } | ||
74 | td->actual_len = trans_len; | ||
75 | td_done = true; | ||
76 | } else if ((td->status & USB_TD_ERROR) && | ||
77 | !(td->status & USB_TD_TX_ER_NAK)) { | ||
78 | /* | ||
79 | * There was an error on the transaction (but not NAK). | ||
80 | * If it is fatal error (data underrun, stall, bad pid or 3 | ||
81 | * errors exceeded), mark this TD as done. | ||
82 | */ | ||
83 | if ((td->status & USB_TD_RX_DATA_UNDERUN) || | ||
84 | (td->status & USB_TD_TX_ER_STALL) || | ||
85 | (td->status & USB_TD_RX_ER_PID) || | ||
86 | (++td->error_cnt >= 3)) { | ||
87 | ed->state = FHCI_ED_HALTED; | ||
88 | td_done = true; | ||
89 | |||
90 | if (td->status & USB_TD_RX_DATA_UNDERUN) { | ||
91 | fhci_dbg(usb->fhci, "td err fu\n"); | ||
92 | td->toggle = !td->toggle; | ||
93 | td->actual_len += trans_len; | ||
94 | } else { | ||
95 | fhci_dbg(usb->fhci, "td err f!u\n"); | ||
96 | } | ||
97 | } else { | ||
98 | fhci_dbg(usb->fhci, "td err !f\n"); | ||
99 | /* it is not a fatal error -retry this transaction */ | ||
100 | td->nak_cnt = 0; | ||
101 | td->error_cnt++; | ||
102 | td->status = USB_TD_OK; | ||
103 | } | ||
104 | } else if (td->status & USB_TD_TX_ER_NAK) { | ||
105 | /* there was a NAK response */ | ||
106 | fhci_vdbg(usb->fhci, "td nack\n"); | ||
107 | td->nak_cnt++; | ||
108 | td->error_cnt = 0; | ||
109 | td->status = USB_TD_OK; | ||
110 | } else { | ||
111 | /* there was no error on transaction */ | ||
112 | td->error_cnt = 0; | ||
113 | td->nak_cnt = 0; | ||
114 | td->toggle = !td->toggle; | ||
115 | td->actual_len += trans_len; | ||
116 | |||
117 | if (td->len == td->actual_len) | ||
118 | td_done = true; | ||
119 | } | ||
120 | |||
121 | if (td_done) | ||
122 | fhci_move_td_from_ed_to_done_list(usb, ed); | ||
123 | } | ||
124 | |||
125 | /* | ||
126 | * Flush all transmitted packets from BDs | ||
127 | * This routine is called when disabling the USB port to flush all | ||
128 | * transmissions that are allready scheduled in the BDs | ||
129 | */ | ||
130 | void fhci_flush_all_transmissions(struct fhci_usb *usb) | ||
131 | { | ||
132 | u8 mode; | ||
133 | struct td *td; | ||
134 | |||
135 | mode = in_8(&usb->fhci->regs->usb_mod); | ||
136 | clrbits8(&usb->fhci->regs->usb_mod, USB_MODE_EN); | ||
137 | |||
138 | fhci_flush_bds(usb); | ||
139 | |||
140 | while ((td = fhci_peek_td_from_frame(usb->actual_frame)) != NULL) { | ||
141 | struct packet *pkt = td->pkt; | ||
142 | |||
143 | pkt->status = USB_TD_TX_ER_TIMEOUT; | ||
144 | fhci_transaction_confirm(usb, pkt); | ||
145 | } | ||
146 | |||
147 | usb->actual_frame->frame_status = FRAME_END_TRANSMISSION; | ||
148 | |||
149 | /* reset the event register */ | ||
150 | out_be16(&usb->fhci->regs->usb_event, 0xffff); | ||
151 | /* enable the USB controller */ | ||
152 | out_8(&usb->fhci->regs->usb_mod, mode | USB_MODE_EN); | ||
153 | } | ||
154 | |||
155 | /* | ||
156 | * This function forms the packet and transmit the packet. This function | ||
157 | * will handle all endpoint type:ISO,interrupt,control and bulk | ||
158 | */ | ||
159 | static int add_packet(struct fhci_usb *usb, struct ed *ed, struct td *td) | ||
160 | { | ||
161 | u32 fw_transaction_time, len = 0; | ||
162 | struct packet *pkt; | ||
163 | u8 *data = NULL; | ||
164 | |||
165 | /* calcalate data address,len and toggle and then add the transaction */ | ||
166 | if (td->toggle == USB_TD_TOGGLE_CARRY) | ||
167 | td->toggle = ed->toggle_carry; | ||
168 | |||
169 | switch (ed->mode) { | ||
170 | case FHCI_TF_ISO: | ||
171 | len = td->len; | ||
172 | if (td->type != FHCI_TA_IN) | ||
173 | data = td->data; | ||
174 | break; | ||
175 | case FHCI_TF_CTRL: | ||
176 | case FHCI_TF_BULK: | ||
177 | len = min(td->len - td->actual_len, ed->max_pkt_size); | ||
178 | if (!((td->type == FHCI_TA_IN) && | ||
179 | ((len + td->actual_len) == td->len))) | ||
180 | data = td->data + td->actual_len; | ||
181 | break; | ||
182 | case FHCI_TF_INTR: | ||
183 | len = min(td->len, ed->max_pkt_size); | ||
184 | if (!((td->type == FHCI_TA_IN) && | ||
185 | ((td->len + CRC_SIZE) >= ed->max_pkt_size))) | ||
186 | data = td->data; | ||
187 | break; | ||
188 | default: | ||
189 | break; | ||
190 | } | ||
191 | |||
192 | if (usb->port_status == FHCI_PORT_FULL) | ||
193 | fw_transaction_time = (((len + PROTOCOL_OVERHEAD) * 11) >> 4); | ||
194 | else | ||
195 | fw_transaction_time = ((len + PROTOCOL_OVERHEAD) * 6); | ||
196 | |||
197 | /* check if there's enough space in this frame to submit this TD */ | ||
198 | if (usb->actual_frame->total_bytes + len + PROTOCOL_OVERHEAD >= | ||
199 | usb->max_bytes_per_frame) { | ||
200 | fhci_vdbg(usb->fhci, "not enough space in this frame: " | ||
201 | "%d %d %d\n", usb->actual_frame->total_bytes, len, | ||
202 | usb->max_bytes_per_frame); | ||
203 | return -1; | ||
204 | } | ||
205 | |||
206 | /* check if there's enough time in this frame to submit this TD */ | ||
207 | if (usb->actual_frame->frame_status != FRAME_IS_PREPARED && | ||
208 | (usb->actual_frame->frame_status & FRAME_END_TRANSMISSION || | ||
209 | (fw_transaction_time + usb->sw_transaction_time >= | ||
210 | 1000 - fhci_get_sof_timer_count(usb)))) { | ||
211 | fhci_dbg(usb->fhci, "not enough time in this frame\n"); | ||
212 | return -1; | ||
213 | } | ||
214 | |||
215 | /* update frame object fields before transmitting */ | ||
216 | pkt = cq_get(usb->ep0->empty_frame_Q); | ||
217 | if (!pkt) { | ||
218 | fhci_dbg(usb->fhci, "there is no empty frame\n"); | ||
219 | return -1; | ||
220 | } | ||
221 | td->pkt = pkt; | ||
222 | |||
223 | pkt->info = 0; | ||
224 | if (data == NULL) { | ||
225 | data = cq_get(usb->ep0->dummy_packets_Q); | ||
226 | BUG_ON(!data); | ||
227 | pkt->info = PKT_DUMMY_PACKET; | ||
228 | } | ||
229 | pkt->data = data; | ||
230 | pkt->len = len; | ||
231 | pkt->status = USB_TD_OK; | ||
232 | /* update TD status field before transmitting */ | ||
233 | td->status = USB_TD_INPROGRESS; | ||
234 | /* update actual frame time object with the actual transmission */ | ||
235 | usb->actual_frame->total_bytes += (len + PROTOCOL_OVERHEAD); | ||
236 | fhci_add_td_to_frame(usb->actual_frame, td); | ||
237 | |||
238 | if (usb->port_status != FHCI_PORT_FULL && | ||
239 | usb->port_status != FHCI_PORT_LOW) { | ||
240 | pkt->status = USB_TD_TX_ER_TIMEOUT; | ||
241 | pkt->len = 0; | ||
242 | fhci_transaction_confirm(usb, pkt); | ||
243 | } else if (fhci_host_transaction(usb, pkt, td->type, ed->dev_addr, | ||
244 | ed->ep_addr, ed->mode, ed->speed, td->toggle)) { | ||
245 | /* remove TD from actual frame */ | ||
246 | list_del_init(&td->frame_lh); | ||
247 | td->status = USB_TD_OK; | ||
248 | if (pkt->info & PKT_DUMMY_PACKET) | ||
249 | cq_put(usb->ep0->dummy_packets_Q, pkt->data); | ||
250 | recycle_frame(usb, pkt); | ||
251 | usb->actual_frame->total_bytes -= (len + PROTOCOL_OVERHEAD); | ||
252 | fhci_err(usb->fhci, "host transaction failed\n"); | ||
253 | return -1; | ||
254 | } | ||
255 | |||
256 | return len; | ||
257 | } | ||
258 | |||
259 | static void move_head_to_tail(struct list_head *list) | ||
260 | { | ||
261 | struct list_head *node = list->next; | ||
262 | |||
263 | if (!list_empty(list)) { | ||
264 | list_del(node); | ||
265 | list_add_tail(node, list); | ||
266 | } | ||
267 | } | ||
268 | |||
269 | /* | ||
270 | * This function goes through the endpoint list and schedules the | ||
271 | * transactions within this list | ||
272 | */ | ||
273 | static int scan_ed_list(struct fhci_usb *usb, | ||
274 | struct list_head *list, enum fhci_tf_mode list_type) | ||
275 | { | ||
276 | static const int frame_part[4] = { | ||
277 | [FHCI_TF_CTRL] = MAX_BYTES_PER_FRAME, | ||
278 | [FHCI_TF_ISO] = (MAX_BYTES_PER_FRAME * | ||
279 | MAX_PERIODIC_FRAME_USAGE) / 100, | ||
280 | [FHCI_TF_BULK] = MAX_BYTES_PER_FRAME, | ||
281 | [FHCI_TF_INTR] = (MAX_BYTES_PER_FRAME * | ||
282 | MAX_PERIODIC_FRAME_USAGE) / 100 | ||
283 | }; | ||
284 | struct ed *ed; | ||
285 | struct td *td; | ||
286 | int ans = 1; | ||
287 | u32 save_transaction_time = usb->sw_transaction_time; | ||
288 | |||
289 | list_for_each_entry(ed, list, node) { | ||
290 | td = ed->td_head; | ||
291 | |||
292 | if (!td || (td && td->status == USB_TD_INPROGRESS)) | ||
293 | continue; | ||
294 | |||
295 | if (ed->state != FHCI_ED_OPER) { | ||
296 | if (ed->state == FHCI_ED_URB_DEL) { | ||
297 | td->status = USB_TD_OK; | ||
298 | fhci_move_td_from_ed_to_done_list(usb, ed); | ||
299 | ed->state = FHCI_ED_SKIP; | ||
300 | } | ||
301 | continue; | ||
302 | } | ||
303 | |||
304 | /* | ||
305 | * if it isn't interrupt pipe or it is not iso pipe and the | ||
306 | * interval time passed | ||
307 | */ | ||
308 | if ((list_type == FHCI_TF_INTR || list_type == FHCI_TF_ISO) && | ||
309 | (((usb->actual_frame->frame_num - | ||
310 | td->start_frame) & 0x7ff) < td->interval)) | ||
311 | continue; | ||
312 | |||
313 | if (add_packet(usb, ed, td) < 0) | ||
314 | continue; | ||
315 | |||
316 | /* update time stamps in the TD */ | ||
317 | td->start_frame = usb->actual_frame->frame_num; | ||
318 | usb->sw_transaction_time += save_transaction_time; | ||
319 | |||
320 | if (usb->actual_frame->total_bytes >= | ||
321 | usb->max_bytes_per_frame) { | ||
322 | usb->actual_frame->frame_status = | ||
323 | FRAME_DATA_END_TRANSMISSION; | ||
324 | fhci_push_dummy_bd(usb->ep0); | ||
325 | ans = 0; | ||
326 | break; | ||
327 | } | ||
328 | |||
329 | if (usb->actual_frame->total_bytes >= frame_part[list_type]) | ||
330 | break; | ||
331 | } | ||
332 | |||
333 | /* be fair to each ED(move list head around) */ | ||
334 | move_head_to_tail(list); | ||
335 | usb->sw_transaction_time = save_transaction_time; | ||
336 | |||
337 | return ans; | ||
338 | } | ||
339 | |||
340 | static u32 rotate_frames(struct fhci_usb *usb) | ||
341 | { | ||
342 | struct fhci_hcd *fhci = usb->fhci; | ||
343 | |||
344 | if (!list_empty(&usb->actual_frame->tds_list)) { | ||
345 | if ((((in_be16(&fhci->pram->frame_num) & 0x07ff) - | ||
346 | usb->actual_frame->frame_num) & 0x7ff) > 5) | ||
347 | fhci_flush_actual_frame(usb); | ||
348 | else | ||
349 | return -EINVAL; | ||
350 | } | ||
351 | |||
352 | usb->actual_frame->frame_status = FRAME_IS_PREPARED; | ||
353 | usb->actual_frame->frame_num = in_be16(&fhci->pram->frame_num) & 0x7ff; | ||
354 | usb->actual_frame->total_bytes = 0; | ||
355 | |||
356 | return 0; | ||
357 | } | ||
358 | |||
359 | /* | ||
360 | * This function schedule the USB transaction and will process the | ||
361 | * endpoint in the following order: iso, interrupt, control and bulk. | ||
362 | */ | ||
363 | void fhci_schedule_transactions(struct fhci_usb *usb) | ||
364 | { | ||
365 | int left = 1; | ||
366 | |||
367 | if (usb->actual_frame->frame_status & FRAME_END_TRANSMISSION) | ||
368 | if (rotate_frames(usb) != 0) | ||
369 | return; | ||
370 | |||
371 | if (usb->actual_frame->frame_status & FRAME_END_TRANSMISSION) | ||
372 | return; | ||
373 | |||
374 | if (usb->actual_frame->total_bytes == 0) { | ||
375 | /* | ||
376 | * schedule the next available ISO transfer | ||
377 | *or next stage of the ISO transfer | ||
378 | */ | ||
379 | scan_ed_list(usb, &usb->hc_list->iso_list, FHCI_TF_ISO); | ||
380 | |||
381 | /* | ||
382 | * schedule the next available interrupt transfer or | ||
383 | * the next stage of the interrupt transfer | ||
384 | */ | ||
385 | scan_ed_list(usb, &usb->hc_list->intr_list, FHCI_TF_INTR); | ||
386 | |||
387 | /* | ||
388 | * schedule the next available control transfer | ||
389 | * or the next stage of the control transfer | ||
390 | */ | ||
391 | left = scan_ed_list(usb, &usb->hc_list->ctrl_list, | ||
392 | FHCI_TF_CTRL); | ||
393 | } | ||
394 | |||
395 | /* | ||
396 | * schedule the next available bulk transfer or the next stage of the | ||
397 | * bulk transfer | ||
398 | */ | ||
399 | if (left > 0) | ||
400 | scan_ed_list(usb, &usb->hc_list->bulk_list, FHCI_TF_BULK); | ||
401 | } | ||
402 | |||
403 | /* Handles SOF interrupt */ | ||
404 | static void sof_interrupt(struct fhci_hcd *fhci) | ||
405 | { | ||
406 | struct fhci_usb *usb = fhci->usb_lld; | ||
407 | |||
408 | if ((usb->port_status == FHCI_PORT_DISABLED) && | ||
409 | (usb->vroot_hub->port.wPortStatus & USB_PORT_STAT_CONNECTION) && | ||
410 | !(usb->vroot_hub->port.wPortChange & USB_PORT_STAT_C_CONNECTION)) { | ||
411 | if (usb->vroot_hub->port.wPortStatus & USB_PORT_STAT_LOW_SPEED) | ||
412 | usb->port_status = FHCI_PORT_LOW; | ||
413 | else | ||
414 | usb->port_status = FHCI_PORT_FULL; | ||
415 | /* Disable IDLE */ | ||
416 | usb->saved_msk &= ~USB_E_IDLE_MASK; | ||
417 | out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk); | ||
418 | } | ||
419 | |||
420 | gtm_set_exact_timer16(fhci->timer, usb->max_frame_usage, false); | ||
421 | |||
422 | fhci_host_transmit_actual_frame(usb); | ||
423 | usb->actual_frame->frame_status = FRAME_IS_TRANSMITTED; | ||
424 | |||
425 | fhci_schedule_transactions(usb); | ||
426 | } | ||
427 | |||
428 | /* Handles device disconnected interrupt on port */ | ||
429 | void fhci_device_disconnected_interrupt(struct fhci_hcd *fhci) | ||
430 | { | ||
431 | struct fhci_usb *usb = fhci->usb_lld; | ||
432 | |||
433 | fhci_dbg(fhci, "-> %s\n", __func__); | ||
434 | |||
435 | fhci_usb_disable_interrupt(usb); | ||
436 | clrbits8(&usb->fhci->regs->usb_mod, USB_MODE_LSS); | ||
437 | usb->port_status = FHCI_PORT_DISABLED; | ||
438 | |||
439 | fhci_stop_sof_timer(fhci); | ||
440 | |||
441 | /* Enable IDLE since we want to know if something comes along */ | ||
442 | usb->saved_msk |= USB_E_IDLE_MASK; | ||
443 | out_be16(&usb->fhci->regs->usb_mask, usb->saved_msk); | ||
444 | |||
445 | usb->vroot_hub->port.wPortStatus &= ~USB_PORT_STAT_CONNECTION; | ||
446 | usb->vroot_hub->port.wPortChange |= USB_PORT_STAT_C_CONNECTION; | ||
447 | usb->max_bytes_per_frame = 0; | ||
448 | fhci_usb_enable_interrupt(usb); | ||
449 | |||
450 | fhci_dbg(fhci, "<- %s\n", __func__); | ||
451 | } | ||
452 | |||
453 | /* detect a new device connected on the USB port */ | ||
454 | void fhci_device_connected_interrupt(struct fhci_hcd *fhci) | ||
455 | { | ||
456 | |||
457 | struct fhci_usb *usb = fhci->usb_lld; | ||
458 | int state; | ||
459 | int ret; | ||
460 | |||
461 | fhci_dbg(fhci, "-> %s\n", __func__); | ||
462 | |||
463 | fhci_usb_disable_interrupt(usb); | ||
464 | state = fhci_ioports_check_bus_state(fhci); | ||
465 | |||
466 | /* low-speed device was connected to the USB port */ | ||
467 | if (state == 1) { | ||
468 | ret = qe_usb_clock_set(fhci->lowspeed_clk, USB_CLOCK >> 3); | ||
469 | if (ret) { | ||
470 | fhci_warn(fhci, "Low-Speed device is not supported, " | ||
471 | "try use BRGx\n"); | ||
472 | goto out; | ||
473 | } | ||
474 | |||
475 | usb->port_status = FHCI_PORT_LOW; | ||
476 | setbits8(&usb->fhci->regs->usb_mod, USB_MODE_LSS); | ||
477 | usb->vroot_hub->port.wPortStatus |= | ||
478 | (USB_PORT_STAT_LOW_SPEED | | ||
479 | USB_PORT_STAT_CONNECTION); | ||
480 | usb->vroot_hub->port.wPortChange |= | ||
481 | USB_PORT_STAT_C_CONNECTION; | ||
482 | usb->max_bytes_per_frame = | ||
483 | (MAX_BYTES_PER_FRAME >> 3) - 7; | ||
484 | fhci_port_enable(usb); | ||
485 | } else if (state == 2) { | ||
486 | ret = qe_usb_clock_set(fhci->fullspeed_clk, USB_CLOCK); | ||
487 | if (ret) { | ||
488 | fhci_warn(fhci, "Full-Speed device is not supported, " | ||
489 | "try use CLKx\n"); | ||
490 | goto out; | ||
491 | } | ||
492 | |||
493 | usb->port_status = FHCI_PORT_FULL; | ||
494 | clrbits8(&usb->fhci->regs->usb_mod, USB_MODE_LSS); | ||
495 | usb->vroot_hub->port.wPortStatus &= | ||
496 | ~USB_PORT_STAT_LOW_SPEED; | ||
497 | usb->vroot_hub->port.wPortStatus |= | ||
498 | USB_PORT_STAT_CONNECTION; | ||
499 | usb->vroot_hub->port.wPortChange |= | ||
500 | USB_PORT_STAT_C_CONNECTION; | ||
501 | usb->max_bytes_per_frame = (MAX_BYTES_PER_FRAME - 15); | ||
502 | fhci_port_enable(usb); | ||
503 | } | ||
504 | out: | ||
505 | fhci_usb_enable_interrupt(usb); | ||
506 | fhci_dbg(fhci, "<- %s\n", __func__); | ||
507 | } | ||
508 | |||
509 | irqreturn_t fhci_frame_limit_timer_irq(int irq, void *_hcd) | ||
510 | { | ||
511 | struct usb_hcd *hcd = _hcd; | ||
512 | struct fhci_hcd *fhci = hcd_to_fhci(hcd); | ||
513 | struct fhci_usb *usb = fhci->usb_lld; | ||
514 | |||
515 | spin_lock(&fhci->lock); | ||
516 | |||
517 | gtm_set_exact_timer16(fhci->timer, 1000, false); | ||
518 | |||
519 | if (usb->actual_frame->frame_status == FRAME_IS_TRANSMITTED) { | ||
520 | usb->actual_frame->frame_status = FRAME_TIMER_END_TRANSMISSION; | ||
521 | fhci_push_dummy_bd(usb->ep0); | ||
522 | } | ||
523 | |||
524 | fhci_schedule_transactions(usb); | ||
525 | |||
526 | spin_unlock(&fhci->lock); | ||
527 | |||
528 | return IRQ_HANDLED; | ||
529 | } | ||
530 | |||
531 | /* Cancel transmission on the USB endpoint */ | ||
532 | static void abort_transmission(struct fhci_usb *usb) | ||
533 | { | ||
534 | fhci_dbg(usb->fhci, "-> %s\n", __func__); | ||
535 | /* issue stop Tx command */ | ||
536 | qe_issue_cmd(QE_USB_STOP_TX, QE_CR_SUBBLOCK_USB, EP_ZERO, 0); | ||
537 | /* flush Tx FIFOs */ | ||
538 | out_8(&usb->fhci->regs->usb_comm, USB_CMD_FLUSH_FIFO | EP_ZERO); | ||
539 | udelay(1000); | ||
540 | /* reset Tx BDs */ | ||
541 | fhci_flush_bds(usb); | ||
542 | /* issue restart Tx command */ | ||
543 | qe_issue_cmd(QE_USB_RESTART_TX, QE_CR_SUBBLOCK_USB, EP_ZERO, 0); | ||
544 | fhci_dbg(usb->fhci, "<- %s\n", __func__); | ||
545 | } | ||
546 | |||
547 | irqreturn_t fhci_irq(struct usb_hcd *hcd) | ||
548 | { | ||
549 | struct fhci_hcd *fhci = hcd_to_fhci(hcd); | ||
550 | struct fhci_usb *usb; | ||
551 | u16 usb_er = 0; | ||
552 | unsigned long flags; | ||
553 | |||
554 | spin_lock_irqsave(&fhci->lock, flags); | ||
555 | |||
556 | usb = fhci->usb_lld; | ||
557 | |||
558 | usb_er |= in_be16(&usb->fhci->regs->usb_event) & | ||
559 | in_be16(&usb->fhci->regs->usb_mask); | ||
560 | |||
561 | /* clear event bits for next time */ | ||
562 | out_be16(&usb->fhci->regs->usb_event, usb_er); | ||
563 | |||
564 | fhci_dbg_isr(fhci, usb_er); | ||
565 | |||
566 | if (usb_er & USB_E_RESET_MASK) { | ||
567 | if ((usb->port_status == FHCI_PORT_FULL) || | ||
568 | (usb->port_status == FHCI_PORT_LOW)) { | ||
569 | fhci_device_disconnected_interrupt(fhci); | ||
570 | usb_er &= ~USB_E_IDLE_MASK; | ||
571 | } else if (usb->port_status == FHCI_PORT_WAITING) { | ||
572 | usb->port_status = FHCI_PORT_DISCONNECTING; | ||
573 | |||
574 | /* Turn on IDLE since we want to disconnect */ | ||
575 | usb->saved_msk |= USB_E_IDLE_MASK; | ||
576 | out_be16(&usb->fhci->regs->usb_event, | ||
577 | usb->saved_msk); | ||
578 | } else if (usb->port_status == FHCI_PORT_DISABLED) { | ||
579 | if (fhci_ioports_check_bus_state(fhci) == 1 && | ||
580 | usb->port_status != FHCI_PORT_LOW && | ||
581 | usb->port_status != FHCI_PORT_FULL) | ||
582 | fhci_device_connected_interrupt(fhci); | ||
583 | } | ||
584 | usb_er &= ~USB_E_RESET_MASK; | ||
585 | } | ||
586 | |||
587 | if (usb_er & USB_E_MSF_MASK) { | ||
588 | abort_transmission(fhci->usb_lld); | ||
589 | usb_er &= ~USB_E_MSF_MASK; | ||
590 | } | ||
591 | |||
592 | if (usb_er & (USB_E_SOF_MASK | USB_E_SFT_MASK)) { | ||
593 | sof_interrupt(fhci); | ||
594 | usb_er &= ~(USB_E_SOF_MASK | USB_E_SFT_MASK); | ||
595 | } | ||
596 | |||
597 | if (usb_er & USB_E_TXB_MASK) { | ||
598 | fhci_tx_conf_interrupt(fhci->usb_lld); | ||
599 | usb_er &= ~USB_E_TXB_MASK; | ||
600 | } | ||
601 | |||
602 | if (usb_er & USB_E_TXE1_MASK) { | ||
603 | fhci_tx_conf_interrupt(fhci->usb_lld); | ||
604 | usb_er &= ~USB_E_TXE1_MASK; | ||
605 | } | ||
606 | |||
607 | if (usb_er & USB_E_IDLE_MASK) { | ||
608 | if (usb->port_status == FHCI_PORT_DISABLED && | ||
609 | usb->port_status != FHCI_PORT_LOW && | ||
610 | usb->port_status != FHCI_PORT_FULL) { | ||
611 | usb_er &= ~USB_E_RESET_MASK; | ||
612 | fhci_device_connected_interrupt(fhci); | ||
613 | } else if (usb->port_status == | ||
614 | FHCI_PORT_DISCONNECTING) { | ||
615 | /* XXX usb->port_status = FHCI_PORT_WAITING; */ | ||
616 | /* Disable IDLE */ | ||
617 | usb->saved_msk &= ~USB_E_IDLE_MASK; | ||
618 | out_be16(&usb->fhci->regs->usb_mask, | ||
619 | usb->saved_msk); | ||
620 | } else { | ||
621 | fhci_dbg_isr(fhci, -1); | ||
622 | } | ||
623 | |||
624 | usb_er &= ~USB_E_IDLE_MASK; | ||
625 | } | ||
626 | |||
627 | spin_unlock_irqrestore(&fhci->lock, flags); | ||
628 | |||
629 | return IRQ_HANDLED; | ||
630 | } | ||
631 | |||
632 | |||
633 | /* | ||
634 | * Process normal completions(error or sucess) and clean the schedule. | ||
635 | * | ||
636 | * This is the main path for handing urbs back to drivers. The only other patth | ||
637 | * is process_del_list(),which unlinks URBs by scanning EDs,instead of scanning | ||
638 | * the (re-reversed) done list as this does. | ||
639 | */ | ||
640 | static void process_done_list(unsigned long data) | ||
641 | { | ||
642 | struct urb *urb; | ||
643 | struct ed *ed; | ||
644 | struct td *td; | ||
645 | struct urb_priv *urb_priv; | ||
646 | struct fhci_hcd *fhci = (struct fhci_hcd *)data; | ||
647 | |||
648 | disable_irq(fhci->timer->irq); | ||
649 | disable_irq(fhci_to_hcd(fhci)->irq); | ||
650 | spin_lock(&fhci->lock); | ||
651 | |||
652 | td = fhci_remove_td_from_done_list(fhci->hc_list); | ||
653 | while (td != NULL) { | ||
654 | urb = td->urb; | ||
655 | urb_priv = urb->hcpriv; | ||
656 | ed = td->ed; | ||
657 | |||
658 | /* update URB's length and status from TD */ | ||
659 | fhci_done_td(urb, td); | ||
660 | urb_priv->tds_cnt++; | ||
661 | |||
662 | /* | ||
663 | * if all this urb's TDs are done, call complete() | ||
664 | * Interrupt transfers are the onley special case: | ||
665 | * they are reissued,until "deleted" by usb_unlink_urb | ||
666 | * (real work done in a SOF intr, by process_del_list) | ||
667 | */ | ||
668 | if (urb_priv->tds_cnt == urb_priv->num_of_tds) { | ||
669 | fhci_urb_complete_free(fhci, urb); | ||
670 | } else if (urb_priv->state == URB_DEL && | ||
671 | ed->state == FHCI_ED_SKIP) { | ||
672 | fhci_del_ed_list(fhci, ed); | ||
673 | ed->state = FHCI_ED_OPER; | ||
674 | } else if (ed->state == FHCI_ED_HALTED) { | ||
675 | urb_priv->state = URB_DEL; | ||
676 | ed->state = FHCI_ED_URB_DEL; | ||
677 | fhci_del_ed_list(fhci, ed); | ||
678 | ed->state = FHCI_ED_OPER; | ||
679 | } | ||
680 | |||
681 | td = fhci_remove_td_from_done_list(fhci->hc_list); | ||
682 | } | ||
683 | |||
684 | spin_unlock(&fhci->lock); | ||
685 | enable_irq(fhci->timer->irq); | ||
686 | enable_irq(fhci_to_hcd(fhci)->irq); | ||
687 | } | ||
688 | |||
689 | DECLARE_TASKLET(fhci_tasklet, process_done_list, 0); | ||
690 | |||
691 | /* transfer complted callback */ | ||
692 | u32 fhci_transfer_confirm_callback(struct fhci_hcd *fhci) | ||
693 | { | ||
694 | if (!fhci->process_done_task->state) | ||
695 | tasklet_schedule(fhci->process_done_task); | ||
696 | return 0; | ||
697 | } | ||
698 | |||
699 | /* | ||
700 | * adds urb to the endpoint descriptor list | ||
701 | * arguments: | ||
702 | * fhci data structure for the Low level host controller | ||
703 | * ep USB Host endpoint data structure | ||
704 | * urb USB request block data structure | ||
705 | */ | ||
706 | void fhci_queue_urb(struct fhci_hcd *fhci, struct urb *urb) | ||
707 | { | ||
708 | struct ed *ed = urb->ep->hcpriv; | ||
709 | struct urb_priv *urb_priv = urb->hcpriv; | ||
710 | u32 data_len = urb->transfer_buffer_length; | ||
711 | int urb_state = 0; | ||
712 | int toggle = 0; | ||
713 | struct td *td; | ||
714 | u8 *data; | ||
715 | u16 cnt = 0; | ||
716 | |||
717 | if (ed == NULL) { | ||
718 | ed = fhci_get_empty_ed(fhci); | ||
719 | ed->dev_addr = usb_pipedevice(urb->pipe); | ||
720 | ed->ep_addr = usb_pipeendpoint(urb->pipe); | ||
721 | switch (usb_pipetype(urb->pipe)) { | ||
722 | case PIPE_CONTROL: | ||
723 | ed->mode = FHCI_TF_CTRL; | ||
724 | break; | ||
725 | case PIPE_BULK: | ||
726 | ed->mode = FHCI_TF_BULK; | ||
727 | break; | ||
728 | case PIPE_INTERRUPT: | ||
729 | ed->mode = FHCI_TF_INTR; | ||
730 | break; | ||
731 | case PIPE_ISOCHRONOUS: | ||
732 | ed->mode = FHCI_TF_ISO; | ||
733 | break; | ||
734 | default: | ||
735 | break; | ||
736 | } | ||
737 | ed->speed = (urb->dev->speed == USB_SPEED_LOW) ? | ||
738 | FHCI_LOW_SPEED : FHCI_FULL_SPEED; | ||
739 | ed->max_pkt_size = usb_maxpacket(urb->dev, | ||
740 | urb->pipe, usb_pipeout(urb->pipe)); | ||
741 | urb->ep->hcpriv = ed; | ||
742 | fhci_dbg(fhci, "new ep speed=%d max_pkt_size=%d\n", | ||
743 | ed->speed, ed->max_pkt_size); | ||
744 | } | ||
745 | |||
746 | /* for ISO transfer calculate start frame index */ | ||
747 | if (ed->mode == FHCI_TF_ISO && urb->transfer_flags & URB_ISO_ASAP) | ||
748 | urb->start_frame = ed->td_head ? ed->last_iso + 1 : | ||
749 | get_frame_num(fhci); | ||
750 | |||
751 | /* | ||
752 | * OHCI handles the DATA toggle itself,we just use the USB | ||
753 | * toggle bits | ||
754 | */ | ||
755 | if (usb_gettoggle(urb->dev, usb_pipeendpoint(urb->pipe), | ||
756 | usb_pipeout(urb->pipe))) | ||
757 | toggle = USB_TD_TOGGLE_CARRY; | ||
758 | else { | ||
759 | toggle = USB_TD_TOGGLE_DATA0; | ||
760 | usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), | ||
761 | usb_pipeout(urb->pipe), 1); | ||
762 | } | ||
763 | |||
764 | urb_priv->tds_cnt = 0; | ||
765 | urb_priv->ed = ed; | ||
766 | if (data_len > 0) | ||
767 | data = urb->transfer_buffer; | ||
768 | else | ||
769 | data = NULL; | ||
770 | |||
771 | switch (ed->mode) { | ||
772 | case FHCI_TF_BULK: | ||
773 | if (urb->transfer_flags & URB_ZERO_PACKET && | ||
774 | urb->transfer_buffer_length > 0 && | ||
775 | ((urb->transfer_buffer_length % | ||
776 | usb_maxpacket(urb->dev, urb->pipe, | ||
777 | usb_pipeout(urb->pipe))) == 0)) | ||
778 | urb_state = US_BULK0; | ||
779 | while (data_len > 4096) { | ||
780 | td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt, | ||
781 | usb_pipeout(urb->pipe) ? FHCI_TA_OUT : | ||
782 | FHCI_TA_IN, | ||
783 | cnt ? USB_TD_TOGGLE_CARRY : | ||
784 | toggle, | ||
785 | data, 4096, 0, 0, true); | ||
786 | data += 4096; | ||
787 | data_len -= 4096; | ||
788 | cnt++; | ||
789 | } | ||
790 | |||
791 | td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt, | ||
792 | usb_pipeout(urb->pipe) ? FHCI_TA_OUT : FHCI_TA_IN, | ||
793 | cnt ? USB_TD_TOGGLE_CARRY : toggle, | ||
794 | data, data_len, 0, 0, true); | ||
795 | cnt++; | ||
796 | |||
797 | if (urb->transfer_flags & URB_ZERO_PACKET && | ||
798 | cnt < urb_priv->num_of_tds) { | ||
799 | td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt, | ||
800 | usb_pipeout(urb->pipe) ? FHCI_TA_OUT : | ||
801 | FHCI_TA_IN, | ||
802 | USB_TD_TOGGLE_CARRY, NULL, 0, 0, 0, true); | ||
803 | cnt++; | ||
804 | } | ||
805 | break; | ||
806 | case FHCI_TF_INTR: | ||
807 | urb->start_frame = get_frame_num(fhci) + 1; | ||
808 | td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, | ||
809 | usb_pipeout(urb->pipe) ? FHCI_TA_OUT : FHCI_TA_IN, | ||
810 | USB_TD_TOGGLE_DATA0, data, data_len, | ||
811 | urb->interval, urb->start_frame, true); | ||
812 | break; | ||
813 | case FHCI_TF_CTRL: | ||
814 | ed->dev_addr = usb_pipedevice(urb->pipe); | ||
815 | ed->max_pkt_size = usb_maxpacket(urb->dev, urb->pipe, | ||
816 | usb_pipeout(urb->pipe)); | ||
817 | td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, FHCI_TA_SETUP, | ||
818 | USB_TD_TOGGLE_DATA0, urb->setup_packet, 8, 0, 0, true); | ||
819 | |||
820 | if (data_len > 0) { | ||
821 | td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, | ||
822 | usb_pipeout(urb->pipe) ? FHCI_TA_OUT : | ||
823 | FHCI_TA_IN, | ||
824 | USB_TD_TOGGLE_DATA1, data, data_len, 0, 0, | ||
825 | true); | ||
826 | } | ||
827 | td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt++, | ||
828 | usb_pipeout(urb->pipe) ? FHCI_TA_IN : FHCI_TA_OUT, | ||
829 | USB_TD_TOGGLE_DATA1, data, 0, 0, 0, true); | ||
830 | urb_state = US_CTRL_SETUP; | ||
831 | break; | ||
832 | case FHCI_TF_ISO: | ||
833 | for (cnt = 0; cnt < urb->number_of_packets; cnt++) { | ||
834 | u16 frame = urb->start_frame; | ||
835 | |||
836 | /* | ||
837 | * FIXME scheduling should handle frame counter | ||
838 | * roll-around ... exotic case (and OHCI has | ||
839 | * a 2^16 iso range, vs other HCs max of 2^10) | ||
840 | */ | ||
841 | frame += cnt * urb->interval; | ||
842 | frame &= 0x07ff; | ||
843 | td = fhci_td_fill(fhci, urb, urb_priv, ed, cnt, | ||
844 | usb_pipeout(urb->pipe) ? FHCI_TA_OUT : | ||
845 | FHCI_TA_IN, | ||
846 | USB_TD_TOGGLE_DATA0, | ||
847 | data + urb->iso_frame_desc[cnt].offset, | ||
848 | urb->iso_frame_desc[cnt].length, | ||
849 | urb->interval, frame, true); | ||
850 | } | ||
851 | break; | ||
852 | default: | ||
853 | break; | ||
854 | } | ||
855 | |||
856 | /* | ||
857 | * set the state of URB | ||
858 | * control pipe:3 states -- setup,data,status | ||
859 | * interrupt and bulk pipe:1 state -- data | ||
860 | */ | ||
861 | urb->pipe &= ~0x1f; | ||
862 | urb->pipe |= urb_state & 0x1f; | ||
863 | |||
864 | urb_priv->state = URB_INPROGRESS; | ||
865 | |||
866 | if (!ed->td_head) { | ||
867 | ed->state = FHCI_ED_OPER; | ||
868 | switch (ed->mode) { | ||
869 | case FHCI_TF_CTRL: | ||
870 | list_add(&ed->node, &fhci->hc_list->ctrl_list); | ||
871 | break; | ||
872 | case FHCI_TF_BULK: | ||
873 | list_add(&ed->node, &fhci->hc_list->bulk_list); | ||
874 | break; | ||
875 | case FHCI_TF_INTR: | ||
876 | list_add(&ed->node, &fhci->hc_list->intr_list); | ||
877 | break; | ||
878 | case FHCI_TF_ISO: | ||
879 | list_add(&ed->node, &fhci->hc_list->iso_list); | ||
880 | break; | ||
881 | default: | ||
882 | break; | ||
883 | } | ||
884 | } | ||
885 | |||
886 | fhci_add_tds_to_ed(ed, urb_priv->tds, urb_priv->num_of_tds); | ||
887 | fhci->active_urbs++; | ||
888 | } | ||
diff --git a/drivers/usb/host/fhci-tds.c b/drivers/usb/host/fhci-tds.c new file mode 100644 index 000000000000..b40332290319 --- /dev/null +++ b/drivers/usb/host/fhci-tds.c | |||
@@ -0,0 +1,626 @@ | |||
1 | /* | ||
2 | * Freescale QUICC Engine USB Host Controller Driver | ||
3 | * | ||
4 | * Copyright (c) Freescale Semicondutor, Inc. 2006. | ||
5 | * Shlomi Gridish <gridish@freescale.com> | ||
6 | * Jerry Huang <Chang-Ming.Huang@freescale.com> | ||
7 | * Copyright (c) Logic Product Development, Inc. 2007 | ||
8 | * Peter Barada <peterb@logicpd.com> | ||
9 | * Copyright (c) MontaVista Software, Inc. 2008. | ||
10 | * Anton Vorontsov <avorontsov@ru.mvista.com> | ||
11 | * | ||
12 | * 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 | ||
14 | * Free Software Foundation; either version 2 of the License, or (at your | ||
15 | * option) any later version. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/types.h> | ||
20 | #include <linux/errno.h> | ||
21 | #include <linux/list.h> | ||
22 | #include <linux/io.h> | ||
23 | #include <linux/usb.h> | ||
24 | #include "../core/hcd.h" | ||
25 | #include "fhci.h" | ||
26 | |||
27 | #define DUMMY_BD_BUFFER 0xdeadbeef | ||
28 | #define DUMMY2_BD_BUFFER 0xbaadf00d | ||
29 | |||
30 | /* Transaction Descriptors bits */ | ||
31 | #define TD_R 0x8000 /* ready bit */ | ||
32 | #define TD_W 0x2000 /* wrap bit */ | ||
33 | #define TD_I 0x1000 /* interrupt on completion */ | ||
34 | #define TD_L 0x0800 /* last */ | ||
35 | #define TD_TC 0x0400 /* transmit CRC */ | ||
36 | #define TD_CNF 0x0200 /* CNF - Must be always 1 */ | ||
37 | #define TD_LSP 0x0100 /* Low-speed transaction */ | ||
38 | #define TD_PID 0x00c0 /* packet id */ | ||
39 | #define TD_RXER 0x0020 /* Rx error or not */ | ||
40 | |||
41 | #define TD_NAK 0x0010 /* No ack. */ | ||
42 | #define TD_STAL 0x0008 /* Stall recieved */ | ||
43 | #define TD_TO 0x0004 /* time out */ | ||
44 | #define TD_UN 0x0002 /* underrun */ | ||
45 | #define TD_NO 0x0010 /* Rx Non Octet Aligned Packet */ | ||
46 | #define TD_AB 0x0008 /* Frame Aborted */ | ||
47 | #define TD_CR 0x0004 /* CRC Error */ | ||
48 | #define TD_OV 0x0002 /* Overrun */ | ||
49 | #define TD_BOV 0x0001 /* Buffer Overrun */ | ||
50 | |||
51 | #define TD_ERRORS (TD_NAK | TD_STAL | TD_TO | TD_UN | \ | ||
52 | TD_NO | TD_AB | TD_CR | TD_OV | TD_BOV) | ||
53 | |||
54 | #define TD_PID_DATA0 0x0080 /* Data 0 toggle */ | ||
55 | #define TD_PID_DATA1 0x00c0 /* Data 1 toggle */ | ||
56 | #define TD_PID_TOGGLE 0x00c0 /* Data 0/1 toggle mask */ | ||
57 | |||
58 | #define TD_TOK_SETUP 0x0000 | ||
59 | #define TD_TOK_OUT 0x4000 | ||
60 | #define TD_TOK_IN 0x8000 | ||
61 | #define TD_ISO 0x1000 | ||
62 | #define TD_ENDP 0x0780 | ||
63 | #define TD_ADDR 0x007f | ||
64 | |||
65 | #define TD_ENDP_SHIFT 7 | ||
66 | |||
67 | struct usb_td { | ||
68 | __be16 status; | ||
69 | __be16 length; | ||
70 | __be32 buf_ptr; | ||
71 | __be16 extra; | ||
72 | __be16 reserved; | ||
73 | }; | ||
74 | |||
75 | static struct usb_td __iomem *next_bd(struct usb_td __iomem *base, | ||
76 | struct usb_td __iomem *td, | ||
77 | u16 status) | ||
78 | { | ||
79 | if (status & TD_W) | ||
80 | return base; | ||
81 | else | ||
82 | return ++td; | ||
83 | } | ||
84 | |||
85 | void fhci_push_dummy_bd(struct endpoint *ep) | ||
86 | { | ||
87 | if (ep->already_pushed_dummy_bd == false) { | ||
88 | u16 td_status = in_be16(&ep->empty_td->status); | ||
89 | |||
90 | out_be32(&ep->empty_td->buf_ptr, DUMMY_BD_BUFFER); | ||
91 | /* get the next TD in the ring */ | ||
92 | ep->empty_td = next_bd(ep->td_base, ep->empty_td, td_status); | ||
93 | ep->already_pushed_dummy_bd = true; | ||
94 | } | ||
95 | } | ||
96 | |||
97 | /* destroy an USB endpoint */ | ||
98 | void fhci_ep0_free(struct fhci_usb *usb) | ||
99 | { | ||
100 | struct endpoint *ep; | ||
101 | int size; | ||
102 | |||
103 | ep = usb->ep0; | ||
104 | if (ep) { | ||
105 | if (ep->td_base) | ||
106 | cpm_muram_free(cpm_muram_offset(ep->td_base)); | ||
107 | |||
108 | if (ep->conf_frame_Q) { | ||
109 | size = cq_howmany(ep->conf_frame_Q); | ||
110 | for (; size; size--) { | ||
111 | struct packet *pkt = cq_get(ep->conf_frame_Q); | ||
112 | |||
113 | kfree(pkt); | ||
114 | } | ||
115 | cq_delete(ep->conf_frame_Q); | ||
116 | } | ||
117 | |||
118 | if (ep->empty_frame_Q) { | ||
119 | size = cq_howmany(ep->empty_frame_Q); | ||
120 | for (; size; size--) { | ||
121 | struct packet *pkt = cq_get(ep->empty_frame_Q); | ||
122 | |||
123 | kfree(pkt); | ||
124 | } | ||
125 | cq_delete(ep->empty_frame_Q); | ||
126 | } | ||
127 | |||
128 | if (ep->dummy_packets_Q) { | ||
129 | size = cq_howmany(ep->dummy_packets_Q); | ||
130 | for (; size; size--) { | ||
131 | u8 *buff = cq_get(ep->dummy_packets_Q); | ||
132 | |||
133 | kfree(buff); | ||
134 | } | ||
135 | cq_delete(ep->dummy_packets_Q); | ||
136 | } | ||
137 | |||
138 | kfree(ep); | ||
139 | usb->ep0 = NULL; | ||
140 | } | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * create the endpoint structure | ||
145 | * | ||
146 | * arguments: | ||
147 | * usb A pointer to the data structure of the USB | ||
148 | * data_mem The data memory partition(BUS) | ||
149 | * ring_len TD ring length | ||
150 | */ | ||
151 | u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem, | ||
152 | u32 ring_len) | ||
153 | { | ||
154 | struct endpoint *ep; | ||
155 | struct usb_td __iomem *td; | ||
156 | unsigned long ep_offset; | ||
157 | char *err_for = "enpoint PRAM"; | ||
158 | int ep_mem_size; | ||
159 | u32 i; | ||
160 | |||
161 | /* we need at least 3 TDs in the ring */ | ||
162 | if (!(ring_len > 2)) { | ||
163 | fhci_err(usb->fhci, "illegal TD ring length parameters\n"); | ||
164 | return -EINVAL; | ||
165 | } | ||
166 | |||
167 | ep = kzalloc(sizeof(*ep), GFP_KERNEL); | ||
168 | if (!ep) | ||
169 | return -ENOMEM; | ||
170 | |||
171 | ep_mem_size = ring_len * sizeof(*td) + sizeof(struct fhci_ep_pram); | ||
172 | ep_offset = cpm_muram_alloc(ep_mem_size, 32); | ||
173 | if (IS_ERR_VALUE(ep_offset)) | ||
174 | goto err; | ||
175 | ep->td_base = cpm_muram_addr(ep_offset); | ||
176 | |||
177 | /* zero all queue pointers */ | ||
178 | ep->conf_frame_Q = cq_new(ring_len + 2); | ||
179 | ep->empty_frame_Q = cq_new(ring_len + 2); | ||
180 | ep->dummy_packets_Q = cq_new(ring_len + 2); | ||
181 | if (!ep->conf_frame_Q || !ep->empty_frame_Q || !ep->dummy_packets_Q) { | ||
182 | err_for = "frame_queues"; | ||
183 | goto err; | ||
184 | } | ||
185 | |||
186 | for (i = 0; i < (ring_len + 1); i++) { | ||
187 | struct packet *pkt; | ||
188 | u8 *buff; | ||
189 | |||
190 | pkt = kmalloc(sizeof(*pkt), GFP_KERNEL); | ||
191 | if (!pkt) { | ||
192 | err_for = "frame"; | ||
193 | goto err; | ||
194 | } | ||
195 | |||
196 | buff = kmalloc(1028 * sizeof(*buff), GFP_KERNEL); | ||
197 | if (!buff) { | ||
198 | kfree(pkt); | ||
199 | err_for = "buffer"; | ||
200 | goto err; | ||
201 | } | ||
202 | cq_put(ep->empty_frame_Q, pkt); | ||
203 | cq_put(ep->dummy_packets_Q, buff); | ||
204 | } | ||
205 | |||
206 | /* we put the endpoint parameter RAM right behind the TD ring */ | ||
207 | ep->ep_pram_ptr = (void __iomem *)ep->td_base + sizeof(*td) * ring_len; | ||
208 | |||
209 | ep->conf_td = ep->td_base; | ||
210 | ep->empty_td = ep->td_base; | ||
211 | |||
212 | ep->already_pushed_dummy_bd = false; | ||
213 | |||
214 | /* initialize tds */ | ||
215 | td = ep->td_base; | ||
216 | for (i = 0; i < ring_len; i++) { | ||
217 | out_be32(&td->buf_ptr, 0); | ||
218 | out_be16(&td->status, 0); | ||
219 | out_be16(&td->length, 0); | ||
220 | out_be16(&td->extra, 0); | ||
221 | td++; | ||
222 | } | ||
223 | td--; | ||
224 | out_be16(&td->status, TD_W); /* for last TD set Wrap bit */ | ||
225 | out_be16(&td->length, 0); | ||
226 | |||
227 | /* endpoint structure has been created */ | ||
228 | usb->ep0 = ep; | ||
229 | |||
230 | return 0; | ||
231 | err: | ||
232 | fhci_ep0_free(usb); | ||
233 | kfree(ep); | ||
234 | fhci_err(usb->fhci, "no memory for the %s\n", err_for); | ||
235 | return -ENOMEM; | ||
236 | } | ||
237 | |||
238 | /* | ||
239 | * initialize the endpoint register according to the given parameters | ||
240 | * | ||
241 | * artuments: | ||
242 | * usb A pointer to the data strucutre of the USB | ||
243 | * ep A pointer to the endpoint structre | ||
244 | * data_mem The data memory partition(BUS) | ||
245 | */ | ||
246 | void fhci_init_ep_registers(struct fhci_usb *usb, struct endpoint *ep, | ||
247 | enum fhci_mem_alloc data_mem) | ||
248 | { | ||
249 | u8 rt; | ||
250 | |||
251 | /* set the endpoint registers according to the endpoint */ | ||
252 | out_be16(&usb->fhci->regs->usb_ep[0], | ||
253 | USB_TRANS_CTR | USB_EP_MF | USB_EP_RTE); | ||
254 | out_be16(&usb->fhci->pram->ep_ptr[0], | ||
255 | cpm_muram_offset(ep->ep_pram_ptr)); | ||
256 | |||
257 | rt = (BUS_MODE_BO_BE | BUS_MODE_GBL); | ||
258 | #ifdef MULTI_DATA_BUS | ||
259 | if (data_mem == MEM_SECONDARY) | ||
260 | rt |= BUS_MODE_DTB; | ||
261 | #endif | ||
262 | out_8(&ep->ep_pram_ptr->rx_func_code, rt); | ||
263 | out_8(&ep->ep_pram_ptr->tx_func_code, rt); | ||
264 | out_be16(&ep->ep_pram_ptr->rx_buff_len, 1028); | ||
265 | out_be16(&ep->ep_pram_ptr->rx_base, 0); | ||
266 | out_be16(&ep->ep_pram_ptr->tx_base, cpm_muram_offset(ep->td_base)); | ||
267 | out_be16(&ep->ep_pram_ptr->rx_bd_ptr, 0); | ||
268 | out_be16(&ep->ep_pram_ptr->tx_bd_ptr, cpm_muram_offset(ep->td_base)); | ||
269 | out_be32(&ep->ep_pram_ptr->tx_state, 0); | ||
270 | } | ||
271 | |||
272 | /* | ||
273 | * Collect the submitted frames and inform the application about them | ||
274 | * It is also prepearing the TDs for new frames. If the Tx interrupts | ||
275 | * are diabled, the application should call that routine to get | ||
276 | * confirmation about the submitted frames. Otherwise, the routine is | ||
277 | * called frome the interrupt service routine during the Tx interrupt. | ||
278 | * In that case the application is informed by calling the application | ||
279 | * specific 'fhci_transaction_confirm' routine | ||
280 | */ | ||
281 | static void fhci_td_transaction_confirm(struct fhci_usb *usb) | ||
282 | { | ||
283 | struct endpoint *ep = usb->ep0; | ||
284 | struct packet *pkt; | ||
285 | struct usb_td __iomem *td; | ||
286 | u16 extra_data; | ||
287 | u16 td_status; | ||
288 | u16 td_length; | ||
289 | u32 buf; | ||
290 | |||
291 | /* | ||
292 | * collect transmitted BDs from the chip. The routine clears all BDs | ||
293 | * with R bit = 0 and the pointer to data buffer is not NULL, that is | ||
294 | * BDs which point to the transmitted data buffer | ||
295 | */ | ||
296 | while (1) { | ||
297 | td = ep->conf_td; | ||
298 | td_status = in_be16(&td->status); | ||
299 | td_length = in_be16(&td->length); | ||
300 | buf = in_be32(&td->buf_ptr); | ||
301 | extra_data = in_be16(&td->extra); | ||
302 | |||
303 | /* check if the TD is empty */ | ||
304 | if (!(!(td_status & TD_R) && ((td_status & ~TD_W) || buf))) | ||
305 | break; | ||
306 | /* check if it is a dummy buffer */ | ||
307 | else if ((buf == DUMMY_BD_BUFFER) && !(td_status & ~TD_W)) | ||
308 | break; | ||
309 | |||
310 | /* mark TD as empty */ | ||
311 | clrbits16(&td->status, ~TD_W); | ||
312 | out_be16(&td->length, 0); | ||
313 | out_be32(&td->buf_ptr, 0); | ||
314 | out_be16(&td->extra, 0); | ||
315 | /* advance the TD pointer */ | ||
316 | ep->conf_td = next_bd(ep->td_base, ep->conf_td, td_status); | ||
317 | |||
318 | /* check if it is a dummy buffer(type2) */ | ||
319 | if ((buf == DUMMY2_BD_BUFFER) && !(td_status & ~TD_W)) | ||
320 | continue; | ||
321 | |||
322 | pkt = cq_get(ep->conf_frame_Q); | ||
323 | if (!pkt) | ||
324 | fhci_err(usb->fhci, "no frame to confirm\n"); | ||
325 | |||
326 | if (td_status & TD_ERRORS) { | ||
327 | if (td_status & TD_RXER) { | ||
328 | if (td_status & TD_CR) | ||
329 | pkt->status = USB_TD_RX_ER_CRC; | ||
330 | else if (td_status & TD_AB) | ||
331 | pkt->status = USB_TD_RX_ER_BITSTUFF; | ||
332 | else if (td_status & TD_OV) | ||
333 | pkt->status = USB_TD_RX_ER_OVERUN; | ||
334 | else if (td_status & TD_BOV) | ||
335 | pkt->status = USB_TD_RX_DATA_OVERUN; | ||
336 | else if (td_status & TD_NO) | ||
337 | pkt->status = USB_TD_RX_ER_NONOCT; | ||
338 | else | ||
339 | fhci_err(usb->fhci, "illegal error " | ||
340 | "occured\n"); | ||
341 | } else if (td_status & TD_NAK) | ||
342 | pkt->status = USB_TD_TX_ER_NAK; | ||
343 | else if (td_status & TD_TO) | ||
344 | pkt->status = USB_TD_TX_ER_TIMEOUT; | ||
345 | else if (td_status & TD_UN) | ||
346 | pkt->status = USB_TD_TX_ER_UNDERUN; | ||
347 | else if (td_status & TD_STAL) | ||
348 | pkt->status = USB_TD_TX_ER_STALL; | ||
349 | else | ||
350 | fhci_err(usb->fhci, "illegal error occured\n"); | ||
351 | } else if ((extra_data & TD_TOK_IN) && | ||
352 | pkt->len > td_length - CRC_SIZE) { | ||
353 | pkt->status = USB_TD_RX_DATA_UNDERUN; | ||
354 | } | ||
355 | |||
356 | if (extra_data & TD_TOK_IN) | ||
357 | pkt->len = td_length - CRC_SIZE; | ||
358 | else if (pkt->info & PKT_ZLP) | ||
359 | pkt->len = 0; | ||
360 | else | ||
361 | pkt->len = td_length; | ||
362 | |||
363 | fhci_transaction_confirm(usb, pkt); | ||
364 | } | ||
365 | } | ||
366 | |||
367 | /* | ||
368 | * Submitting a data frame to a specified endpoint of a USB device | ||
369 | * The frame is put in the driver's transmit queue for this endpoint | ||
370 | * | ||
371 | * Arguments: | ||
372 | * usb A pointer to the USB structure | ||
373 | * pkt A pointer to the user frame structure | ||
374 | * trans_type Transaction tyep - IN,OUT or SETUP | ||
375 | * dest_addr Device address - 0~127 | ||
376 | * dest_ep Endpoint number of the device - 0~16 | ||
377 | * trans_mode Pipe type - ISO,Interrupt,bulk or control | ||
378 | * dest_speed USB speed - Low speed or FULL speed | ||
379 | * data_toggle Data sequence toggle - 0 or 1 | ||
380 | */ | ||
381 | u32 fhci_host_transaction(struct fhci_usb *usb, | ||
382 | struct packet *pkt, | ||
383 | enum fhci_ta_type trans_type, | ||
384 | u8 dest_addr, | ||
385 | u8 dest_ep, | ||
386 | enum fhci_tf_mode trans_mode, | ||
387 | enum fhci_speed dest_speed, u8 data_toggle) | ||
388 | { | ||
389 | struct endpoint *ep = usb->ep0; | ||
390 | struct usb_td __iomem *td; | ||
391 | u16 extra_data; | ||
392 | u16 td_status; | ||
393 | |||
394 | fhci_usb_disable_interrupt(usb); | ||
395 | /* start from the next BD that should be filled */ | ||
396 | td = ep->empty_td; | ||
397 | td_status = in_be16(&td->status); | ||
398 | |||
399 | if (td_status & TD_R && in_be16(&td->length)) { | ||
400 | /* if the TD is not free */ | ||
401 | fhci_usb_enable_interrupt(usb); | ||
402 | return -1; | ||
403 | } | ||
404 | |||
405 | /* get the next TD in the ring */ | ||
406 | ep->empty_td = next_bd(ep->td_base, ep->empty_td, td_status); | ||
407 | fhci_usb_enable_interrupt(usb); | ||
408 | pkt->priv_data = td; | ||
409 | out_be32(&td->buf_ptr, virt_to_phys(pkt->data)); | ||
410 | /* sets up transaction parameters - addr,endp,dir,and type */ | ||
411 | extra_data = (dest_ep << TD_ENDP_SHIFT) | dest_addr; | ||
412 | switch (trans_type) { | ||
413 | case FHCI_TA_IN: | ||
414 | extra_data |= TD_TOK_IN; | ||
415 | break; | ||
416 | case FHCI_TA_OUT: | ||
417 | extra_data |= TD_TOK_OUT; | ||
418 | break; | ||
419 | case FHCI_TA_SETUP: | ||
420 | extra_data |= TD_TOK_SETUP; | ||
421 | break; | ||
422 | } | ||
423 | if (trans_mode == FHCI_TF_ISO) | ||
424 | extra_data |= TD_ISO; | ||
425 | out_be16(&td->extra, extra_data); | ||
426 | |||
427 | /* sets up the buffer descriptor */ | ||
428 | td_status = ((td_status & TD_W) | TD_R | TD_L | TD_I | TD_CNF); | ||
429 | if (!(pkt->info & PKT_NO_CRC)) | ||
430 | td_status |= TD_TC; | ||
431 | |||
432 | switch (trans_type) { | ||
433 | case FHCI_TA_IN: | ||
434 | if (data_toggle) | ||
435 | pkt->info |= PKT_PID_DATA1; | ||
436 | else | ||
437 | pkt->info |= PKT_PID_DATA0; | ||
438 | break; | ||
439 | default: | ||
440 | if (data_toggle) { | ||
441 | td_status |= TD_PID_DATA1; | ||
442 | pkt->info |= PKT_PID_DATA1; | ||
443 | } else { | ||
444 | td_status |= TD_PID_DATA0; | ||
445 | pkt->info |= PKT_PID_DATA0; | ||
446 | } | ||
447 | break; | ||
448 | } | ||
449 | |||
450 | if ((dest_speed == FHCI_LOW_SPEED) && | ||
451 | (usb->port_status == FHCI_PORT_FULL)) | ||
452 | td_status |= TD_LSP; | ||
453 | |||
454 | out_be16(&td->status, td_status); | ||
455 | |||
456 | /* set up buffer length */ | ||
457 | if (trans_type == FHCI_TA_IN) | ||
458 | out_be16(&td->length, pkt->len + CRC_SIZE); | ||
459 | else | ||
460 | out_be16(&td->length, pkt->len); | ||
461 | |||
462 | /* put the frame to the confirmation queue */ | ||
463 | cq_put(ep->conf_frame_Q, pkt); | ||
464 | |||
465 | if (cq_howmany(ep->conf_frame_Q) == 1) | ||
466 | out_8(&usb->fhci->regs->usb_comm, USB_CMD_STR_FIFO); | ||
467 | |||
468 | return 0; | ||
469 | } | ||
470 | |||
471 | /* Reset the Tx BD ring */ | ||
472 | void fhci_flush_bds(struct fhci_usb *usb) | ||
473 | { | ||
474 | u16 extra_data; | ||
475 | u16 td_status; | ||
476 | u32 buf; | ||
477 | struct usb_td __iomem *td; | ||
478 | struct endpoint *ep = usb->ep0; | ||
479 | |||
480 | td = ep->td_base; | ||
481 | while (1) { | ||
482 | td_status = in_be16(&td->status); | ||
483 | buf = in_be32(&td->buf_ptr); | ||
484 | extra_data = in_be16(&td->extra); | ||
485 | |||
486 | /* if the TD is not empty - we'll confirm it as Timeout */ | ||
487 | if (td_status & TD_R) | ||
488 | out_be16(&td->status, (td_status & ~TD_R) | TD_TO); | ||
489 | /* if this TD is dummy - let's skip this TD */ | ||
490 | else if (in_be32(&td->buf_ptr) == DUMMY_BD_BUFFER) | ||
491 | out_be32(&td->buf_ptr, DUMMY2_BD_BUFFER); | ||
492 | /* if this is the last TD - break */ | ||
493 | if (td_status & TD_W) | ||
494 | break; | ||
495 | |||
496 | td++; | ||
497 | } | ||
498 | |||
499 | fhci_td_transaction_confirm(usb); | ||
500 | |||
501 | td = ep->td_base; | ||
502 | do { | ||
503 | out_be16(&td->status, 0); | ||
504 | out_be16(&td->length, 0); | ||
505 | out_be32(&td->buf_ptr, 0); | ||
506 | out_be16(&td->extra, 0); | ||
507 | td++; | ||
508 | } while (!(in_be16(&td->status) & TD_W)); | ||
509 | out_be16(&td->status, TD_W); /* for last TD set Wrap bit */ | ||
510 | out_be16(&td->length, 0); | ||
511 | out_be32(&td->buf_ptr, 0); | ||
512 | out_be16(&td->extra, 0); | ||
513 | |||
514 | out_be16(&ep->ep_pram_ptr->tx_bd_ptr, | ||
515 | in_be16(&ep->ep_pram_ptr->tx_base)); | ||
516 | out_be32(&ep->ep_pram_ptr->tx_state, 0); | ||
517 | out_be16(&ep->ep_pram_ptr->tx_cnt, 0); | ||
518 | ep->empty_td = ep->td_base; | ||
519 | ep->conf_td = ep->td_base; | ||
520 | } | ||
521 | |||
522 | /* | ||
523 | * Flush all transmitted packets from TDs in the actual frame. | ||
524 | * This routine is called when something wrong with the controller and | ||
525 | * we want to get rid of the actual frame and start again next frame | ||
526 | */ | ||
527 | void fhci_flush_actual_frame(struct fhci_usb *usb) | ||
528 | { | ||
529 | u8 mode; | ||
530 | u16 tb_ptr; | ||
531 | u16 extra_data; | ||
532 | u16 td_status; | ||
533 | u32 buf_ptr; | ||
534 | struct usb_td __iomem *td; | ||
535 | struct endpoint *ep = usb->ep0; | ||
536 | |||
537 | /* disable the USB controller */ | ||
538 | mode = in_8(&usb->fhci->regs->usb_mod); | ||
539 | out_8(&usb->fhci->regs->usb_mod, mode & ~USB_MODE_EN); | ||
540 | |||
541 | tb_ptr = in_be16(&ep->ep_pram_ptr->tx_bd_ptr); | ||
542 | td = cpm_muram_addr(tb_ptr); | ||
543 | td_status = in_be16(&td->status); | ||
544 | buf_ptr = in_be32(&td->buf_ptr); | ||
545 | extra_data = in_be16(&td->extra); | ||
546 | do { | ||
547 | if (td_status & TD_R) { | ||
548 | out_be16(&td->status, (td_status & ~TD_R) | TD_TO); | ||
549 | } else { | ||
550 | out_be32(&td->buf_ptr, 0); | ||
551 | ep->already_pushed_dummy_bd = false; | ||
552 | break; | ||
553 | } | ||
554 | |||
555 | /* advance the TD pointer */ | ||
556 | td = next_bd(ep->td_base, td, td_status); | ||
557 | td_status = in_be16(&td->status); | ||
558 | buf_ptr = in_be32(&td->buf_ptr); | ||
559 | extra_data = in_be16(&td->extra); | ||
560 | } while ((td_status & TD_R) || buf_ptr); | ||
561 | |||
562 | fhci_td_transaction_confirm(usb); | ||
563 | |||
564 | out_be16(&ep->ep_pram_ptr->tx_bd_ptr, | ||
565 | in_be16(&ep->ep_pram_ptr->tx_base)); | ||
566 | out_be32(&ep->ep_pram_ptr->tx_state, 0); | ||
567 | out_be16(&ep->ep_pram_ptr->tx_cnt, 0); | ||
568 | ep->empty_td = ep->td_base; | ||
569 | ep->conf_td = ep->td_base; | ||
570 | |||
571 | usb->actual_frame->frame_status = FRAME_TIMER_END_TRANSMISSION; | ||
572 | |||
573 | /* reset the event register */ | ||
574 | out_be16(&usb->fhci->regs->usb_event, 0xffff); | ||
575 | /* enable the USB controller */ | ||
576 | out_8(&usb->fhci->regs->usb_mod, mode | USB_MODE_EN); | ||
577 | } | ||
578 | |||
579 | /* handles Tx confirm and Tx error interrupt */ | ||
580 | void fhci_tx_conf_interrupt(struct fhci_usb *usb) | ||
581 | { | ||
582 | fhci_td_transaction_confirm(usb); | ||
583 | |||
584 | /* | ||
585 | * Schedule another transaction to this frame only if we have | ||
586 | * already confirmed all transaction in the frame. | ||
587 | */ | ||
588 | if (((fhci_get_sof_timer_count(usb) < usb->max_frame_usage) || | ||
589 | (usb->actual_frame->frame_status & FRAME_END_TRANSMISSION)) && | ||
590 | (list_empty(&usb->actual_frame->tds_list))) | ||
591 | fhci_schedule_transactions(usb); | ||
592 | } | ||
593 | |||
594 | void fhci_host_transmit_actual_frame(struct fhci_usb *usb) | ||
595 | { | ||
596 | u16 tb_ptr; | ||
597 | u16 td_status; | ||
598 | struct usb_td __iomem *td; | ||
599 | struct endpoint *ep = usb->ep0; | ||
600 | |||
601 | tb_ptr = in_be16(&ep->ep_pram_ptr->tx_bd_ptr); | ||
602 | td = cpm_muram_addr(tb_ptr); | ||
603 | |||
604 | if (in_be32(&td->buf_ptr) == DUMMY_BD_BUFFER) { | ||
605 | struct usb_td __iomem *old_td = td; | ||
606 | |||
607 | ep->already_pushed_dummy_bd = false; | ||
608 | td_status = in_be16(&td->status); | ||
609 | /* gets the next TD in the ring */ | ||
610 | td = next_bd(ep->td_base, td, td_status); | ||
611 | tb_ptr = cpm_muram_offset(td); | ||
612 | out_be16(&ep->ep_pram_ptr->tx_bd_ptr, tb_ptr); | ||
613 | |||
614 | /* start transmit only if we have something in the TDs */ | ||
615 | if (in_be16(&td->status) & TD_R) | ||
616 | out_8(&usb->fhci->regs->usb_comm, USB_CMD_STR_FIFO); | ||
617 | |||
618 | if (in_be32(&ep->conf_td->buf_ptr) == DUMMY_BD_BUFFER) { | ||
619 | out_be32(&old_td->buf_ptr, 0); | ||
620 | ep->conf_td = next_bd(ep->td_base, ep->conf_td, | ||
621 | td_status); | ||
622 | } else { | ||
623 | out_be32(&old_td->buf_ptr, DUMMY2_BD_BUFFER); | ||
624 | } | ||
625 | } | ||
626 | } | ||
diff --git a/drivers/usb/host/fhci.h b/drivers/usb/host/fhci.h new file mode 100644 index 000000000000..7116284ed21a --- /dev/null +++ b/drivers/usb/host/fhci.h | |||
@@ -0,0 +1,607 @@ | |||
1 | /* | ||
2 | * Freescale QUICC Engine USB Host Controller Driver | ||
3 | * | ||
4 | * Copyright (c) Freescale Semicondutor, Inc. 2006. | ||
5 | * Shlomi Gridish <gridish@freescale.com> | ||
6 | * Jerry Huang <Chang-Ming.Huang@freescale.com> | ||
7 | * Copyright (c) Logic Product Development, Inc. 2007 | ||
8 | * Peter Barada <peterb@logicpd.com> | ||
9 | * Copyright (c) MontaVista Software, Inc. 2008. | ||
10 | * Anton Vorontsov <avorontsov@ru.mvista.com> | ||
11 | * | ||
12 | * 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 | ||
14 | * Free Software Foundation; either version 2 of the License, or (at your | ||
15 | * option) any later version. | ||
16 | */ | ||
17 | |||
18 | #ifndef __FHCI_H | ||
19 | #define __FHCI_H | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/types.h> | ||
23 | #include <linux/spinlock.h> | ||
24 | #include <linux/interrupt.h> | ||
25 | #include <linux/kfifo.h> | ||
26 | #include <linux/io.h> | ||
27 | #include <linux/usb.h> | ||
28 | #include <asm/qe.h> | ||
29 | #include "../core/hcd.h" | ||
30 | |||
31 | #define USB_CLOCK 48000000 | ||
32 | |||
33 | #define FHCI_PRAM_SIZE 0x100 | ||
34 | |||
35 | #define MAX_EDS 32 | ||
36 | #define MAX_TDS 32 | ||
37 | |||
38 | |||
39 | /* CRC16 field size */ | ||
40 | #define CRC_SIZE 2 | ||
41 | |||
42 | /* USB protocol overhead for each frame transmitted from the host */ | ||
43 | #define PROTOCOL_OVERHEAD 7 | ||
44 | |||
45 | /* Packet structure, info field */ | ||
46 | #define PKT_PID_DATA0 0x80000000 /* PID - Data toggle zero */ | ||
47 | #define PKT_PID_DATA1 0x40000000 /* PID - Data toggle one */ | ||
48 | #define PKT_PID_SETUP 0x20000000 /* PID - Setup bit */ | ||
49 | #define PKT_SETUP_STATUS 0x10000000 /* Setup status bit */ | ||
50 | #define PKT_SETADDR_STATUS 0x08000000 /* Set address status bit */ | ||
51 | #define PKT_SET_HOST_LAST 0x04000000 /* Last data packet */ | ||
52 | #define PKT_HOST_DATA 0x02000000 /* Data packet */ | ||
53 | #define PKT_FIRST_IN_FRAME 0x01000000 /* First packet in the frame */ | ||
54 | #define PKT_TOKEN_FRAME 0x00800000 /* Token packet */ | ||
55 | #define PKT_ZLP 0x00400000 /* Zero length packet */ | ||
56 | #define PKT_IN_TOKEN_FRAME 0x00200000 /* IN token packet */ | ||
57 | #define PKT_OUT_TOKEN_FRAME 0x00100000 /* OUT token packet */ | ||
58 | #define PKT_SETUP_TOKEN_FRAME 0x00080000 /* SETUP token packet */ | ||
59 | #define PKT_STALL_FRAME 0x00040000 /* STALL packet */ | ||
60 | #define PKT_NACK_FRAME 0x00020000 /* NACK packet */ | ||
61 | #define PKT_NO_PID 0x00010000 /* No PID */ | ||
62 | #define PKT_NO_CRC 0x00008000 /* don't append CRC */ | ||
63 | #define PKT_HOST_COMMAND 0x00004000 /* Host command packet */ | ||
64 | #define PKT_DUMMY_PACKET 0x00002000 /* Dummy packet, used for mmm */ | ||
65 | #define PKT_LOW_SPEED_PACKET 0x00001000 /* Low-Speed packet */ | ||
66 | |||
67 | #define TRANS_OK (0) | ||
68 | #define TRANS_INPROGRESS (-1) | ||
69 | #define TRANS_DISCARD (-2) | ||
70 | #define TRANS_FAIL (-3) | ||
71 | |||
72 | #define PS_INT 0 | ||
73 | #define PS_DISCONNECTED 1 | ||
74 | #define PS_CONNECTED 2 | ||
75 | #define PS_READY 3 | ||
76 | #define PS_MISSING 4 | ||
77 | |||
78 | /* Transfer Descriptor status field */ | ||
79 | #define USB_TD_OK 0x00000000 /* TD transmited or received ok */ | ||
80 | #define USB_TD_INPROGRESS 0x80000000 /* TD is being transmitted */ | ||
81 | #define USB_TD_RX_ER_NONOCT 0x40000000 /* Tx Non Octet Aligned Packet */ | ||
82 | #define USB_TD_RX_ER_BITSTUFF 0x20000000 /* Frame Aborted-Received pkt */ | ||
83 | #define USB_TD_RX_ER_CRC 0x10000000 /* CRC error */ | ||
84 | #define USB_TD_RX_ER_OVERUN 0x08000000 /* Over - run occured */ | ||
85 | #define USB_TD_RX_ER_PID 0x04000000 /* wrong PID received */ | ||
86 | #define USB_TD_RX_DATA_UNDERUN 0x02000000 /* shorter than expected */ | ||
87 | #define USB_TD_RX_DATA_OVERUN 0x01000000 /* longer than expected */ | ||
88 | #define USB_TD_TX_ER_NAK 0x00800000 /* NAK handshake */ | ||
89 | #define USB_TD_TX_ER_STALL 0x00400000 /* STALL handshake */ | ||
90 | #define USB_TD_TX_ER_TIMEOUT 0x00200000 /* transmit time out */ | ||
91 | #define USB_TD_TX_ER_UNDERUN 0x00100000 /* transmit underrun */ | ||
92 | |||
93 | #define USB_TD_ERROR (USB_TD_RX_ER_NONOCT | USB_TD_RX_ER_BITSTUFF | \ | ||
94 | USB_TD_RX_ER_CRC | USB_TD_RX_ER_OVERUN | USB_TD_RX_ER_PID | \ | ||
95 | USB_TD_RX_DATA_UNDERUN | USB_TD_RX_DATA_OVERUN | \ | ||
96 | USB_TD_TX_ER_NAK | USB_TD_TX_ER_STALL | \ | ||
97 | USB_TD_TX_ER_TIMEOUT | USB_TD_TX_ER_UNDERUN) | ||
98 | |||
99 | /* Transfer Descriptor toggle field */ | ||
100 | #define USB_TD_TOGGLE_DATA0 0 | ||
101 | #define USB_TD_TOGGLE_DATA1 1 | ||
102 | #define USB_TD_TOGGLE_CARRY 2 | ||
103 | |||
104 | /* #define MULTI_DATA_BUS */ | ||
105 | |||
106 | /* Bus mode register RBMR/TBMR */ | ||
107 | #define BUS_MODE_GBL 0x20 /* Global snooping */ | ||
108 | #define BUS_MODE_BO 0x18 /* Byte ordering */ | ||
109 | #define BUS_MODE_BO_BE 0x10 /* Byte ordering - Big-endian */ | ||
110 | #define BUS_MODE_DTB 0x02 /* Data bus */ | ||
111 | |||
112 | /* FHCI QE USB Register Description */ | ||
113 | |||
114 | /* USB Mode Register bit define */ | ||
115 | #define USB_MODE_EN 0x01 | ||
116 | #define USB_MODE_HOST 0x02 | ||
117 | #define USB_MODE_TEST 0x04 | ||
118 | #define USB_MODE_SFTE 0x08 | ||
119 | #define USB_MODE_RESUME 0x40 | ||
120 | #define USB_MODE_LSS 0x80 | ||
121 | |||
122 | /* USB Slave Address Register Mask */ | ||
123 | #define USB_SLVADDR_MASK 0x7F | ||
124 | |||
125 | /* USB Endpoint register define */ | ||
126 | #define USB_EPNUM_MASK 0xF000 | ||
127 | #define USB_EPNUM_SHIFT 12 | ||
128 | |||
129 | #define USB_TRANS_MODE_SHIFT 8 | ||
130 | #define USB_TRANS_CTR 0x0000 | ||
131 | #define USB_TRANS_INT 0x0100 | ||
132 | #define USB_TRANS_BULK 0x0200 | ||
133 | #define USB_TRANS_ISO 0x0300 | ||
134 | |||
135 | #define USB_EP_MF 0x0020 | ||
136 | #define USB_EP_RTE 0x0010 | ||
137 | |||
138 | #define USB_THS_SHIFT 2 | ||
139 | #define USB_THS_MASK 0x000c | ||
140 | #define USB_THS_NORMAL 0x0 | ||
141 | #define USB_THS_IGNORE_IN 0x0004 | ||
142 | #define USB_THS_NACK 0x0008 | ||
143 | #define USB_THS_STALL 0x000c | ||
144 | |||
145 | #define USB_RHS_SHIFT 0 | ||
146 | #define USB_RHS_MASK 0x0003 | ||
147 | #define USB_RHS_NORMAL 0x0 | ||
148 | #define USB_RHS_IGNORE_OUT 0x0001 | ||
149 | #define USB_RHS_NACK 0x0002 | ||
150 | #define USB_RHS_STALL 0x0003 | ||
151 | |||
152 | #define USB_RTHS_MASK 0x000f | ||
153 | |||
154 | /* USB Command Register define */ | ||
155 | #define USB_CMD_STR_FIFO 0x80 | ||
156 | #define USB_CMD_FLUSH_FIFO 0x40 | ||
157 | #define USB_CMD_ISFT 0x20 | ||
158 | #define USB_CMD_DSFT 0x10 | ||
159 | #define USB_CMD_EP_MASK 0x03 | ||
160 | |||
161 | /* USB Event and Mask Register define */ | ||
162 | #define USB_E_MSF_MASK 0x0800 | ||
163 | #define USB_E_SFT_MASK 0x0400 | ||
164 | #define USB_E_RESET_MASK 0x0200 | ||
165 | #define USB_E_IDLE_MASK 0x0100 | ||
166 | #define USB_E_TXE4_MASK 0x0080 | ||
167 | #define USB_E_TXE3_MASK 0x0040 | ||
168 | #define USB_E_TXE2_MASK 0x0020 | ||
169 | #define USB_E_TXE1_MASK 0x0010 | ||
170 | #define USB_E_SOF_MASK 0x0008 | ||
171 | #define USB_E_BSY_MASK 0x0004 | ||
172 | #define USB_E_TXB_MASK 0x0002 | ||
173 | #define USB_E_RXB_MASK 0x0001 | ||
174 | |||
175 | /* Freescale USB Host controller registers */ | ||
176 | struct fhci_regs { | ||
177 | u8 usb_mod; /* mode register */ | ||
178 | u8 usb_addr; /* address register */ | ||
179 | u8 usb_comm; /* command register */ | ||
180 | u8 reserved1[1]; | ||
181 | __be16 usb_ep[4]; /* endpoint register */ | ||
182 | u8 reserved2[4]; | ||
183 | __be16 usb_event; /* event register */ | ||
184 | u8 reserved3[2]; | ||
185 | __be16 usb_mask; /* mask register */ | ||
186 | u8 reserved4[1]; | ||
187 | u8 usb_status; /* status register */ | ||
188 | __be16 usb_sof_tmr; /* Start Of Frame timer */ | ||
189 | u8 reserved5[2]; | ||
190 | __be16 usb_frame_num; /* frame number register */ | ||
191 | u8 reserved6[1]; | ||
192 | }; | ||
193 | |||
194 | /* Freescale USB HOST */ | ||
195 | struct fhci_pram { | ||
196 | __be16 ep_ptr[4]; /* Endpoint porter reg */ | ||
197 | __be32 rx_state; /* Rx internal state */ | ||
198 | __be32 rx_ptr; /* Rx internal data pointer */ | ||
199 | __be16 frame_num; /* Frame number */ | ||
200 | __be16 rx_cnt; /* Rx byte count */ | ||
201 | __be32 rx_temp; /* Rx temp */ | ||
202 | __be32 rx_data_temp; /* Rx data temp */ | ||
203 | __be16 rx_u_ptr; /* Rx microcode return address temp */ | ||
204 | u8 reserved1[2]; /* reserved area */ | ||
205 | __be32 sof_tbl; /* SOF lookup table pointer */ | ||
206 | u8 sof_u_crc_temp; /* SOF micorcode CRC5 temp reg */ | ||
207 | u8 reserved2[0xdb]; | ||
208 | }; | ||
209 | |||
210 | /* Freescale USB Endpoint*/ | ||
211 | struct fhci_ep_pram { | ||
212 | __be16 rx_base; /* Rx BD base address */ | ||
213 | __be16 tx_base; /* Tx BD base address */ | ||
214 | u8 rx_func_code; /* Rx function code */ | ||
215 | u8 tx_func_code; /* Tx function code */ | ||
216 | __be16 rx_buff_len; /* Rx buffer length */ | ||
217 | __be16 rx_bd_ptr; /* Rx BD pointer */ | ||
218 | __be16 tx_bd_ptr; /* Tx BD pointer */ | ||
219 | __be32 tx_state; /* Tx internal state */ | ||
220 | __be32 tx_ptr; /* Tx internal data pointer */ | ||
221 | __be16 tx_crc; /* temp transmit CRC */ | ||
222 | __be16 tx_cnt; /* Tx byte count */ | ||
223 | __be32 tx_temp; /* Tx temp */ | ||
224 | __be16 tx_u_ptr; /* Tx microcode return address temp */ | ||
225 | __be16 reserved; | ||
226 | }; | ||
227 | |||
228 | struct fhci_controller_list { | ||
229 | struct list_head ctrl_list; /* control endpoints */ | ||
230 | struct list_head bulk_list; /* bulk endpoints */ | ||
231 | struct list_head iso_list; /* isochronous endpoints */ | ||
232 | struct list_head intr_list; /* interruput endpoints */ | ||
233 | struct list_head done_list; /* done transfers */ | ||
234 | }; | ||
235 | |||
236 | struct virtual_root_hub { | ||
237 | int dev_num; /* USB address of the root hub */ | ||
238 | u32 feature; /* indicates what feature has been set */ | ||
239 | struct usb_hub_status hub; | ||
240 | struct usb_port_status port; | ||
241 | }; | ||
242 | |||
243 | enum fhci_gpios { | ||
244 | GPIO_USBOE = 0, | ||
245 | GPIO_USBTP, | ||
246 | GPIO_USBTN, | ||
247 | GPIO_USBRP, | ||
248 | GPIO_USBRN, | ||
249 | /* these are optional */ | ||
250 | GPIO_SPEED, | ||
251 | GPIO_POWER, | ||
252 | NUM_GPIOS, | ||
253 | }; | ||
254 | |||
255 | enum fhci_pins { | ||
256 | PIN_USBOE = 0, | ||
257 | PIN_USBTP, | ||
258 | PIN_USBTN, | ||
259 | NUM_PINS, | ||
260 | }; | ||
261 | |||
262 | struct fhci_hcd { | ||
263 | enum qe_clock fullspeed_clk; | ||
264 | enum qe_clock lowspeed_clk; | ||
265 | struct qe_pin *pins[NUM_PINS]; | ||
266 | int gpios[NUM_GPIOS]; | ||
267 | bool alow_gpios[NUM_GPIOS]; | ||
268 | |||
269 | struct fhci_regs __iomem *regs; /* I/O memory used to communicate */ | ||
270 | struct fhci_pram __iomem *pram; /* Parameter RAM */ | ||
271 | struct gtm_timer *timer; | ||
272 | |||
273 | spinlock_t lock; | ||
274 | struct fhci_usb *usb_lld; /* Low-level driver */ | ||
275 | struct virtual_root_hub *vroot_hub; /* the virtual root hub */ | ||
276 | int active_urbs; | ||
277 | struct fhci_controller_list *hc_list; | ||
278 | struct tasklet_struct *process_done_task; /* tasklet for done list */ | ||
279 | |||
280 | struct list_head empty_eds; | ||
281 | struct list_head empty_tds; | ||
282 | |||
283 | #ifdef CONFIG_FHCI_DEBUG | ||
284 | int usb_irq_stat[13]; | ||
285 | struct dentry *dfs_root; | ||
286 | struct dentry *dfs_regs; | ||
287 | struct dentry *dfs_irq_stat; | ||
288 | #endif | ||
289 | }; | ||
290 | |||
291 | #define USB_FRAME_USAGE 90 | ||
292 | #define FRAME_TIME_USAGE (USB_FRAME_USAGE*10) /* frame time usage */ | ||
293 | #define SW_FIX_TIME_BETWEEN_TRANSACTION 150 /* SW */ | ||
294 | #define MAX_BYTES_PER_FRAME (USB_FRAME_USAGE*15) | ||
295 | #define MAX_PERIODIC_FRAME_USAGE 90 | ||
296 | |||
297 | /* transaction type */ | ||
298 | enum fhci_ta_type { | ||
299 | FHCI_TA_IN = 0, /* input transaction */ | ||
300 | FHCI_TA_OUT, /* output transaction */ | ||
301 | FHCI_TA_SETUP, /* setup transaction */ | ||
302 | }; | ||
303 | |||
304 | /* transfer mode */ | ||
305 | enum fhci_tf_mode { | ||
306 | FHCI_TF_CTRL = 0, | ||
307 | FHCI_TF_ISO, | ||
308 | FHCI_TF_BULK, | ||
309 | FHCI_TF_INTR, | ||
310 | }; | ||
311 | |||
312 | enum fhci_speed { | ||
313 | FHCI_FULL_SPEED, | ||
314 | FHCI_LOW_SPEED, | ||
315 | }; | ||
316 | |||
317 | /* endpoint state */ | ||
318 | enum fhci_ed_state { | ||
319 | FHCI_ED_NEW = 0, /* pipe is new */ | ||
320 | FHCI_ED_OPER, /* pipe is operating */ | ||
321 | FHCI_ED_URB_DEL, /* pipe is in hold because urb is being deleted */ | ||
322 | FHCI_ED_SKIP, /* skip this pipe */ | ||
323 | FHCI_ED_HALTED, /* pipe is halted */ | ||
324 | }; | ||
325 | |||
326 | enum fhci_port_status { | ||
327 | FHCI_PORT_POWER_OFF = 0, | ||
328 | FHCI_PORT_DISABLED, | ||
329 | FHCI_PORT_DISCONNECTING, | ||
330 | FHCI_PORT_WAITING, /* waiting for connection */ | ||
331 | FHCI_PORT_FULL, /* full speed connected */ | ||
332 | FHCI_PORT_LOW, /* low speed connected */ | ||
333 | }; | ||
334 | |||
335 | enum fhci_mem_alloc { | ||
336 | MEM_CACHABLE_SYS = 0x00000001, /* primary DDR,cachable */ | ||
337 | MEM_NOCACHE_SYS = 0x00000004, /* primary DDR,non-cachable */ | ||
338 | MEM_SECONDARY = 0x00000002, /* either secondary DDR or SDRAM */ | ||
339 | MEM_PRAM = 0x00000008, /* multi-user RAM identifier */ | ||
340 | }; | ||
341 | |||
342 | /* USB default parameters*/ | ||
343 | #define DEFAULT_RING_LEN 8 | ||
344 | #define DEFAULT_DATA_MEM MEM_CACHABLE_SYS | ||
345 | |||
346 | struct ed { | ||
347 | u8 dev_addr; /* device address */ | ||
348 | u8 ep_addr; /* endpoint address */ | ||
349 | enum fhci_tf_mode mode; /* USB transfer mode */ | ||
350 | enum fhci_speed speed; | ||
351 | unsigned int max_pkt_size; | ||
352 | enum fhci_ed_state state; | ||
353 | struct list_head td_list; /* a list of all queued TD to this pipe */ | ||
354 | struct list_head node; | ||
355 | |||
356 | /* read only parameters, should be cleared upon initialization */ | ||
357 | u8 toggle_carry; /* toggle carry from the last TD submitted */ | ||
358 | u32 last_iso; /* time stamp of last queued ISO transfer */ | ||
359 | struct td *td_head; /* a pointer to the current TD handled */ | ||
360 | }; | ||
361 | |||
362 | struct td { | ||
363 | void *data; /* a pointer to the data buffer */ | ||
364 | unsigned int len; /* length of the data to be submitted */ | ||
365 | unsigned int actual_len; /* actual bytes transfered on this td */ | ||
366 | enum fhci_ta_type type; /* transaction type */ | ||
367 | u8 toggle; /* toggle for next trans. within this TD */ | ||
368 | u16 iso_index; /* ISO transaction index */ | ||
369 | u16 start_frame; /* start frame time stamp */ | ||
370 | u16 interval; /* interval between trans. (for ISO/Intr) */ | ||
371 | u32 status; /* status of the TD */ | ||
372 | struct ed *ed; /* a handle to the corresponding ED */ | ||
373 | struct urb *urb; /* a handle to the corresponding URB */ | ||
374 | bool ioc; /* Inform On Completion */ | ||
375 | struct list_head node; | ||
376 | |||
377 | /* read only parameters should be cleared upon initialization */ | ||
378 | struct packet *pkt; | ||
379 | int nak_cnt; | ||
380 | int error_cnt; | ||
381 | struct list_head frame_lh; | ||
382 | }; | ||
383 | |||
384 | struct packet { | ||
385 | u8 *data; /* packet data */ | ||
386 | u32 len; /* packet length */ | ||
387 | u32 status; /* status of the packet - equivalent to the status | ||
388 | * field for the corresponding structure td */ | ||
389 | u32 info; /* packet information */ | ||
390 | void __iomem *priv_data; /* private data of the driver (TDs or BDs) */ | ||
391 | }; | ||
392 | |||
393 | /* struct for each URB */ | ||
394 | #define URB_INPROGRESS 0 | ||
395 | #define URB_DEL 1 | ||
396 | |||
397 | /* URB states (state field) */ | ||
398 | #define US_BULK 0 | ||
399 | #define US_BULK0 1 | ||
400 | |||
401 | /* three setup states */ | ||
402 | #define US_CTRL_SETUP 2 | ||
403 | #define US_CTRL_DATA 1 | ||
404 | #define US_CTRL_ACK 0 | ||
405 | |||
406 | #define EP_ZERO 0 | ||
407 | |||
408 | struct urb_priv { | ||
409 | int num_of_tds; | ||
410 | int tds_cnt; | ||
411 | int state; | ||
412 | |||
413 | struct td **tds; | ||
414 | struct ed *ed; | ||
415 | struct timer_list time_out; | ||
416 | }; | ||
417 | |||
418 | struct endpoint { | ||
419 | /* Pointer to ep parameter RAM */ | ||
420 | struct fhci_ep_pram __iomem *ep_pram_ptr; | ||
421 | |||
422 | /* Host transactions */ | ||
423 | struct usb_td __iomem *td_base; /* first TD in the ring */ | ||
424 | struct usb_td __iomem *conf_td; /* next TD for confirm after transac */ | ||
425 | struct usb_td __iomem *empty_td;/* next TD for new transaction req. */ | ||
426 | struct kfifo *empty_frame_Q; /* Empty frames list to use */ | ||
427 | struct kfifo *conf_frame_Q; /* frames passed to TDs,waiting for tx */ | ||
428 | struct kfifo *dummy_packets_Q;/* dummy packets for the CRC overun */ | ||
429 | |||
430 | bool already_pushed_dummy_bd; | ||
431 | }; | ||
432 | |||
433 | /* struct for each 1mSec frame time */ | ||
434 | #define FRAME_IS_TRANSMITTED 0x00 | ||
435 | #define FRAME_TIMER_END_TRANSMISSION 0x01 | ||
436 | #define FRAME_DATA_END_TRANSMISSION 0x02 | ||
437 | #define FRAME_END_TRANSMISSION 0x03 | ||
438 | #define FRAME_IS_PREPARED 0x04 | ||
439 | |||
440 | struct fhci_time_frame { | ||
441 | u16 frame_num; /* frame number */ | ||
442 | u16 total_bytes; /* total bytes submitted within this frame */ | ||
443 | u8 frame_status; /* flag that indicates to stop fill this frame */ | ||
444 | struct list_head tds_list; /* all tds of this frame */ | ||
445 | }; | ||
446 | |||
447 | /* internal driver structure*/ | ||
448 | struct fhci_usb { | ||
449 | u16 saved_msk; /* saving of the USB mask register */ | ||
450 | struct endpoint *ep0; /* pointer for endpoint0 structure */ | ||
451 | int intr_nesting_cnt; /* interrupt nesting counter */ | ||
452 | u16 max_frame_usage; /* max frame time usage,in micro-sec */ | ||
453 | u16 max_bytes_per_frame; /* max byte can be tx in one time frame */ | ||
454 | u32 sw_transaction_time; /* sw complete trans time,in micro-sec */ | ||
455 | struct fhci_time_frame *actual_frame; | ||
456 | struct fhci_controller_list *hc_list; /* main structure for hc */ | ||
457 | struct virtual_root_hub *vroot_hub; | ||
458 | enum fhci_port_status port_status; /* v_rh port status */ | ||
459 | |||
460 | u32 (*transfer_confirm)(struct fhci_hcd *fhci); | ||
461 | |||
462 | struct fhci_hcd *fhci; | ||
463 | }; | ||
464 | |||
465 | /* | ||
466 | * Various helpers and prototypes below. | ||
467 | */ | ||
468 | |||
469 | static inline u16 get_frame_num(struct fhci_hcd *fhci) | ||
470 | { | ||
471 | return in_be16(&fhci->pram->frame_num) & 0x07ff; | ||
472 | } | ||
473 | |||
474 | #define fhci_dbg(fhci, fmt, args...) \ | ||
475 | dev_dbg(fhci_to_hcd(fhci)->self.controller, fmt, ##args) | ||
476 | #define fhci_vdbg(fhci, fmt, args...) \ | ||
477 | dev_vdbg(fhci_to_hcd(fhci)->self.controller, fmt, ##args) | ||
478 | #define fhci_err(fhci, fmt, args...) \ | ||
479 | dev_err(fhci_to_hcd(fhci)->self.controller, fmt, ##args) | ||
480 | #define fhci_info(fhci, fmt, args...) \ | ||
481 | dev_info(fhci_to_hcd(fhci)->self.controller, fmt, ##args) | ||
482 | #define fhci_warn(fhci, fmt, args...) \ | ||
483 | dev_warn(fhci_to_hcd(fhci)->self.controller, fmt, ##args) | ||
484 | |||
485 | static inline struct fhci_hcd *hcd_to_fhci(struct usb_hcd *hcd) | ||
486 | { | ||
487 | return (struct fhci_hcd *)hcd->hcd_priv; | ||
488 | } | ||
489 | |||
490 | static inline struct usb_hcd *fhci_to_hcd(struct fhci_hcd *fhci) | ||
491 | { | ||
492 | return container_of((void *)fhci, struct usb_hcd, hcd_priv); | ||
493 | } | ||
494 | |||
495 | /* fifo of pointers */ | ||
496 | static inline struct kfifo *cq_new(int size) | ||
497 | { | ||
498 | return kfifo_alloc(size * sizeof(void *), GFP_KERNEL, NULL); | ||
499 | } | ||
500 | |||
501 | static inline void cq_delete(struct kfifo *kfifo) | ||
502 | { | ||
503 | kfifo_free(kfifo); | ||
504 | } | ||
505 | |||
506 | static inline unsigned int cq_howmany(struct kfifo *kfifo) | ||
507 | { | ||
508 | return __kfifo_len(kfifo) / sizeof(void *); | ||
509 | } | ||
510 | |||
511 | static inline int cq_put(struct kfifo *kfifo, void *p) | ||
512 | { | ||
513 | return __kfifo_put(kfifo, (void *)&p, sizeof(p)); | ||
514 | } | ||
515 | |||
516 | static inline void *cq_get(struct kfifo *kfifo) | ||
517 | { | ||
518 | void *p = NULL; | ||
519 | |||
520 | __kfifo_get(kfifo, (void *)&p, sizeof(p)); | ||
521 | return p; | ||
522 | } | ||
523 | |||
524 | /* fhci-hcd.c */ | ||
525 | void fhci_start_sof_timer(struct fhci_hcd *fhci); | ||
526 | void fhci_stop_sof_timer(struct fhci_hcd *fhci); | ||
527 | u16 fhci_get_sof_timer_count(struct fhci_usb *usb); | ||
528 | void fhci_usb_enable_interrupt(struct fhci_usb *usb); | ||
529 | void fhci_usb_disable_interrupt(struct fhci_usb *usb); | ||
530 | int fhci_ioports_check_bus_state(struct fhci_hcd *fhci); | ||
531 | |||
532 | /* fhci-mem.c */ | ||
533 | void fhci_recycle_empty_td(struct fhci_hcd *fhci, struct td *td); | ||
534 | void fhci_recycle_empty_ed(struct fhci_hcd *fhci, struct ed *ed); | ||
535 | struct ed *fhci_get_empty_ed(struct fhci_hcd *fhci); | ||
536 | struct td *fhci_td_fill(struct fhci_hcd *fhci, struct urb *urb, | ||
537 | struct urb_priv *urb_priv, struct ed *ed, u16 index, | ||
538 | enum fhci_ta_type type, int toggle, u8 *data, u32 len, | ||
539 | u16 interval, u16 start_frame, bool ioc); | ||
540 | void fhci_add_tds_to_ed(struct ed *ed, struct td **td_list, int number); | ||
541 | |||
542 | /* fhci-hub.c */ | ||
543 | void fhci_config_transceiver(struct fhci_hcd *fhci, | ||
544 | enum fhci_port_status status); | ||
545 | void fhci_port_disable(struct fhci_hcd *fhci); | ||
546 | void fhci_port_enable(void *lld); | ||
547 | void fhci_io_port_generate_reset(struct fhci_hcd *fhci); | ||
548 | void fhci_port_reset(void *lld); | ||
549 | int fhci_hub_status_data(struct usb_hcd *hcd, char *buf); | ||
550 | int fhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | ||
551 | u16 wIndex, char *buf, u16 wLength); | ||
552 | |||
553 | /* fhci-tds.c */ | ||
554 | void fhci_flush_bds(struct fhci_usb *usb); | ||
555 | void fhci_flush_actual_frame(struct fhci_usb *usb); | ||
556 | u32 fhci_host_transaction(struct fhci_usb *usb, struct packet *pkt, | ||
557 | enum fhci_ta_type trans_type, u8 dest_addr, | ||
558 | u8 dest_ep, enum fhci_tf_mode trans_mode, | ||
559 | enum fhci_speed dest_speed, u8 data_toggle); | ||
560 | void fhci_host_transmit_actual_frame(struct fhci_usb *usb); | ||
561 | void fhci_tx_conf_interrupt(struct fhci_usb *usb); | ||
562 | void fhci_push_dummy_bd(struct endpoint *ep); | ||
563 | u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem, | ||
564 | u32 ring_len); | ||
565 | void fhci_init_ep_registers(struct fhci_usb *usb, | ||
566 | struct endpoint *ep, | ||
567 | enum fhci_mem_alloc data_mem); | ||
568 | void fhci_ep0_free(struct fhci_usb *usb); | ||
569 | |||
570 | /* fhci-sched.c */ | ||
571 | extern struct tasklet_struct fhci_tasklet; | ||
572 | void fhci_transaction_confirm(struct fhci_usb *usb, struct packet *pkt); | ||
573 | void fhci_flush_all_transmissions(struct fhci_usb *usb); | ||
574 | void fhci_schedule_transactions(struct fhci_usb *usb); | ||
575 | void fhci_device_connected_interrupt(struct fhci_hcd *fhci); | ||
576 | void fhci_device_disconnected_interrupt(struct fhci_hcd *fhci); | ||
577 | void fhci_queue_urb(struct fhci_hcd *fhci, struct urb *urb); | ||
578 | u32 fhci_transfer_confirm_callback(struct fhci_hcd *fhci); | ||
579 | irqreturn_t fhci_irq(struct usb_hcd *hcd); | ||
580 | irqreturn_t fhci_frame_limit_timer_irq(int irq, void *_hcd); | ||
581 | |||
582 | /* fhci-q.h */ | ||
583 | void fhci_urb_complete_free(struct fhci_hcd *fhci, struct urb *urb); | ||
584 | struct td *fhci_remove_td_from_ed(struct ed *ed); | ||
585 | struct td *fhci_remove_td_from_frame(struct fhci_time_frame *frame); | ||
586 | void fhci_move_td_from_ed_to_done_list(struct fhci_usb *usb, struct ed *ed); | ||
587 | struct td *fhci_peek_td_from_frame(struct fhci_time_frame *frame); | ||
588 | void fhci_add_td_to_frame(struct fhci_time_frame *frame, struct td *td); | ||
589 | struct td *fhci_remove_td_from_done_list(struct fhci_controller_list *p_list); | ||
590 | void fhci_done_td(struct urb *urb, struct td *td); | ||
591 | void fhci_del_ed_list(struct fhci_hcd *fhci, struct ed *ed); | ||
592 | |||
593 | #ifdef CONFIG_FHCI_DEBUG | ||
594 | |||
595 | void fhci_dbg_isr(struct fhci_hcd *fhci, int usb_er); | ||
596 | void fhci_dfs_destroy(struct fhci_hcd *fhci); | ||
597 | void fhci_dfs_create(struct fhci_hcd *fhci); | ||
598 | |||
599 | #else | ||
600 | |||
601 | static inline void fhci_dbg_isr(struct fhci_hcd *fhci, int usb_er) {} | ||
602 | static inline void fhci_dfs_destroy(struct fhci_hcd *fhci) {} | ||
603 | static inline void fhci_dfs_create(struct fhci_hcd *fhci) {} | ||
604 | |||
605 | #endif /* CONFIG_FHCI_DEBUG */ | ||
606 | |||
607 | #endif /* __FHCI_H */ | ||
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 65a9609f4ad6..25db704f3a2a 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -593,12 +593,10 @@ static int ohci_run (struct ohci_hcd *ohci) | |||
593 | * to be checked in case boot firmware (BIOS/SMM/...) has set up | 593 | * to be checked in case boot firmware (BIOS/SMM/...) has set up |
594 | * wakeup in a way the bus isn't aware of (e.g., legacy PCI PM). | 594 | * wakeup in a way the bus isn't aware of (e.g., legacy PCI PM). |
595 | * If the bus glue detected wakeup capability then it should | 595 | * If the bus glue detected wakeup capability then it should |
596 | * already be enabled. Either way, if wakeup should be enabled | 596 | * already be enabled; if so we'll just enable it again. |
597 | * but isn't, we'll enable it now. | ||
598 | */ | 597 | */ |
599 | if ((ohci->hc_control & OHCI_CTRL_RWC) != 0 | 598 | if ((ohci->hc_control & OHCI_CTRL_RWC) != 0) |
600 | && !device_can_wakeup(hcd->self.controller)) | 599 | device_set_wakeup_capable(hcd->self.controller, 1); |
601 | device_init_wakeup(hcd->self.controller, 1); | ||
602 | 600 | ||
603 | switch (ohci->hc_control & OHCI_CTRL_HCFS) { | 601 | switch (ohci->hc_control & OHCI_CTRL_HCFS) { |
604 | case OHCI_USB_OPER: | 602 | case OHCI_USB_OPER: |
@@ -999,7 +997,7 @@ MODULE_LICENSE ("GPL"); | |||
999 | #define SA1111_DRIVER ohci_hcd_sa1111_driver | 997 | #define SA1111_DRIVER ohci_hcd_sa1111_driver |
1000 | #endif | 998 | #endif |
1001 | 999 | ||
1002 | #ifdef CONFIG_ARCH_S3C2410 | 1000 | #if defined(CONFIG_ARCH_S3C2410) || defined(CONFIG_ARCH_S3C64XX) |
1003 | #include "ohci-s3c2410.c" | 1001 | #include "ohci-s3c2410.c" |
1004 | #define PLATFORM_DRIVER ohci_hcd_s3c2410_driver | 1002 | #define PLATFORM_DRIVER ohci_hcd_s3c2410_driver |
1005 | #endif | 1003 | #endif |
@@ -1051,7 +1049,8 @@ MODULE_LICENSE ("GPL"); | |||
1051 | 1049 | ||
1052 | #if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ | 1050 | #if defined(CONFIG_CPU_SUBTYPE_SH7720) || \ |
1053 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ | 1051 | defined(CONFIG_CPU_SUBTYPE_SH7721) || \ |
1054 | defined(CONFIG_CPU_SUBTYPE_SH7763) | 1052 | defined(CONFIG_CPU_SUBTYPE_SH7763) || \ |
1053 | defined(CONFIG_CPU_SUBTYPE_SH7786) | ||
1055 | #include "ohci-sh.c" | 1054 | #include "ohci-sh.c" |
1056 | #define PLATFORM_DRIVER ohci_hcd_sh_driver | 1055 | #define PLATFORM_DRIVER ohci_hcd_sh_driver |
1057 | #endif | 1056 | #endif |
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 4bbddb73abd9..f3aaba35e912 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c | |||
@@ -315,14 +315,14 @@ static int usb_hcd_omap_probe (const struct hc_driver *driver, | |||
315 | return -ENODEV; | 315 | return -ENODEV; |
316 | } | 316 | } |
317 | 317 | ||
318 | usb_host_ck = clk_get(0, "usb_hhc_ck"); | 318 | usb_host_ck = clk_get(&pdev->dev, "usb_hhc_ck"); |
319 | if (IS_ERR(usb_host_ck)) | 319 | if (IS_ERR(usb_host_ck)) |
320 | return PTR_ERR(usb_host_ck); | 320 | return PTR_ERR(usb_host_ck); |
321 | 321 | ||
322 | if (!cpu_is_omap15xx()) | 322 | if (!cpu_is_omap15xx()) |
323 | usb_dc_ck = clk_get(0, "usb_dc_ck"); | 323 | usb_dc_ck = clk_get(&pdev->dev, "usb_dc_ck"); |
324 | else | 324 | else |
325 | usb_dc_ck = clk_get(0, "lb_ck"); | 325 | usb_dc_ck = clk_get(&pdev->dev, "lb_ck"); |
326 | 326 | ||
327 | if (IS_ERR(usb_dc_ck)) { | 327 | if (IS_ERR(usb_dc_ck)) { |
328 | clk_put(usb_host_ck); | 328 | clk_put(usb_host_ck); |
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 8b28ae7865ba..f9961b4c0da3 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -487,8 +487,6 @@ static struct pci_driver ohci_pci_driver = { | |||
487 | 487 | ||
488 | #ifdef CONFIG_PM | 488 | #ifdef CONFIG_PM |
489 | .suspend = usb_hcd_pci_suspend, | 489 | .suspend = usb_hcd_pci_suspend, |
490 | .suspend_late = usb_hcd_pci_suspend_late, | ||
491 | .resume_early = usb_hcd_pci_resume_early, | ||
492 | .resume = usb_hcd_pci_resume, | 490 | .resume = usb_hcd_pci_resume, |
493 | #endif | 491 | #endif |
494 | 492 | ||
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.c b/drivers/usb/host/uhci-hcd.c index 4e221060f58c..cf5e4cf7ea42 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -942,8 +942,6 @@ static struct pci_driver uhci_pci_driver = { | |||
942 | 942 | ||
943 | #ifdef CONFIG_PM | 943 | #ifdef CONFIG_PM |
944 | .suspend = usb_hcd_pci_suspend, | 944 | .suspend = usb_hcd_pci_suspend, |
945 | .suspend_late = usb_hcd_pci_suspend_late, | ||
946 | .resume_early = usb_hcd_pci_resume_early, | ||
947 | .resume = usb_hcd_pci_resume, | 945 | .resume = usb_hcd_pci_resume, |
948 | #endif /* PM */ | 946 | #endif /* PM */ |
949 | }; | 947 | }; |
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/host/whci/asl.c b/drivers/usb/host/whci/asl.c index 577c0d29849d..958751ccea43 100644 --- a/drivers/usb/host/whci/asl.c +++ b/drivers/usb/host/whci/asl.c | |||
@@ -170,12 +170,17 @@ void asl_stop(struct whc *whc) | |||
170 | void asl_update(struct whc *whc, uint32_t wusbcmd) | 170 | void asl_update(struct whc *whc, uint32_t wusbcmd) |
171 | { | 171 | { |
172 | struct wusbhc *wusbhc = &whc->wusbhc; | 172 | struct wusbhc *wusbhc = &whc->wusbhc; |
173 | long t; | ||
173 | 174 | ||
174 | mutex_lock(&wusbhc->mutex); | 175 | mutex_lock(&wusbhc->mutex); |
175 | if (wusbhc->active) { | 176 | if (wusbhc->active) { |
176 | whc_write_wusbcmd(whc, wusbcmd, wusbcmd); | 177 | whc_write_wusbcmd(whc, wusbcmd, wusbcmd); |
177 | wait_event(whc->async_list_wq, | 178 | t = wait_event_timeout( |
178 | (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0); | 179 | whc->async_list_wq, |
180 | (le_readl(whc->base + WUSBCMD) & WUSBCMD_ASYNC_UPDATED) == 0, | ||
181 | msecs_to_jiffies(1000)); | ||
182 | if (t == 0) | ||
183 | whc_hw_error(whc, "ASL update timeout"); | ||
179 | } | 184 | } |
180 | mutex_unlock(&wusbhc->mutex); | 185 | mutex_unlock(&wusbhc->mutex); |
181 | } | 186 | } |
@@ -222,13 +227,13 @@ void scan_async_work(struct work_struct *work) | |||
222 | * Now that the ASL is updated, complete the removal of any | 227 | * Now that the ASL is updated, complete the removal of any |
223 | * removed qsets. | 228 | * removed qsets. |
224 | */ | 229 | */ |
225 | spin_lock(&whc->lock); | 230 | spin_lock_irq(&whc->lock); |
226 | 231 | ||
227 | list_for_each_entry_safe(qset, t, &whc->async_removed_list, list_node) { | 232 | list_for_each_entry_safe(qset, t, &whc->async_removed_list, list_node) { |
228 | qset_remove_complete(whc, qset); | 233 | qset_remove_complete(whc, qset); |
229 | } | 234 | } |
230 | 235 | ||
231 | spin_unlock(&whc->lock); | 236 | spin_unlock_irq(&whc->lock); |
232 | } | 237 | } |
233 | 238 | ||
234 | /** | 239 | /** |
diff --git a/drivers/usb/host/whci/hw.c b/drivers/usb/host/whci/hw.c index d498e7203217..6afa2e379160 100644 --- a/drivers/usb/host/whci/hw.c +++ b/drivers/usb/host/whci/hw.c | |||
@@ -87,3 +87,18 @@ out: | |||
87 | 87 | ||
88 | return ret; | 88 | return ret; |
89 | } | 89 | } |
90 | |||
91 | /** | ||
92 | * whc_hw_error - recover from a hardware error | ||
93 | * @whc: the WHCI HC that broke. | ||
94 | * @reason: a description of the failure. | ||
95 | * | ||
96 | * Recover from broken hardware with a full reset. | ||
97 | */ | ||
98 | void whc_hw_error(struct whc *whc, const char *reason) | ||
99 | { | ||
100 | struct wusbhc *wusbhc = &whc->wusbhc; | ||
101 | |||
102 | dev_err(&whc->umc->dev, "hardware error: %s\n", reason); | ||
103 | wusbhc_reset_all(wusbhc); | ||
104 | } | ||
diff --git a/drivers/usb/host/whci/pzl.c b/drivers/usb/host/whci/pzl.c index 2ae5abf69a6a..df8b85f07092 100644 --- a/drivers/usb/host/whci/pzl.c +++ b/drivers/usb/host/whci/pzl.c | |||
@@ -183,12 +183,17 @@ void pzl_stop(struct whc *whc) | |||
183 | void pzl_update(struct whc *whc, uint32_t wusbcmd) | 183 | void pzl_update(struct whc *whc, uint32_t wusbcmd) |
184 | { | 184 | { |
185 | struct wusbhc *wusbhc = &whc->wusbhc; | 185 | struct wusbhc *wusbhc = &whc->wusbhc; |
186 | long t; | ||
186 | 187 | ||
187 | mutex_lock(&wusbhc->mutex); | 188 | mutex_lock(&wusbhc->mutex); |
188 | if (wusbhc->active) { | 189 | if (wusbhc->active) { |
189 | whc_write_wusbcmd(whc, wusbcmd, wusbcmd); | 190 | whc_write_wusbcmd(whc, wusbcmd, wusbcmd); |
190 | wait_event(whc->periodic_list_wq, | 191 | t = wait_event_timeout( |
191 | (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0); | 192 | whc->periodic_list_wq, |
193 | (le_readl(whc->base + WUSBCMD) & WUSBCMD_PERIODIC_UPDATED) == 0, | ||
194 | msecs_to_jiffies(1000)); | ||
195 | if (t == 0) | ||
196 | whc_hw_error(whc, "PZL update timeout"); | ||
192 | } | 197 | } |
193 | mutex_unlock(&wusbhc->mutex); | 198 | mutex_unlock(&wusbhc->mutex); |
194 | } | 199 | } |
@@ -250,13 +255,13 @@ void scan_periodic_work(struct work_struct *work) | |||
250 | * Now that the PZL is updated, complete the removal of any | 255 | * Now that the PZL is updated, complete the removal of any |
251 | * removed qsets. | 256 | * removed qsets. |
252 | */ | 257 | */ |
253 | spin_lock(&whc->lock); | 258 | spin_lock_irq(&whc->lock); |
254 | 259 | ||
255 | list_for_each_entry_safe(qset, t, &whc->periodic_removed_list, list_node) { | 260 | list_for_each_entry_safe(qset, t, &whc->periodic_removed_list, list_node) { |
256 | qset_remove_complete(whc, qset); | 261 | qset_remove_complete(whc, qset); |
257 | } | 262 | } |
258 | 263 | ||
259 | spin_unlock(&whc->lock); | 264 | spin_unlock_irq(&whc->lock); |
260 | } | 265 | } |
261 | 266 | ||
262 | /** | 267 | /** |
diff --git a/drivers/usb/host/whci/whcd.h b/drivers/usb/host/whci/whcd.h index 0f3540f04f53..d3543a181dc9 100644 --- a/drivers/usb/host/whci/whcd.h +++ b/drivers/usb/host/whci/whcd.h | |||
@@ -137,6 +137,7 @@ void whc_clean_up(struct whc *whc); | |||
137 | /* hw.c */ | 137 | /* hw.c */ |
138 | void whc_write_wusbcmd(struct whc *whc, u32 mask, u32 val); | 138 | void whc_write_wusbcmd(struct whc *whc, u32 mask, u32 val); |
139 | int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len); | 139 | int whc_do_gencmd(struct whc *whc, u32 cmd, u32 params, void *addr, size_t len); |
140 | void whc_hw_error(struct whc *whc, const char *reason); | ||
140 | 141 | ||
141 | /* wusb.c */ | 142 | /* wusb.c */ |
142 | int whc_wusbhc_start(struct wusbhc *wusbhc); | 143 | int whc_wusbhc_start(struct wusbhc *wusbhc); |
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index 878c77ca086e..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, |
@@ -499,6 +499,7 @@ static int mdc800_usb_probe (struct usb_interface *intf, | |||
499 | retval = usb_register_dev(intf, &mdc800_class); | 499 | retval = usb_register_dev(intf, &mdc800_class); |
500 | if (retval) { | 500 | if (retval) { |
501 | dev_err(&intf->dev, "Not able to get a minor for this device.\n"); | 501 | dev_err(&intf->dev, "Not able to get a minor for this device.\n"); |
502 | mutex_unlock(&mdc800->io_lock); | ||
502 | return -ENODEV; | 503 | return -ENODEV; |
503 | } | 504 | } |
504 | 505 | ||
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/adutux.c b/drivers/usb/misc/adutux.c index 7b6922e08ed1..203526542013 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c | |||
@@ -376,7 +376,7 @@ static int adu_release(struct inode *inode, struct file *file) | |||
376 | if (dev->open_count <= 0) { | 376 | if (dev->open_count <= 0) { |
377 | dbg(1," %s : device not opened", __func__); | 377 | dbg(1," %s : device not opened", __func__); |
378 | retval = -ENODEV; | 378 | retval = -ENODEV; |
379 | goto exit; | 379 | goto unlock; |
380 | } | 380 | } |
381 | 381 | ||
382 | adu_release_internal(dev); | 382 | adu_release_internal(dev); |
@@ -385,9 +385,9 @@ static int adu_release(struct inode *inode, struct file *file) | |||
385 | if (!dev->open_count) /* ... and we're the last user */ | 385 | if (!dev->open_count) /* ... and we're the last user */ |
386 | adu_delete(dev); | 386 | adu_delete(dev); |
387 | } | 387 | } |
388 | 388 | unlock: | |
389 | exit: | ||
390 | mutex_unlock(&adutux_mutex); | 389 | mutex_unlock(&adutux_mutex); |
390 | exit: | ||
391 | dbg(2," %s : leave, return value %d", __func__, retval); | 391 | dbg(2," %s : leave, return value %d", __func__, retval); |
392 | return retval; | 392 | return retval; |
393 | } | 393 | } |
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/ldusb.c b/drivers/usb/misc/ldusb.c index 189a9db03509..ad4fb15b5dcb 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c | |||
@@ -57,7 +57,6 @@ | |||
57 | #define USB_DEVICE_ID_LD_MACHINETEST 0x2040 /* USB Product ID of Machine Test System */ | 57 | #define USB_DEVICE_ID_LD_MACHINETEST 0x2040 /* USB Product ID of Machine Test System */ |
58 | 58 | ||
59 | #define USB_VENDOR_ID_VERNIER 0x08f7 | 59 | #define USB_VENDOR_ID_VERNIER 0x08f7 |
60 | #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 | ||
61 | #define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 | 60 | #define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 |
62 | #define USB_DEVICE_ID_VERNIER_SKIP 0x0003 | 61 | #define USB_DEVICE_ID_VERNIER_SKIP 0x0003 |
63 | #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 | 62 | #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 |
@@ -85,7 +84,6 @@ static struct usb_device_id ld_usb_table [] = { | |||
85 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_NETWORKANALYSER) }, | 84 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_NETWORKANALYSER) }, |
86 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERCONTROL) }, | 85 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POWERCONTROL) }, |
87 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETEST) }, | 86 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_MACHINETEST) }, |
88 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) }, | ||
89 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, | 87 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, |
90 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, | 88 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, |
91 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) }, | 89 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) }, |
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/misc/vstusb.c b/drivers/usb/misc/vstusb.c index 63dff9ba73c5..f26ea8dc1577 100644 --- a/drivers/usb/misc/vstusb.c +++ b/drivers/usb/misc/vstusb.c | |||
@@ -401,6 +401,7 @@ static ssize_t vstusb_write(struct file *file, const char __user *buffer, | |||
401 | } | 401 | } |
402 | 402 | ||
403 | if (copy_from_user(buf, buffer, count)) { | 403 | if (copy_from_user(buf, buffer, count)) { |
404 | mutex_unlock(&vstdev->lock); | ||
404 | dev_err(&dev->dev, "%s: can't copy_from_user\n", __func__); | 405 | dev_err(&dev->dev, "%s: can't copy_from_user\n", __func__); |
405 | retval = -EFAULT; | 406 | retval = -EFAULT; |
406 | goto exit; | 407 | goto exit; |
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index e06810aef2df..f8d9045d668a 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c | |||
@@ -37,9 +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) | ||
42 | |||
40 | #ifdef CONFIG_COMPAT | 43 | #ifdef CONFIG_COMPAT |
41 | #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) |
42 | #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) | ||
43 | #endif | 47 | #endif |
44 | 48 | ||
45 | /* | 49 | /* |
@@ -91,7 +95,29 @@ struct mon_bin_hdr { | |||
91 | int status; | 95 | int status; |
92 | unsigned int len_urb; /* Length of data (submitted or actual) */ | 96 | unsigned int len_urb; /* Length of data (submitted or actual) */ |
93 | unsigned int len_cap; /* Delivered length */ | 97 | unsigned int len_cap; /* Delivered length */ |
94 | 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; | ||
95 | }; | 121 | }; |
96 | 122 | ||
97 | /* per file statistic */ | 123 | /* per file statistic */ |
@@ -101,7 +127,7 @@ struct mon_bin_stats { | |||
101 | }; | 127 | }; |
102 | 128 | ||
103 | struct mon_bin_get { | 129 | struct mon_bin_get { |
104 | struct mon_bin_hdr __user *hdr; /* Only 48 bytes, not 64. */ | 130 | struct mon_bin_hdr __user *hdr; /* Can be 48 bytes or 64. */ |
105 | void __user *data; | 131 | void __user *data; |
106 | size_t alloc; /* Length of data (can be zero) */ | 132 | size_t alloc; /* Length of data (can be zero) */ |
107 | }; | 133 | }; |
@@ -130,6 +156,11 @@ struct mon_bin_mfetch32 { | |||
130 | #define PKT_ALIGN 64 | 156 | #define PKT_ALIGN 64 |
131 | #define PKT_SIZE 64 | 157 | #define PKT_SIZE 64 |
132 | 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 | |||
133 | /* max number of USB bus supported */ | 164 | /* max number of USB bus supported */ |
134 | #define MON_BIN_MAX_MINOR 128 | 165 | #define MON_BIN_MAX_MINOR 128 |
135 | 166 | ||
@@ -359,12 +390,8 @@ static inline char mon_bin_get_setup(unsigned char *setupb, | |||
359 | const struct urb *urb, char ev_type) | 390 | const struct urb *urb, char ev_type) |
360 | { | 391 | { |
361 | 392 | ||
362 | if (!usb_endpoint_xfer_control(&urb->ep->desc) || ev_type != 'S') | ||
363 | return '-'; | ||
364 | |||
365 | if (urb->setup_packet == NULL) | 393 | if (urb->setup_packet == NULL) |
366 | return 'Z'; | 394 | return 'Z'; |
367 | |||
368 | memcpy(setupb, urb->setup_packet, SETUP_LEN); | 395 | memcpy(setupb, urb->setup_packet, SETUP_LEN); |
369 | return 0; | 396 | return 0; |
370 | } | 397 | } |
@@ -386,6 +413,26 @@ static char mon_bin_get_data(const struct mon_reader_bin *rp, | |||
386 | return 0; | 413 | return 0; |
387 | } | 414 | } |
388 | 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 | |||
389 | 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, |
390 | char ev_type, int status) | 437 | char ev_type, int status) |
391 | { | 438 | { |
@@ -395,6 +442,7 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
395 | unsigned int urb_length; | 442 | unsigned int urb_length; |
396 | unsigned int offset; | 443 | unsigned int offset; |
397 | unsigned int length; | 444 | unsigned int length; |
445 | unsigned int ndesc, lendesc; | ||
398 | unsigned char dir; | 446 | unsigned char dir; |
399 | struct mon_bin_hdr *ep; | 447 | struct mon_bin_hdr *ep; |
400 | char data_tag = 0; | 448 | char data_tag = 0; |
@@ -406,6 +454,19 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
406 | /* | 454 | /* |
407 | * Find the maximum allowable length, then allocate space. | 455 | * Find the maximum allowable length, then allocate space. |
408 | */ | 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 | |||
409 | urb_length = (ev_type == 'S') ? | 470 | urb_length = (ev_type == 'S') ? |
410 | urb->transfer_buffer_length : urb->actual_length; | 471 | urb->transfer_buffer_length : urb->actual_length; |
411 | length = urb_length; | 472 | length = urb_length; |
@@ -428,10 +489,12 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
428 | dir = 0; | 489 | dir = 0; |
429 | } | 490 | } |
430 | 491 | ||
431 | if (rp->mmap_active) | 492 | if (rp->mmap_active) { |
432 | offset = mon_buff_area_alloc_contiguous(rp, length + PKT_SIZE); | 493 | offset = mon_buff_area_alloc_contiguous(rp, |
433 | else | 494 | length + PKT_SIZE + lendesc); |
434 | offset = mon_buff_area_alloc(rp, length + PKT_SIZE); | 495 | } else { |
496 | offset = mon_buff_area_alloc(rp, length + PKT_SIZE + lendesc); | ||
497 | } | ||
435 | if (offset == ~0) { | 498 | if (offset == ~0) { |
436 | rp->cnt_lost++; | 499 | rp->cnt_lost++; |
437 | spin_unlock_irqrestore(&rp->b_lock, flags); | 500 | spin_unlock_irqrestore(&rp->b_lock, flags); |
@@ -455,9 +518,31 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
455 | ep->ts_usec = ts.tv_usec; | 518 | ep->ts_usec = ts.tv_usec; |
456 | ep->status = status; | 519 | ep->status = status; |
457 | ep->len_urb = urb_length; | 520 | ep->len_urb = urb_length; |
458 | 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 | } | ||
459 | 545 | ||
460 | ep->flag_setup = mon_bin_get_setup(ep->setup, urb, ev_type); | ||
461 | if (length != 0) { | 546 | if (length != 0) { |
462 | ep->flag_data = mon_bin_get_data(rp, offset, urb, length); | 547 | ep->flag_data = mon_bin_get_data(rp, offset, urb, length); |
463 | if (ep->flag_data != 0) { /* Yes, it's 0x00, not '0' */ | 548 | if (ep->flag_data != 0) { /* Yes, it's 0x00, not '0' */ |
@@ -591,7 +676,8 @@ err_alloc: | |||
591 | * Returns zero or error. | 676 | * Returns zero or error. |
592 | */ | 677 | */ |
593 | 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, |
594 | 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) | ||
595 | { | 681 | { |
596 | unsigned long flags; | 682 | unsigned long flags; |
597 | struct mon_bin_hdr *ep; | 683 | struct mon_bin_hdr *ep; |
@@ -608,7 +694,7 @@ static int mon_bin_get_event(struct file *file, struct mon_reader_bin *rp, | |||
608 | 694 | ||
609 | ep = MON_OFF2HDR(rp, rp->b_out); | 695 | ep = MON_OFF2HDR(rp, rp->b_out); |
610 | 696 | ||
611 | if (copy_to_user(hdr, ep, sizeof(struct mon_bin_hdr))) { | 697 | if (copy_to_user(hdr, ep, hdrbytes)) { |
612 | mutex_unlock(&rp->fetch_lock); | 698 | mutex_unlock(&rp->fetch_lock); |
613 | return -EFAULT; | 699 | return -EFAULT; |
614 | } | 700 | } |
@@ -656,6 +742,7 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf, | |||
656 | size_t nbytes, loff_t *ppos) | 742 | size_t nbytes, loff_t *ppos) |
657 | { | 743 | { |
658 | struct mon_reader_bin *rp = file->private_data; | 744 | struct mon_reader_bin *rp = file->private_data; |
745 | unsigned int hdrbytes = PKT_SZ_API0; | ||
659 | unsigned long flags; | 746 | unsigned long flags; |
660 | struct mon_bin_hdr *ep; | 747 | struct mon_bin_hdr *ep; |
661 | unsigned int offset; | 748 | unsigned int offset; |
@@ -673,8 +760,8 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf, | |||
673 | 760 | ||
674 | ep = MON_OFF2HDR(rp, rp->b_out); | 761 | ep = MON_OFF2HDR(rp, rp->b_out); |
675 | 762 | ||
676 | if (rp->b_read < sizeof(struct mon_bin_hdr)) { | 763 | if (rp->b_read < hdrbytes) { |
677 | step_len = min(nbytes, sizeof(struct mon_bin_hdr) - rp->b_read); | 764 | step_len = min(nbytes, (size_t)(hdrbytes - rp->b_read)); |
678 | ptr = ((char *)ep) + rp->b_read; | 765 | ptr = ((char *)ep) + rp->b_read; |
679 | if (step_len && copy_to_user(buf, ptr, step_len)) { | 766 | if (step_len && copy_to_user(buf, ptr, step_len)) { |
680 | mutex_unlock(&rp->fetch_lock); | 767 | mutex_unlock(&rp->fetch_lock); |
@@ -686,13 +773,13 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf, | |||
686 | done += step_len; | 773 | done += step_len; |
687 | } | 774 | } |
688 | 775 | ||
689 | if (rp->b_read >= sizeof(struct mon_bin_hdr)) { | 776 | if (rp->b_read >= hdrbytes) { |
690 | step_len = ep->len_cap; | 777 | step_len = ep->len_cap; |
691 | step_len -= rp->b_read - sizeof(struct mon_bin_hdr); | 778 | step_len -= rp->b_read - hdrbytes; |
692 | if (step_len > nbytes) | 779 | if (step_len > nbytes) |
693 | step_len = nbytes; | 780 | step_len = nbytes; |
694 | offset = rp->b_out + PKT_SIZE; | 781 | offset = rp->b_out + PKT_SIZE; |
695 | offset += rp->b_read - sizeof(struct mon_bin_hdr); | 782 | offset += rp->b_read - hdrbytes; |
696 | if (offset >= rp->b_size) | 783 | if (offset >= rp->b_size) |
697 | offset -= rp->b_size; | 784 | offset -= rp->b_size; |
698 | if (copy_from_buf(rp, offset, buf, step_len)) { | 785 | if (copy_from_buf(rp, offset, buf, step_len)) { |
@@ -708,7 +795,7 @@ static ssize_t mon_bin_read(struct file *file, char __user *buf, | |||
708 | /* | 795 | /* |
709 | * 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. |
710 | */ | 797 | */ |
711 | if (rp->b_read >= sizeof(struct mon_bin_hdr) + ep->len_cap) { | 798 | if (rp->b_read >= hdrbytes + ep->len_cap) { |
712 | spin_lock_irqsave(&rp->b_lock, flags); | 799 | spin_lock_irqsave(&rp->b_lock, flags); |
713 | mon_buff_area_free(rp, PKT_SIZE + ep->len_cap); | 800 | mon_buff_area_free(rp, PKT_SIZE + ep->len_cap); |
714 | spin_unlock_irqrestore(&rp->b_lock, flags); | 801 | spin_unlock_irqrestore(&rp->b_lock, flags); |
@@ -907,6 +994,7 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file, | |||
907 | break; | 994 | break; |
908 | 995 | ||
909 | case MON_IOCX_GET: | 996 | case MON_IOCX_GET: |
997 | case MON_IOCX_GETX: | ||
910 | { | 998 | { |
911 | struct mon_bin_get getb; | 999 | struct mon_bin_get getb; |
912 | 1000 | ||
@@ -916,26 +1004,12 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file, | |||
916 | 1004 | ||
917 | if (getb.alloc > 0x10000000) /* Want to cast to u32 */ | 1005 | if (getb.alloc > 0x10000000) /* Want to cast to u32 */ |
918 | return -EINVAL; | 1006 | return -EINVAL; |
919 | ret = mon_bin_get_event(file, rp, | 1007 | ret = mon_bin_get_event(file, rp, getb.hdr, |
920 | 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); | ||
921 | } | 1010 | } |
922 | break; | 1011 | break; |
923 | 1012 | ||
924 | #ifdef CONFIG_COMPAT | ||
925 | case MON_IOCX_GET32: { | ||
926 | struct mon_bin_get32 getb; | ||
927 | |||
928 | if (copy_from_user(&getb, (void __user *)arg, | ||
929 | sizeof(struct mon_bin_get32))) | ||
930 | return -EFAULT; | ||
931 | |||
932 | ret = mon_bin_get_event(file, rp, | ||
933 | compat_ptr(getb.hdr32), compat_ptr(getb.data32), | ||
934 | getb.alloc32); | ||
935 | } | ||
936 | break; | ||
937 | #endif | ||
938 | |||
939 | case MON_IOCX_MFETCH: | 1013 | case MON_IOCX_MFETCH: |
940 | { | 1014 | { |
941 | struct mon_bin_mfetch mfetch; | 1015 | struct mon_bin_mfetch mfetch; |
@@ -962,7 +1036,59 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file, | |||
962 | } | 1036 | } |
963 | break; | 1037 | break; |
964 | 1038 | ||
1039 | case MON_IOCG_STATS: { | ||
1040 | struct mon_bin_stats __user *sp; | ||
1041 | unsigned int nevents; | ||
1042 | unsigned int ndropped; | ||
1043 | |||
1044 | spin_lock_irqsave(&rp->b_lock, flags); | ||
1045 | ndropped = rp->cnt_lost; | ||
1046 | rp->cnt_lost = 0; | ||
1047 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
1048 | nevents = mon_bin_queued(rp); | ||
1049 | |||
1050 | sp = (struct mon_bin_stats __user *)arg; | ||
1051 | if (put_user(rp->cnt_lost, &sp->dropped)) | ||
1052 | return -EFAULT; | ||
1053 | if (put_user(nevents, &sp->queued)) | ||
1054 | return -EFAULT; | ||
1055 | |||
1056 | } | ||
1057 | break; | ||
1058 | |||
1059 | default: | ||
1060 | return -ENOTTY; | ||
1061 | } | ||
1062 | |||
1063 | return ret; | ||
1064 | } | ||
1065 | |||
965 | #ifdef CONFIG_COMPAT | 1066 | #ifdef CONFIG_COMPAT |
1067 | static long mon_bin_compat_ioctl(struct file *file, | ||
1068 | unsigned int cmd, unsigned long arg) | ||
1069 | { | ||
1070 | struct mon_reader_bin *rp = file->private_data; | ||
1071 | int ret; | ||
1072 | |||
1073 | switch (cmd) { | ||
1074 | |||
1075 | case MON_IOCX_GET32: | ||
1076 | case MON_IOCX_GETX32: | ||
1077 | { | ||
1078 | struct mon_bin_get32 getb; | ||
1079 | |||
1080 | if (copy_from_user(&getb, (void __user *)arg, | ||
1081 | sizeof(struct mon_bin_get32))) | ||
1082 | return -EFAULT; | ||
1083 | |||
1084 | ret = mon_bin_get_event(file, rp, compat_ptr(getb.hdr32), | ||
1085 | (cmd == MON_IOCX_GET32)? PKT_SZ_API0: PKT_SZ_API1, | ||
1086 | compat_ptr(getb.data32), getb.alloc32); | ||
1087 | if (ret < 0) | ||
1088 | return ret; | ||
1089 | } | ||
1090 | return 0; | ||
1091 | |||
966 | case MON_IOCX_MFETCH32: | 1092 | case MON_IOCX_MFETCH32: |
967 | { | 1093 | { |
968 | struct mon_bin_mfetch32 mfetch; | 1094 | struct mon_bin_mfetch32 mfetch; |
@@ -986,37 +1112,25 @@ static int mon_bin_ioctl(struct inode *inode, struct file *file, | |||
986 | return ret; | 1112 | return ret; |
987 | if (put_user(ret, &uptr->nfetch32)) | 1113 | if (put_user(ret, &uptr->nfetch32)) |
988 | return -EFAULT; | 1114 | return -EFAULT; |
989 | ret = 0; | ||
990 | } | 1115 | } |
991 | break; | 1116 | return 0; |
992 | #endif | ||
993 | |||
994 | case MON_IOCG_STATS: { | ||
995 | struct mon_bin_stats __user *sp; | ||
996 | unsigned int nevents; | ||
997 | unsigned int ndropped; | ||
998 | |||
999 | spin_lock_irqsave(&rp->b_lock, flags); | ||
1000 | ndropped = rp->cnt_lost; | ||
1001 | rp->cnt_lost = 0; | ||
1002 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
1003 | nevents = mon_bin_queued(rp); | ||
1004 | 1117 | ||
1005 | sp = (struct mon_bin_stats __user *)arg; | 1118 | case MON_IOCG_STATS: |
1006 | if (put_user(rp->cnt_lost, &sp->dropped)) | 1119 | return mon_bin_ioctl(NULL, file, cmd, |
1007 | return -EFAULT; | 1120 | (unsigned long) compat_ptr(arg)); |
1008 | if (put_user(nevents, &sp->queued)) | ||
1009 | return -EFAULT; | ||
1010 | 1121 | ||
1011 | } | 1122 | case MON_IOCQ_URB_LEN: |
1012 | break; | 1123 | case MON_IOCQ_RING_SIZE: |
1124 | case MON_IOCT_RING_SIZE: | ||
1125 | case MON_IOCH_MFLUSH: | ||
1126 | return mon_bin_ioctl(NULL, file, cmd, arg); | ||
1013 | 1127 | ||
1014 | default: | 1128 | default: |
1015 | return -ENOTTY; | 1129 | ; |
1016 | } | 1130 | } |
1017 | 1131 | return -ENOTTY; | |
1018 | return ret; | ||
1019 | } | 1132 | } |
1133 | #endif /* CONFIG_COMPAT */ | ||
1020 | 1134 | ||
1021 | static unsigned int | 1135 | static unsigned int |
1022 | mon_bin_poll(struct file *file, struct poll_table_struct *wait) | 1136 | mon_bin_poll(struct file *file, struct poll_table_struct *wait) |
@@ -1094,6 +1208,9 @@ static const struct file_operations mon_fops_binary = { | |||
1094 | /* .write = mon_text_write, */ | 1208 | /* .write = mon_text_write, */ |
1095 | .poll = mon_bin_poll, | 1209 | .poll = mon_bin_poll, |
1096 | .ioctl = mon_bin_ioctl, | 1210 | .ioctl = mon_bin_ioctl, |
1211 | #ifdef CONFIG_COMPAT | ||
1212 | .compat_ioctl = mon_bin_compat_ioctl, | ||
1213 | #endif | ||
1097 | .release = mon_bin_release, | 1214 | .release = mon_bin_release, |
1098 | .mmap = mon_bin_mmap, | 1215 | .mmap = mon_bin_mmap, |
1099 | }; | 1216 | }; |
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index 5af7379cd9a3..b66e8544d8b9 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig | |||
@@ -11,6 +11,7 @@ config USB_MUSB_HDRC | |||
11 | depends on (USB || USB_GADGET) && HAVE_CLK | 11 | depends on (USB || USB_GADGET) && HAVE_CLK |
12 | depends on !SUPERH | 12 | depends on !SUPERH |
13 | select TWL4030_USB if MACH_OMAP_3430SDP | 13 | select TWL4030_USB if MACH_OMAP_3430SDP |
14 | select USB_OTG_UTILS | ||
14 | tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' | 15 | tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' |
15 | help | 16 | help |
16 | Say Y here if your system has a dual role high speed USB | 17 | Say Y here if your system has a dual role high speed USB |
@@ -19,8 +20,8 @@ config USB_MUSB_HDRC | |||
19 | it's being used with, including the USB peripheral role, | 20 | it's being used with, including the USB peripheral role, |
20 | or the USB host role, or both. | 21 | or the USB host role, or both. |
21 | 22 | ||
22 | Texas Instruments parts using this IP include DaVinci 644x, | 23 | Texas Instruments familiies using this IP include DaVinci |
23 | OMAP 243x, OMAP 343x, and TUSB 6010. | 24 | (35x, 644x ...), OMAP 243x, OMAP 3, and TUSB 6010. |
24 | 25 | ||
25 | Analog Devices parts using this IP include Blackfin BF54x, | 26 | Analog Devices parts using this IP include Blackfin BF54x, |
26 | BF525 and BF527. | 27 | BF525 and BF527. |
@@ -39,7 +40,7 @@ config USB_MUSB_SOC | |||
39 | default y if (BF54x && !BF544) | 40 | default y if (BF54x && !BF544) |
40 | default y if (BF52x && !BF522 && !BF523) | 41 | default y if (BF52x && !BF522 && !BF523) |
41 | 42 | ||
42 | comment "DaVinci 644x USB support" | 43 | comment "DaVinci 35x and 644x USB support" |
43 | depends on USB_MUSB_HDRC && ARCH_DAVINCI | 44 | depends on USB_MUSB_HDRC && ARCH_DAVINCI |
44 | 45 | ||
45 | comment "OMAP 243x high speed USB support" | 46 | comment "OMAP 243x high speed USB support" |
@@ -49,7 +50,7 @@ comment "OMAP 343x high speed USB support" | |||
49 | depends on USB_MUSB_HDRC && ARCH_OMAP34XX | 50 | depends on USB_MUSB_HDRC && ARCH_OMAP34XX |
50 | 51 | ||
51 | comment "Blackfin high speed USB Support" | 52 | comment "Blackfin high speed USB Support" |
52 | depends on USB_MUSB_HDRC && (BF54x && !BF544) || (BF52x && !BF522 && !BF523) | 53 | depends on USB_MUSB_HDRC && ((BF54x && !BF544) || (BF52x && !BF522 && !BF523)) |
53 | 54 | ||
54 | config USB_TUSB6010 | 55 | config USB_TUSB6010 |
55 | boolean "TUSB 6010 support" | 56 | boolean "TUSB 6010 support" |
diff --git a/drivers/usb/musb/cppi_dma.c b/drivers/usb/musb/cppi_dma.c index 5ad6d0893cbe..569ef0fed0f6 100644 --- a/drivers/usb/musb/cppi_dma.c +++ b/drivers/usb/musb/cppi_dma.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/usb.h> | 9 | #include <linux/usb.h> |
10 | 10 | ||
11 | #include "musb_core.h" | 11 | #include "musb_core.h" |
12 | #include "musb_debug.h" | ||
12 | #include "cppi_dma.h" | 13 | #include "cppi_dma.h" |
13 | 14 | ||
14 | 15 | ||
@@ -423,6 +424,7 @@ cppi_rndis_update(struct cppi_channel *c, int is_rx, | |||
423 | } | 424 | } |
424 | } | 425 | } |
425 | 426 | ||
427 | #ifdef CONFIG_USB_MUSB_DEBUG | ||
426 | static void cppi_dump_rxbd(const char *tag, struct cppi_descriptor *bd) | 428 | static void cppi_dump_rxbd(const char *tag, struct cppi_descriptor *bd) |
427 | { | 429 | { |
428 | pr_debug("RXBD/%s %08x: " | 430 | pr_debug("RXBD/%s %08x: " |
@@ -431,10 +433,11 @@ static void cppi_dump_rxbd(const char *tag, struct cppi_descriptor *bd) | |||
431 | bd->hw_next, bd->hw_bufp, bd->hw_off_len, | 433 | bd->hw_next, bd->hw_bufp, bd->hw_off_len, |
432 | bd->hw_options); | 434 | bd->hw_options); |
433 | } | 435 | } |
436 | #endif | ||
434 | 437 | ||
435 | static void cppi_dump_rxq(int level, const char *tag, struct cppi_channel *rx) | 438 | static void cppi_dump_rxq(int level, const char *tag, struct cppi_channel *rx) |
436 | { | 439 | { |
437 | #if MUSB_DEBUG > 0 | 440 | #ifdef CONFIG_USB_MUSB_DEBUG |
438 | struct cppi_descriptor *bd; | 441 | struct cppi_descriptor *bd; |
439 | 442 | ||
440 | if (!_dbg_level(level)) | 443 | if (!_dbg_level(level)) |
@@ -881,12 +884,14 @@ cppi_next_rx_segment(struct musb *musb, struct cppi_channel *rx, int onepacket) | |||
881 | bd->hw_options |= CPPI_SOP_SET; | 884 | bd->hw_options |= CPPI_SOP_SET; |
882 | tail->hw_options |= CPPI_EOP_SET; | 885 | tail->hw_options |= CPPI_EOP_SET; |
883 | 886 | ||
884 | if (debug >= 5) { | 887 | #ifdef CONFIG_USB_MUSB_DEBUG |
888 | if (_dbg_level(5)) { | ||
885 | struct cppi_descriptor *d; | 889 | struct cppi_descriptor *d; |
886 | 890 | ||
887 | for (d = rx->head; d; d = d->next) | 891 | for (d = rx->head; d; d = d->next) |
888 | cppi_dump_rxbd("S", d); | 892 | cppi_dump_rxbd("S", d); |
889 | } | 893 | } |
894 | #endif | ||
890 | 895 | ||
891 | /* in case the preceding transfer left some state... */ | 896 | /* in case the preceding transfer left some state... */ |
892 | tail = rx->last_processed; | 897 | tail = rx->last_processed; |
@@ -990,6 +995,7 @@ static int cppi_channel_program(struct dma_channel *ch, | |||
990 | cppi_ch->offset = 0; | 995 | cppi_ch->offset = 0; |
991 | cppi_ch->maxpacket = maxpacket; | 996 | cppi_ch->maxpacket = maxpacket; |
992 | cppi_ch->buf_len = len; | 997 | cppi_ch->buf_len = len; |
998 | cppi_ch->channel.actual_len = 0; | ||
993 | 999 | ||
994 | /* TX channel? or RX? */ | 1000 | /* TX channel? or RX? */ |
995 | if (cppi_ch->transmit) | 1001 | if (cppi_ch->transmit) |
diff --git a/drivers/usb/musb/davinci.c b/drivers/usb/musb/davinci.c index 0d566dc5ce06..10d11ab113ab 100644 --- a/drivers/usb/musb/davinci.c +++ b/drivers/usb/musb/davinci.c | |||
@@ -32,9 +32,10 @@ | |||
32 | #include <linux/io.h> | 32 | #include <linux/io.h> |
33 | #include <linux/gpio.h> | 33 | #include <linux/gpio.h> |
34 | 34 | ||
35 | #include <mach/arch/hardware.h> | 35 | #include <mach/hardware.h> |
36 | #include <mach/arch/memory.h> | 36 | #include <mach/memory.h> |
37 | #include <mach/arch/gpio.h> | 37 | #include <mach/gpio.h> |
38 | |||
38 | #include <asm/mach-types.h> | 39 | #include <asm/mach-types.h> |
39 | 40 | ||
40 | #include "musb_core.h" | 41 | #include "musb_core.h" |
@@ -47,6 +48,9 @@ | |||
47 | #include "cppi_dma.h" | 48 | #include "cppi_dma.h" |
48 | 49 | ||
49 | 50 | ||
51 | #define USB_PHY_CTRL IO_ADDRESS(USBPHY_CTL_PADDR) | ||
52 | #define DM355_DEEPSLEEP IO_ADDRESS(DM355_DEEPSLEEP_PADDR) | ||
53 | |||
50 | /* 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 |
51 | * 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 |
52 | * and, when in host mode, autosuspending idle root ports... PHYPLLON | 56 | * and, when in host mode, autosuspending idle root ports... PHYPLLON |
@@ -55,20 +59,26 @@ | |||
55 | 59 | ||
56 | static inline void phy_on(void) | 60 | static inline void phy_on(void) |
57 | { | 61 | { |
58 | /* start the on-chip PHY and its PLL */ | 62 | u32 phy_ctrl = __raw_readl(USB_PHY_CTRL); |
59 | __raw_writel(USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON, | 63 | |
60 | (void __force __iomem *) IO_ADDRESS(USBPHY_CTL_PADDR)); | 64 | /* power everything up; start the on-chip PHY and its PLL */ |
61 | while ((__raw_readl((void __force __iomem *) | 65 | phy_ctrl &= ~(USBPHY_OSCPDWN | USBPHY_OTGPDWN | USBPHY_PHYPDWN); |
62 | IO_ADDRESS(USBPHY_CTL_PADDR)) | 66 | phy_ctrl |= USBPHY_SESNDEN | USBPHY_VBDTCTEN | USBPHY_PHYPLLON; |
63 | & 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) | ||
64 | cpu_relax(); | 71 | cpu_relax(); |
65 | } | 72 | } |
66 | 73 | ||
67 | static inline void phy_off(void) | 74 | static inline void phy_off(void) |
68 | { | 75 | { |
69 | /* powerdown the on-chip PHY and its oscillator */ | 76 | u32 phy_ctrl = __raw_readl(USB_PHY_CTRL); |
70 | __raw_writel(USBPHY_OSCPDWN | USBPHY_PHYPDWN, (void __force __iomem *) | 77 | |
71 | 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); | ||
72 | } | 82 | } |
73 | 83 | ||
74 | static int dma_off = 1; | 84 | static int dma_off = 1; |
@@ -125,10 +135,6 @@ void musb_platform_disable(struct musb *musb) | |||
125 | } | 135 | } |
126 | 136 | ||
127 | 137 | ||
128 | /* REVISIT it's not clear whether DaVinci can support full OTG. */ | ||
129 | |||
130 | static int vbus_state = -1; | ||
131 | |||
132 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | 138 | #ifdef CONFIG_USB_MUSB_HDRC_HCD |
133 | #define portstate(stmt) stmt | 139 | #define portstate(stmt) stmt |
134 | #else | 140 | #else |
@@ -136,10 +142,19 @@ static int vbus_state = -1; | |||
136 | #endif | 142 | #endif |
137 | 143 | ||
138 | 144 | ||
139 | /* 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 | */ | ||
140 | 153 | ||
141 | #ifdef CONFIG_MACH_DAVINCI_EVM | 154 | #ifdef CONFIG_MACH_DAVINCI_EVM |
142 | 155 | ||
156 | static int vbus_state = -1; | ||
157 | |||
143 | /* I2C operations are always synchronous, and require a task context. | 158 | /* I2C operations are always synchronous, and require a task context. |
144 | * With unloaded systems, using the shared workqueue seems to suffice | 159 | * With unloaded systems, using the shared workqueue seems to suffice |
145 | * to satisfy the 100msec A_WAIT_VRISE timeout... | 160 | * to satisfy the 100msec A_WAIT_VRISE timeout... |
@@ -149,12 +164,12 @@ static void evm_deferred_drvvbus(struct work_struct *ignored) | |||
149 | gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); | 164 | gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); |
150 | vbus_state = !vbus_state; | 165 | vbus_state = !vbus_state; |
151 | } | 166 | } |
152 | static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus); | ||
153 | 167 | ||
154 | #endif /* EVM */ | 168 | #endif /* EVM */ |
155 | 169 | ||
156 | 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) |
157 | { | 171 | { |
172 | #ifdef CONFIG_MACH_DAVINCI_EVM | ||
158 | if (is_on) | 173 | if (is_on) |
159 | is_on = 1; | 174 | is_on = 1; |
160 | 175 | ||
@@ -162,16 +177,17 @@ static void davinci_source_power(struct musb *musb, int is_on, int immediate) | |||
162 | return; | 177 | return; |
163 | vbus_state = !is_on; /* 0/1 vs "-1 == unknown/init" */ | 178 | vbus_state = !is_on; /* 0/1 vs "-1 == unknown/init" */ |
164 | 179 | ||
165 | #ifdef CONFIG_MACH_DAVINCI_EVM | ||
166 | if (machine_is_davinci_evm()) { | 180 | if (machine_is_davinci_evm()) { |
181 | static DECLARE_WORK(evm_vbus_work, evm_deferred_drvvbus); | ||
182 | |||
167 | if (immediate) | 183 | if (immediate) |
168 | gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); | 184 | gpio_set_value_cansleep(GPIO_nVBUS_DRV, vbus_state); |
169 | else | 185 | else |
170 | schedule_work(&evm_vbus_work); | 186 | schedule_work(&evm_vbus_work); |
171 | } | 187 | } |
172 | #endif | ||
173 | if (immediate) | 188 | if (immediate) |
174 | vbus_state = is_on; | 189 | vbus_state = is_on; |
190 | #endif | ||
175 | } | 191 | } |
176 | 192 | ||
177 | static void davinci_set_vbus(struct musb *musb, int is_on) | 193 | static void davinci_set_vbus(struct musb *musb, int is_on) |
@@ -370,30 +386,14 @@ int musb_platform_set_mode(struct musb *musb, u8 mode) | |||
370 | return -EIO; | 386 | return -EIO; |
371 | } | 387 | } |
372 | 388 | ||
373 | int musb_platform_set_mode(struct musb *musb, u8 mode) | ||
374 | { | ||
375 | /* EVM can't do this (right?) */ | ||
376 | return -EIO; | ||
377 | } | ||
378 | |||
379 | int __init musb_platform_init(struct musb *musb) | 389 | int __init musb_platform_init(struct musb *musb) |
380 | { | 390 | { |
381 | void __iomem *tibase = musb->ctrl_base; | 391 | void __iomem *tibase = musb->ctrl_base; |
382 | u32 revision; | 392 | u32 revision; |
383 | 393 | ||
384 | musb->mregs += DAVINCI_BASE_OFFSET; | 394 | musb->mregs += DAVINCI_BASE_OFFSET; |
385 | #if 0 | ||
386 | /* REVISIT there's something odd about clocking, this | ||
387 | * didn't appear do the job ... | ||
388 | */ | ||
389 | musb->clock = clk_get(pDevice, "usb"); | ||
390 | if (IS_ERR(musb->clock)) | ||
391 | return PTR_ERR(musb->clock); | ||
392 | 395 | ||
393 | status = clk_enable(musb->clock); | 396 | clk_enable(musb->clock); |
394 | if (status < 0) | ||
395 | return -ENODEV; | ||
396 | #endif | ||
397 | 397 | ||
398 | /* returns zero if e.g. not clocked */ | 398 | /* returns zero if e.g. not clocked */ |
399 | revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG); | 399 | revision = musb_readl(tibase, DAVINCI_USB_VERSION_REG); |
@@ -406,6 +406,17 @@ int __init musb_platform_init(struct musb *musb) | |||
406 | musb->board_set_vbus = davinci_set_vbus; | 406 | musb->board_set_vbus = davinci_set_vbus; |
407 | davinci_source_power(musb, 0, 1); | 407 | davinci_source_power(musb, 0, 1); |
408 | 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 | |||
409 | /* reset the controller */ | 420 | /* reset the controller */ |
410 | musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1); | 421 | musb_writel(tibase, DAVINCI_USB_CTRL_REG, 0x1); |
411 | 422 | ||
@@ -416,8 +427,7 @@ int __init musb_platform_init(struct musb *musb) | |||
416 | 427 | ||
417 | /* NOTE: irqs are in mixed mode, not bypass to pure-musb */ | 428 | /* NOTE: irqs are in mixed mode, not bypass to pure-musb */ |
418 | pr_debug("DaVinci OTG revision %08x phy %03x control %02x\n", | 429 | pr_debug("DaVinci OTG revision %08x phy %03x control %02x\n", |
419 | revision, __raw_readl((void __force __iomem *) | 430 | revision, __raw_readl(USB_PHY_CTRL), |
420 | IO_ADDRESS(USBPHY_CTL_PADDR)), | ||
421 | musb_readb(tibase, DAVINCI_USB_CTRL_REG)); | 431 | musb_readb(tibase, DAVINCI_USB_CTRL_REG)); |
422 | 432 | ||
423 | musb->isr = davinci_interrupt; | 433 | musb->isr = davinci_interrupt; |
@@ -458,5 +468,8 @@ int musb_platform_exit(struct musb *musb) | |||
458 | } | 468 | } |
459 | 469 | ||
460 | phy_off(); | 470 | phy_off(); |
471 | |||
472 | clk_disable(musb->clock); | ||
473 | |||
461 | return 0; | 474 | return 0; |
462 | } | 475 | } |
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 6c7faacfb535..338cd1611ab3 100644 --- a/drivers/usb/musb/musb_core.c +++ b/drivers/usb/musb/musb_core.c | |||
@@ -115,7 +115,7 @@ | |||
115 | 115 | ||
116 | 116 | ||
117 | unsigned musb_debug; | 117 | unsigned musb_debug; |
118 | module_param(musb_debug, uint, S_IRUGO | S_IWUSR); | 118 | module_param_named(debug, musb_debug, uint, S_IRUGO | S_IWUSR); |
119 | MODULE_PARM_DESC(debug, "Debug message level. Default = 0"); | 119 | MODULE_PARM_DESC(debug, "Debug message level. Default = 0"); |
120 | 120 | ||
121 | #define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia" | 121 | #define DRIVER_AUTHOR "Mentor Graphics, Texas Instruments, Nokia" |
@@ -767,8 +767,9 @@ static irqreturn_t musb_stage2_irq(struct musb *musb, u8 int_usb, | |||
767 | #ifdef CONFIG_USB_MUSB_HDRC_HCD | 767 | #ifdef CONFIG_USB_MUSB_HDRC_HCD |
768 | case OTG_STATE_A_HOST: | 768 | case OTG_STATE_A_HOST: |
769 | case OTG_STATE_A_SUSPEND: | 769 | case OTG_STATE_A_SUSPEND: |
770 | usb_hcd_resume_root_hub(musb_to_hcd(musb)); | ||
770 | musb_root_disconnect(musb); | 771 | musb_root_disconnect(musb); |
771 | if (musb->a_wait_bcon != 0) | 772 | if (musb->a_wait_bcon != 0 && is_otg_enabled(musb)) |
772 | musb_platform_try_idle(musb, jiffies | 773 | musb_platform_try_idle(musb, jiffies |
773 | + msecs_to_jiffies(musb->a_wait_bcon)); | 774 | + msecs_to_jiffies(musb->a_wait_bcon)); |
774 | break; | 775 | break; |
@@ -1815,7 +1816,7 @@ static void musb_free(struct musb *musb) | |||
1815 | #ifdef CONFIG_SYSFS | 1816 | #ifdef CONFIG_SYSFS |
1816 | device_remove_file(musb->controller, &dev_attr_mode); | 1817 | device_remove_file(musb->controller, &dev_attr_mode); |
1817 | device_remove_file(musb->controller, &dev_attr_vbus); | 1818 | device_remove_file(musb->controller, &dev_attr_vbus); |
1818 | #ifdef CONFIG_USB_MUSB_OTG | 1819 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC |
1819 | device_remove_file(musb->controller, &dev_attr_srp); | 1820 | device_remove_file(musb->controller, &dev_attr_srp); |
1820 | #endif | 1821 | #endif |
1821 | #endif | 1822 | #endif |
@@ -1824,8 +1825,9 @@ static void musb_free(struct musb *musb) | |||
1824 | musb_gadget_cleanup(musb); | 1825 | musb_gadget_cleanup(musb); |
1825 | #endif | 1826 | #endif |
1826 | 1827 | ||
1827 | if (musb->nIrq >= 0 && musb->irq_wake) { | 1828 | if (musb->nIrq >= 0) { |
1828 | disable_irq_wake(musb->nIrq); | 1829 | if (musb->irq_wake) |
1830 | disable_irq_wake(musb->nIrq); | ||
1829 | free_irq(musb->nIrq, musb); | 1831 | free_irq(musb->nIrq, musb); |
1830 | } | 1832 | } |
1831 | if (is_dma_capable() && musb->dma_controller) { | 1833 | if (is_dma_capable() && musb->dma_controller) { |
@@ -2062,7 +2064,7 @@ fail2: | |||
2062 | #ifdef CONFIG_SYSFS | 2064 | #ifdef CONFIG_SYSFS |
2063 | device_remove_file(musb->controller, &dev_attr_mode); | 2065 | device_remove_file(musb->controller, &dev_attr_mode); |
2064 | device_remove_file(musb->controller, &dev_attr_vbus); | 2066 | device_remove_file(musb->controller, &dev_attr_vbus); |
2065 | #ifdef CONFIG_USB_MUSB_OTG | 2067 | #ifdef CONFIG_USB_GADGET_MUSB_HDRC |
2066 | device_remove_file(musb->controller, &dev_attr_srp); | 2068 | device_remove_file(musb->controller, &dev_attr_srp); |
2067 | #endif | 2069 | #endif |
2068 | #endif | 2070 | #endif |
@@ -2242,10 +2244,10 @@ static int __init musb_init(void) | |||
2242 | return platform_driver_probe(&musb_driver, musb_probe); | 2244 | return platform_driver_probe(&musb_driver, musb_probe); |
2243 | } | 2245 | } |
2244 | 2246 | ||
2245 | /* make us init after usbcore and before usb | 2247 | /* make us init after usbcore and i2c (transceivers, regulators, etc) |
2246 | * gadget and host-side drivers start to register | 2248 | * and before usb gadget and host-side drivers start to register |
2247 | */ | 2249 | */ |
2248 | subsys_initcall(musb_init); | 2250 | fs_initcall(musb_init); |
2249 | 2251 | ||
2250 | static void __exit musb_cleanup(void) | 2252 | static void __exit musb_cleanup(void) |
2251 | { | 2253 | { |
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_gadget.c b/drivers/usb/musb/musb_gadget.c index 6197daeab8f9..c7ebd0867fcc 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c | |||
@@ -575,7 +575,7 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
575 | struct usb_request *request = &req->request; | 575 | struct usb_request *request = &req->request; |
576 | struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out; | 576 | struct musb_ep *musb_ep = &musb->endpoints[epnum].ep_out; |
577 | void __iomem *epio = musb->endpoints[epnum].regs; | 577 | void __iomem *epio = musb->endpoints[epnum].regs; |
578 | u16 fifo_count = 0; | 578 | unsigned fifo_count = 0; |
579 | u16 len = musb_ep->packet_sz; | 579 | u16 len = musb_ep->packet_sz; |
580 | 580 | ||
581 | csr = musb_readw(epio, MUSB_RXCSR); | 581 | csr = musb_readw(epio, MUSB_RXCSR); |
@@ -687,7 +687,7 @@ static void rxstate(struct musb *musb, struct musb_request *req) | |||
687 | len, fifo_count, | 687 | len, fifo_count, |
688 | musb_ep->packet_sz); | 688 | musb_ep->packet_sz); |
689 | 689 | ||
690 | fifo_count = min(len, fifo_count); | 690 | fifo_count = min_t(unsigned, len, fifo_count); |
691 | 691 | ||
692 | #ifdef CONFIG_USB_TUSB_OMAP_DMA | 692 | #ifdef CONFIG_USB_TUSB_OMAP_DMA |
693 | if (tusb_dma_omap() && musb_ep->dma) { | 693 | if (tusb_dma_omap() && musb_ep->dma) { |
@@ -874,10 +874,10 @@ static int musb_gadget_enable(struct usb_ep *ep, | |||
874 | status = -EBUSY; | 874 | status = -EBUSY; |
875 | goto fail; | 875 | goto fail; |
876 | } | 876 | } |
877 | musb_ep->type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; | 877 | musb_ep->type = usb_endpoint_type(desc); |
878 | 878 | ||
879 | /* check direction and (later) maxpacket size against endpoint */ | 879 | /* check direction and (later) maxpacket size against endpoint */ |
880 | if ((desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) != epnum) | 880 | if (usb_endpoint_num(desc) != epnum) |
881 | goto fail; | 881 | goto fail; |
882 | 882 | ||
883 | /* REVISIT this rules out high bandwidth periodic transfers */ | 883 | /* REVISIT this rules out high bandwidth periodic transfers */ |
@@ -890,7 +890,7 @@ static int musb_gadget_enable(struct usb_ep *ep, | |||
890 | * packet size (or fail), set the mode, clear the fifo | 890 | * packet size (or fail), set the mode, clear the fifo |
891 | */ | 891 | */ |
892 | musb_ep_select(mbase, epnum); | 892 | musb_ep_select(mbase, epnum); |
893 | if (desc->bEndpointAddress & USB_DIR_IN) { | 893 | if (usb_endpoint_dir_in(desc)) { |
894 | u16 int_txe = musb_readw(mbase, MUSB_INTRTXE); | 894 | u16 int_txe = musb_readw(mbase, MUSB_INTRTXE); |
895 | 895 | ||
896 | if (hw_ep->is_shared_fifo) | 896 | if (hw_ep->is_shared_fifo) |
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c index 99fa61234876..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", |
@@ -335,16 +330,11 @@ musb_save_toggle(struct musb_hw_ep *ep, int is_in, struct urb *urb) | |||
335 | static struct musb_qh * | 330 | static struct musb_qh * |
336 | musb_giveback(struct musb_qh *qh, struct urb *urb, int status) | 331 | musb_giveback(struct musb_qh *qh, struct urb *urb, int status) |
337 | { | 332 | { |
338 | int is_in; | ||
339 | struct musb_hw_ep *ep = qh->hw_ep; | 333 | struct musb_hw_ep *ep = qh->hw_ep; |
340 | struct musb *musb = ep->musb; | 334 | struct musb *musb = ep->musb; |
335 | int is_in = usb_pipein(urb->pipe); | ||
341 | int ready = qh->is_ready; | 336 | int ready = qh->is_ready; |
342 | 337 | ||
343 | if (ep->is_shared_fifo) | ||
344 | is_in = 1; | ||
345 | else | ||
346 | is_in = usb_pipein(urb->pipe); | ||
347 | |||
348 | /* save toggle eagerly, for paranoia */ | 338 | /* save toggle eagerly, for paranoia */ |
349 | switch (qh->type) { | 339 | switch (qh->type) { |
350 | case USB_ENDPOINT_XFER_BULK: | 340 | case USB_ENDPOINT_XFER_BULK: |
@@ -400,7 +390,6 @@ musb_giveback(struct musb_qh *qh, struct urb *urb, int status) | |||
400 | * de-allocated if it's tracked and allocated; | 390 | * de-allocated if it's tracked and allocated; |
401 | * and where we'd update the schedule tree... | 391 | * and where we'd update the schedule tree... |
402 | */ | 392 | */ |
403 | musb->periodic[ep->epnum] = NULL; | ||
404 | kfree(qh); | 393 | kfree(qh); |
405 | qh = NULL; | 394 | qh = NULL; |
406 | break; | 395 | break; |
@@ -432,7 +421,7 @@ musb_advance_schedule(struct musb *musb, struct urb *urb, | |||
432 | else | 421 | else |
433 | qh = musb_giveback(qh, urb, urb->status); | 422 | qh = musb_giveback(qh, urb, urb->status); |
434 | 423 | ||
435 | if (qh && qh->is_ready && !list_empty(&qh->hep->urb_list)) { | 424 | if (qh != NULL && qh->is_ready) { |
436 | DBG(4, "... next ep%d %cX urb %p\n", | 425 | DBG(4, "... next ep%d %cX urb %p\n", |
437 | hw_ep->epnum, is_in ? 'R' : 'T', | 426 | hw_ep->epnum, is_in ? 'R' : 'T', |
438 | next_urb(qh)); | 427 | next_urb(qh)); |
@@ -942,8 +931,8 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb) | |||
942 | switch (musb->ep0_stage) { | 931 | switch (musb->ep0_stage) { |
943 | case MUSB_EP0_IN: | 932 | case MUSB_EP0_IN: |
944 | fifo_dest = urb->transfer_buffer + urb->actual_length; | 933 | fifo_dest = urb->transfer_buffer + urb->actual_length; |
945 | fifo_count = min(len, ((u16) (urb->transfer_buffer_length | 934 | fifo_count = min_t(size_t, len, urb->transfer_buffer_length - |
946 | - urb->actual_length))); | 935 | urb->actual_length); |
947 | if (fifo_count < len) | 936 | if (fifo_count < len) |
948 | urb->status = -EOVERFLOW; | 937 | urb->status = -EOVERFLOW; |
949 | 938 | ||
@@ -976,10 +965,9 @@ static bool musb_h_ep0_continue(struct musb *musb, u16 len, struct urb *urb) | |||
976 | } | 965 | } |
977 | /* FALLTHROUGH */ | 966 | /* FALLTHROUGH */ |
978 | case MUSB_EP0_OUT: | 967 | case MUSB_EP0_OUT: |
979 | fifo_count = min(qh->maxpacket, ((u16) | 968 | fifo_count = min_t(size_t, qh->maxpacket, |
980 | (urb->transfer_buffer_length | 969 | urb->transfer_buffer_length - |
981 | - urb->actual_length))); | 970 | urb->actual_length); |
982 | |||
983 | if (fifo_count) { | 971 | if (fifo_count) { |
984 | fifo_dest = (u8 *) (urb->transfer_buffer | 972 | fifo_dest = (u8 *) (urb->transfer_buffer |
985 | + urb->actual_length); | 973 | + urb->actual_length); |
@@ -1051,7 +1039,8 @@ irqreturn_t musb_h_ep0_irq(struct musb *musb) | |||
1051 | 1039 | ||
1052 | /* 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 |
1053 | * control transfer, if another one is queued, so that | 1041 | * control transfer, if another one is queued, so that |
1054 | * ep0 is more likely to stay busy. | 1042 | * ep0 is more likely to stay busy. That's already done |
1043 | * for bulk RX transfers. | ||
1055 | * | 1044 | * |
1056 | * if (qh->ring.next != &musb->control), then | 1045 | * if (qh->ring.next != &musb->control), then |
1057 | * we have a candidate... NAKing is *NOT* an error | 1046 | * we have a candidate... NAKing is *NOT* an error |
@@ -1161,7 +1150,8 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
1161 | struct urb *urb; | 1150 | struct urb *urb; |
1162 | struct musb_hw_ep *hw_ep = musb->endpoints + epnum; | 1151 | struct musb_hw_ep *hw_ep = musb->endpoints + epnum; |
1163 | void __iomem *epio = hw_ep->regs; | 1152 | void __iomem *epio = hw_ep->regs; |
1164 | struct musb_qh *qh = hw_ep->out_qh; | 1153 | struct musb_qh *qh = hw_ep->is_shared_fifo ? hw_ep->in_qh |
1154 | : hw_ep->out_qh; | ||
1165 | u32 status = 0; | 1155 | u32 status = 0; |
1166 | void __iomem *mbase = musb->mregs; | 1156 | void __iomem *mbase = musb->mregs; |
1167 | struct dma_channel *dma; | 1157 | struct dma_channel *dma; |
@@ -1202,6 +1192,7 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
1202 | /* 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 |
1203 | * transfer, if there's some other (nonperiodic) tx urb | 1193 | * transfer, if there's some other (nonperiodic) tx urb |
1204 | * 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. | ||
1205 | * | 1196 | * |
1206 | * if (bulk && qh->ring.next != &musb->out_bulk), then | 1197 | * if (bulk && qh->ring.next != &musb->out_bulk), then |
1207 | * we have a candidate... NAKing is *NOT* an error | 1198 | * we have a candidate... NAKing is *NOT* an error |
@@ -1308,7 +1299,8 @@ void musb_host_tx(struct musb *musb, u8 epnum) | |||
1308 | * packets before updating TXCSR ... other docs disagree ... | 1299 | * packets before updating TXCSR ... other docs disagree ... |
1309 | */ | 1300 | */ |
1310 | /* PIO: start next packet in this URB */ | 1301 | /* PIO: start next packet in this URB */ |
1311 | wLength = min(qh->maxpacket, (u16) wLength); | 1302 | if (wLength > qh->maxpacket) |
1303 | wLength = qh->maxpacket; | ||
1312 | musb_write_fifo(hw_ep, wLength, buf); | 1304 | musb_write_fifo(hw_ep, wLength, buf); |
1313 | qh->segsize = wLength; | 1305 | qh->segsize = wLength; |
1314 | 1306 | ||
@@ -1362,6 +1354,50 @@ finish: | |||
1362 | 1354 | ||
1363 | #endif | 1355 | #endif |
1364 | 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 | |||
1365 | /* | 1401 | /* |
1366 | * 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, |
1367 | * and high-bandwidth IN transfer cases. | 1403 | * and high-bandwidth IN transfer cases. |
@@ -1425,18 +1461,26 @@ void musb_host_rx(struct musb *musb, u8 epnum) | |||
1425 | } else if (rx_csr & MUSB_RXCSR_DATAERROR) { | 1461 | } else if (rx_csr & MUSB_RXCSR_DATAERROR) { |
1426 | 1462 | ||
1427 | if (USB_ENDPOINT_XFER_ISOC != qh->type) { | 1463 | if (USB_ENDPOINT_XFER_ISOC != qh->type) { |
1428 | /* NOTE this code path would be a good place to PAUSE a | 1464 | DBG(6, "RX end %d NAK timeout\n", epnum); |
1429 | * transfer, if there's some other (nonperiodic) rx urb | 1465 | |
1430 | * 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. | ||
1431 | * | 1469 | * |
1432 | * if (bulk && qh->ring.next != &musb->in_bulk), then | 1470 | * Devices like Ethernet and serial adapters keep |
1433 | * we have a candidate... NAKing is *NOT* an error | 1471 | * reads posted at all times, which will starve |
1472 | * other devices without this logic. | ||
1434 | */ | 1473 | */ |
1435 | 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 | } | ||
1436 | musb_ep_select(mbase, epnum); | 1480 | musb_ep_select(mbase, epnum); |
1437 | musb_writew(epio, MUSB_RXCSR, | 1481 | rx_csr |= MUSB_RXCSR_H_WZC_BITS; |
1438 | MUSB_RXCSR_H_WZC_BITS | 1482 | rx_csr &= ~MUSB_RXCSR_DATAERROR; |
1439 | | MUSB_RXCSR_H_REQPKT); | 1483 | musb_writew(epio, MUSB_RXCSR, rx_csr); |
1440 | 1484 | ||
1441 | goto finish; | 1485 | goto finish; |
1442 | } else { | 1486 | } else { |
@@ -1715,31 +1759,27 @@ static int musb_schedule( | |||
1715 | 1759 | ||
1716 | /* else, periodic transfers get muxed to other endpoints */ | 1760 | /* else, periodic transfers get muxed to other endpoints */ |
1717 | 1761 | ||
1718 | /* FIXME this doesn't consider direction, so it can only | 1762 | /* |
1719 | * 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 |
1720 | * the previous cases handled all non-shared endpoints... | ||
1721 | */ | ||
1722 | |||
1723 | /* we know this qh hasn't been scheduled, so all we need to do | ||
1724 | * is choose which hardware endpoint to put it on ... | 1764 | * is choose which hardware endpoint to put it on ... |
1725 | * | 1765 | * |
1726 | * REVISIT what we really want here is a regular schedule tree | 1766 | * REVISIT what we really want here is a regular schedule tree |
1727 | * like e.g. OHCI uses, but for now musb->periodic is just an | 1767 | * like e.g. OHCI uses. |
1728 | * array of the _single_ logical endpoint associated with a | ||
1729 | * given physical one (identity mapping logical->physical). | ||
1730 | * | ||
1731 | * that simplistic approach makes TT scheduling a lot simpler; | ||
1732 | * there is none, and thus none of its complexity... | ||
1733 | */ | 1768 | */ |
1734 | best_diff = 4096; | 1769 | best_diff = 4096; |
1735 | best_end = -1; | 1770 | best_end = -1; |
1736 | 1771 | ||
1737 | 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++) { | ||
1738 | int diff; | 1775 | int diff; |
1739 | 1776 | ||
1740 | 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) | ||
1741 | continue; | 1781 | continue; |
1742 | hw_ep = &musb->endpoints[epnum]; | 1782 | |
1743 | if (hw_ep == musb->bulk_ep) | 1783 | if (hw_ep == musb->bulk_ep) |
1744 | continue; | 1784 | continue; |
1745 | 1785 | ||
@@ -1760,6 +1800,17 @@ static int musb_schedule( | |||
1760 | head = &musb->in_bulk; | 1800 | head = &musb->in_bulk; |
1761 | else | 1801 | else |
1762 | 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; | ||
1763 | goto success; | 1814 | goto success; |
1764 | } else if (best_end < 0) { | 1815 | } else if (best_end < 0) { |
1765 | return -ENOSPC; | 1816 | return -ENOSPC; |
@@ -1768,7 +1819,6 @@ static int musb_schedule( | |||
1768 | idle = 1; | 1819 | idle = 1; |
1769 | qh->mux = 0; | 1820 | qh->mux = 0; |
1770 | hw_ep = musb->endpoints + best_end; | 1821 | hw_ep = musb->endpoints + best_end; |
1771 | musb->periodic[best_end] = qh; | ||
1772 | DBG(4, "qh %p periodic slot %d\n", qh, best_end); | 1822 | DBG(4, "qh %p periodic slot %d\n", qh, best_end); |
1773 | success: | 1823 | success: |
1774 | if (head) { | 1824 | if (head) { |
@@ -1847,8 +1897,8 @@ static int musb_urb_enqueue( | |||
1847 | goto done; | 1897 | goto done; |
1848 | } | 1898 | } |
1849 | 1899 | ||
1850 | qh->epnum = epd->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; | 1900 | qh->epnum = usb_endpoint_num(epd); |
1851 | qh->type = epd->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; | 1901 | qh->type = usb_endpoint_type(epd); |
1852 | 1902 | ||
1853 | /* NOTE: urb->dev->devnum is wrong during SET_ADDRESS */ | 1903 | /* NOTE: urb->dev->devnum is wrong during SET_ADDRESS */ |
1854 | qh->addr_reg = (u8) usb_pipedevice(urb->pipe); | 1904 | qh->addr_reg = (u8) usb_pipedevice(urb->pipe); |
@@ -1867,19 +1917,21 @@ static int musb_urb_enqueue( | |||
1867 | } | 1917 | } |
1868 | qh->type_reg = type_reg; | 1918 | qh->type_reg = type_reg; |
1869 | 1919 | ||
1870 | /* precompute rxinterval/txinterval register */ | 1920 | /* Precompute RXINTERVAL/TXINTERVAL register */ |
1871 | interval = min((u8)16, epd->bInterval); /* log encoding */ | ||
1872 | switch (qh->type) { | 1921 | switch (qh->type) { |
1873 | case USB_ENDPOINT_XFER_INT: | 1922 | case USB_ENDPOINT_XFER_INT: |
1874 | /* fullspeed uses linear encoding */ | 1923 | /* |
1875 | if (USB_SPEED_FULL == urb->dev->speed) { | 1924 | * Full/low speeds use the linear encoding, |
1876 | interval = epd->bInterval; | 1925 | * high speed uses the logarithmic encoding. |
1877 | if (!interval) | 1926 | */ |
1878 | interval = 1; | 1927 | if (urb->dev->speed <= USB_SPEED_FULL) { |
1928 | interval = max_t(u8, epd->bInterval, 1); | ||
1929 | break; | ||
1879 | } | 1930 | } |
1880 | /* FALLTHROUGH */ | 1931 | /* FALLTHROUGH */ |
1881 | case USB_ENDPOINT_XFER_ISOC: | 1932 | case USB_ENDPOINT_XFER_ISOC: |
1882 | /* iso always uses log encoding */ | 1933 | /* ISO always uses logarithmic encoding */ |
1934 | interval = min_t(u8, epd->bInterval, 16); | ||
1883 | break; | 1935 | break; |
1884 | default: | 1936 | default: |
1885 | /* REVISIT we actually want to use NAK limits, hinting to the | 1937 | /* REVISIT we actually want to use NAK limits, hinting to the |
@@ -1890,13 +1942,11 @@ static int musb_urb_enqueue( | |||
1890 | * | 1942 | * |
1891 | * The downside of disabling this is that transfer scheduling | 1943 | * The downside of disabling this is that transfer scheduling |
1892 | * gets VERY unfair for nonperiodic transfers; a misbehaving | 1944 | * gets VERY unfair for nonperiodic transfers; a misbehaving |
1893 | * peripheral could make that hurt. Or for reads, one that's | 1945 | * peripheral could make that hurt. That's perfectly normal |
1894 | * perfectly normal: network and other drivers keep reads | 1946 | * for reads from network or serial adapters ... so we have |
1895 | * posted at all times, having one pending for a week should | 1947 | * partial NAKlimit support for bulk RX. |
1896 | * be perfectly safe. | ||
1897 | * | 1948 | * |
1898 | * The upside of disabling it is avoidng transfer scheduling | 1949 | * The upside of disabling it is simpler transfer scheduling. |
1899 | * code to put this aside for while. | ||
1900 | */ | 1950 | */ |
1901 | interval = 0; | 1951 | interval = 0; |
1902 | } | 1952 | } |
@@ -2037,9 +2087,9 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
2037 | goto done; | 2087 | goto done; |
2038 | 2088 | ||
2039 | /* Any URB not actively programmed into endpoint hardware can be | 2089 | /* Any URB not actively programmed into endpoint hardware can be |
2040 | * immediately given back. Such an URB must be at the head of its | 2090 | * immediately given back; that's any URB not at the head of an |
2041 | * endpoint queue, unless someday we get real DMA queues. And even | 2091 | * endpoint queue, unless someday we get real DMA queues. And even |
2042 | * then, it might not be known to the hardware... | 2092 | * if it's at the head, it might not be known to the hardware... |
2043 | * | 2093 | * |
2044 | * Otherwise abort current transfer, pending dma, etc.; urb->status | 2094 | * Otherwise abort current transfer, pending dma, etc.; urb->status |
2045 | * has already been updated. This is a synchronous abort; it'd be | 2095 | * has already been updated. This is a synchronous abort; it'd be |
@@ -2078,6 +2128,15 @@ static int musb_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
2078 | qh->is_ready = 0; | 2128 | qh->is_ready = 0; |
2079 | __musb_giveback(musb, urb, 0); | 2129 | __musb_giveback(musb, urb, 0); |
2080 | qh->is_ready = ready; | 2130 | qh->is_ready = ready; |
2131 | |||
2132 | /* If nothing else (usually musb_giveback) is using it | ||
2133 | * and its URB list has emptied, recycle this qh. | ||
2134 | */ | ||
2135 | if (ready && list_empty(&qh->hep->urb_list)) { | ||
2136 | qh->hep->hcpriv = NULL; | ||
2137 | list_del(&qh->ring); | ||
2138 | kfree(qh); | ||
2139 | } | ||
2081 | } else | 2140 | } else |
2082 | ret = musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN); | 2141 | ret = musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN); |
2083 | done: | 2142 | done: |
@@ -2093,15 +2152,16 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) | |||
2093 | unsigned long flags; | 2152 | unsigned long flags; |
2094 | struct musb *musb = hcd_to_musb(hcd); | 2153 | struct musb *musb = hcd_to_musb(hcd); |
2095 | u8 is_in = epnum & USB_DIR_IN; | 2154 | u8 is_in = epnum & USB_DIR_IN; |
2096 | struct musb_qh *qh = hep->hcpriv; | 2155 | struct musb_qh *qh; |
2097 | struct urb *urb, *tmp; | 2156 | struct urb *urb; |
2098 | struct list_head *sched; | 2157 | struct list_head *sched; |
2099 | 2158 | ||
2100 | if (!qh) | ||
2101 | return; | ||
2102 | |||
2103 | spin_lock_irqsave(&musb->lock, flags); | 2159 | spin_lock_irqsave(&musb->lock, flags); |
2104 | 2160 | ||
2161 | qh = hep->hcpriv; | ||
2162 | if (qh == NULL) | ||
2163 | goto exit; | ||
2164 | |||
2105 | switch (qh->type) { | 2165 | switch (qh->type) { |
2106 | case USB_ENDPOINT_XFER_CONTROL: | 2166 | case USB_ENDPOINT_XFER_CONTROL: |
2107 | sched = &musb->control; | 2167 | sched = &musb->control; |
@@ -2135,13 +2195,28 @@ musb_h_disable(struct usb_hcd *hcd, struct usb_host_endpoint *hep) | |||
2135 | 2195 | ||
2136 | /* cleanup */ | 2196 | /* cleanup */ |
2137 | musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN); | 2197 | musb_cleanup_urb(urb, qh, urb->pipe & USB_DIR_IN); |
2138 | } else | ||
2139 | urb = NULL; | ||
2140 | 2198 | ||
2141 | /* then just nuke all the others */ | 2199 | /* Then nuke all the others ... and advance the |
2142 | list_for_each_entry_safe_from(urb, tmp, &hep->urb_list, urb_list) | 2200 | * queue on hw_ep (e.g. bulk ring) when we're done. |
2143 | musb_giveback(qh, urb, -ESHUTDOWN); | 2201 | */ |
2202 | while (!list_empty(&hep->urb_list)) { | ||
2203 | urb = next_urb(qh); | ||
2204 | urb->status = -ESHUTDOWN; | ||
2205 | musb_advance_schedule(musb, urb, qh->hw_ep, is_in); | ||
2206 | } | ||
2207 | } else { | ||
2208 | /* Just empty the queue; the hardware is busy with | ||
2209 | * other transfers, and since !qh->is_ready nothing | ||
2210 | * will activate any of these as it advances. | ||
2211 | */ | ||
2212 | while (!list_empty(&hep->urb_list)) | ||
2213 | __musb_giveback(musb, next_urb(qh), -ESHUTDOWN); | ||
2144 | 2214 | ||
2215 | hep->hcpriv = NULL; | ||
2216 | list_del(&qh->ring); | ||
2217 | kfree(qh); | ||
2218 | } | ||
2219 | exit: | ||
2145 | spin_unlock_irqrestore(&musb->lock, flags); | 2220 | spin_unlock_irqrestore(&musb->lock, flags); |
2146 | } | 2221 | } |
2147 | 2222 | ||
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/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c index 52f7f29cebda..7e073a0d7ac9 100644 --- a/drivers/usb/musb/tusb6010_omap.c +++ b/drivers/usb/musb/tusb6010_omap.c | |||
@@ -15,8 +15,8 @@ | |||
15 | #include <linux/usb.h> | 15 | #include <linux/usb.h> |
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/dma-mapping.h> | 17 | #include <linux/dma-mapping.h> |
18 | #include <asm/arch/dma.h> | 18 | #include <mach/dma.h> |
19 | #include <asm/arch/mux.h> | 19 | #include <mach/mux.h> |
20 | 20 | ||
21 | #include "musb_core.h" | 21 | #include "musb_core.h" |
22 | 22 | ||
diff --git a/drivers/usb/otg/Kconfig b/drivers/usb/otg/Kconfig index 8e8dbdb9b39b..aa884d072f0b 100644 --- a/drivers/usb/otg/Kconfig +++ b/drivers/usb/otg/Kconfig | |||
@@ -6,14 +6,14 @@ | |||
6 | 6 | ||
7 | comment "OTG and related infrastructure" | 7 | comment "OTG and related infrastructure" |
8 | 8 | ||
9 | if USB || USB_GADGET | ||
10 | |||
11 | config USB_OTG_UTILS | 9 | config USB_OTG_UTILS |
12 | bool | 10 | bool |
13 | help | 11 | help |
14 | Select this to make sure the build includes objects from | 12 | Select this to make sure the build includes objects from |
15 | the OTG infrastructure directory. | 13 | the OTG infrastructure directory. |
16 | 14 | ||
15 | if USB || USB_GADGET | ||
16 | |||
17 | # | 17 | # |
18 | # USB Transceiver Drivers | 18 | # USB Transceiver Drivers |
19 | # | 19 | # |
@@ -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/aircable.c b/drivers/usb/serial/aircable.c index 537f953bd7f8..6d106e74265e 100644 --- a/drivers/usb/serial/aircable.c +++ b/drivers/usb/serial/aircable.c | |||
@@ -621,9 +621,9 @@ static int __init aircable_init(void) | |||
621 | goto failed_usb_register; | 621 | goto failed_usb_register; |
622 | return 0; | 622 | return 0; |
623 | 623 | ||
624 | failed_serial_register: | ||
625 | usb_serial_deregister(&aircable_device); | ||
626 | failed_usb_register: | 624 | failed_usb_register: |
625 | usb_serial_deregister(&aircable_device); | ||
626 | failed_serial_register: | ||
627 | return retval; | 627 | return retval; |
628 | } | 628 | } |
629 | 629 | ||
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 cfaf1f085535..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 [] = { |
@@ -79,15 +79,19 @@ static struct usb_device_id id_table [] = { | |||
79 | { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ | 79 | { USB_DEVICE(0x10C4, 0x814A) }, /* West Mountain Radio RIGblaster P&P */ |
80 | { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ | 80 | { USB_DEVICE(0x10C4, 0x814B) }, /* West Mountain Radio RIGtalk */ |
81 | { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ | 81 | { USB_DEVICE(0x10C4, 0x815E) }, /* Helicomm IP-Link 1220-DVM */ |
82 | { USB_DEVICE(0x10C4, 0x819F) }, /* MJS USB Toslink Switcher */ | ||
82 | { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */ | 83 | { USB_DEVICE(0x10C4, 0x81A6) }, /* ThinkOptics WavIt */ |
83 | { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */ | 84 | { USB_DEVICE(0x10C4, 0x81AC) }, /* MSD Dash Hawk */ |
84 | { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ | 85 | { USB_DEVICE(0x10C4, 0x81C8) }, /* Lipowsky Industrie Elektronik GmbH, Baby-JTAG */ |
85 | { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */ | 86 | { USB_DEVICE(0x10C4, 0x81E2) }, /* Lipowsky Industrie Elektronik GmbH, Baby-LIN */ |
86 | { USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */ | 87 | { USB_DEVICE(0x10C4, 0x81E7) }, /* Aerocomm Radio */ |
87 | { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ | 88 | { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ |
89 | { USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */ | ||
90 | { USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demostration module */ | ||
88 | { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */ | 91 | { USB_DEVICE(0x10c4, 0x8293) }, /* Telegesys ETRX2USB */ |
89 | { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ | 92 | { USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */ |
90 | { 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) */ | ||
91 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ | 95 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ |
92 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ | 96 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ |
93 | { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */ | 97 | { USB_DEVICE(0x10C4, 0xF001) }, /* Elan Digital Systems USBscope50 */ |
@@ -222,7 +226,7 @@ static int cp2101_get_config(struct usb_serial_port *port, u8 request, | |||
222 | kfree(buf); | 226 | kfree(buf); |
223 | 227 | ||
224 | if (result != size) { | 228 | if (result != size) { |
225 | dev_err(&port->dev, "%s - Unable to send config request, " | 229 | dbg("%s - Unable to send config request, " |
226 | "request=0x%x size=%d result=%d\n", | 230 | "request=0x%x size=%d result=%d\n", |
227 | __func__, request, size, result); | 231 | __func__, request, size, result); |
228 | return -EPROTO; | 232 | return -EPROTO; |
@@ -273,7 +277,7 @@ static int cp2101_set_config(struct usb_serial_port *port, u8 request, | |||
273 | kfree(buf); | 277 | kfree(buf); |
274 | 278 | ||
275 | if ((size > 2 && result != size) || result < 0) { | 279 | if ((size > 2 && result != size) || result < 0) { |
276 | dev_err(&port->dev, "%s - Unable to send request, " | 280 | dbg("%s - Unable to send request, " |
277 | "request=0x%x size=%d result=%d\n", | 281 | "request=0x%x size=%d result=%d\n", |
278 | __func__, request, size, result); | 282 | __func__, request, size, result); |
279 | return -EPROTO; | 283 | return -EPROTO; |
@@ -298,6 +302,47 @@ static inline int cp2101_set_config_single(struct usb_serial_port *port, | |||
298 | return cp2101_set_config(port, request, &data, 2); | 302 | return cp2101_set_config(port, request, &data, 2); |
299 | } | 303 | } |
300 | 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 | |||
301 | 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, |
302 | struct file *filp) | 347 | struct file *filp) |
303 | { | 348 | { |
@@ -328,10 +373,12 @@ static int cp2101_open(struct tty_struct *tty, struct usb_serial_port *port, | |||
328 | } | 373 | } |
329 | 374 | ||
330 | /* Configure the termios structure */ | 375 | /* Configure the termios structure */ |
331 | cp2101_get_termios(tty); | 376 | cp2101_get_termios(tty, port); |
332 | 377 | ||
333 | /* Set the DTR and RTS pins low */ | 378 | /* Set the DTR and RTS pins low */ |
334 | 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); | ||
335 | 382 | ||
336 | return 0; | 383 | return 0; |
337 | } | 384 | } |
@@ -373,9 +420,31 @@ static void cp2101_close(struct tty_struct *tty, struct usb_serial_port *port, | |||
373 | * from the device, corrects any unsupported values, and configures the | 420 | * from the device, corrects any unsupported values, and configures the |
374 | * termios structure to reflect the state of the device | 421 | * termios structure to reflect the state of the device |
375 | */ | 422 | */ |
376 | 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) | ||
377 | { | 447 | { |
378 | struct usb_serial_port *port = tty->driver_data; | ||
379 | unsigned int cflag, modem_ctl[4]; | 448 | unsigned int cflag, modem_ctl[4]; |
380 | unsigned int baud; | 449 | unsigned int baud; |
381 | unsigned int bits; | 450 | unsigned int bits; |
@@ -385,12 +454,12 @@ static void cp2101_get_termios (struct tty_struct *tty) | |||
385 | cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2); | 454 | cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2); |
386 | /* Convert to baudrate */ | 455 | /* Convert to baudrate */ |
387 | if (baud) | 456 | if (baud) |
388 | baud = BAUD_RATE_GEN_FREQ / baud; | 457 | baud = cp2101_quantise_baudrate((BAUD_RATE_GEN_FREQ + baud/2)/ baud); |
389 | 458 | ||
390 | dbg("%s - baud rate = %d", __func__, baud); | 459 | dbg("%s - baud rate = %d", __func__, baud); |
460 | *baudp = baud; | ||
391 | 461 | ||
392 | tty_encode_baud_rate(tty, baud, baud); | 462 | cflag = *cflagp; |
393 | cflag = tty->termios->c_cflag; | ||
394 | 463 | ||
395 | cp2101_get_config(port, CP2101_BITS, &bits, 2); | 464 | cp2101_get_config(port, CP2101_BITS, &bits, 2); |
396 | cflag &= ~CSIZE; | 465 | cflag &= ~CSIZE; |
@@ -496,7 +565,7 @@ static void cp2101_get_termios (struct tty_struct *tty) | |||
496 | cflag &= ~CRTSCTS; | 565 | cflag &= ~CRTSCTS; |
497 | } | 566 | } |
498 | 567 | ||
499 | tty->termios->c_cflag = cflag; | 568 | *cflagp = cflag; |
500 | } | 569 | } |
501 | 570 | ||
502 | static void cp2101_set_termios(struct tty_struct *tty, | 571 | static void cp2101_set_termios(struct tty_struct *tty, |
@@ -514,46 +583,16 @@ static void cp2101_set_termios(struct tty_struct *tty, | |||
514 | tty->termios->c_cflag &= ~CMSPAR; | 583 | tty->termios->c_cflag &= ~CMSPAR; |
515 | cflag = tty->termios->c_cflag; | 584 | cflag = tty->termios->c_cflag; |
516 | old_cflag = old_termios->c_cflag; | 585 | old_cflag = old_termios->c_cflag; |
517 | baud = tty_get_baud_rate(tty); | 586 | baud = cp2101_quantise_baudrate(tty_get_baud_rate(tty)); |
518 | 587 | ||
519 | /* If the baud rate is to be updated*/ | 588 | /* If the baud rate is to be updated*/ |
520 | if (baud != tty_termios_baud_rate(old_termios)) { | 589 | if (baud != tty_termios_baud_rate(old_termios) && baud != 0) { |
521 | switch (baud) { | 590 | dbg("%s - Setting baud rate to %d baud", __func__, |
522 | case 0: | 591 | baud); |
523 | case 600: | 592 | if (cp2101_set_config_single(port, CP2101_BAUDRATE, |
524 | case 1200: | 593 | ((BAUD_RATE_GEN_FREQ + baud/2) / baud))) { |
525 | case 1800: | 594 | dbg("Baud rate requested not supported by device\n"); |
526 | case 2400: | 595 | baud = tty_termios_baud_rate(old_termios); |
527 | case 4800: | ||
528 | case 7200: | ||
529 | case 9600: | ||
530 | case 14400: | ||
531 | case 19200: | ||
532 | case 28800: | ||
533 | case 38400: | ||
534 | case 55854: | ||
535 | case 57600: | ||
536 | case 115200: | ||
537 | case 127117: | ||
538 | case 230400: | ||
539 | case 460800: | ||
540 | case 921600: | ||
541 | case 3686400: | ||
542 | break; | ||
543 | default: | ||
544 | baud = 9600; | ||
545 | break; | ||
546 | } | ||
547 | |||
548 | if (baud) { | ||
549 | dbg("%s - Setting baud rate to %d baud", __func__, | ||
550 | baud); | ||
551 | if (cp2101_set_config_single(port, CP2101_BAUDRATE, | ||
552 | (BAUD_RATE_GEN_FREQ / baud))) { | ||
553 | dev_err(&port->dev, "Baud rate requested not " | ||
554 | "supported by device\n"); | ||
555 | baud = tty_termios_baud_rate(old_termios); | ||
556 | } | ||
557 | } | 596 | } |
558 | } | 597 | } |
559 | /* Report back the resulting baud rate */ | 598 | /* Report back the resulting baud rate */ |
@@ -585,14 +624,14 @@ static void cp2101_set_termios(struct tty_struct *tty, | |||
585 | dbg("%s - data bits = 9", __func__); | 624 | dbg("%s - data bits = 9", __func__); |
586 | break;*/ | 625 | break;*/ |
587 | default: | 626 | default: |
588 | dev_err(&port->dev, "cp2101 driver does not " | 627 | dbg("cp2101 driver does not " |
589 | "support the number of bits requested," | 628 | "support the number of bits requested," |
590 | " using 8 bit mode\n"); | 629 | " using 8 bit mode\n"); |
591 | bits |= BITS_DATA_8; | 630 | bits |= BITS_DATA_8; |
592 | break; | 631 | break; |
593 | } | 632 | } |
594 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) | 633 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) |
595 | dev_err(&port->dev, "Number of data bits requested " | 634 | dbg("Number of data bits requested " |
596 | "not supported by device\n"); | 635 | "not supported by device\n"); |
597 | } | 636 | } |
598 | 637 | ||
@@ -609,7 +648,7 @@ static void cp2101_set_termios(struct tty_struct *tty, | |||
609 | } | 648 | } |
610 | } | 649 | } |
611 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) | 650 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) |
612 | dev_err(&port->dev, "Parity mode not supported " | 651 | dbg("Parity mode not supported " |
613 | "by device\n"); | 652 | "by device\n"); |
614 | } | 653 | } |
615 | 654 | ||
@@ -624,7 +663,7 @@ static void cp2101_set_termios(struct tty_struct *tty, | |||
624 | dbg("%s - stop bits = 1", __func__); | 663 | dbg("%s - stop bits = 1", __func__); |
625 | } | 664 | } |
626 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) | 665 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) |
627 | dev_err(&port->dev, "Number of stop bits requested " | 666 | dbg("Number of stop bits requested " |
628 | "not supported by device\n"); | 667 | "not supported by device\n"); |
629 | } | 668 | } |
630 | 669 | ||
@@ -658,6 +697,12 @@ static int cp2101_tiocmset (struct tty_struct *tty, struct file *file, | |||
658 | unsigned int set, unsigned int clear) | 697 | unsigned int set, unsigned int clear) |
659 | { | 698 | { |
660 | 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 | { | ||
661 | unsigned int control = 0; | 706 | unsigned int control = 0; |
662 | 707 | ||
663 | dbg("%s - port %d", __func__, port->number); | 708 | dbg("%s - port %d", __func__, port->number); |
@@ -682,7 +727,6 @@ static int cp2101_tiocmset (struct tty_struct *tty, struct file *file, | |||
682 | dbg("%s - control = 0x%.4x", __func__, control); | 727 | dbg("%s - control = 0x%.4x", __func__, control); |
683 | 728 | ||
684 | return cp2101_set_config(port, CP2101_CONTROL, &control, 2); | 729 | return cp2101_set_config(port, CP2101_CONTROL, &control, 2); |
685 | |||
686 | } | 730 | } |
687 | 731 | ||
688 | 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 c70a8f667d85..dcc87aaa8628 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -660,6 +660,14 @@ static struct usb_device_id id_table_combined [] = { | |||
660 | { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, | 660 | { USB_DEVICE(PAPOUCH_VID, PAPOUCH_QUIDO4x4_PID) }, |
661 | { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) }, | 661 | { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DGQG_PID) }, |
662 | { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, | 662 | { USB_DEVICE(FTDI_VID, FTDI_DOMINTELL_DUSB_PID) }, |
663 | { USB_DEVICE(ALTI2_VID, ALTI2_N3_PID) }, | ||
664 | { USB_DEVICE(FTDI_VID, DIEBOLD_BCS_SE923_PID) }, | ||
665 | { USB_DEVICE(FTDI_VID, FTDI_NDI_HUC_PID) }, | ||
666 | { USB_DEVICE(ATMEL_VID, STK541_PID) }, | ||
667 | { USB_DEVICE(DE_VID, STB_PID) }, | ||
668 | { USB_DEVICE(DE_VID, WHT_PID) }, | ||
669 | { USB_DEVICE(ADI_VID, ADI_GNICE_PID), | ||
670 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | ||
663 | { }, /* Optional parameter entry */ | 671 | { }, /* Optional parameter entry */ |
664 | { } /* Terminating entry */ | 672 | { } /* Terminating entry */ |
665 | }; | 673 | }; |
@@ -1062,8 +1070,10 @@ static int set_serial_info(struct tty_struct *tty, | |||
1062 | 1070 | ||
1063 | if (!capable(CAP_SYS_ADMIN)) { | 1071 | if (!capable(CAP_SYS_ADMIN)) { |
1064 | if (((new_serial.flags & ~ASYNC_USR_MASK) != | 1072 | if (((new_serial.flags & ~ASYNC_USR_MASK) != |
1065 | (priv->flags & ~ASYNC_USR_MASK))) | 1073 | (priv->flags & ~ASYNC_USR_MASK))) { |
1074 | unlock_kernel(); | ||
1066 | return -EPERM; | 1075 | return -EPERM; |
1076 | } | ||
1067 | priv->flags = ((priv->flags & ~ASYNC_USR_MASK) | | 1077 | priv->flags = ((priv->flags & ~ASYNC_USR_MASK) | |
1068 | (new_serial.flags & ASYNC_USR_MASK)); | 1078 | (new_serial.flags & ASYNC_USR_MASK)); |
1069 | priv->custom_divisor = new_serial.custom_divisor; | 1079 | priv->custom_divisor = new_serial.custom_divisor; |
@@ -1928,18 +1938,16 @@ static void ftdi_process_read(struct work_struct *work) | |||
1928 | /* Compare new line status to the old one, signal if different/ | 1938 | /* Compare new line status to the old one, signal if different/ |
1929 | N.B. packet may be processed more than once, but differences | 1939 | N.B. packet may be processed more than once, but differences |
1930 | are only processed once. */ | 1940 | are only processed once. */ |
1931 | if (priv != NULL) { | 1941 | char new_status = data[packet_offset + 0] & |
1932 | char new_status = data[packet_offset + 0] & | 1942 | FTDI_STATUS_B0_MASK; |
1933 | FTDI_STATUS_B0_MASK; | 1943 | if (new_status != priv->prev_status) { |
1934 | if (new_status != priv->prev_status) { | 1944 | priv->diff_status |= |
1935 | priv->diff_status |= | 1945 | new_status ^ priv->prev_status; |
1936 | new_status ^ priv->prev_status; | 1946 | wake_up_interruptible(&priv->delta_msr_wait); |
1937 | wake_up_interruptible(&priv->delta_msr_wait); | 1947 | priv->prev_status = new_status; |
1938 | priv->prev_status = new_status; | ||
1939 | } | ||
1940 | } | 1948 | } |
1941 | 1949 | ||
1942 | length = min(PKTSZ, urb->actual_length-packet_offset)-2; | 1950 | length = min_t(u32, PKTSZ, urb->actual_length-packet_offset)-2; |
1943 | if (length < 0) { | 1951 | if (length < 0) { |
1944 | dev_err(&port->dev, "%s - bad packet length: %d\n", | 1952 | dev_err(&port->dev, "%s - bad packet length: %d\n", |
1945 | __func__, length+2); | 1953 | __func__, length+2); |
@@ -2284,11 +2292,8 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) | |||
2284 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, | 2292 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, |
2285 | 0, 0, | 2293 | 0, 0, |
2286 | buf, 1, WDR_TIMEOUT); | 2294 | buf, 1, WDR_TIMEOUT); |
2287 | if (ret < 0) { | 2295 | if (ret < 0) |
2288 | dbg("%s Could not get modem status of device - err: %d", __func__, | ||
2289 | ret); | ||
2290 | return ret; | 2296 | return ret; |
2291 | } | ||
2292 | break; | 2297 | break; |
2293 | case FT8U232AM: | 2298 | case FT8U232AM: |
2294 | case FT232BM: | 2299 | case FT232BM: |
@@ -2303,15 +2308,11 @@ static int ftdi_tiocmget(struct tty_struct *tty, struct file *file) | |||
2303 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, | 2308 | FTDI_SIO_GET_MODEM_STATUS_REQUEST_TYPE, |
2304 | 0, priv->interface, | 2309 | 0, priv->interface, |
2305 | buf, 2, WDR_TIMEOUT); | 2310 | buf, 2, WDR_TIMEOUT); |
2306 | if (ret < 0) { | 2311 | if (ret < 0) |
2307 | dbg("%s Could not get modem status of device - err: %d", __func__, | ||
2308 | ret); | ||
2309 | return ret; | 2312 | return ret; |
2310 | } | ||
2311 | break; | 2313 | break; |
2312 | default: | 2314 | default: |
2313 | return -EFAULT; | 2315 | return -EFAULT; |
2314 | break; | ||
2315 | } | 2316 | } |
2316 | 2317 | ||
2317 | 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/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 373ee09975bb..daaf63db0b50 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -844,6 +844,9 @@ | |||
844 | #define TML_VID 0x1B91 /* Vendor ID */ | 844 | #define TML_VID 0x1B91 /* Vendor ID */ |
845 | #define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ | 845 | #define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ |
846 | 846 | ||
847 | /* NDI Polaris System */ | ||
848 | #define FTDI_NDI_HUC_PID 0xDA70 | ||
849 | |||
847 | /* Propox devices */ | 850 | /* Propox devices */ |
848 | #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 | 851 | #define FTDI_PROPOX_JTAGCABLEII_PID 0xD738 |
849 | 852 | ||
@@ -854,6 +857,10 @@ | |||
854 | #define FTDI_DOMINTELL_DGQG_PID 0xEF50 /* Master */ | 857 | #define FTDI_DOMINTELL_DGQG_PID 0xEF50 /* Master */ |
855 | #define FTDI_DOMINTELL_DUSB_PID 0xEF51 /* DUSB01 module */ | 858 | #define FTDI_DOMINTELL_DUSB_PID 0xEF51 /* DUSB01 module */ |
856 | 859 | ||
860 | /* Alti-2 products http://www.alti-2.com */ | ||
861 | #define ALTI2_VID 0x1BC9 | ||
862 | #define ALTI2_N3_PID 0x6001 /* Neptune 3 */ | ||
863 | |||
857 | /* Commands */ | 864 | /* Commands */ |
858 | #define FTDI_SIO_RESET 0 /* Reset the port */ | 865 | #define FTDI_SIO_RESET 0 /* Reset the port */ |
859 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ | 866 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ |
@@ -881,6 +888,31 @@ | |||
881 | #define RATOC_PRODUCT_ID_USB60F 0xb020 | 888 | #define RATOC_PRODUCT_ID_USB60F 0xb020 |
882 | 889 | ||
883 | /* | 890 | /* |
891 | * DIEBOLD BCS SE923 | ||
892 | */ | ||
893 | #define DIEBOLD_BCS_SE923_PID 0xfb99 | ||
894 | |||
895 | /* | ||
896 | * Atmel STK541 | ||
897 | */ | ||
898 | #define ATMEL_VID 0x03eb /* Vendor ID */ | ||
899 | #define STK541_PID 0x2109 /* Zigbee Controller */ | ||
900 | |||
901 | /* | ||
902 | * Dresden Elektronic Sensor Terminal Board | ||
903 | */ | ||
904 | #define DE_VID 0x1cf1 /* Vendor ID */ | ||
905 | #define STB_PID 0x0001 /* Sensor Terminal Board */ | ||
906 | #define WHT_PID 0x0004 /* Wireless Handheld Terminal */ | ||
907 | |||
908 | /* | ||
909 | * Blackfin gnICE JTAG | ||
910 | * http://docs.blackfin.uclinux.org/doku.php?id=hw:jtag:gnice | ||
911 | */ | ||
912 | #define ADI_VID 0x0456 | ||
913 | #define ADI_GNICE_PID 0xF000 | ||
914 | |||
915 | /* | ||
884 | * BmRequestType: 1100 0000b | 916 | * BmRequestType: 1100 0000b |
885 | * bRequest: FTDI_E2_READ | 917 | * bRequest: FTDI_E2_READ |
886 | * wValue: 0 | 918 | * wValue: 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 5ed183477aaf..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 |
@@ -89,6 +91,7 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po | |||
89 | #define OPTION_PRODUCT_ETNA_MODEM_GT 0x7041 | 91 | #define OPTION_PRODUCT_ETNA_MODEM_GT 0x7041 |
90 | #define OPTION_PRODUCT_ETNA_MODEM_EX 0x7061 | 92 | #define OPTION_PRODUCT_ETNA_MODEM_EX 0x7061 |
91 | #define OPTION_PRODUCT_ETNA_KOI_MODEM 0x7100 | 93 | #define OPTION_PRODUCT_ETNA_KOI_MODEM 0x7100 |
94 | #define OPTION_PRODUCT_GTM380_MODEM 0x7201 | ||
92 | 95 | ||
93 | #define HUAWEI_VENDOR_ID 0x12D1 | 96 | #define HUAWEI_VENDOR_ID 0x12D1 |
94 | #define HUAWEI_PRODUCT_E600 0x1001 | 97 | #define HUAWEI_PRODUCT_E600 0x1001 |
@@ -158,6 +161,13 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po | |||
158 | #define HUAWEI_PRODUCT_E143E 0x143E | 161 | #define HUAWEI_PRODUCT_E143E 0x143E |
159 | #define HUAWEI_PRODUCT_E143F 0x143F | 162 | #define HUAWEI_PRODUCT_E143F 0x143F |
160 | 163 | ||
164 | #define QUANTA_VENDOR_ID 0x0408 | ||
165 | #define QUANTA_PRODUCT_Q101 0xEA02 | ||
166 | #define QUANTA_PRODUCT_Q111 0xEA03 | ||
167 | #define QUANTA_PRODUCT_GLX 0xEA04 | ||
168 | #define QUANTA_PRODUCT_GKE 0xEA05 | ||
169 | #define QUANTA_PRODUCT_GLE 0xEA06 | ||
170 | |||
161 | #define NOVATELWIRELESS_VENDOR_ID 0x1410 | 171 | #define NOVATELWIRELESS_VENDOR_ID 0x1410 |
162 | 172 | ||
163 | /* YISO PRODUCTS */ | 173 | /* YISO PRODUCTS */ |
@@ -190,16 +200,18 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po | |||
190 | /* OVATION PRODUCTS */ | 200 | /* OVATION PRODUCTS */ |
191 | #define NOVATELWIRELESS_PRODUCT_MC727 0x4100 | 201 | #define NOVATELWIRELESS_PRODUCT_MC727 0x4100 |
192 | #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 | 202 | #define NOVATELWIRELESS_PRODUCT_MC950D 0x4400 |
203 | #define NOVATELWIRELESS_PRODUCT_U727 0x5010 | ||
193 | 204 | ||
194 | /* FUTURE NOVATEL PRODUCTS */ | 205 | /* FUTURE NOVATEL PRODUCTS */ |
195 | #define NOVATELWIRELESS_PRODUCT_EVDO_1 0x6000 | 206 | #define NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED 0X6000 |
196 | #define NOVATELWIRELESS_PRODUCT_HSPA_1 0x7000 | 207 | #define NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED 0X6001 |
197 | #define NOVATELWIRELESS_PRODUCT_EMBEDDED_1 0x8000 | 208 | #define NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED 0X7000 |
198 | #define NOVATELWIRELESS_PRODUCT_GLOBAL_1 0x9000 | 209 | #define NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED 0X7001 |
199 | #define NOVATELWIRELESS_PRODUCT_EVDO_2 0x6001 | 210 | #define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED 0X8000 |
200 | #define NOVATELWIRELESS_PRODUCT_HSPA_2 0x7001 | 211 | #define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0X8001 |
201 | #define NOVATELWIRELESS_PRODUCT_EMBEDDED_2 0x8001 | 212 | #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0X9000 |
202 | #define NOVATELWIRELESS_PRODUCT_GLOBAL_2 0x9001 | 213 | #define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0X9001 |
214 | #define NOVATELWIRELESS_PRODUCT_GLOBAL 0XA001 | ||
203 | 215 | ||
204 | /* AMOI PRODUCTS */ | 216 | /* AMOI PRODUCTS */ |
205 | #define AMOI_VENDOR_ID 0x1614 | 217 | #define AMOI_VENDOR_ID 0x1614 |
@@ -209,6 +221,27 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po | |||
209 | 221 | ||
210 | #define DELL_VENDOR_ID 0x413C | 222 | #define DELL_VENDOR_ID 0x413C |
211 | 223 | ||
224 | /* Dell modems */ | ||
225 | #define DELL_PRODUCT_5700_MINICARD 0x8114 | ||
226 | #define DELL_PRODUCT_5500_MINICARD 0x8115 | ||
227 | #define DELL_PRODUCT_5505_MINICARD 0x8116 | ||
228 | #define DELL_PRODUCT_5700_EXPRESSCARD 0x8117 | ||
229 | #define DELL_PRODUCT_5510_EXPRESSCARD 0x8118 | ||
230 | |||
231 | #define DELL_PRODUCT_5700_MINICARD_SPRINT 0x8128 | ||
232 | #define DELL_PRODUCT_5700_MINICARD_TELUS 0x8129 | ||
233 | |||
234 | #define DELL_PRODUCT_5720_MINICARD_VZW 0x8133 | ||
235 | #define DELL_PRODUCT_5720_MINICARD_SPRINT 0x8134 | ||
236 | #define DELL_PRODUCT_5720_MINICARD_TELUS 0x8135 | ||
237 | #define DELL_PRODUCT_5520_MINICARD_CINGULAR 0x8136 | ||
238 | #define DELL_PRODUCT_5520_MINICARD_GENERIC_L 0x8137 | ||
239 | #define DELL_PRODUCT_5520_MINICARD_GENERIC_I 0x8138 | ||
240 | |||
241 | #define DELL_PRODUCT_5730_MINICARD_SPRINT 0x8180 | ||
242 | #define DELL_PRODUCT_5730_MINICARD_TELUS 0x8181 | ||
243 | #define DELL_PRODUCT_5730_MINICARD_VZW 0x8182 | ||
244 | |||
212 | #define KYOCERA_VENDOR_ID 0x0c88 | 245 | #define KYOCERA_VENDOR_ID 0x0c88 |
213 | #define KYOCERA_PRODUCT_KPC650 0x17da | 246 | #define KYOCERA_PRODUCT_KPC650 0x17da |
214 | #define KYOCERA_PRODUCT_KPC680 0x180a | 247 | #define KYOCERA_PRODUCT_KPC680 0x180a |
@@ -224,7 +257,7 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po | |||
224 | #define ONDA_VENDOR_ID 0x19d2 | 257 | #define ONDA_VENDOR_ID 0x19d2 |
225 | #define ONDA_PRODUCT_MSA501HS 0x0001 | 258 | #define ONDA_PRODUCT_MSA501HS 0x0001 |
226 | #define ONDA_PRODUCT_ET502HS 0x0002 | 259 | #define ONDA_PRODUCT_ET502HS 0x0002 |
227 | #define ONDA_PRODUCT_MT503HS 0x0200 | 260 | #define ONDA_PRODUCT_MT503HS 0x2000 |
228 | 261 | ||
229 | #define BANDRICH_VENDOR_ID 0x1A8D | 262 | #define BANDRICH_VENDOR_ID 0x1A8D |
230 | #define BANDRICH_PRODUCT_C100_1 0x1002 | 263 | #define BANDRICH_PRODUCT_C100_1 0x1002 |
@@ -259,19 +292,13 @@ static int option_send_setup(struct tty_struct *tty, struct usb_serial_port *po | |||
259 | 292 | ||
260 | /* ZTE PRODUCTS */ | 293 | /* ZTE PRODUCTS */ |
261 | #define ZTE_VENDOR_ID 0x19d2 | 294 | #define ZTE_VENDOR_ID 0x19d2 |
295 | #define ZTE_PRODUCT_MF622 0x0001 | ||
262 | #define ZTE_PRODUCT_MF628 0x0015 | 296 | #define ZTE_PRODUCT_MF628 0x0015 |
263 | #define ZTE_PRODUCT_MF626 0x0031 | 297 | #define ZTE_PRODUCT_MF626 0x0031 |
264 | #define ZTE_PRODUCT_CDMA_TECH 0xfffe | 298 | #define ZTE_PRODUCT_CDMA_TECH 0xfffe |
265 | 299 | ||
266 | /* Ericsson products */ | 300 | #define BENQ_VENDOR_ID 0x04a5 |
267 | #define ERICSSON_VENDOR_ID 0x0bdb | 301 | #define BENQ_PRODUCT_H10 0x4068 |
268 | #define ERICSSON_PRODUCT_F3507G 0x1900 | ||
269 | |||
270 | /* Pantech products */ | ||
271 | #define PANTECH_VENDOR_ID 0x106c | ||
272 | #define PANTECH_PRODUCT_PC5740 0x3701 | ||
273 | #define PANTECH_PRODUCT_PC5750 0x3702 /* PX-500 */ | ||
274 | #define PANTECH_PRODUCT_UM150 0x3711 | ||
275 | 302 | ||
276 | static struct usb_device_id option_ids[] = { | 303 | static struct usb_device_id option_ids[] = { |
277 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, | 304 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
@@ -298,6 +325,12 @@ static struct usb_device_id option_ids[] = { | |||
298 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_GT) }, | 325 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_GT) }, |
299 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_EX) }, | 326 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_MODEM_EX) }, |
300 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) }, | 327 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_MODEM) }, |
328 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTM380_MODEM) }, | ||
329 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_Q101) }, | ||
330 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_Q111) }, | ||
331 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) }, | ||
332 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) }, | ||
333 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) }, | ||
301 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) }, | 334 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) }, |
302 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) }, | 335 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) }, |
303 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) }, | 336 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) }, |
@@ -383,31 +416,37 @@ static struct usb_device_id option_ids[] = { | |||
383 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */ | 416 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */ |
384 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */ | 417 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */ |
385 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ | 418 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */ |
386 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_1) }, /* Novatel EVDO product */ | 419 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel MC727/U727/USB727 */ |
387 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_1) }, /* Novatel HSPA product */ | 420 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_FULLSPEED) }, /* Novatel EVDO product */ |
388 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_1) }, /* Novatel Embedded product */ | 421 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_FULLSPEED) }, /* Novatel HSPA product */ |
389 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL_1) }, /* Novatel Global product */ | 422 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_FULLSPEED) }, /* Novatel EVDO Embedded product */ |
390 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_2) }, /* Novatel EVDO product */ | 423 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED) }, /* Novatel HSPA Embedded product */ |
391 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_2) }, /* Novatel HSPA product */ | 424 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_HIGHSPEED) }, /* Novatel EVDO product */ |
392 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_2) }, /* Novatel Embedded product */ | 425 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED) }, /* Novatel HSPA product */ |
393 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL_2) }, /* Novatel Global product */ | 426 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED) }, /* Novatel EVDO Embedded product */ |
427 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED) }, /* Novatel HSPA Embedded product */ | ||
428 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL) }, /* Novatel Global product */ | ||
394 | 429 | ||
395 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, | 430 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) }, |
396 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, | 431 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) }, |
397 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H02) }, | 432 | { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H02) }, |
398 | 433 | ||
399 | { USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */ | 434 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */ |
400 | { USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ | 435 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5500_MINICARD) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ |
401 | { USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ | 436 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5505_MINICARD) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ |
402 | { USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */ | 437 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_EXPRESSCARD) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */ |
403 | { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */ | 438 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5510_EXPRESSCARD) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */ |
404 | { USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */ | 439 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD_SPRINT) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */ |
405 | { USB_DEVICE(DELL_VENDOR_ID, 0x8129) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite ET620 CDMA/EV-DO */ | 440 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5700_MINICARD_TELUS) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite ET620 CDMA/EV-DO */ |
406 | { USB_DEVICE(DELL_VENDOR_ID, 0x8133) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ | 441 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_VZW) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ |
407 | { USB_DEVICE(DELL_VENDOR_ID, 0x8136) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ | 442 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_SPRINT) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ |
408 | { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */ | 443 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5720_MINICARD_TELUS) }, /* Dell Wireless 5720 == Novatel EV620 CDMA/EV-DO */ |
409 | { USB_DEVICE(DELL_VENDOR_ID, 0x8138) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */ | 444 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_CINGULAR) }, /* Dell Wireless HSDPA 5520 == Novatel Expedite EU860D */ |
410 | { USB_DEVICE(DELL_VENDOR_ID, 0x8147) }, /* Dell Wireless 5530 Mobile Broadband (3G HSPA) Mini-Card */ | 445 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_L) }, /* Dell Wireless HSDPA 5520 */ |
446 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5520_MINICARD_GENERIC_I) }, /* Dell Wireless 5520 Voda I Mobile Broadband (3G HSDPA) Minicard */ | ||
447 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ | ||
448 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ | ||
449 | { USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */ | ||
411 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ | 450 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */ |
412 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, | 451 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, |
413 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, | 452 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) }, |
@@ -472,13 +511,12 @@ static struct usb_device_id option_ids[] = { | |||
472 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ | 511 | { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */ |
473 | { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ | 512 | { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */ |
474 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, | 513 | { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UC864E) }, |
514 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622) }, | ||
475 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626) }, | 515 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF626) }, |
476 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) }, | 516 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_MF628) }, |
477 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, | 517 | { USB_DEVICE(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH) }, |
478 | { USB_DEVICE(ERICSSON_VENDOR_ID, ERICSSON_PRODUCT_F3507G) }, | 518 | { USB_DEVICE(BENQ_VENDOR_ID, BENQ_PRODUCT_H10) }, |
479 | { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_PC5740) }, | 519 | { USB_DEVICE(0x1da5, 0x4515) }, /* BenQ H20 */ |
480 | { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_PC5750) }, | ||
481 | { USB_DEVICE(PANTECH_VENDOR_ID, PANTECH_PRODUCT_UM150) }, | ||
482 | { } /* Terminating entry */ | 520 | { } /* Terminating entry */ |
483 | }; | 521 | }; |
484 | MODULE_DEVICE_TABLE(usb, option_ids); | 522 | MODULE_DEVICE_TABLE(usb, option_ids); |
@@ -487,6 +525,8 @@ static struct usb_driver option_driver = { | |||
487 | .name = "option", | 525 | .name = "option", |
488 | .probe = usb_serial_probe, | 526 | .probe = usb_serial_probe, |
489 | .disconnect = usb_serial_disconnect, | 527 | .disconnect = usb_serial_disconnect, |
528 | .suspend = usb_serial_suspend, | ||
529 | .resume = usb_serial_resume, | ||
490 | .id_table = option_ids, | 530 | .id_table = option_ids, |
491 | .no_dynamic_id = 1, | 531 | .no_dynamic_id = 1, |
492 | }; | 532 | }; |
@@ -515,6 +555,8 @@ static struct usb_serial_driver option_1port_device = { | |||
515 | .attach = option_startup, | 555 | .attach = option_startup, |
516 | .shutdown = option_shutdown, | 556 | .shutdown = option_shutdown, |
517 | .read_int_callback = option_instat_callback, | 557 | .read_int_callback = option_instat_callback, |
558 | .suspend = option_suspend, | ||
559 | .resume = option_resume, | ||
518 | }; | 560 | }; |
519 | 561 | ||
520 | static int debug; | 562 | static int debug; |
@@ -785,10 +827,10 @@ static void option_instat_callback(struct urb *urb) | |||
785 | req_pkt->bRequestType, req_pkt->bRequest); | 827 | req_pkt->bRequestType, req_pkt->bRequest); |
786 | } | 828 | } |
787 | } else | 829 | } else |
788 | dbg("%s: error %d", __func__, status); | 830 | err("%s: error %d", __func__, status); |
789 | 831 | ||
790 | /* Resubmit urb so we continue receiving IRQ data */ | 832 | /* Resubmit urb so we continue receiving IRQ data */ |
791 | if (status != -ESHUTDOWN) { | 833 | if (status != -ESHUTDOWN && status != -ENOENT) { |
792 | urb->dev = serial->dev; | 834 | urb->dev = serial->dev; |
793 | err = usb_submit_urb(urb, GFP_ATOMIC); | 835 | err = usb_submit_urb(urb, GFP_ATOMIC); |
794 | if (err) | 836 | if (err) |
@@ -807,7 +849,6 @@ static int option_write_room(struct tty_struct *tty) | |||
807 | 849 | ||
808 | portdata = usb_get_serial_port_data(port); | 850 | portdata = usb_get_serial_port_data(port); |
809 | 851 | ||
810 | |||
811 | for (i = 0; i < N_OUT_URB; i++) { | 852 | for (i = 0; i < N_OUT_URB; i++) { |
812 | this_urb = portdata->out_urbs[i]; | 853 | this_urb = portdata->out_urbs[i]; |
813 | if (this_urb && !test_bit(i, &portdata->out_busy)) | 854 | if (this_urb && !test_bit(i, &portdata->out_busy)) |
@@ -1069,14 +1110,12 @@ bail_out_error: | |||
1069 | return 1; | 1110 | return 1; |
1070 | } | 1111 | } |
1071 | 1112 | ||
1072 | static void option_shutdown(struct usb_serial *serial) | 1113 | static void stop_read_write_urbs(struct usb_serial *serial) |
1073 | { | 1114 | { |
1074 | int i, j; | 1115 | int i, j; |
1075 | struct usb_serial_port *port; | 1116 | struct usb_serial_port *port; |
1076 | struct option_port_private *portdata; | 1117 | struct option_port_private *portdata; |
1077 | 1118 | ||
1078 | dbg("%s", __func__); | ||
1079 | |||
1080 | /* Stop reading/writing urbs */ | 1119 | /* Stop reading/writing urbs */ |
1081 | for (i = 0; i < serial->num_ports; ++i) { | 1120 | for (i = 0; i < serial->num_ports; ++i) { |
1082 | port = serial->port[i]; | 1121 | port = serial->port[i]; |
@@ -1086,6 +1125,17 @@ static void option_shutdown(struct usb_serial *serial) | |||
1086 | for (j = 0; j < N_OUT_URB; j++) | 1125 | for (j = 0; j < N_OUT_URB; j++) |
1087 | usb_kill_urb(portdata->out_urbs[j]); | 1126 | usb_kill_urb(portdata->out_urbs[j]); |
1088 | } | 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); | ||
1089 | 1139 | ||
1090 | /* Now free them */ | 1140 | /* Now free them */ |
1091 | for (i = 0; i < serial->num_ports; ++i) { | 1141 | for (i = 0; i < serial->num_ports; ++i) { |
@@ -1116,6 +1166,66 @@ static void option_shutdown(struct usb_serial *serial) | |||
1116 | } | 1166 | } |
1117 | } | 1167 | } |
1118 | 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 | |||
1119 | MODULE_AUTHOR(DRIVER_AUTHOR); | 1229 | MODULE_AUTHOR(DRIVER_AUTHOR); |
1120 | MODULE_DESCRIPTION(DRIVER_DESC); | 1230 | MODULE_DESCRIPTION(DRIVER_DESC); |
1121 | 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/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 3cf41df302d7..2620bf6fe5e1 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -176,7 +176,7 @@ static unsigned int product_5052_count; | |||
176 | /* the array dimension is the number of default entries plus */ | 176 | /* the array dimension is the number of default entries plus */ |
177 | /* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */ | 177 | /* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */ |
178 | /* null entry */ | 178 | /* null entry */ |
179 | static struct usb_device_id ti_id_table_3410[7+TI_EXTRA_VID_PID_COUNT+1] = { | 179 | static struct usb_device_id ti_id_table_3410[10+TI_EXTRA_VID_PID_COUNT+1] = { |
180 | { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, | 180 | { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, |
181 | { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, | 181 | { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, |
182 | { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) }, | 182 | { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) }, |
@@ -184,16 +184,20 @@ static struct usb_device_id ti_id_table_3410[7+TI_EXTRA_VID_PID_COUNT+1] = { | |||
184 | { USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_PRODUCT_ID) }, | 184 | { USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_PRODUCT_ID) }, |
185 | { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) }, | 185 | { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) }, |
186 | { USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) }, | 186 | { USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) }, |
187 | { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, | ||
188 | { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) }, | ||
189 | { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) }, | ||
187 | }; | 190 | }; |
188 | 191 | ||
189 | static struct usb_device_id ti_id_table_5052[4+TI_EXTRA_VID_PID_COUNT+1] = { | 192 | static struct usb_device_id ti_id_table_5052[5+TI_EXTRA_VID_PID_COUNT+1] = { |
190 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) }, | 193 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) }, |
191 | { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) }, | 194 | { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) }, |
192 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) }, | 195 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) }, |
193 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) }, | 196 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) }, |
197 | { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, | ||
194 | }; | 198 | }; |
195 | 199 | ||
196 | static struct usb_device_id ti_id_table_combined[6+2*TI_EXTRA_VID_PID_COUNT+1] = { | 200 | static struct usb_device_id ti_id_table_combined[14+2*TI_EXTRA_VID_PID_COUNT+1] = { |
197 | { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, | 201 | { USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) }, |
198 | { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, | 202 | { USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) }, |
199 | { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) }, | 203 | { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) }, |
@@ -205,6 +209,9 @@ static struct usb_device_id ti_id_table_combined[6+2*TI_EXTRA_VID_PID_COUNT+1] = | |||
205 | { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) }, | 209 | { USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) }, |
206 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) }, | 210 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) }, |
207 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) }, | 211 | { USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) }, |
212 | { USB_DEVICE(IBM_VENDOR_ID, IBM_4543_PRODUCT_ID) }, | ||
213 | { USB_DEVICE(IBM_VENDOR_ID, IBM_454B_PRODUCT_ID) }, | ||
214 | { USB_DEVICE(IBM_VENDOR_ID, IBM_454C_PRODUCT_ID) }, | ||
208 | { } | 215 | { } |
209 | }; | 216 | }; |
210 | 217 | ||
diff --git a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h index 7e4752fbf232..f323c6025858 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.h +++ b/drivers/usb/serial/ti_usb_3410_5052.h | |||
@@ -27,7 +27,11 @@ | |||
27 | 27 | ||
28 | /* Vendor and product ids */ | 28 | /* Vendor and product ids */ |
29 | #define TI_VENDOR_ID 0x0451 | 29 | #define TI_VENDOR_ID 0x0451 |
30 | #define IBM_VENDOR_ID 0x04b3 | ||
30 | #define TI_3410_PRODUCT_ID 0x3410 | 31 | #define TI_3410_PRODUCT_ID 0x3410 |
32 | #define IBM_4543_PRODUCT_ID 0x4543 | ||
33 | #define IBM_454B_PRODUCT_ID 0x454b | ||
34 | #define IBM_454C_PRODUCT_ID 0x454c | ||
31 | #define TI_3410_EZ430_ID 0xF430 /* TI ez430 development tool */ | 35 | #define TI_3410_EZ430_ID 0xF430 /* TI ez430 development tool */ |
32 | #define TI_5052_BOOT_PRODUCT_ID 0x5052 /* no EEPROM, no firmware */ | 36 | #define TI_5052_BOOT_PRODUCT_ID 0x5052 /* no EEPROM, no firmware */ |
33 | #define TI_5152_BOOT_PRODUCT_ID 0x5152 /* no EEPROM, no firmware */ | 37 | #define TI_5152_BOOT_PRODUCT_ID 0x5152 /* no EEPROM, no firmware */ |
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 2a42b862aa9f..4ca3b5860643 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c | |||
@@ -64,6 +64,7 @@ | |||
64 | */ | 64 | */ |
65 | #define VENDOR_ID_NOKIA 0x0421 | 65 | #define VENDOR_ID_NOKIA 0x0421 |
66 | #define VENDOR_ID_NIKON 0x04b0 | 66 | #define VENDOR_ID_NIKON 0x04b0 |
67 | #define VENDOR_ID_PENTAX 0x0a17 | ||
67 | #define VENDOR_ID_MOTOROLA 0x22b8 | 68 | #define VENDOR_ID_MOTOROLA 0x22b8 |
68 | 69 | ||
69 | /*********************************************************************** | 70 | /*********************************************************************** |
@@ -134,6 +135,12 @@ static int slave_configure(struct scsi_device *sdev) | |||
134 | if (sdev->request_queue->max_sectors > max_sectors) | 135 | if (sdev->request_queue->max_sectors > max_sectors) |
135 | blk_queue_max_sectors(sdev->request_queue, | 136 | blk_queue_max_sectors(sdev->request_queue, |
136 | 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); | ||
137 | } | 144 | } |
138 | 145 | ||
139 | /* 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. |
@@ -158,6 +165,7 @@ static int slave_configure(struct scsi_device *sdev) | |||
158 | switch (le16_to_cpu(us->pusb_dev->descriptor.idVendor)) { | 165 | switch (le16_to_cpu(us->pusb_dev->descriptor.idVendor)) { |
159 | case VENDOR_ID_NOKIA: | 166 | case VENDOR_ID_NOKIA: |
160 | case VENDOR_ID_NIKON: | 167 | case VENDOR_ID_NIKON: |
168 | case VENDOR_ID_PENTAX: | ||
161 | case VENDOR_ID_MOTOROLA: | 169 | case VENDOR_ID_MOTOROLA: |
162 | if (!(us->fflags & (US_FL_FIX_CAPACITY | | 170 | if (!(us->fflags & (US_FL_FIX_CAPACITY | |
163 | US_FL_CAPACITY_OK))) | 171 | US_FL_CAPACITY_OK))) |
@@ -561,4 +569,4 @@ unsigned char usb_stor_sense_invalidCDB[18] = { | |||
561 | [7] = 0x0a, /* additional length */ | 569 | [7] = 0x0a, /* additional length */ |
562 | [12] = 0x24 /* Invalid Field in CDB */ | 570 | [12] = 0x24 /* Invalid Field in CDB */ |
563 | }; | 571 | }; |
564 | 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 1d5438e6363b..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 |
@@ -558,32 +564,10 @@ static void last_sector_hacks(struct us_data *us, struct scsi_cmnd *srb) | |||
558 | 564 | ||
559 | if (srb->result == SAM_STAT_GOOD && scsi_get_resid(srb) == 0) { | 565 | if (srb->result == SAM_STAT_GOOD && scsi_get_resid(srb) == 0) { |
560 | 566 | ||
561 | /* The command succeeded. If the capacity is odd | 567 | /* The command succeeded. We know this device doesn't |
562 | * (i.e., if the sector number is even) then the | 568 | * have the last-sector bug, so stop checking it. |
563 | * "always-even" heuristic would be wrong for this | ||
564 | * device. Issue a WARN() so that the kerneloops.org | ||
565 | * project will be notified and we will then know to | ||
566 | * mark the device with a CAPACITY_OK flag. Hopefully | ||
567 | * this will occur for only a few devices. | ||
568 | * | ||
569 | * Use the sign of us->last_sector_hacks to tell whether | ||
570 | * the warning has already been issued; we don't need | ||
571 | * more than one warning per device. | ||
572 | */ | 569 | */ |
573 | if (!(sector & 1) && us->use_last_sector_hacks > 0) { | 570 | us->use_last_sector_hacks = 0; |
574 | unsigned vid = le16_to_cpu( | ||
575 | us->pusb_dev->descriptor.idVendor); | ||
576 | unsigned pid = le16_to_cpu( | ||
577 | us->pusb_dev->descriptor.idProduct); | ||
578 | unsigned rev = le16_to_cpu( | ||
579 | us->pusb_dev->descriptor.bcdDevice); | ||
580 | |||
581 | WARN(1, "%s: Successful last sector success at %u, " | ||
582 | "device %04x:%04x:%04x\n", | ||
583 | sdkp->disk->disk_name, sector, | ||
584 | vid, pid, rev); | ||
585 | us->use_last_sector_hacks = -1; | ||
586 | } | ||
587 | 571 | ||
588 | } else { | 572 | } else { |
589 | /* The command failed. Allow up to 3 retries in case this | 573 | /* The command failed. Allow up to 3 retries in case this |
@@ -599,14 +583,6 @@ static void last_sector_hacks(struct us_data *us, struct scsi_cmnd *srb) | |||
599 | srb->result = SAM_STAT_CHECK_CONDITION; | 583 | srb->result = SAM_STAT_CHECK_CONDITION; |
600 | memcpy(srb->sense_buffer, record_not_found, | 584 | memcpy(srb->sense_buffer, record_not_found, |
601 | sizeof(record_not_found)); | 585 | sizeof(record_not_found)); |
602 | |||
603 | /* In theory we might want to issue a WARN() here if the | ||
604 | * capacity is even, since it could indicate the device | ||
605 | * has the READ CAPACITY bug _and_ the real capacity is | ||
606 | * odd. But it could also indicate that the device | ||
607 | * simply can't access its last sector, a failure mode | ||
608 | * which is surprisingly common. So no warning. | ||
609 | */ | ||
610 | } | 586 | } |
611 | 587 | ||
612 | done: | 588 | done: |
@@ -970,6 +946,7 @@ int usb_stor_CB_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
970 | usb_stor_clear_halt(us, pipe); | 946 | usb_stor_clear_halt(us, pipe); |
971 | return USB_STOR_TRANSPORT_FAILED; | 947 | return USB_STOR_TRANSPORT_FAILED; |
972 | } | 948 | } |
949 | EXPORT_SYMBOL_GPL(usb_stor_CB_transport); | ||
973 | 950 | ||
974 | /* | 951 | /* |
975 | * Bulk only transport | 952 | * Bulk only transport |
@@ -1186,6 +1163,7 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us) | |||
1186 | /* 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 */ |
1187 | return USB_STOR_TRANSPORT_ERROR; | 1164 | return USB_STOR_TRANSPORT_ERROR; |
1188 | } | 1165 | } |
1166 | EXPORT_SYMBOL_GPL(usb_stor_Bulk_transport); | ||
1189 | 1167 | ||
1190 | /*********************************************************************** | 1168 | /*********************************************************************** |
1191 | * Reset routines | 1169 | * Reset routines |
@@ -1260,6 +1238,7 @@ int usb_stor_CB_reset(struct us_data *us) | |||
1260 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 1238 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
1261 | 0, us->ifnum, us->iobuf, CB_RESET_CMD_SIZE); | 1239 | 0, us->ifnum, us->iobuf, CB_RESET_CMD_SIZE); |
1262 | } | 1240 | } |
1241 | EXPORT_SYMBOL_GPL(usb_stor_CB_reset); | ||
1263 | 1242 | ||
1264 | /* 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 |
1265 | * clearing the subsequent endpoint halts that may occur. | 1244 | * clearing the subsequent endpoint halts that may occur. |
@@ -1272,6 +1251,7 @@ int usb_stor_Bulk_reset(struct us_data *us) | |||
1272 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 1251 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
1273 | 0, us->ifnum, NULL, 0); | 1252 | 0, us->ifnum, NULL, 0); |
1274 | } | 1253 | } |
1254 | EXPORT_SYMBOL_GPL(usb_stor_Bulk_reset); | ||
1275 | 1255 | ||
1276 | /* 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 |
1277 | * 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 a7f9513fa19d..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", |
@@ -226,7 +219,7 @@ UNUSUAL_DEV( 0x0421, 0x047c, 0x0370, 0x0610, | |||
226 | US_FL_MAX_SECTORS_64 ), | 219 | US_FL_MAX_SECTORS_64 ), |
227 | 220 | ||
228 | /* Reported by Manuel Osdoba <manuel.osdoba@tu-ilmenau.de> */ | 221 | /* Reported by Manuel Osdoba <manuel.osdoba@tu-ilmenau.de> */ |
229 | UNUSUAL_DEV( 0x0421, 0x0492, 0x0452, 0x0452, | 222 | UNUSUAL_DEV( 0x0421, 0x0492, 0x0452, 0x9999, |
230 | "Nokia", | 223 | "Nokia", |
231 | "Nokia 6233", | 224 | "Nokia 6233", |
232 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 225 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
@@ -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", |
@@ -907,13 +802,13 @@ UNUSUAL_DEV( 0x05e3, 0x0701, 0x0000, 0xffff, | |||
907 | "Genesys Logic", | 802 | "Genesys Logic", |
908 | "USB to IDE Optical", | 803 | "USB to IDE Optical", |
909 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 804 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
910 | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ), | 805 | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 | US_FL_IGNORE_RESIDUE ), |
911 | 806 | ||
912 | UNUSUAL_DEV( 0x05e3, 0x0702, 0x0000, 0xffff, | 807 | UNUSUAL_DEV( 0x05e3, 0x0702, 0x0000, 0xffff, |
913 | "Genesys Logic", | 808 | "Genesys Logic", |
914 | "USB to IDE Disk", | 809 | "USB to IDE Disk", |
915 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 810 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
916 | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 ), | 811 | US_FL_GO_SLOW | US_FL_MAX_SECTORS_64 | US_FL_IGNORE_RESIDUE ), |
917 | 812 | ||
918 | /* Reported by Ben Efros <ben@pc-doctor.com> */ | 813 | /* Reported by Ben Efros <ben@pc-doctor.com> */ |
919 | UNUSUAL_DEV( 0x05e3, 0x0723, 0x9451, 0x9451, | 814 | UNUSUAL_DEV( 0x05e3, 0x0723, 0x9451, 0x9451, |
@@ -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", |
@@ -951,7 +838,9 @@ UNUSUAL_DEV( 0x066f, 0x8000, 0x0001, 0x0001, | |||
951 | US_FL_FIX_CAPACITY ), | 838 | US_FL_FIX_CAPACITY ), |
952 | 839 | ||
953 | /* Reported by Richard -=[]=- <micro_flyer@hotmail.com> */ | 840 | /* Reported by Richard -=[]=- <micro_flyer@hotmail.com> */ |
954 | UNUSUAL_DEV( 0x067b, 0x2507, 0x0100, 0x0100, | 841 | /* Change to bcdDeviceMin (0x0100 to 0x0001) reported by |
842 | * Thomas Bartosik <tbartdev@gmx-topmail.de> */ | ||
843 | UNUSUAL_DEV( 0x067b, 0x2507, 0x0001, 0x0100, | ||
955 | "Prolific Technology Inc.", | 844 | "Prolific Technology Inc.", |
956 | "Mass Storage Device", | 845 | "Mass Storage Device", |
957 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 846 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
@@ -995,6 +884,16 @@ UNUSUAL_DEV( 0x071b, 0x3203, 0x0000, 0x0000, | |||
995 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 884 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
996 | US_FL_NO_WP_DETECT | US_FL_MAX_SECTORS_64), | 885 | US_FL_NO_WP_DETECT | US_FL_MAX_SECTORS_64), |
997 | 886 | ||
887 | /* Reported by Jean-Baptiste Onofre <jb@nanthrax.net> | ||
888 | * Support the following product : | ||
889 | * "Dane-Elec MediaTouch" | ||
890 | */ | ||
891 | UNUSUAL_DEV( 0x071b, 0x32bb, 0x0000, 0x0000, | ||
892 | "RockChip", | ||
893 | "MTP", | ||
894 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
895 | US_FL_NO_WP_DETECT | US_FL_MAX_SECTORS_64), | ||
896 | |||
998 | /* Reported by Massimiliano Ghilardi <massimiliano.ghilardi@gmail.com> | 897 | /* Reported by Massimiliano Ghilardi <massimiliano.ghilardi@gmail.com> |
999 | * This USB MP3/AVI player device fails and disconnects if more than 128 | 898 | * This USB MP3/AVI player device fails and disconnects if more than 128 |
1000 | * sectors (64kB) are read/written in a single command, and may be present | 899 | * sectors (64kB) are read/written in a single command, and may be present |
@@ -1031,35 +930,12 @@ UNUSUAL_DEV( 0x0781, 0x0002, 0x0009, 0x0009, | |||
1031 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 930 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1032 | US_FL_FIX_CAPACITY ), | 931 | US_FL_FIX_CAPACITY ), |
1033 | 932 | ||
1034 | #ifdef CONFIG_USB_STORAGE_USBAT | ||
1035 | UNUSUAL_DEV( 0x0781, 0x0005, 0x0005, 0x0005, | ||
1036 | "Sandisk", | ||
1037 | "ImageMate SDDR-05b", | ||
1038 | US_SC_SCSI, US_PR_USBAT, init_usbat_flash, | ||
1039 | US_FL_SINGLE_LUN ), | ||
1040 | #endif | ||
1041 | |||
1042 | UNUSUAL_DEV( 0x0781, 0x0100, 0x0100, 0x0100, | 933 | UNUSUAL_DEV( 0x0781, 0x0100, 0x0100, 0x0100, |
1043 | "Sandisk", | 934 | "Sandisk", |
1044 | "ImageMate SDDR-12", | 935 | "ImageMate SDDR-12", |
1045 | US_SC_SCSI, US_PR_CB, NULL, | 936 | US_SC_SCSI, US_PR_CB, NULL, |
1046 | US_FL_SINGLE_LUN ), | 937 | US_FL_SINGLE_LUN ), |
1047 | 938 | ||
1048 | #ifdef CONFIG_USB_STORAGE_SDDR09 | ||
1049 | UNUSUAL_DEV( 0x0781, 0x0200, 0x0000, 0x9999, | ||
1050 | "Sandisk", | ||
1051 | "ImageMate SDDR-09", | ||
1052 | US_SC_SCSI, US_PR_EUSB_SDDR09, usb_stor_sddr09_init, | ||
1053 | 0), | ||
1054 | #endif | ||
1055 | |||
1056 | #ifdef CONFIG_USB_STORAGE_FREECOM | ||
1057 | UNUSUAL_DEV( 0x07ab, 0xfc01, 0x0000, 0x9999, | ||
1058 | "Freecom", | ||
1059 | "USB-IDE", | ||
1060 | US_SC_QIC, US_PR_FREECOM, freecom_init, 0), | ||
1061 | #endif | ||
1062 | |||
1063 | /* Reported by Eero Volotinen <eero@ping-viini.org> */ | 939 | /* Reported by Eero Volotinen <eero@ping-viini.org> */ |
1064 | UNUSUAL_DEV( 0x07ab, 0xfccd, 0x0000, 0x9999, | 940 | UNUSUAL_DEV( 0x07ab, 0xfccd, 0x0000, 0x9999, |
1065 | "Freecom Technologies", | 941 | "Freecom Technologies", |
@@ -1079,12 +955,7 @@ UNUSUAL_DEV( 0x07af, 0x0005, 0x0100, 0x0100, | |||
1079 | US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init, | 955 | US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init, |
1080 | US_FL_SCM_MULT_TARG ), | 956 | US_FL_SCM_MULT_TARG ), |
1081 | 957 | ||
1082 | #ifdef CONFIG_USB_STORAGE_SDDR09 | 958 | #ifdef NO_SDDR09 |
1083 | UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100, | ||
1084 | "Microtech", | ||
1085 | "CameraMate (DPCM_USB)", | ||
1086 | US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ), | ||
1087 | #else | ||
1088 | UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100, | 959 | UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100, |
1089 | "Microtech", | 960 | "Microtech", |
1090 | "CameraMate", | 961 | "CameraMate", |
@@ -1092,108 +963,6 @@ UNUSUAL_DEV( 0x07af, 0x0006, 0x0100, 0x0100, | |||
1092 | US_FL_SINGLE_LUN ), | 963 | US_FL_SINGLE_LUN ), |
1093 | #endif | 964 | #endif |
1094 | 965 | ||
1095 | #ifdef CONFIG_USB_STORAGE_ALAUDA | ||
1096 | UNUSUAL_DEV( 0x07b4, 0x010a, 0x0102, 0x0102, | ||
1097 | "Olympus", | ||
1098 | "MAUSB-10 (Alauda)", | ||
1099 | US_SC_SCSI, US_PR_ALAUDA, init_alauda, 0 ), | ||
1100 | #endif | ||
1101 | |||
1102 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
1103 | UNUSUAL_DEV( 0x07c4, 0xa000, 0x0000, 0x0015, | ||
1104 | "Datafab", | ||
1105 | "MDCFE-B USB CF Reader", | ||
1106 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
1107 | 0 ), | ||
1108 | |||
1109 | /* | ||
1110 | * The following Datafab-based devices may or may not work | ||
1111 | * using the current driver...the 0xffff is arbitrary since I | ||
1112 | * don't know what device versions exist for these guys. | ||
1113 | * | ||
1114 | * The 0xa003 and 0xa004 devices in particular I'm curious about. | ||
1115 | * I'm told they exist but so far nobody has come forward to say that | ||
1116 | * they work with this driver. Given the success we've had getting | ||
1117 | * other Datafab-based cards operational with this driver, I've decided | ||
1118 | * to leave these two devices in the list. | ||
1119 | */ | ||
1120 | UNUSUAL_DEV( 0x07c4, 0xa001, 0x0000, 0xffff, | ||
1121 | "SIIG/Datafab", | ||
1122 | "SIIG/Datafab Memory Stick+CF Reader/Writer", | ||
1123 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
1124 | 0 ), | ||
1125 | |||
1126 | /* Reported by Josef Reisinger <josef.reisinger@netcologne.de> */ | ||
1127 | UNUSUAL_DEV( 0x07c4, 0xa002, 0x0000, 0xffff, | ||
1128 | "Datafab/Unknown", | ||
1129 | "MD2/MD3 Disk enclosure", | ||
1130 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
1131 | US_FL_SINGLE_LUN ), | ||
1132 | |||
1133 | UNUSUAL_DEV( 0x07c4, 0xa003, 0x0000, 0xffff, | ||
1134 | "Datafab/Unknown", | ||
1135 | "Datafab-based Reader", | ||
1136 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
1137 | 0 ), | ||
1138 | |||
1139 | UNUSUAL_DEV( 0x07c4, 0xa004, 0x0000, 0xffff, | ||
1140 | "Datafab/Unknown", | ||
1141 | "Datafab-based Reader", | ||
1142 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
1143 | 0 ), | ||
1144 | |||
1145 | UNUSUAL_DEV( 0x07c4, 0xa005, 0x0000, 0xffff, | ||
1146 | "PNY/Datafab", | ||
1147 | "PNY/Datafab CF+SM Reader", | ||
1148 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
1149 | 0 ), | ||
1150 | |||
1151 | UNUSUAL_DEV( 0x07c4, 0xa006, 0x0000, 0xffff, | ||
1152 | "Simple Tech/Datafab", | ||
1153 | "Simple Tech/Datafab CF+SM Reader", | ||
1154 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
1155 | 0 ), | ||
1156 | #endif | ||
1157 | |||
1158 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
1159 | /* Contributed by Peter Waechtler */ | ||
1160 | UNUSUAL_DEV( 0x07c4, 0xa103, 0x0000, 0x9999, | ||
1161 | "Datafab", | ||
1162 | "MDSM-B reader", | ||
1163 | US_SC_SCSI, US_PR_SDDR55, NULL, | ||
1164 | US_FL_FIX_INQUIRY ), | ||
1165 | #endif | ||
1166 | |||
1167 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
1168 | /* Submitted by Olaf Hering <olh@suse.de> */ | ||
1169 | UNUSUAL_DEV( 0x07c4, 0xa109, 0x0000, 0xffff, | ||
1170 | "Datafab Systems, Inc.", | ||
1171 | "USB to CF + SM Combo (LC1)", | ||
1172 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
1173 | 0 ), | ||
1174 | #endif | ||
1175 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
1176 | /* SM part - aeb <Andries.Brouwer@cwi.nl> */ | ||
1177 | UNUSUAL_DEV( 0x07c4, 0xa109, 0x0000, 0xffff, | ||
1178 | "Datafab Systems, Inc.", | ||
1179 | "USB to CF + SM Combo (LC1)", | ||
1180 | US_SC_SCSI, US_PR_SDDR55, NULL, | ||
1181 | US_FL_SINGLE_LUN ), | ||
1182 | #endif | ||
1183 | |||
1184 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
1185 | /* Reported by Felix Moeller <felix@derklecks.de> | ||
1186 | * in Germany this is sold by Hama with the productnumber 46952 | ||
1187 | * as "DualSlot CompactFlash(TM) & MStick Drive USB" | ||
1188 | */ | ||
1189 | UNUSUAL_DEV( 0x07c4, 0xa10b, 0x0000, 0xffff, | ||
1190 | "DataFab Systems Inc.", | ||
1191 | "USB CF+MS", | ||
1192 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
1193 | 0 ), | ||
1194 | |||
1195 | #endif | ||
1196 | |||
1197 | /* Datafab KECF-USB / Sagatek DCS-CF / Simpletech Flashlink UCF-100 | 966 | /* Datafab KECF-USB / Sagatek DCS-CF / Simpletech Flashlink UCF-100 |
1198 | * 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, |
1199 | * 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. |
@@ -1204,7 +973,7 @@ UNUSUAL_DEV( 0x07c4, 0xa400, 0x0000, 0xffff, | |||
1204 | "Datafab", | 973 | "Datafab", |
1205 | "KECF-USB", | 974 | "KECF-USB", |
1206 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 975 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1207 | US_FL_FIX_INQUIRY ), | 976 | US_FL_FIX_INQUIRY | US_FL_FIX_CAPACITY ), |
1208 | 977 | ||
1209 | /* Reported by Rauch Wolke <rauchwolke@gmx.net> */ | 978 | /* Reported by Rauch Wolke <rauchwolke@gmx.net> */ |
1210 | UNUSUAL_DEV( 0x07c4, 0xa4a5, 0x0000, 0xffff, | 979 | UNUSUAL_DEV( 0x07c4, 0xa4a5, 0x0000, 0xffff, |
@@ -1251,6 +1020,13 @@ UNUSUAL_DEV( 0x0840, 0x0084, 0x0001, 0x0001, | |||
1251 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1020 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1252 | US_FL_FIX_CAPACITY), | 1021 | US_FL_FIX_CAPACITY), |
1253 | 1022 | ||
1023 | /* Reported by Martijn Hijdra <martijn.hijdra@gmail.com> */ | ||
1024 | UNUSUAL_DEV( 0x0840, 0x0085, 0x0001, 0x0001, | ||
1025 | "Argosy", | ||
1026 | "Storage", | ||
1027 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1028 | US_FL_FIX_CAPACITY), | ||
1029 | |||
1254 | /* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>. | 1030 | /* Entry and supporting patch by Theodore Kilgore <kilgota@auburn.edu>. |
1255 | * Flag will support Bulk devices which use a standards-violating 32-byte | 1031 | * Flag will support Bulk devices which use a standards-violating 32-byte |
1256 | * Command Block Wrapper. Here, the "DC2MEGA" cameras (several brands) with | 1032 | * Command Block Wrapper. Here, the "DC2MEGA" cameras (several brands) with |
@@ -1337,21 +1113,6 @@ UNUSUAL_DEV( 0x0a17, 0x0004, 0x1000, 0x1000, | |||
1337 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1113 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1338 | US_FL_FIX_INQUIRY ), | 1114 | US_FL_FIX_INQUIRY ), |
1339 | 1115 | ||
1340 | |||
1341 | /* Submitted by Per Winkvist <per.winkvist@uk.com> */ | ||
1342 | UNUSUAL_DEV( 0x0a17, 0x006, 0x0000, 0xffff, | ||
1343 | "Pentax", | ||
1344 | "Optio S/S4", | ||
1345 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1346 | US_FL_FIX_INQUIRY ), | ||
1347 | |||
1348 | /* Reported by Jaak Ristioja <Ristioja@gmail.com> */ | ||
1349 | UNUSUAL_DEV( 0x0a17, 0x006e, 0x0100, 0x0100, | ||
1350 | "Pentax", | ||
1351 | "K10D", | ||
1352 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1353 | US_FL_FIX_CAPACITY ), | ||
1354 | |||
1355 | /* These are virtual windows driver CDs, which the zd1211rw driver | 1116 | /* These are virtual windows driver CDs, which the zd1211rw driver |
1356 | * automatically converts into WLAN devices. */ | 1117 | * automatically converts into WLAN devices. */ |
1357 | UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101, | 1118 | UNUSUAL_DEV( 0x0ace, 0x2011, 0x0101, 0x0101, |
@@ -1388,6 +1149,16 @@ UNUSUAL_DEV( 0x0af0, 0x7401, 0x0000, 0x0000, | |||
1388 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1149 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1389 | 0 ), | 1150 | 0 ), |
1390 | 1151 | ||
1152 | /* Reported by Jan Dumon <j.dumon@option.com> | ||
1153 | * This device (wrongly) has a vendor-specific device descriptor. | ||
1154 | * The entry is needed so usb-storage can bind to it's mass-storage | ||
1155 | * interface as an interface driver */ | ||
1156 | UNUSUAL_DEV( 0x0af0, 0x7501, 0x0000, 0x0000, | ||
1157 | "Option", | ||
1158 | "GI 0431 SD-Card", | ||
1159 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1160 | 0 ), | ||
1161 | |||
1391 | /* Reported by Ben Efros <ben@pc-doctor.com> */ | 1162 | /* Reported by Ben Efros <ben@pc-doctor.com> */ |
1392 | UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000, | 1163 | UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000, |
1393 | "Seagate", | 1164 | "Seagate", |
@@ -1395,29 +1166,6 @@ UNUSUAL_DEV( 0x0bc2, 0x3010, 0x0000, 0x0000, | |||
1395 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1166 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1396 | US_FL_SANE_SENSE ), | 1167 | US_FL_SANE_SENSE ), |
1397 | 1168 | ||
1398 | #ifdef CONFIG_USB_STORAGE_ISD200 | ||
1399 | UNUSUAL_DEV( 0x0bf6, 0xa001, 0x0100, 0x0110, | ||
1400 | "ATI", | ||
1401 | "USB Cable 205", | ||
1402 | US_SC_ISD200, US_PR_BULK, isd200_Initialization, | ||
1403 | 0 ), | ||
1404 | #endif | ||
1405 | |||
1406 | #ifdef CONFIG_USB_STORAGE_DATAFAB | ||
1407 | UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff, | ||
1408 | "Acomdata", | ||
1409 | "CF", | ||
1410 | US_SC_SCSI, US_PR_DATAFAB, NULL, | ||
1411 | US_FL_SINGLE_LUN ), | ||
1412 | #endif | ||
1413 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
1414 | UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff, | ||
1415 | "Acomdata", | ||
1416 | "SM", | ||
1417 | US_SC_SCSI, US_PR_SDDR55, NULL, | ||
1418 | US_FL_SINGLE_LUN ), | ||
1419 | #endif | ||
1420 | |||
1421 | UNUSUAL_DEV( 0x0d49, 0x7310, 0x0000, 0x9999, | 1169 | UNUSUAL_DEV( 0x0d49, 0x7310, 0x0000, 0x9999, |
1422 | "Maxtor", | 1170 | "Maxtor", |
1423 | "USB to SATA", | 1171 | "USB to SATA", |
@@ -1434,23 +1182,6 @@ UNUSUAL_DEV( 0x0c45, 0x1060, 0x0100, 0x0100, | |||
1434 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1182 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1435 | US_FL_SINGLE_LUN ), | 1183 | US_FL_SINGLE_LUN ), |
1436 | 1184 | ||
1437 | /* Submitted by: Nick Sillik <n.sillik@temple.edu> | ||
1438 | * Needed for OneTouch extension to usb-storage | ||
1439 | * | ||
1440 | */ | ||
1441 | #ifdef CONFIG_USB_STORAGE_ONETOUCH | ||
1442 | UNUSUAL_DEV( 0x0d49, 0x7000, 0x0000, 0x9999, | ||
1443 | "Maxtor", | ||
1444 | "OneTouch External Harddrive", | ||
1445 | US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input, | ||
1446 | 0), | ||
1447 | UNUSUAL_DEV( 0x0d49, 0x7010, 0x0000, 0x9999, | ||
1448 | "Maxtor", | ||
1449 | "OneTouch External Harddrive", | ||
1450 | US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input, | ||
1451 | 0), | ||
1452 | #endif | ||
1453 | |||
1454 | /* Submitted by Joris Struyve <joris@struyve.be> */ | 1185 | /* Submitted by Joris Struyve <joris@struyve.be> */ |
1455 | UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff, | 1186 | UNUSUAL_DEV( 0x0d96, 0x410a, 0x0001, 0xffff, |
1456 | "Medion", | 1187 | "Medion", |
@@ -1589,6 +1320,13 @@ UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, | |||
1589 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1320 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1590 | US_FL_NO_WP_DETECT ), | 1321 | US_FL_NO_WP_DETECT ), |
1591 | 1322 | ||
1323 | /* Reported by The Solutor <thesolutor@gmail.com> */ | ||
1324 | UNUSUAL_DEV( 0x0fce, 0xd0e1, 0x0000, 0x0000, | ||
1325 | "Sony Ericsson", | ||
1326 | "MD400", | ||
1327 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1328 | US_FL_IGNORE_DEVICE), | ||
1329 | |||
1592 | /* Reported by Jan Mate <mate@fiit.stuba.sk> | 1330 | /* Reported by Jan Mate <mate@fiit.stuba.sk> |
1593 | * and by Soeren Sonnenburg <kernel@nn7.de> */ | 1331 | * and by Soeren Sonnenburg <kernel@nn7.de> */ |
1594 | UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000, | 1332 | UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000, |
@@ -2031,15 +1769,11 @@ UNUSUAL_DEV( 0x1652, 0x6600, 0x0201, 0x0201, | |||
2031 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1769 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
2032 | US_FL_IGNORE_RESIDUE ), | 1770 | US_FL_IGNORE_RESIDUE ), |
2033 | 1771 | ||
2034 | /* Reported by Mauro Andreolini <andreoli@weblab.ing.unimo.it> | 1772 | UNUSUAL_DEV( 0x2116, 0x0320, 0x0001, 0x0001, |
2035 | * This entry is needed to bypass the ZeroCD mechanism | 1773 | "ST", |
2036 | * and to properly load as a modem device. | 1774 | "2A", |
2037 | */ | ||
2038 | UNUSUAL_DEV( 0x19d2, 0x2000, 0x0000, 0x0000, | ||
2039 | "Onda ET502HS", | ||
2040 | "USB MMC Storage", | ||
2041 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1775 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
2042 | US_FL_IGNORE_DEVICE), | 1776 | US_FL_FIX_CAPACITY), |
2043 | 1777 | ||
2044 | /* patch submitted by Davide Perini <perini.davide@dpsoftware.org> | 1778 | /* patch submitted by Davide Perini <perini.davide@dpsoftware.org> |
2045 | * and Renato Perini <rperini@email.it> | 1779 | * and Renato Perini <rperini@email.it> |
@@ -2100,14 +1834,6 @@ UNUSUAL_DEV( 0x4146, 0xba01, 0x0100, 0x0100, | |||
2100 | "Micro Mini 1GB", | 1834 | "Micro Mini 1GB", |
2101 | US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), | 1835 | US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), |
2102 | 1836 | ||
2103 | #ifdef CONFIG_USB_STORAGE_SDDR55 | ||
2104 | UNUSUAL_DEV( 0x55aa, 0xa103, 0x0000, 0x9999, | ||
2105 | "Sandisk", | ||
2106 | "ImageMate SDDR55", | ||
2107 | US_SC_SCSI, US_PR_SDDR55, NULL, | ||
2108 | US_FL_SINGLE_LUN), | ||
2109 | #endif | ||
2110 | |||
2111 | /* Reported by Andrew Simmons <andrew.simmons@gmail.com> */ | 1837 | /* Reported by Andrew Simmons <andrew.simmons@gmail.com> */ |
2112 | UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001, | 1838 | UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001, |
2113 | "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 e2e7e4bc8463..f0aac0cf315a 100644 --- a/drivers/usb/wusbcore/devconnect.c +++ b/drivers/usb/wusbcore/devconnect.c | |||
@@ -386,6 +386,7 @@ static void __wusbhc_dev_disconnect(struct wusbhc *wusbhc, | |||
386 | | USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED); | 386 | | USB_PORT_STAT_LOW_SPEED | USB_PORT_STAT_HIGH_SPEED); |
387 | port->change |= USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE; | 387 | port->change |= USB_PORT_STAT_C_CONNECTION | USB_PORT_STAT_C_ENABLE; |
388 | if (wusb_dev) { | 388 | if (wusb_dev) { |
389 | dev_dbg(wusbhc->dev, "disconnecting device from port %d\n", wusb_dev->port_idx); | ||
389 | if (!list_empty(&wusb_dev->cack_node)) | 390 | if (!list_empty(&wusb_dev->cack_node)) |
390 | list_del_init(&wusb_dev->cack_node); | 391 | list_del_init(&wusb_dev->cack_node); |
391 | /* For the one in cack_add() */ | 392 | /* For the one in cack_add() */ |
@@ -888,6 +889,8 @@ static void wusb_dev_add_ncb(struct usb_device *usb_dev) | |||
888 | if (usb_dev->wusb == 0 || usb_dev->devnum == 1) | 889 | if (usb_dev->wusb == 0 || usb_dev->devnum == 1) |
889 | return; /* skip non wusb and wusb RHs */ | 890 | return; /* skip non wusb and wusb RHs */ |
890 | 891 | ||
892 | usb_set_device_state(usb_dev, USB_STATE_UNAUTHENTICATED); | ||
893 | |||
891 | wusbhc = wusbhc_get_by_usb_dev(usb_dev); | 894 | wusbhc = wusbhc_get_by_usb_dev(usb_dev); |
892 | if (wusbhc == NULL) | 895 | if (wusbhc == NULL) |
893 | goto error_nodev; | 896 | goto error_nodev; |
diff --git a/drivers/usb/wusbcore/rh.c b/drivers/usb/wusbcore/rh.c index 3937bf6f8cef..9fe4246cecb9 100644 --- a/drivers/usb/wusbcore/rh.c +++ b/drivers/usb/wusbcore/rh.c | |||
@@ -100,6 +100,9 @@ static int wusbhc_rh_port_reset(struct wusbhc *wusbhc, u8 port_idx) | |||
100 | struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx); | 100 | struct wusb_port *port = wusb_port_by_idx(wusbhc, port_idx); |
101 | struct wusb_dev *wusb_dev = port->wusb_dev; | 101 | struct wusb_dev *wusb_dev = port->wusb_dev; |
102 | 102 | ||
103 | if (wusb_dev == NULL) | ||
104 | return -ENOTCONN; | ||
105 | |||
103 | port->status |= USB_PORT_STAT_RESET; | 106 | port->status |= USB_PORT_STAT_RESET; |
104 | port->change |= USB_PORT_STAT_C_RESET; | 107 | port->change |= USB_PORT_STAT_C_RESET; |
105 | 108 | ||
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: |
diff --git a/drivers/usb/wusbcore/wa-xfer.c b/drivers/usb/wusbcore/wa-xfer.c index 238a96aee3a1..613a5fc490d3 100644 --- a/drivers/usb/wusbcore/wa-xfer.c +++ b/drivers/usb/wusbcore/wa-xfer.c | |||
@@ -921,8 +921,10 @@ static void wa_urb_enqueue_b(struct wa_xfer *xfer) | |||
921 | result = -ENODEV; | 921 | result = -ENODEV; |
922 | /* FIXME: segmentation broken -- kills DWA */ | 922 | /* FIXME: segmentation broken -- kills DWA */ |
923 | mutex_lock(&wusbhc->mutex); /* get a WUSB dev */ | 923 | mutex_lock(&wusbhc->mutex); /* get a WUSB dev */ |
924 | if (urb->dev == NULL) | 924 | if (urb->dev == NULL) { |
925 | mutex_unlock(&wusbhc->mutex); | ||
925 | goto error_dev_gone; | 926 | goto error_dev_gone; |
927 | } | ||
926 | wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev); | 928 | wusb_dev = __wusb_dev_get_by_usb_dev(wusbhc, urb->dev); |
927 | if (wusb_dev == NULL) { | 929 | if (wusb_dev == NULL) { |
928 | mutex_unlock(&wusbhc->mutex); | 930 | mutex_unlock(&wusbhc->mutex); |