diff options
Diffstat (limited to 'drivers/usb')
168 files changed, 7832 insertions, 6121 deletions
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 8ed6c75adf0f..638b8009b3bc 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c | |||
@@ -36,7 +36,7 @@ | |||
36 | #include <linux/stat.h> | 36 | #include <linux/stat.h> |
37 | #include <linux/timer.h> | 37 | #include <linux/timer.h> |
38 | #include <linux/types.h> | 38 | #include <linux/types.h> |
39 | #include <linux/usb_ch9.h> | 39 | #include <linux/usb/ch9.h> |
40 | #include <linux/workqueue.h> | 40 | #include <linux/workqueue.h> |
41 | 41 | ||
42 | #include "usbatm.h" | 42 | #include "usbatm.h" |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 7f1fa956dcdb..98199628e394 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -677,10 +677,10 @@ static const __u8 acm_tty_size[] = { | |||
677 | 5, 6, 7, 8 | 677 | 5, 6, 7, 8 |
678 | }; | 678 | }; |
679 | 679 | ||
680 | static void acm_tty_set_termios(struct tty_struct *tty, struct termios *termios_old) | 680 | static void acm_tty_set_termios(struct tty_struct *tty, struct ktermios *termios_old) |
681 | { | 681 | { |
682 | struct acm *acm = tty->driver_data; | 682 | struct acm *acm = tty->driver_data; |
683 | struct termios *termios = tty->termios; | 683 | struct ktermios *termios = tty->termios; |
684 | struct usb_cdc_line_coding newline; | 684 | struct usb_cdc_line_coding newline; |
685 | int newctrl = acm->ctrlout; | 685 | int newctrl = acm->ctrlout; |
686 | 686 | ||
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 6303970e93c1..63e50a1f1396 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c | |||
@@ -130,7 +130,7 @@ MFG:HEWLETT-PACKARD;MDL:DESKJET 970C;CMD:MLC,PCL,PML;CLASS:PRINTER;DESCRIPTION:H | |||
130 | 130 | ||
131 | struct usblp { | 131 | struct usblp { |
132 | struct usb_device *dev; /* USB device */ | 132 | struct usb_device *dev; /* USB device */ |
133 | struct semaphore sem; /* locks this struct, especially "dev" */ | 133 | struct mutex mut; /* locks this struct, especially "dev" */ |
134 | char *writebuf; /* write transfer_buffer */ | 134 | char *writebuf; /* write transfer_buffer */ |
135 | char *readbuf; /* read transfer_buffer */ | 135 | char *readbuf; /* read transfer_buffer */ |
136 | char *statusbuf; /* status transfer_buffer */ | 136 | char *statusbuf; /* status transfer_buffer */ |
@@ -217,6 +217,7 @@ static const struct quirk_printer_struct quirk_printers[] = { | |||
217 | { 0x0409, 0xbef4, USBLP_QUIRK_BIDIR }, /* NEC Picty760 (HP OEM) */ | 217 | { 0x0409, 0xbef4, USBLP_QUIRK_BIDIR }, /* NEC Picty760 (HP OEM) */ |
218 | { 0x0409, 0xf0be, USBLP_QUIRK_BIDIR }, /* NEC Picty920 (HP OEM) */ | 218 | { 0x0409, 0xf0be, USBLP_QUIRK_BIDIR }, /* NEC Picty920 (HP OEM) */ |
219 | { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */ | 219 | { 0x0409, 0xf1be, USBLP_QUIRK_BIDIR }, /* NEC Picty800 (HP OEM) */ |
220 | { 0x0482, 0x0010, USBLP_QUIRK_BIDIR }, /* Kyocera Mita FS 820, by zut <kernel@zut.de> */ | ||
220 | { 0, 0 } | 221 | { 0, 0 } |
221 | }; | 222 | }; |
222 | 223 | ||
@@ -397,6 +398,9 @@ static int usblp_open(struct inode *inode, struct file *file) | |||
397 | retval = 0; | 398 | retval = 0; |
398 | #endif | 399 | #endif |
399 | 400 | ||
401 | retval = usb_autopm_get_interface(intf); | ||
402 | if (retval < 0) | ||
403 | goto out; | ||
400 | usblp->used = 1; | 404 | usblp->used = 1; |
401 | file->private_data = usblp; | 405 | file->private_data = usblp; |
402 | 406 | ||
@@ -441,6 +445,7 @@ static int usblp_release(struct inode *inode, struct file *file) | |||
441 | usblp->used = 0; | 445 | usblp->used = 0; |
442 | if (usblp->present) { | 446 | if (usblp->present) { |
443 | usblp_unlink_urbs(usblp); | 447 | usblp_unlink_urbs(usblp); |
448 | usb_autopm_put_interface(usblp->intf); | ||
444 | } else /* finish cleanup from disconnect */ | 449 | } else /* finish cleanup from disconnect */ |
445 | usblp_cleanup (usblp); | 450 | usblp_cleanup (usblp); |
446 | mutex_unlock (&usblp_mutex); | 451 | mutex_unlock (&usblp_mutex); |
@@ -465,7 +470,7 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
465 | int twoints[2]; | 470 | int twoints[2]; |
466 | int retval = 0; | 471 | int retval = 0; |
467 | 472 | ||
468 | down (&usblp->sem); | 473 | mutex_lock (&usblp->mut); |
469 | if (!usblp->present) { | 474 | if (!usblp->present) { |
470 | retval = -ENODEV; | 475 | retval = -ENODEV; |
471 | goto done; | 476 | goto done; |
@@ -644,14 +649,14 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
644 | } | 649 | } |
645 | 650 | ||
646 | done: | 651 | done: |
647 | up (&usblp->sem); | 652 | mutex_unlock (&usblp->mut); |
648 | return retval; | 653 | return retval; |
649 | } | 654 | } |
650 | 655 | ||
651 | static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | 656 | static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) |
652 | { | 657 | { |
653 | struct usblp *usblp = file->private_data; | 658 | struct usblp *usblp = file->private_data; |
654 | int timeout, rv, err = 0, transfer_length = 0; | 659 | int timeout, intr, rv, err = 0, transfer_length = 0; |
655 | size_t writecount = 0; | 660 | size_t writecount = 0; |
656 | 661 | ||
657 | while (writecount < count) { | 662 | while (writecount < count) { |
@@ -668,14 +673,16 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
668 | if (rv < 0) | 673 | if (rv < 0) |
669 | return writecount ? writecount : -EINTR; | 674 | return writecount ? writecount : -EINTR; |
670 | } | 675 | } |
671 | down (&usblp->sem); | 676 | intr = mutex_lock_interruptible (&usblp->mut); |
677 | if (intr) | ||
678 | return writecount ? writecount : -EINTR; | ||
672 | if (!usblp->present) { | 679 | if (!usblp->present) { |
673 | up (&usblp->sem); | 680 | mutex_unlock (&usblp->mut); |
674 | return -ENODEV; | 681 | return -ENODEV; |
675 | } | 682 | } |
676 | 683 | ||
677 | if (usblp->sleeping) { | 684 | if (usblp->sleeping) { |
678 | up (&usblp->sem); | 685 | mutex_unlock (&usblp->mut); |
679 | return writecount ? writecount : -ENODEV; | 686 | return writecount ? writecount : -ENODEV; |
680 | } | 687 | } |
681 | 688 | ||
@@ -687,10 +694,10 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
687 | err = usblp->writeurb->status; | 694 | err = usblp->writeurb->status; |
688 | } else | 695 | } else |
689 | err = usblp_check_status(usblp, err); | 696 | err = usblp_check_status(usblp, err); |
690 | up (&usblp->sem); | 697 | mutex_unlock (&usblp->mut); |
691 | 698 | ||
692 | /* if the fault was due to disconnect, let khubd's | 699 | /* if the fault was due to disconnect, let khubd's |
693 | * call to usblp_disconnect() grab usblp->sem ... | 700 | * call to usblp_disconnect() grab usblp->mut ... |
694 | */ | 701 | */ |
695 | schedule (); | 702 | schedule (); |
696 | continue; | 703 | continue; |
@@ -702,7 +709,7 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
702 | */ | 709 | */ |
703 | writecount += transfer_length; | 710 | writecount += transfer_length; |
704 | if (writecount == count) { | 711 | if (writecount == count) { |
705 | up(&usblp->sem); | 712 | mutex_unlock(&usblp->mut); |
706 | break; | 713 | break; |
707 | } | 714 | } |
708 | 715 | ||
@@ -714,7 +721,7 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
714 | 721 | ||
715 | if (copy_from_user(usblp->writeurb->transfer_buffer, | 722 | if (copy_from_user(usblp->writeurb->transfer_buffer, |
716 | buffer + writecount, transfer_length)) { | 723 | buffer + writecount, transfer_length)) { |
717 | up(&usblp->sem); | 724 | mutex_unlock(&usblp->mut); |
718 | return writecount ? writecount : -EFAULT; | 725 | return writecount ? writecount : -EFAULT; |
719 | } | 726 | } |
720 | 727 | ||
@@ -727,10 +734,10 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
727 | count = -EIO; | 734 | count = -EIO; |
728 | else | 735 | else |
729 | count = writecount ? writecount : -ENOMEM; | 736 | count = writecount ? writecount : -ENOMEM; |
730 | up (&usblp->sem); | 737 | mutex_unlock (&usblp->mut); |
731 | break; | 738 | break; |
732 | } | 739 | } |
733 | up (&usblp->sem); | 740 | mutex_unlock (&usblp->mut); |
734 | } | 741 | } |
735 | 742 | ||
736 | return count; | 743 | return count; |
@@ -739,12 +746,14 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
739 | static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) | 746 | static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) |
740 | { | 747 | { |
741 | struct usblp *usblp = file->private_data; | 748 | struct usblp *usblp = file->private_data; |
742 | int rv; | 749 | int rv, intr; |
743 | 750 | ||
744 | if (!usblp->bidir) | 751 | if (!usblp->bidir) |
745 | return -EINVAL; | 752 | return -EINVAL; |
746 | 753 | ||
747 | down (&usblp->sem); | 754 | intr = mutex_lock_interruptible (&usblp->mut); |
755 | if (intr) | ||
756 | return -EINTR; | ||
748 | if (!usblp->present) { | 757 | if (!usblp->present) { |
749 | count = -ENODEV; | 758 | count = -ENODEV; |
750 | goto done; | 759 | goto done; |
@@ -757,9 +766,9 @@ static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, | |||
757 | count = -EAGAIN; | 766 | count = -EAGAIN; |
758 | goto done; | 767 | goto done; |
759 | } | 768 | } |
760 | up(&usblp->sem); | 769 | mutex_unlock(&usblp->mut); |
761 | rv = wait_event_interruptible(usblp->wait, usblp->rcomplete || !usblp->present); | 770 | rv = wait_event_interruptible(usblp->wait, usblp->rcomplete || !usblp->present); |
762 | down(&usblp->sem); | 771 | mutex_lock(&usblp->mut); |
763 | if (rv < 0) { | 772 | if (rv < 0) { |
764 | count = -EINTR; | 773 | count = -EINTR; |
765 | goto done; | 774 | goto done; |
@@ -807,7 +816,7 @@ static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, | |||
807 | } | 816 | } |
808 | 817 | ||
809 | done: | 818 | done: |
810 | up (&usblp->sem); | 819 | mutex_unlock (&usblp->mut); |
811 | return count; | 820 | return count; |
812 | } | 821 | } |
813 | 822 | ||
@@ -886,7 +895,7 @@ static int usblp_probe(struct usb_interface *intf, | |||
886 | goto abort; | 895 | goto abort; |
887 | } | 896 | } |
888 | usblp->dev = dev; | 897 | usblp->dev = dev; |
889 | init_MUTEX (&usblp->sem); | 898 | mutex_init (&usblp->mut); |
890 | init_waitqueue_head(&usblp->wait); | 899 | init_waitqueue_head(&usblp->wait); |
891 | usblp->ifnum = intf->cur_altsetting->desc.bInterfaceNumber; | 900 | usblp->ifnum = intf->cur_altsetting->desc.bInterfaceNumber; |
892 | usblp->intf = intf; | 901 | usblp->intf = intf; |
@@ -1178,7 +1187,7 @@ static void usblp_disconnect(struct usb_interface *intf) | |||
1178 | device_remove_file(&intf->dev, &dev_attr_ieee1284_id); | 1187 | device_remove_file(&intf->dev, &dev_attr_ieee1284_id); |
1179 | 1188 | ||
1180 | mutex_lock (&usblp_mutex); | 1189 | mutex_lock (&usblp_mutex); |
1181 | down (&usblp->sem); | 1190 | mutex_lock (&usblp->mut); |
1182 | usblp->present = 0; | 1191 | usblp->present = 0; |
1183 | usb_set_intfdata (intf, NULL); | 1192 | usb_set_intfdata (intf, NULL); |
1184 | 1193 | ||
@@ -1187,7 +1196,7 @@ static void usblp_disconnect(struct usb_interface *intf) | |||
1187 | usblp->writebuf, usblp->writeurb->transfer_dma); | 1196 | usblp->writebuf, usblp->writeurb->transfer_dma); |
1188 | usb_buffer_free (usblp->dev, USBLP_BUF_SIZE, | 1197 | usb_buffer_free (usblp->dev, USBLP_BUF_SIZE, |
1189 | usblp->readbuf, usblp->readurb->transfer_dma); | 1198 | usblp->readbuf, usblp->readurb->transfer_dma); |
1190 | up (&usblp->sem); | 1199 | mutex_unlock (&usblp->mut); |
1191 | 1200 | ||
1192 | if (!usblp->used) | 1201 | if (!usblp->used) |
1193 | usblp_cleanup (usblp); | 1202 | usblp_cleanup (usblp); |
@@ -1198,14 +1207,9 @@ static int usblp_suspend (struct usb_interface *intf, pm_message_t message) | |||
1198 | { | 1207 | { |
1199 | struct usblp *usblp = usb_get_intfdata (intf); | 1208 | struct usblp *usblp = usb_get_intfdata (intf); |
1200 | 1209 | ||
1201 | /* this races against normal access and open */ | ||
1202 | mutex_lock (&usblp_mutex); | ||
1203 | down (&usblp->sem); | ||
1204 | /* we take no more IO */ | 1210 | /* we take no more IO */ |
1205 | usblp->sleeping = 1; | 1211 | usblp->sleeping = 1; |
1206 | usblp_unlink_urbs(usblp); | 1212 | usblp_unlink_urbs(usblp); |
1207 | up (&usblp->sem); | ||
1208 | mutex_unlock (&usblp_mutex); | ||
1209 | 1213 | ||
1210 | return 0; | 1214 | return 0; |
1211 | } | 1215 | } |
@@ -1215,15 +1219,9 @@ static int usblp_resume (struct usb_interface *intf) | |||
1215 | struct usblp *usblp = usb_get_intfdata (intf); | 1219 | struct usblp *usblp = usb_get_intfdata (intf); |
1216 | int r; | 1220 | int r; |
1217 | 1221 | ||
1218 | mutex_lock (&usblp_mutex); | ||
1219 | down (&usblp->sem); | ||
1220 | |||
1221 | usblp->sleeping = 0; | 1222 | usblp->sleeping = 0; |
1222 | r = handle_bidir (usblp); | 1223 | r = handle_bidir (usblp); |
1223 | 1224 | ||
1224 | up (&usblp->sem); | ||
1225 | mutex_unlock (&usblp_mutex); | ||
1226 | |||
1227 | return r; | 1225 | return r; |
1228 | } | 1226 | } |
1229 | 1227 | ||
@@ -1246,6 +1244,7 @@ static struct usb_driver usblp_driver = { | |||
1246 | .suspend = usblp_suspend, | 1244 | .suspend = usblp_suspend, |
1247 | .resume = usblp_resume, | 1245 | .resume = usblp_resume, |
1248 | .id_table = usblp_ids, | 1246 | .id_table = usblp_ids, |
1247 | .supports_autosuspend = 1, | ||
1249 | }; | 1248 | }; |
1250 | 1249 | ||
1251 | static int __init usblp_init(void) | 1250 | static int __init usblp_init(void) |
diff --git a/drivers/usb/core/Kconfig b/drivers/usb/core/Kconfig index f8324d8d06ac..2fc0f88a3d86 100644 --- a/drivers/usb/core/Kconfig +++ b/drivers/usb/core/Kconfig | |||
@@ -33,19 +33,6 @@ config USB_DEVICEFS | |||
33 | 33 | ||
34 | Most users want to say Y here. | 34 | Most users want to say Y here. |
35 | 35 | ||
36 | config USB_BANDWIDTH | ||
37 | bool "Enforce USB bandwidth allocation (EXPERIMENTAL)" | ||
38 | depends on USB && EXPERIMENTAL | ||
39 | help | ||
40 | If you say Y here, the USB subsystem enforces USB bandwidth | ||
41 | allocation and will prevent some device opens from succeeding | ||
42 | if they would cause USB bandwidth usage to go above 90% of | ||
43 | the bus bandwidth. | ||
44 | |||
45 | If you say N here, these conditions will cause warning messages | ||
46 | about USB bandwidth usage to be logged and some devices or | ||
47 | drivers may not work correctly. | ||
48 | |||
49 | config USB_DYNAMIC_MINORS | 36 | config USB_DYNAMIC_MINORS |
50 | bool "Dynamic USB minor allocation (EXPERIMENTAL)" | 37 | bool "Dynamic USB minor allocation (EXPERIMENTAL)" |
51 | depends on USB && EXPERIMENTAL | 38 | depends on USB && EXPERIMENTAL |
@@ -72,22 +59,6 @@ config USB_SUSPEND | |||
72 | 59 | ||
73 | If you are unsure about this, say N here. | 60 | If you are unsure about this, say N here. |
74 | 61 | ||
75 | config USB_MULTITHREAD_PROBE | ||
76 | bool "USB Multi-threaded probe (EXPERIMENTAL)" | ||
77 | depends on USB && EXPERIMENTAL | ||
78 | default n | ||
79 | help | ||
80 | Say Y here if you want the USB core to spawn a new thread for | ||
81 | every USB device that is probed. This can cause a small speedup | ||
82 | in boot times on systems with a lot of different USB devices. | ||
83 | |||
84 | This option should be safe to enable, but if any odd probing | ||
85 | problems are found, please disable it, or dynamically turn it | ||
86 | off in the /sys/module/usbcore/parameters/multithread_probe | ||
87 | file | ||
88 | |||
89 | When in doubt, say N. | ||
90 | |||
91 | config USB_OTG | 62 | config USB_OTG |
92 | bool | 63 | bool |
93 | depends on USB && EXPERIMENTAL | 64 | depends on USB && EXPERIMENTAL |
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c index c3915dc28608..ead2475406b8 100644 --- a/drivers/usb/core/buffer.c +++ b/drivers/usb/core/buffer.c | |||
@@ -49,9 +49,9 @@ static const size_t pool_max [HCD_BUFFER_POOLS] = { | |||
49 | * | 49 | * |
50 | * Call hcd_buffer_destroy() to clean up after using those pools. | 50 | * Call hcd_buffer_destroy() to clean up after using those pools. |
51 | */ | 51 | */ |
52 | int hcd_buffer_create (struct usb_hcd *hcd) | 52 | int hcd_buffer_create(struct usb_hcd *hcd) |
53 | { | 53 | { |
54 | char name [16]; | 54 | char name[16]; |
55 | int i, size; | 55 | int i, size; |
56 | 56 | ||
57 | if (!hcd->self.controller->dma_mask) | 57 | if (!hcd->self.controller->dma_mask) |
@@ -60,11 +60,11 @@ int hcd_buffer_create (struct usb_hcd *hcd) | |||
60 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { | 60 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { |
61 | if (!(size = pool_max [i])) | 61 | if (!(size = pool_max [i])) |
62 | continue; | 62 | continue; |
63 | snprintf (name, sizeof name, "buffer-%d", size); | 63 | snprintf(name, sizeof name, "buffer-%d", size); |
64 | hcd->pool [i] = dma_pool_create (name, hcd->self.controller, | 64 | hcd->pool[i] = dma_pool_create(name, hcd->self.controller, |
65 | size, size, 0); | 65 | size, size, 0); |
66 | if (!hcd->pool [i]) { | 66 | if (!hcd->pool [i]) { |
67 | hcd_buffer_destroy (hcd); | 67 | hcd_buffer_destroy(hcd); |
68 | return -ENOMEM; | 68 | return -ENOMEM; |
69 | } | 69 | } |
70 | } | 70 | } |
@@ -79,14 +79,14 @@ int hcd_buffer_create (struct usb_hcd *hcd) | |||
79 | * | 79 | * |
80 | * This frees the buffer pools created by hcd_buffer_create(). | 80 | * This frees the buffer pools created by hcd_buffer_create(). |
81 | */ | 81 | */ |
82 | void hcd_buffer_destroy (struct usb_hcd *hcd) | 82 | void hcd_buffer_destroy(struct usb_hcd *hcd) |
83 | { | 83 | { |
84 | int i; | 84 | int i; |
85 | 85 | ||
86 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { | 86 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { |
87 | struct dma_pool *pool = hcd->pool [i]; | 87 | struct dma_pool *pool = hcd->pool[i]; |
88 | if (pool) { | 88 | if (pool) { |
89 | dma_pool_destroy (pool); | 89 | dma_pool_destroy(pool); |
90 | hcd->pool[i] = NULL; | 90 | hcd->pool[i] = NULL; |
91 | } | 91 | } |
92 | } | 92 | } |
@@ -97,8 +97,8 @@ void hcd_buffer_destroy (struct usb_hcd *hcd) | |||
97 | * better sharing and to leverage mm/slab.c intelligence. | 97 | * better sharing and to leverage mm/slab.c intelligence. |
98 | */ | 98 | */ |
99 | 99 | ||
100 | void *hcd_buffer_alloc ( | 100 | void *hcd_buffer_alloc( |
101 | struct usb_bus *bus, | 101 | struct usb_bus *bus, |
102 | size_t size, | 102 | size_t size, |
103 | gfp_t mem_flags, | 103 | gfp_t mem_flags, |
104 | dma_addr_t *dma | 104 | dma_addr_t *dma |
@@ -110,18 +110,18 @@ void *hcd_buffer_alloc ( | |||
110 | /* some USB hosts just use PIO */ | 110 | /* some USB hosts just use PIO */ |
111 | if (!bus->controller->dma_mask) { | 111 | if (!bus->controller->dma_mask) { |
112 | *dma = ~(dma_addr_t) 0; | 112 | *dma = ~(dma_addr_t) 0; |
113 | return kmalloc (size, mem_flags); | 113 | return kmalloc(size, mem_flags); |
114 | } | 114 | } |
115 | 115 | ||
116 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { | 116 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { |
117 | if (size <= pool_max [i]) | 117 | if (size <= pool_max [i]) |
118 | return dma_pool_alloc (hcd->pool [i], mem_flags, dma); | 118 | return dma_pool_alloc(hcd->pool [i], mem_flags, dma); |
119 | } | 119 | } |
120 | return dma_alloc_coherent (hcd->self.controller, size, dma, 0); | 120 | return dma_alloc_coherent(hcd->self.controller, size, dma, 0); |
121 | } | 121 | } |
122 | 122 | ||
123 | void hcd_buffer_free ( | 123 | void hcd_buffer_free( |
124 | struct usb_bus *bus, | 124 | struct usb_bus *bus, |
125 | size_t size, | 125 | size_t size, |
126 | void *addr, | 126 | void *addr, |
127 | dma_addr_t dma | 127 | dma_addr_t dma |
@@ -134,15 +134,15 @@ void hcd_buffer_free ( | |||
134 | return; | 134 | return; |
135 | 135 | ||
136 | if (!bus->controller->dma_mask) { | 136 | if (!bus->controller->dma_mask) { |
137 | kfree (addr); | 137 | kfree(addr); |
138 | return; | 138 | return; |
139 | } | 139 | } |
140 | 140 | ||
141 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { | 141 | for (i = 0; i < HCD_BUFFER_POOLS; i++) { |
142 | if (size <= pool_max [i]) { | 142 | if (size <= pool_max [i]) { |
143 | dma_pool_free (hcd->pool [i], addr, dma); | 143 | dma_pool_free(hcd->pool [i], addr, dma); |
144 | return; | 144 | return; |
145 | } | 145 | } |
146 | } | 146 | } |
147 | dma_free_coherent (hcd->self.controller, size, addr, dma); | 147 | dma_free_coherent(hcd->self.controller, size, addr, dma); |
148 | } | 148 | } |
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index ea398e5d50af..a47c30b2d764 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c | |||
@@ -104,7 +104,7 @@ static const char *format_config = | |||
104 | 104 | ||
105 | static const char *format_iface = | 105 | static const char *format_iface = |
106 | /* I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/ | 106 | /* I: If#=dd Alt=dd #EPs=dd Cls=xx(sssss) Sub=xx Prot=xx Driver=xxxx*/ |
107 | "I: If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n"; | 107 | "I:%c If#=%2d Alt=%2d #EPs=%2d Cls=%02x(%-5s) Sub=%02x Prot=%02x Driver=%s\n"; |
108 | 108 | ||
109 | static const char *format_endpt = | 109 | static const char *format_endpt = |
110 | /* E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=D?s */ | 110 | /* E: Ad=xx(s) Atr=xx(ssss) MxPS=dddd Ivl=D?s */ |
@@ -164,10 +164,10 @@ static const char *class_decode(const int class) | |||
164 | for (ix = 0; clas_info[ix].class != -1; ix++) | 164 | for (ix = 0; clas_info[ix].class != -1; ix++) |
165 | if (clas_info[ix].class == class) | 165 | if (clas_info[ix].class == class) |
166 | break; | 166 | break; |
167 | return (clas_info[ix].class_name); | 167 | return clas_info[ix].class_name; |
168 | } | 168 | } |
169 | 169 | ||
170 | static char *usb_dump_endpoint_descriptor ( | 170 | static char *usb_dump_endpoint_descriptor( |
171 | int speed, | 171 | int speed, |
172 | char *start, | 172 | char *start, |
173 | char *end, | 173 | char *end, |
@@ -212,9 +212,9 @@ static char *usb_dump_endpoint_descriptor ( | |||
212 | break; | 212 | break; |
213 | case USB_ENDPOINT_XFER_INT: | 213 | case USB_ENDPOINT_XFER_INT: |
214 | type = "Int."; | 214 | type = "Int."; |
215 | if (speed == USB_SPEED_HIGH) { | 215 | if (speed == USB_SPEED_HIGH) |
216 | interval = 1 << (desc->bInterval - 1); | 216 | interval = 1 << (desc->bInterval - 1); |
217 | } else | 217 | else |
218 | interval = desc->bInterval; | 218 | interval = desc->bInterval; |
219 | break; | 219 | break; |
220 | default: /* "can't happen" */ | 220 | default: /* "can't happen" */ |
@@ -242,15 +242,19 @@ static char *usb_dump_interface_descriptor(char *start, char *end, | |||
242 | { | 242 | { |
243 | const struct usb_interface_descriptor *desc = &intfc->altsetting[setno].desc; | 243 | const struct usb_interface_descriptor *desc = &intfc->altsetting[setno].desc; |
244 | const char *driver_name = ""; | 244 | const char *driver_name = ""; |
245 | int active = 0; | ||
245 | 246 | ||
246 | if (start > end) | 247 | if (start > end) |
247 | return start; | 248 | return start; |
248 | down_read(&usb_bus_type.subsys.rwsem); | 249 | down_read(&usb_bus_type.subsys.rwsem); |
249 | if (iface) | 250 | if (iface) { |
250 | driver_name = (iface->dev.driver | 251 | driver_name = (iface->dev.driver |
251 | ? iface->dev.driver->name | 252 | ? iface->dev.driver->name |
252 | : "(none)"); | 253 | : "(none)"); |
254 | active = (desc == &iface->cur_altsetting->desc); | ||
255 | } | ||
253 | start += sprintf(start, format_iface, | 256 | start += sprintf(start, format_iface, |
257 | active ? '*' : ' ', /* mark active altsetting */ | ||
254 | desc->bInterfaceNumber, | 258 | desc->bInterfaceNumber, |
255 | desc->bAlternateSetting, | 259 | desc->bAlternateSetting, |
256 | desc->bNumEndpoints, | 260 | desc->bNumEndpoints, |
@@ -343,7 +347,7 @@ static char *usb_dump_device_descriptor(char *start, char *end, const struct usb | |||
343 | 347 | ||
344 | if (start > end) | 348 | if (start > end) |
345 | return start; | 349 | return start; |
346 | start += sprintf (start, format_device1, | 350 | start += sprintf(start, format_device1, |
347 | bcdUSB >> 8, bcdUSB & 0xff, | 351 | bcdUSB >> 8, bcdUSB & 0xff, |
348 | desc->bDeviceClass, | 352 | desc->bDeviceClass, |
349 | class_decode (desc->bDeviceClass), | 353 | class_decode (desc->bDeviceClass), |
@@ -363,7 +367,7 @@ static char *usb_dump_device_descriptor(char *start, char *end, const struct usb | |||
363 | /* | 367 | /* |
364 | * Dump the different strings that this device holds. | 368 | * Dump the different strings that this device holds. |
365 | */ | 369 | */ |
366 | static char *usb_dump_device_strings (char *start, char *end, struct usb_device *dev) | 370 | static char *usb_dump_device_strings(char *start, char *end, struct usb_device *dev) |
367 | { | 371 | { |
368 | if (start > end) | 372 | if (start > end) |
369 | return start; | 373 | return start; |
@@ -395,7 +399,7 @@ static char *usb_dump_desc(char *start, char *end, struct usb_device *dev) | |||
395 | if (start > end) | 399 | if (start > end) |
396 | return start; | 400 | return start; |
397 | 401 | ||
398 | start = usb_dump_device_strings (start, end, dev); | 402 | start = usb_dump_device_strings(start, end, dev); |
399 | 403 | ||
400 | for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { | 404 | for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { |
401 | if (start > end) | 405 | if (start > end) |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 3ed4cb2d56d9..2087766f9e88 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -522,19 +522,19 @@ static int check_ctrlrecip(struct dev_state *ps, unsigned int requesttype, unsig | |||
522 | 522 | ||
523 | static struct usb_device *usbdev_lookup_minor(int minor) | 523 | static struct usb_device *usbdev_lookup_minor(int minor) |
524 | { | 524 | { |
525 | struct class_device *class_dev; | 525 | struct device *device; |
526 | struct usb_device *dev = NULL; | 526 | struct usb_device *udev = NULL; |
527 | 527 | ||
528 | down(&usb_device_class->sem); | 528 | down(&usb_device_class->sem); |
529 | list_for_each_entry(class_dev, &usb_device_class->children, node) { | 529 | list_for_each_entry(device, &usb_device_class->devices, node) { |
530 | if (class_dev->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { | 530 | if (device->devt == MKDEV(USB_DEVICE_MAJOR, minor)) { |
531 | dev = class_dev->class_data; | 531 | udev = device->platform_data; |
532 | break; | 532 | break; |
533 | } | 533 | } |
534 | } | 534 | } |
535 | up(&usb_device_class->sem); | 535 | up(&usb_device_class->sem); |
536 | 536 | ||
537 | return dev; | 537 | return udev; |
538 | }; | 538 | }; |
539 | 539 | ||
540 | /* | 540 | /* |
@@ -570,6 +570,7 @@ static int usbdev_open(struct inode *inode, struct file *file) | |||
570 | ps->dev = dev; | 570 | ps->dev = dev; |
571 | ps->file = file; | 571 | ps->file = file; |
572 | spin_lock_init(&ps->lock); | 572 | spin_lock_init(&ps->lock); |
573 | INIT_LIST_HEAD(&ps->list); | ||
573 | INIT_LIST_HEAD(&ps->async_pending); | 574 | INIT_LIST_HEAD(&ps->async_pending); |
574 | INIT_LIST_HEAD(&ps->async_completed); | 575 | INIT_LIST_HEAD(&ps->async_completed); |
575 | init_waitqueue_head(&ps->wait); | 576 | init_waitqueue_head(&ps->wait); |
@@ -962,7 +963,11 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
962 | kfree(dr); | 963 | kfree(dr); |
963 | return -EFAULT; | 964 | return -EFAULT; |
964 | } | 965 | } |
965 | snoop(&ps->dev->dev, "control urb\n"); | 966 | snoop(&ps->dev->dev, "control urb: bRequest=%02x " |
967 | "bRrequestType=%02x wValue=%04x " | ||
968 | "wIndex=%04x wLength=%04x\n", | ||
969 | dr->bRequest, dr->bRequestType, dr->wValue, | ||
970 | dr->wIndex, dr->wLength); | ||
966 | break; | 971 | break; |
967 | 972 | ||
968 | case USBDEVFS_URB_TYPE_BULK: | 973 | case USBDEVFS_URB_TYPE_BULK: |
@@ -1592,19 +1597,19 @@ static int usbdev_add(struct usb_device *dev) | |||
1592 | { | 1597 | { |
1593 | int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); | 1598 | int minor = ((dev->bus->busnum-1) * 128) + (dev->devnum-1); |
1594 | 1599 | ||
1595 | dev->class_dev = class_device_create(usb_device_class, NULL, | 1600 | dev->usbfs_dev = device_create(usb_device_class, &dev->dev, |
1596 | MKDEV(USB_DEVICE_MAJOR, minor), &dev->dev, | 1601 | MKDEV(USB_DEVICE_MAJOR, minor), |
1597 | "usbdev%d.%d", dev->bus->busnum, dev->devnum); | 1602 | "usbdev%d.%d", dev->bus->busnum, dev->devnum); |
1598 | if (IS_ERR(dev->class_dev)) | 1603 | if (IS_ERR(dev->usbfs_dev)) |
1599 | return PTR_ERR(dev->class_dev); | 1604 | return PTR_ERR(dev->usbfs_dev); |
1600 | 1605 | ||
1601 | dev->class_dev->class_data = dev; | 1606 | dev->usbfs_dev->platform_data = dev; |
1602 | return 0; | 1607 | return 0; |
1603 | } | 1608 | } |
1604 | 1609 | ||
1605 | static void usbdev_remove(struct usb_device *dev) | 1610 | static void usbdev_remove(struct usb_device *dev) |
1606 | { | 1611 | { |
1607 | class_device_unregister(dev->class_dev); | 1612 | device_unregister(dev->usbfs_dev); |
1608 | } | 1613 | } |
1609 | 1614 | ||
1610 | static int usbdev_notify(struct notifier_block *self, unsigned long action, | 1615 | static int usbdev_notify(struct notifier_block *self, unsigned long action, |
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index d6eb5ce1dd1d..600d1bc8272a 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -28,24 +28,16 @@ | |||
28 | #include "hcd.h" | 28 | #include "hcd.h" |
29 | #include "usb.h" | 29 | #include "usb.h" |
30 | 30 | ||
31 | static int usb_match_one_id(struct usb_interface *interface, | ||
32 | const struct usb_device_id *id); | ||
33 | |||
34 | struct usb_dynid { | ||
35 | struct list_head node; | ||
36 | struct usb_device_id id; | ||
37 | }; | ||
38 | |||
39 | #ifdef CONFIG_HOTPLUG | 31 | #ifdef CONFIG_HOTPLUG |
40 | 32 | ||
41 | /* | 33 | /* |
42 | * Adds a new dynamic USBdevice ID to this driver, | 34 | * Adds a new dynamic USBdevice ID to this driver, |
43 | * and cause the driver to probe for all devices again. | 35 | * and cause the driver to probe for all devices again. |
44 | */ | 36 | */ |
45 | static ssize_t store_new_id(struct device_driver *driver, | 37 | ssize_t usb_store_new_id(struct usb_dynids *dynids, |
46 | const char *buf, size_t count) | 38 | struct device_driver *driver, |
39 | const char *buf, size_t count) | ||
47 | { | 40 | { |
48 | struct usb_driver *usb_drv = to_usb_driver(driver); | ||
49 | struct usb_dynid *dynid; | 41 | struct usb_dynid *dynid; |
50 | u32 idVendor = 0; | 42 | u32 idVendor = 0; |
51 | u32 idProduct = 0; | 43 | u32 idProduct = 0; |
@@ -65,9 +57,9 @@ static ssize_t store_new_id(struct device_driver *driver, | |||
65 | dynid->id.idProduct = idProduct; | 57 | dynid->id.idProduct = idProduct; |
66 | dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE; | 58 | dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE; |
67 | 59 | ||
68 | spin_lock(&usb_drv->dynids.lock); | 60 | spin_lock(&dynids->lock); |
69 | list_add_tail(&usb_drv->dynids.list, &dynid->node); | 61 | list_add_tail(&dynids->list, &dynid->node); |
70 | spin_unlock(&usb_drv->dynids.lock); | 62 | spin_unlock(&dynids->lock); |
71 | 63 | ||
72 | if (get_driver(driver)) { | 64 | if (get_driver(driver)) { |
73 | retval = driver_attach(driver); | 65 | retval = driver_attach(driver); |
@@ -78,6 +70,15 @@ static ssize_t store_new_id(struct device_driver *driver, | |||
78 | return retval; | 70 | return retval; |
79 | return count; | 71 | return count; |
80 | } | 72 | } |
73 | EXPORT_SYMBOL_GPL(usb_store_new_id); | ||
74 | |||
75 | static ssize_t store_new_id(struct device_driver *driver, | ||
76 | const char *buf, size_t count) | ||
77 | { | ||
78 | struct usb_driver *usb_drv = to_usb_driver(driver); | ||
79 | |||
80 | return usb_store_new_id(&usb_drv->dynids, driver, buf, count); | ||
81 | } | ||
81 | static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); | 82 | static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id); |
82 | 83 | ||
83 | static int usb_create_newid_file(struct usb_driver *usb_drv) | 84 | static int usb_create_newid_file(struct usb_driver *usb_drv) |
@@ -365,8 +366,8 @@ void usb_driver_release_interface(struct usb_driver *driver, | |||
365 | EXPORT_SYMBOL(usb_driver_release_interface); | 366 | EXPORT_SYMBOL(usb_driver_release_interface); |
366 | 367 | ||
367 | /* returns 0 if no match, 1 if match */ | 368 | /* returns 0 if no match, 1 if match */ |
368 | static int usb_match_one_id(struct usb_interface *interface, | 369 | int usb_match_one_id(struct usb_interface *interface, |
369 | const struct usb_device_id *id) | 370 | const struct usb_device_id *id) |
370 | { | 371 | { |
371 | struct usb_host_interface *intf; | 372 | struct usb_host_interface *intf; |
372 | struct usb_device *dev; | 373 | struct usb_device *dev; |
@@ -432,6 +433,8 @@ static int usb_match_one_id(struct usb_interface *interface, | |||
432 | 433 | ||
433 | return 1; | 434 | return 1; |
434 | } | 435 | } |
436 | EXPORT_SYMBOL_GPL(usb_match_one_id); | ||
437 | |||
435 | /** | 438 | /** |
436 | * usb_match_id - find first usb_device_id matching device or interface | 439 | * usb_match_id - find first usb_device_id matching device or interface |
437 | * @interface: the interface of interest | 440 | * @interface: the interface of interest |
@@ -750,7 +753,8 @@ EXPORT_SYMBOL_GPL(usb_deregister_device_driver); | |||
750 | * usb_register_dev() to enable that functionality. This function no longer | 753 | * usb_register_dev() to enable that functionality. This function no longer |
751 | * takes care of that. | 754 | * takes care of that. |
752 | */ | 755 | */ |
753 | int usb_register_driver(struct usb_driver *new_driver, struct module *owner) | 756 | int usb_register_driver(struct usb_driver *new_driver, struct module *owner, |
757 | const char *mod_name) | ||
754 | { | 758 | { |
755 | int retval = 0; | 759 | int retval = 0; |
756 | 760 | ||
@@ -763,6 +767,7 @@ int usb_register_driver(struct usb_driver *new_driver, struct module *owner) | |||
763 | new_driver->drvwrap.driver.probe = usb_probe_interface; | 767 | new_driver->drvwrap.driver.probe = usb_probe_interface; |
764 | new_driver->drvwrap.driver.remove = usb_unbind_interface; | 768 | new_driver->drvwrap.driver.remove = usb_unbind_interface; |
765 | new_driver->drvwrap.driver.owner = owner; | 769 | new_driver->drvwrap.driver.owner = owner; |
770 | new_driver->drvwrap.driver.mod_name = mod_name; | ||
766 | spin_lock_init(&new_driver->dynids.lock); | 771 | spin_lock_init(&new_driver->dynids.lock); |
767 | INIT_LIST_HEAD(&new_driver->dynids.list); | 772 | INIT_LIST_HEAD(&new_driver->dynids.list); |
768 | 773 | ||
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c index c505b767cee1..5e628ae3aec7 100644 --- a/drivers/usb/core/endpoint.c +++ b/drivers/usb/core/endpoint.c | |||
@@ -268,6 +268,7 @@ static void ep_device_release(struct device *dev) | |||
268 | struct ep_device *ep_dev = to_ep_device(dev); | 268 | struct ep_device *ep_dev = to_ep_device(dev); |
269 | 269 | ||
270 | dev_dbg(dev, "%s called for %s\n", __FUNCTION__, dev->bus_id); | 270 | dev_dbg(dev, "%s called for %s\n", __FUNCTION__, dev->bus_id); |
271 | endpoint_free_minor(ep_dev); | ||
271 | kfree(ep_dev); | 272 | kfree(ep_dev); |
272 | } | 273 | } |
273 | 274 | ||
@@ -349,7 +350,6 @@ void usb_remove_ep_files(struct usb_host_endpoint *endpoint) | |||
349 | sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress); | 350 | sprintf(name, "ep_%02x", endpoint->desc.bEndpointAddress); |
350 | sysfs_remove_link(&ep_dev->dev.parent->kobj, name); | 351 | sysfs_remove_link(&ep_dev->dev.parent->kobj, name); |
351 | sysfs_remove_group(&ep_dev->dev.kobj, &ep_dev_attr_grp); | 352 | sysfs_remove_group(&ep_dev->dev.kobj, &ep_dev_attr_grp); |
352 | endpoint_free_minor(ep_dev); | ||
353 | device_unregister(&ep_dev->dev); | 353 | device_unregister(&ep_dev->dev); |
354 | endpoint->ep_dev = NULL; | 354 | endpoint->ep_dev = NULL; |
355 | destroy_endpoint_class(); | 355 | destroy_endpoint_class(); |
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index f794f07cfb33..01c857ac27af 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c | |||
@@ -194,14 +194,13 @@ int usb_register_dev(struct usb_interface *intf, | |||
194 | ++temp; | 194 | ++temp; |
195 | else | 195 | else |
196 | temp = name; | 196 | temp = name; |
197 | intf->class_dev = class_device_create(usb_class->class, NULL, | 197 | intf->usb_dev = device_create(usb_class->class, &intf->dev, |
198 | MKDEV(USB_MAJOR, minor), | 198 | MKDEV(USB_MAJOR, minor), "%s", temp); |
199 | &intf->dev, "%s", temp); | 199 | if (IS_ERR(intf->usb_dev)) { |
200 | if (IS_ERR(intf->class_dev)) { | ||
201 | spin_lock (&minor_lock); | 200 | spin_lock (&minor_lock); |
202 | usb_minors[intf->minor] = NULL; | 201 | usb_minors[intf->minor] = NULL; |
203 | spin_unlock (&minor_lock); | 202 | spin_unlock (&minor_lock); |
204 | retval = PTR_ERR(intf->class_dev); | 203 | retval = PTR_ERR(intf->usb_dev); |
205 | } | 204 | } |
206 | exit: | 205 | exit: |
207 | return retval; | 206 | return retval; |
@@ -242,8 +241,8 @@ void usb_deregister_dev(struct usb_interface *intf, | |||
242 | spin_unlock (&minor_lock); | 241 | spin_unlock (&minor_lock); |
243 | 242 | ||
244 | snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); | 243 | snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); |
245 | class_device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); | 244 | device_destroy(usb_class->class, MKDEV(USB_MAJOR, intf->minor)); |
246 | intf->class_dev = NULL; | 245 | intf->usb_dev = NULL; |
247 | intf->minor = -1; | 246 | intf->minor = -1; |
248 | destroy_usb_class(); | 247 | destroy_usb_class(); |
249 | } | 248 | } |
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index ebb20ff7ac58..b531a4fd30c2 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c | |||
@@ -25,6 +25,20 @@ static inline const char *plural(int n) | |||
25 | return (n == 1 ? "" : "s"); | 25 | return (n == 1 ? "" : "s"); |
26 | } | 26 | } |
27 | 27 | ||
28 | static int is_rndis(struct usb_interface_descriptor *desc) | ||
29 | { | ||
30 | return desc->bInterfaceClass == USB_CLASS_COMM | ||
31 | && desc->bInterfaceSubClass == 2 | ||
32 | && desc->bInterfaceProtocol == 0xff; | ||
33 | } | ||
34 | |||
35 | static int is_activesync(struct usb_interface_descriptor *desc) | ||
36 | { | ||
37 | return desc->bInterfaceClass == USB_CLASS_MISC | ||
38 | && desc->bInterfaceSubClass == 1 | ||
39 | && desc->bInterfaceProtocol == 1; | ||
40 | } | ||
41 | |||
28 | static int choose_configuration(struct usb_device *udev) | 42 | static int choose_configuration(struct usb_device *udev) |
29 | { | 43 | { |
30 | int i; | 44 | int i; |
@@ -87,14 +101,12 @@ static int choose_configuration(struct usb_device *udev) | |||
87 | continue; | 101 | continue; |
88 | } | 102 | } |
89 | 103 | ||
90 | /* If the first config's first interface is COMM/2/0xff | 104 | /* When the first config's first interface is one of Microsoft's |
91 | * (MSFT RNDIS), rule it out unless Linux has host-side | 105 | * pet nonstandard Ethernet-over-USB protocols, ignore it unless |
92 | * RNDIS support. */ | 106 | * this kernel has enabled the necessary host side driver. |
93 | if (i == 0 && desc | 107 | */ |
94 | && desc->bInterfaceClass == USB_CLASS_COMM | 108 | if (i == 0 && desc && (is_rndis(desc) || is_activesync(desc))) { |
95 | && desc->bInterfaceSubClass == 2 | 109 | #if !defined(CONFIG_USB_NET_RNDIS_HOST) && !defined(CONFIG_USB_NET_RNDIS_HOST_MODULE) |
96 | && desc->bInterfaceProtocol == 0xff) { | ||
97 | #ifndef CONFIG_USB_NET_RNDIS_HOST | ||
98 | continue; | 110 | continue; |
99 | #else | 111 | #else |
100 | best = c; | 112 | best = c; |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 10064af65d17..b26c19e8d19f 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -45,8 +45,6 @@ | |||
45 | #include "hub.h" | 45 | #include "hub.h" |
46 | 46 | ||
47 | 47 | ||
48 | // #define USB_BANDWIDTH_MESSAGES | ||
49 | |||
50 | /*-------------------------------------------------------------------------*/ | 48 | /*-------------------------------------------------------------------------*/ |
51 | 49 | ||
52 | /* | 50 | /* |
@@ -891,136 +889,6 @@ long usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount) | |||
891 | } | 889 | } |
892 | EXPORT_SYMBOL (usb_calc_bus_time); | 890 | EXPORT_SYMBOL (usb_calc_bus_time); |
893 | 891 | ||
894 | /* | ||
895 | * usb_check_bandwidth(): | ||
896 | * | ||
897 | * old_alloc is from host_controller->bandwidth_allocated in microseconds; | ||
898 | * bustime is from calc_bus_time(), but converted to microseconds. | ||
899 | * | ||
900 | * returns <bustime in us> if successful, | ||
901 | * or -ENOSPC if bandwidth request fails. | ||
902 | * | ||
903 | * FIXME: | ||
904 | * This initial implementation does not use Endpoint.bInterval | ||
905 | * in managing bandwidth allocation. | ||
906 | * It probably needs to be expanded to use Endpoint.bInterval. | ||
907 | * This can be done as a later enhancement (correction). | ||
908 | * | ||
909 | * This will also probably require some kind of | ||
910 | * frame allocation tracking...meaning, for example, | ||
911 | * that if multiple drivers request interrupts every 10 USB frames, | ||
912 | * they don't all have to be allocated at | ||
913 | * frame numbers N, N+10, N+20, etc. Some of them could be at | ||
914 | * N+11, N+21, N+31, etc., and others at | ||
915 | * N+12, N+22, N+32, etc. | ||
916 | * | ||
917 | * Similarly for isochronous transfers... | ||
918 | * | ||
919 | * Individual HCDs can schedule more directly ... this logic | ||
920 | * is not correct for high speed transfers. | ||
921 | */ | ||
922 | int usb_check_bandwidth (struct usb_device *dev, struct urb *urb) | ||
923 | { | ||
924 | unsigned int pipe = urb->pipe; | ||
925 | long bustime; | ||
926 | int is_in = usb_pipein (pipe); | ||
927 | int is_iso = usb_pipeisoc (pipe); | ||
928 | int old_alloc = dev->bus->bandwidth_allocated; | ||
929 | int new_alloc; | ||
930 | |||
931 | |||
932 | bustime = NS_TO_US (usb_calc_bus_time (dev->speed, is_in, is_iso, | ||
933 | usb_maxpacket (dev, pipe, !is_in))); | ||
934 | if (is_iso) | ||
935 | bustime /= urb->number_of_packets; | ||
936 | |||
937 | new_alloc = old_alloc + (int) bustime; | ||
938 | if (new_alloc > FRAME_TIME_MAX_USECS_ALLOC) { | ||
939 | #ifdef DEBUG | ||
940 | char *mode = | ||
941 | #ifdef CONFIG_USB_BANDWIDTH | ||
942 | ""; | ||
943 | #else | ||
944 | "would have "; | ||
945 | #endif | ||
946 | dev_dbg (&dev->dev, "usb_check_bandwidth %sFAILED: %d + %ld = %d usec\n", | ||
947 | mode, old_alloc, bustime, new_alloc); | ||
948 | #endif | ||
949 | #ifdef CONFIG_USB_BANDWIDTH | ||
950 | bustime = -ENOSPC; /* report error */ | ||
951 | #endif | ||
952 | } | ||
953 | |||
954 | return bustime; | ||
955 | } | ||
956 | EXPORT_SYMBOL (usb_check_bandwidth); | ||
957 | |||
958 | |||
959 | /** | ||
960 | * usb_claim_bandwidth - records bandwidth for a periodic transfer | ||
961 | * @dev: source/target of request | ||
962 | * @urb: request (urb->dev == dev) | ||
963 | * @bustime: bandwidth consumed, in (average) microseconds per frame | ||
964 | * @isoc: true iff the request is isochronous | ||
965 | * | ||
966 | * Bus bandwidth reservations are recorded purely for diagnostic purposes. | ||
967 | * HCDs are expected not to overcommit periodic bandwidth, and to record such | ||
968 | * reservations whenever endpoints are added to the periodic schedule. | ||
969 | * | ||
970 | * FIXME averaging per-frame is suboptimal. Better to sum over the HCD's | ||
971 | * entire periodic schedule ... 32 frames for OHCI, 1024 for UHCI, settable | ||
972 | * for EHCI (256/512/1024 frames, default 1024) and have the bus expose how | ||
973 | * large its periodic schedule is. | ||
974 | */ | ||
975 | void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, int bustime, int isoc) | ||
976 | { | ||
977 | dev->bus->bandwidth_allocated += bustime; | ||
978 | if (isoc) | ||
979 | dev->bus->bandwidth_isoc_reqs++; | ||
980 | else | ||
981 | dev->bus->bandwidth_int_reqs++; | ||
982 | urb->bandwidth = bustime; | ||
983 | |||
984 | #ifdef USB_BANDWIDTH_MESSAGES | ||
985 | dev_dbg (&dev->dev, "bandwidth alloc increased by %d (%s) to %d for %d requesters\n", | ||
986 | bustime, | ||
987 | isoc ? "ISOC" : "INTR", | ||
988 | dev->bus->bandwidth_allocated, | ||
989 | dev->bus->bandwidth_int_reqs + dev->bus->bandwidth_isoc_reqs); | ||
990 | #endif | ||
991 | } | ||
992 | EXPORT_SYMBOL (usb_claim_bandwidth); | ||
993 | |||
994 | |||
995 | /** | ||
996 | * usb_release_bandwidth - reverses effect of usb_claim_bandwidth() | ||
997 | * @dev: source/target of request | ||
998 | * @urb: request (urb->dev == dev) | ||
999 | * @isoc: true iff the request is isochronous | ||
1000 | * | ||
1001 | * This records that previously allocated bandwidth has been released. | ||
1002 | * Bandwidth is released when endpoints are removed from the host controller's | ||
1003 | * periodic schedule. | ||
1004 | */ | ||
1005 | void usb_release_bandwidth (struct usb_device *dev, struct urb *urb, int isoc) | ||
1006 | { | ||
1007 | dev->bus->bandwidth_allocated -= urb->bandwidth; | ||
1008 | if (isoc) | ||
1009 | dev->bus->bandwidth_isoc_reqs--; | ||
1010 | else | ||
1011 | dev->bus->bandwidth_int_reqs--; | ||
1012 | |||
1013 | #ifdef USB_BANDWIDTH_MESSAGES | ||
1014 | dev_dbg (&dev->dev, "bandwidth alloc reduced by %d (%s) to %d for %d requesters\n", | ||
1015 | urb->bandwidth, | ||
1016 | isoc ? "ISOC" : "INTR", | ||
1017 | dev->bus->bandwidth_allocated, | ||
1018 | dev->bus->bandwidth_int_reqs + dev->bus->bandwidth_isoc_reqs); | ||
1019 | #endif | ||
1020 | urb->bandwidth = 0; | ||
1021 | } | ||
1022 | EXPORT_SYMBOL (usb_release_bandwidth); | ||
1023 | |||
1024 | 892 | ||
1025 | /*-------------------------------------------------------------------------*/ | 893 | /*-------------------------------------------------------------------------*/ |
1026 | 894 | ||
@@ -1034,11 +902,6 @@ static void urb_unlink (struct urb *urb) | |||
1034 | { | 902 | { |
1035 | unsigned long flags; | 903 | unsigned long flags; |
1036 | 904 | ||
1037 | /* Release any periodic transfer bandwidth */ | ||
1038 | if (urb->bandwidth) | ||
1039 | usb_release_bandwidth (urb->dev, urb, | ||
1040 | usb_pipeisoc (urb->pipe)); | ||
1041 | |||
1042 | /* clear all state linking urb to this dev (and hcd) */ | 905 | /* clear all state linking urb to this dev (and hcd) */ |
1043 | 906 | ||
1044 | spin_lock_irqsave (&hcd_data_lock, flags); | 907 | spin_lock_irqsave (&hcd_data_lock, flags); |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 8f8df0d4382e..2a269ca20517 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -308,10 +308,6 @@ extern void usb_destroy_configuration(struct usb_device *dev); | |||
308 | #define NS_TO_US(ns) ((ns + 500L) / 1000L) | 308 | #define NS_TO_US(ns) ((ns + 500L) / 1000L) |
309 | /* convert & round nanoseconds to microseconds */ | 309 | /* convert & round nanoseconds to microseconds */ |
310 | 310 | ||
311 | extern void usb_claim_bandwidth (struct usb_device *dev, struct urb *urb, | ||
312 | int bustime, int isoc); | ||
313 | extern void usb_release_bandwidth (struct usb_device *dev, struct urb *urb, | ||
314 | int isoc); | ||
315 | 311 | ||
316 | /* | 312 | /* |
317 | * Full/low speed bandwidth allocation constants/support. | 313 | * Full/low speed bandwidth allocation constants/support. |
@@ -324,8 +320,6 @@ extern void usb_release_bandwidth (struct usb_device *dev, struct urb *urb, | |||
324 | #define FRAME_TIME_MAX_BITS_ALLOC (90L * FRAME_TIME_BITS / 100L) | 320 | #define FRAME_TIME_MAX_BITS_ALLOC (90L * FRAME_TIME_BITS / 100L) |
325 | #define FRAME_TIME_MAX_USECS_ALLOC (90L * FRAME_TIME_USECS / 100L) | 321 | #define FRAME_TIME_MAX_USECS_ALLOC (90L * FRAME_TIME_USECS / 100L) |
326 | 322 | ||
327 | extern int usb_check_bandwidth (struct usb_device *dev, struct urb *urb); | ||
328 | |||
329 | /* | 323 | /* |
330 | * Ceiling [nano/micro]seconds (typical) for that many bytes at high speed | 324 | * Ceiling [nano/micro]seconds (typical) for that many bytes at high speed |
331 | * ISO is a bit less, no ACK ... from USB 2.0 spec, 5.11.3 (and needed | 325 | * ISO is a bit less, no ACK ... from USB 2.0 spec, 5.11.3 (and needed |
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 2651c2e2a89f..590ec82d0515 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -87,16 +87,6 @@ static DECLARE_WAIT_QUEUE_HEAD(khubd_wait); | |||
87 | 87 | ||
88 | static struct task_struct *khubd_task; | 88 | static struct task_struct *khubd_task; |
89 | 89 | ||
90 | /* multithreaded probe logic */ | ||
91 | static int multithread_probe = | ||
92 | #ifdef CONFIG_USB_MULTITHREAD_PROBE | ||
93 | 1; | ||
94 | #else | ||
95 | 0; | ||
96 | #endif | ||
97 | module_param(multithread_probe, bool, S_IRUGO); | ||
98 | MODULE_PARM_DESC(multithread_probe, "Run each USB device probe in a new thread"); | ||
99 | |||
100 | /* cycle leds on hubs that aren't blinking for attention */ | 90 | /* cycle leds on hubs that aren't blinking for attention */ |
101 | static int blinkenlights = 0; | 91 | static int blinkenlights = 0; |
102 | module_param (blinkenlights, bool, S_IRUGO); | 92 | module_param (blinkenlights, bool, S_IRUGO); |
@@ -1263,9 +1253,28 @@ static inline void show_string(struct usb_device *udev, char *id, char *string) | |||
1263 | static int __usb_port_suspend(struct usb_device *, int port1); | 1253 | static int __usb_port_suspend(struct usb_device *, int port1); |
1264 | #endif | 1254 | #endif |
1265 | 1255 | ||
1266 | static int __usb_new_device(void *void_data) | 1256 | /** |
1257 | * usb_new_device - perform initial device setup (usbcore-internal) | ||
1258 | * @udev: newly addressed device (in ADDRESS state) | ||
1259 | * | ||
1260 | * This is called with devices which have been enumerated, but not yet | ||
1261 | * configured. The device descriptor is available, but not descriptors | ||
1262 | * for any device configuration. The caller must have locked either | ||
1263 | * the parent hub (if udev is a normal device) or else the | ||
1264 | * usb_bus_list_lock (if udev is a root hub). The parent's pointer to | ||
1265 | * udev has already been installed, but udev is not yet visible through | ||
1266 | * sysfs or other filesystem code. | ||
1267 | * | ||
1268 | * It will return if the device is configured properly or not. Zero if | ||
1269 | * the interface was registered with the driver core; else a negative | ||
1270 | * errno value. | ||
1271 | * | ||
1272 | * This call is synchronous, and may not be used in an interrupt context. | ||
1273 | * | ||
1274 | * Only the hub driver or root-hub registrar should ever call this. | ||
1275 | */ | ||
1276 | int usb_new_device(struct usb_device *udev) | ||
1267 | { | 1277 | { |
1268 | struct usb_device *udev = void_data; | ||
1269 | int err; | 1278 | int err; |
1270 | 1279 | ||
1271 | /* Lock ourself into memory in order to keep a probe sequence | 1280 | /* Lock ourself into memory in order to keep a probe sequence |
@@ -1382,44 +1391,6 @@ fail: | |||
1382 | goto exit; | 1391 | goto exit; |
1383 | } | 1392 | } |
1384 | 1393 | ||
1385 | /** | ||
1386 | * usb_new_device - perform initial device setup (usbcore-internal) | ||
1387 | * @udev: newly addressed device (in ADDRESS state) | ||
1388 | * | ||
1389 | * This is called with devices which have been enumerated, but not yet | ||
1390 | * configured. The device descriptor is available, but not descriptors | ||
1391 | * for any device configuration. The caller must have locked either | ||
1392 | * the parent hub (if udev is a normal device) or else the | ||
1393 | * usb_bus_list_lock (if udev is a root hub). The parent's pointer to | ||
1394 | * udev has already been installed, but udev is not yet visible through | ||
1395 | * sysfs or other filesystem code. | ||
1396 | * | ||
1397 | * The return value for this function depends on if the | ||
1398 | * multithread_probe variable is set or not. If it's set, it will | ||
1399 | * return a if the probe thread was successfully created or not. If the | ||
1400 | * variable is not set, it will return if the device is configured | ||
1401 | * properly or not. interfaces, in sysfs); else a negative errno value. | ||
1402 | * | ||
1403 | * This call is synchronous, and may not be used in an interrupt context. | ||
1404 | * | ||
1405 | * Only the hub driver or root-hub registrar should ever call this. | ||
1406 | */ | ||
1407 | int usb_new_device(struct usb_device *udev) | ||
1408 | { | ||
1409 | struct task_struct *probe_task; | ||
1410 | int ret = 0; | ||
1411 | |||
1412 | if (multithread_probe) { | ||
1413 | probe_task = kthread_run(__usb_new_device, udev, | ||
1414 | "usb-probe-%s", udev->devnum); | ||
1415 | if (IS_ERR(probe_task)) | ||
1416 | ret = PTR_ERR(probe_task); | ||
1417 | } else | ||
1418 | ret = __usb_new_device(udev); | ||
1419 | |||
1420 | return ret; | ||
1421 | } | ||
1422 | |||
1423 | static int hub_port_status(struct usb_hub *hub, int port1, | 1394 | static int hub_port_status(struct usb_hub *hub, int port1, |
1424 | u16 *status, u16 *change) | 1395 | u16 *status, u16 *change) |
1425 | { | 1396 | { |
diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index b5d6a79af0be..11dad22da41c 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c | |||
@@ -379,7 +379,7 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig) | |||
379 | { | 379 | { |
380 | loff_t retval = -EINVAL; | 380 | loff_t retval = -EINVAL; |
381 | 381 | ||
382 | mutex_lock(&file->f_dentry->d_inode->i_mutex); | 382 | mutex_lock(&file->f_path.dentry->d_inode->i_mutex); |
383 | switch(orig) { | 383 | switch(orig) { |
384 | case 0: | 384 | case 0: |
385 | if (offset > 0) { | 385 | if (offset > 0) { |
@@ -396,7 +396,7 @@ static loff_t default_file_lseek (struct file *file, loff_t offset, int orig) | |||
396 | default: | 396 | default: |
397 | break; | 397 | break; |
398 | } | 398 | } |
399 | mutex_unlock(&file->f_dentry->d_inode->i_mutex); | 399 | mutex_unlock(&file->f_path.dentry->d_inode->i_mutex); |
400 | return retval; | 400 | return retval; |
401 | } | 401 | } |
402 | 402 | ||
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 149aa8bfb1fe..8aca3574c2b5 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -1545,11 +1545,7 @@ int usb_driver_set_configuration(struct usb_device *udev, int config) | |||
1545 | INIT_WORK(&req->work, driver_set_config_work); | 1545 | INIT_WORK(&req->work, driver_set_config_work); |
1546 | 1546 | ||
1547 | usb_get_dev(udev); | 1547 | usb_get_dev(udev); |
1548 | if (!schedule_work(&req->work)) { | 1548 | schedule_work(&req->work); |
1549 | usb_put_dev(udev); | ||
1550 | kfree(req); | ||
1551 | return -EINVAL; | ||
1552 | } | ||
1553 | return 0; | 1549 | return 0; |
1554 | } | 1550 | } |
1555 | EXPORT_SYMBOL_GPL(usb_driver_set_configuration); | 1551 | EXPORT_SYMBOL_GPL(usb_driver_set_configuration); |
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 55d8f575206d..4eaa0ee8e72f 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -16,16 +16,16 @@ | |||
16 | 16 | ||
17 | /* Active configuration fields */ | 17 | /* Active configuration fields */ |
18 | #define usb_actconfig_show(field, multiplier, format_string) \ | 18 | #define usb_actconfig_show(field, multiplier, format_string) \ |
19 | static ssize_t show_##field (struct device *dev, \ | 19 | static ssize_t show_##field(struct device *dev, \ |
20 | struct device_attribute *attr, char *buf) \ | 20 | struct device_attribute *attr, char *buf) \ |
21 | { \ | 21 | { \ |
22 | struct usb_device *udev; \ | 22 | struct usb_device *udev; \ |
23 | struct usb_host_config *actconfig; \ | 23 | struct usb_host_config *actconfig; \ |
24 | \ | 24 | \ |
25 | udev = to_usb_device (dev); \ | 25 | udev = to_usb_device(dev); \ |
26 | actconfig = udev->actconfig; \ | 26 | actconfig = udev->actconfig; \ |
27 | if (actconfig) \ | 27 | if (actconfig) \ |
28 | return sprintf (buf, format_string, \ | 28 | return sprintf(buf, format_string, \ |
29 | actconfig->desc.field * multiplier); \ | 29 | actconfig->desc.field * multiplier); \ |
30 | else \ | 30 | else \ |
31 | return 0; \ | 31 | return 0; \ |
@@ -35,9 +35,9 @@ static ssize_t show_##field (struct device *dev, \ | |||
35 | usb_actconfig_show(field, multiplier, format_string) \ | 35 | usb_actconfig_show(field, multiplier, format_string) \ |
36 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); | 36 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); |
37 | 37 | ||
38 | usb_actconfig_attr (bNumInterfaces, 1, "%2d\n") | 38 | usb_actconfig_attr(bNumInterfaces, 1, "%2d\n") |
39 | usb_actconfig_attr (bmAttributes, 1, "%2x\n") | 39 | usb_actconfig_attr(bmAttributes, 1, "%2x\n") |
40 | usb_actconfig_attr (bMaxPower, 2, "%3dmA\n") | 40 | usb_actconfig_attr(bMaxPower, 2, "%3dmA\n") |
41 | 41 | ||
42 | static ssize_t show_configuration_string(struct device *dev, | 42 | static ssize_t show_configuration_string(struct device *dev, |
43 | struct device_attribute *attr, char *buf) | 43 | struct device_attribute *attr, char *buf) |
@@ -45,7 +45,7 @@ static ssize_t show_configuration_string(struct device *dev, | |||
45 | struct usb_device *udev; | 45 | struct usb_device *udev; |
46 | struct usb_host_config *actconfig; | 46 | struct usb_host_config *actconfig; |
47 | 47 | ||
48 | udev = to_usb_device (dev); | 48 | udev = to_usb_device(dev); |
49 | actconfig = udev->actconfig; | 49 | actconfig = udev->actconfig; |
50 | if ((!actconfig) || (!actconfig->string)) | 50 | if ((!actconfig) || (!actconfig->string)) |
51 | return 0; | 51 | return 0; |
@@ -57,16 +57,16 @@ static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL); | |||
57 | usb_actconfig_show(bConfigurationValue, 1, "%u\n"); | 57 | usb_actconfig_show(bConfigurationValue, 1, "%u\n"); |
58 | 58 | ||
59 | static ssize_t | 59 | static ssize_t |
60 | set_bConfigurationValue (struct device *dev, struct device_attribute *attr, | 60 | set_bConfigurationValue(struct device *dev, struct device_attribute *attr, |
61 | const char *buf, size_t count) | 61 | const char *buf, size_t count) |
62 | { | 62 | { |
63 | struct usb_device *udev = to_usb_device (dev); | 63 | struct usb_device *udev = to_usb_device(dev); |
64 | int config, value; | 64 | int config, value; |
65 | 65 | ||
66 | if (sscanf (buf, "%u", &config) != 1 || config > 255) | 66 | if (sscanf(buf, "%u", &config) != 1 || config > 255) |
67 | return -EINVAL; | 67 | return -EINVAL; |
68 | usb_lock_device(udev); | 68 | usb_lock_device(udev); |
69 | value = usb_set_configuration (udev, config); | 69 | value = usb_set_configuration(udev, config); |
70 | usb_unlock_device(udev); | 70 | usb_unlock_device(udev); |
71 | return (value < 0) ? value : count; | 71 | return (value < 0) ? value : count; |
72 | } | 72 | } |
@@ -81,7 +81,7 @@ static ssize_t show_##name(struct device *dev, \ | |||
81 | { \ | 81 | { \ |
82 | struct usb_device *udev; \ | 82 | struct usb_device *udev; \ |
83 | \ | 83 | \ |
84 | udev = to_usb_device (dev); \ | 84 | udev = to_usb_device(dev); \ |
85 | return sprintf(buf, "%s\n", udev->name); \ | 85 | return sprintf(buf, "%s\n", udev->name); \ |
86 | } \ | 86 | } \ |
87 | static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL); | 87 | static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL); |
@@ -91,12 +91,12 @@ usb_string_attr(manufacturer); | |||
91 | usb_string_attr(serial); | 91 | usb_string_attr(serial); |
92 | 92 | ||
93 | static ssize_t | 93 | static ssize_t |
94 | show_speed (struct device *dev, struct device_attribute *attr, char *buf) | 94 | show_speed(struct device *dev, struct device_attribute *attr, char *buf) |
95 | { | 95 | { |
96 | struct usb_device *udev; | 96 | struct usb_device *udev; |
97 | char *speed; | 97 | char *speed; |
98 | 98 | ||
99 | udev = to_usb_device (dev); | 99 | udev = to_usb_device(dev); |
100 | 100 | ||
101 | switch (udev->speed) { | 101 | switch (udev->speed) { |
102 | case USB_SPEED_LOW: | 102 | case USB_SPEED_LOW: |
@@ -112,22 +112,22 @@ show_speed (struct device *dev, struct device_attribute *attr, char *buf) | |||
112 | default: | 112 | default: |
113 | speed = "unknown"; | 113 | speed = "unknown"; |
114 | } | 114 | } |
115 | return sprintf (buf, "%s\n", speed); | 115 | return sprintf(buf, "%s\n", speed); |
116 | } | 116 | } |
117 | static DEVICE_ATTR(speed, S_IRUGO, show_speed, NULL); | 117 | static DEVICE_ATTR(speed, S_IRUGO, show_speed, NULL); |
118 | 118 | ||
119 | static ssize_t | 119 | static ssize_t |
120 | show_devnum (struct device *dev, struct device_attribute *attr, char *buf) | 120 | show_devnum(struct device *dev, struct device_attribute *attr, char *buf) |
121 | { | 121 | { |
122 | struct usb_device *udev; | 122 | struct usb_device *udev; |
123 | 123 | ||
124 | udev = to_usb_device (dev); | 124 | udev = to_usb_device(dev); |
125 | return sprintf (buf, "%d\n", udev->devnum); | 125 | return sprintf(buf, "%d\n", udev->devnum); |
126 | } | 126 | } |
127 | static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL); | 127 | static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL); |
128 | 128 | ||
129 | static ssize_t | 129 | static ssize_t |
130 | show_version (struct device *dev, struct device_attribute *attr, char *buf) | 130 | show_version(struct device *dev, struct device_attribute *attr, char *buf) |
131 | { | 131 | { |
132 | struct usb_device *udev; | 132 | struct usb_device *udev; |
133 | u16 bcdUSB; | 133 | u16 bcdUSB; |
@@ -139,25 +139,25 @@ show_version (struct device *dev, struct device_attribute *attr, char *buf) | |||
139 | static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); | 139 | static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); |
140 | 140 | ||
141 | static ssize_t | 141 | static ssize_t |
142 | show_maxchild (struct device *dev, struct device_attribute *attr, char *buf) | 142 | show_maxchild(struct device *dev, struct device_attribute *attr, char *buf) |
143 | { | 143 | { |
144 | struct usb_device *udev; | 144 | struct usb_device *udev; |
145 | 145 | ||
146 | udev = to_usb_device (dev); | 146 | udev = to_usb_device(dev); |
147 | return sprintf (buf, "%d\n", udev->maxchild); | 147 | return sprintf(buf, "%d\n", udev->maxchild); |
148 | } | 148 | } |
149 | static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL); | 149 | static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL); |
150 | 150 | ||
151 | /* Descriptor fields */ | 151 | /* Descriptor fields */ |
152 | #define usb_descriptor_attr_le16(field, format_string) \ | 152 | #define usb_descriptor_attr_le16(field, format_string) \ |
153 | static ssize_t \ | 153 | static ssize_t \ |
154 | show_##field (struct device *dev, struct device_attribute *attr, \ | 154 | show_##field(struct device *dev, struct device_attribute *attr, \ |
155 | char *buf) \ | 155 | char *buf) \ |
156 | { \ | 156 | { \ |
157 | struct usb_device *udev; \ | 157 | struct usb_device *udev; \ |
158 | \ | 158 | \ |
159 | udev = to_usb_device (dev); \ | 159 | udev = to_usb_device(dev); \ |
160 | return sprintf (buf, format_string, \ | 160 | return sprintf(buf, format_string, \ |
161 | le16_to_cpu(udev->descriptor.field)); \ | 161 | le16_to_cpu(udev->descriptor.field)); \ |
162 | } \ | 162 | } \ |
163 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); | 163 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); |
@@ -168,21 +168,21 @@ usb_descriptor_attr_le16(bcdDevice, "%04x\n") | |||
168 | 168 | ||
169 | #define usb_descriptor_attr(field, format_string) \ | 169 | #define usb_descriptor_attr(field, format_string) \ |
170 | static ssize_t \ | 170 | static ssize_t \ |
171 | show_##field (struct device *dev, struct device_attribute *attr, \ | 171 | show_##field(struct device *dev, struct device_attribute *attr, \ |
172 | char *buf) \ | 172 | char *buf) \ |
173 | { \ | 173 | { \ |
174 | struct usb_device *udev; \ | 174 | struct usb_device *udev; \ |
175 | \ | 175 | \ |
176 | udev = to_usb_device (dev); \ | 176 | udev = to_usb_device(dev); \ |
177 | return sprintf (buf, format_string, udev->descriptor.field); \ | 177 | return sprintf(buf, format_string, udev->descriptor.field); \ |
178 | } \ | 178 | } \ |
179 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); | 179 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); |
180 | 180 | ||
181 | usb_descriptor_attr (bDeviceClass, "%02x\n") | 181 | usb_descriptor_attr(bDeviceClass, "%02x\n") |
182 | usb_descriptor_attr (bDeviceSubClass, "%02x\n") | 182 | usb_descriptor_attr(bDeviceSubClass, "%02x\n") |
183 | usb_descriptor_attr (bDeviceProtocol, "%02x\n") | 183 | usb_descriptor_attr(bDeviceProtocol, "%02x\n") |
184 | usb_descriptor_attr (bNumConfigurations, "%d\n") | 184 | usb_descriptor_attr(bNumConfigurations, "%d\n") |
185 | usb_descriptor_attr (bMaxPacketSize0, "%d\n") | 185 | usb_descriptor_attr(bMaxPacketSize0, "%d\n") |
186 | 186 | ||
187 | static struct attribute *dev_attrs[] = { | 187 | static struct attribute *dev_attrs[] = { |
188 | /* current configuration's attributes */ | 188 | /* current configuration's attributes */ |
@@ -220,17 +220,17 @@ int usb_create_sysfs_dev_files(struct usb_device *udev) | |||
220 | return retval; | 220 | return retval; |
221 | 221 | ||
222 | if (udev->manufacturer) { | 222 | if (udev->manufacturer) { |
223 | retval = device_create_file (dev, &dev_attr_manufacturer); | 223 | retval = device_create_file(dev, &dev_attr_manufacturer); |
224 | if (retval) | 224 | if (retval) |
225 | goto error; | 225 | goto error; |
226 | } | 226 | } |
227 | if (udev->product) { | 227 | if (udev->product) { |
228 | retval = device_create_file (dev, &dev_attr_product); | 228 | retval = device_create_file(dev, &dev_attr_product); |
229 | if (retval) | 229 | if (retval) |
230 | goto error; | 230 | goto error; |
231 | } | 231 | } |
232 | if (udev->serial) { | 232 | if (udev->serial) { |
233 | retval = device_create_file (dev, &dev_attr_serial); | 233 | retval = device_create_file(dev, &dev_attr_serial); |
234 | if (retval) | 234 | if (retval) |
235 | goto error; | 235 | goto error; |
236 | } | 236 | } |
@@ -246,7 +246,7 @@ error: | |||
246 | return retval; | 246 | return retval; |
247 | } | 247 | } |
248 | 248 | ||
249 | void usb_remove_sysfs_dev_files (struct usb_device *udev) | 249 | void usb_remove_sysfs_dev_files(struct usb_device *udev) |
250 | { | 250 | { |
251 | struct device *dev = &udev->dev; | 251 | struct device *dev = &udev->dev; |
252 | 252 | ||
@@ -264,22 +264,22 @@ void usb_remove_sysfs_dev_files (struct usb_device *udev) | |||
264 | /* Interface fields */ | 264 | /* Interface fields */ |
265 | #define usb_intf_attr(field, format_string) \ | 265 | #define usb_intf_attr(field, format_string) \ |
266 | static ssize_t \ | 266 | static ssize_t \ |
267 | show_##field (struct device *dev, struct device_attribute *attr, \ | 267 | show_##field(struct device *dev, struct device_attribute *attr, \ |
268 | char *buf) \ | 268 | char *buf) \ |
269 | { \ | 269 | { \ |
270 | struct usb_interface *intf = to_usb_interface (dev); \ | 270 | struct usb_interface *intf = to_usb_interface(dev); \ |
271 | \ | 271 | \ |
272 | return sprintf (buf, format_string, \ | 272 | return sprintf(buf, format_string, \ |
273 | intf->cur_altsetting->desc.field); \ | 273 | intf->cur_altsetting->desc.field); \ |
274 | } \ | 274 | } \ |
275 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); | 275 | static DEVICE_ATTR(field, S_IRUGO, show_##field, NULL); |
276 | 276 | ||
277 | usb_intf_attr (bInterfaceNumber, "%02x\n") | 277 | usb_intf_attr(bInterfaceNumber, "%02x\n") |
278 | usb_intf_attr (bAlternateSetting, "%2d\n") | 278 | usb_intf_attr(bAlternateSetting, "%2d\n") |
279 | usb_intf_attr (bNumEndpoints, "%02x\n") | 279 | usb_intf_attr(bNumEndpoints, "%02x\n") |
280 | usb_intf_attr (bInterfaceClass, "%02x\n") | 280 | usb_intf_attr(bInterfaceClass, "%02x\n") |
281 | usb_intf_attr (bInterfaceSubClass, "%02x\n") | 281 | usb_intf_attr(bInterfaceSubClass, "%02x\n") |
282 | usb_intf_attr (bInterfaceProtocol, "%02x\n") | 282 | usb_intf_attr(bInterfaceProtocol, "%02x\n") |
283 | 283 | ||
284 | static ssize_t show_interface_string(struct device *dev, | 284 | static ssize_t show_interface_string(struct device *dev, |
285 | struct device_attribute *attr, char *buf) | 285 | struct device_attribute *attr, char *buf) |
@@ -288,8 +288,8 @@ static ssize_t show_interface_string(struct device *dev, | |||
288 | struct usb_device *udev; | 288 | struct usb_device *udev; |
289 | int len; | 289 | int len; |
290 | 290 | ||
291 | intf = to_usb_interface (dev); | 291 | intf = to_usb_interface(dev); |
292 | udev = interface_to_usbdev (intf); | 292 | udev = interface_to_usbdev(intf); |
293 | len = snprintf(buf, 256, "%s", intf->cur_altsetting->string); | 293 | len = snprintf(buf, 256, "%s", intf->cur_altsetting->string); |
294 | if (len < 0) | 294 | if (len < 0) |
295 | return 0; | 295 | return 0; |
@@ -384,7 +384,7 @@ error: | |||
384 | return retval; | 384 | return retval; |
385 | } | 385 | } |
386 | 386 | ||
387 | void usb_remove_sysfs_intf_files (struct usb_interface *intf) | 387 | void usb_remove_sysfs_intf_files(struct usb_interface *intf) |
388 | { | 388 | { |
389 | usb_remove_intf_ep_files(intf); | 389 | usb_remove_intf_ep_files(intf); |
390 | sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp); | 390 | sysfs_remove_group(&intf->dev.kobj, &intf_attr_grp); |
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 9801d08edacf..94ea9727ff55 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c | |||
@@ -235,16 +235,15 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
235 | 235 | ||
236 | urb->status = -EINPROGRESS; | 236 | urb->status = -EINPROGRESS; |
237 | urb->actual_length = 0; | 237 | urb->actual_length = 0; |
238 | urb->bandwidth = 0; | ||
239 | 238 | ||
240 | /* Lots of sanity checks, so HCDs can rely on clean data | 239 | /* Lots of sanity checks, so HCDs can rely on clean data |
241 | * and don't need to duplicate tests | 240 | * and don't need to duplicate tests |
242 | */ | 241 | */ |
243 | pipe = urb->pipe; | 242 | pipe = urb->pipe; |
244 | temp = usb_pipetype (pipe); | 243 | temp = usb_pipetype(pipe); |
245 | is_out = usb_pipeout (pipe); | 244 | is_out = usb_pipeout(pipe); |
246 | 245 | ||
247 | if (!usb_pipecontrol (pipe) && dev->state < USB_STATE_CONFIGURED) | 246 | if (!usb_pipecontrol(pipe) && dev->state < USB_STATE_CONFIGURED) |
248 | return -ENODEV; | 247 | return -ENODEV; |
249 | 248 | ||
250 | /* FIXME there should be a sharable lock protecting us against | 249 | /* FIXME there should be a sharable lock protecting us against |
@@ -253,11 +252,11 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
253 | * checks get made.) | 252 | * checks get made.) |
254 | */ | 253 | */ |
255 | 254 | ||
256 | max = usb_maxpacket (dev, pipe, is_out); | 255 | max = usb_maxpacket(dev, pipe, is_out); |
257 | if (max <= 0) { | 256 | if (max <= 0) { |
258 | dev_dbg(&dev->dev, | 257 | dev_dbg(&dev->dev, |
259 | "bogus endpoint ep%d%s in %s (bad maxpacket %d)\n", | 258 | "bogus endpoint ep%d%s in %s (bad maxpacket %d)\n", |
260 | usb_pipeendpoint (pipe), is_out ? "out" : "in", | 259 | usb_pipeendpoint(pipe), is_out ? "out" : "in", |
261 | __FUNCTION__, max); | 260 | __FUNCTION__, max); |
262 | return -EMSGSIZE; | 261 | return -EMSGSIZE; |
263 | } | 262 | } |
@@ -279,11 +278,11 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
279 | if (urb->number_of_packets <= 0) | 278 | if (urb->number_of_packets <= 0) |
280 | return -EINVAL; | 279 | return -EINVAL; |
281 | for (n = 0; n < urb->number_of_packets; n++) { | 280 | for (n = 0; n < urb->number_of_packets; n++) { |
282 | len = urb->iso_frame_desc [n].length; | 281 | len = urb->iso_frame_desc[n].length; |
283 | if (len < 0 || len > max) | 282 | if (len < 0 || len > max) |
284 | return -EMSGSIZE; | 283 | return -EMSGSIZE; |
285 | urb->iso_frame_desc [n].status = -EXDEV; | 284 | urb->iso_frame_desc[n].status = -EXDEV; |
286 | urb->iso_frame_desc [n].actual_length = 0; | 285 | urb->iso_frame_desc[n].actual_length = 0; |
287 | } | 286 | } |
288 | } | 287 | } |
289 | 288 | ||
@@ -322,7 +321,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
322 | 321 | ||
323 | /* fail if submitter gave bogus flags */ | 322 | /* fail if submitter gave bogus flags */ |
324 | if (urb->transfer_flags != orig_flags) { | 323 | if (urb->transfer_flags != orig_flags) { |
325 | err ("BOGUS urb flags, %x --> %x", | 324 | err("BOGUS urb flags, %x --> %x", |
326 | orig_flags, urb->transfer_flags); | 325 | orig_flags, urb->transfer_flags); |
327 | return -EINVAL; | 326 | return -EINVAL; |
328 | } | 327 | } |
@@ -373,7 +372,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
373 | urb->interval = temp; | 372 | urb->interval = temp; |
374 | } | 373 | } |
375 | 374 | ||
376 | return usb_hcd_submit_urb (urb, mem_flags); | 375 | return usb_hcd_submit_urb(urb, mem_flags); |
377 | } | 376 | } |
378 | 377 | ||
379 | /*-------------------------------------------------------------------*/ | 378 | /*-------------------------------------------------------------------*/ |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 02426d0b9a34..3db721cd557a 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -233,7 +233,7 @@ static void usb_autosuspend_work(struct work_struct *work) | |||
233 | * @parent: hub to which device is connected; null to allocate a root hub | 233 | * @parent: hub to which device is connected; null to allocate a root hub |
234 | * @bus: bus used to access the device | 234 | * @bus: bus used to access the device |
235 | * @port1: one-based index of port; ignored for root hubs | 235 | * @port1: one-based index of port; ignored for root hubs |
236 | * Context: !in_interrupt () | 236 | * Context: !in_interrupt() |
237 | * | 237 | * |
238 | * Only hub drivers (including virtual root hub drivers for host | 238 | * Only hub drivers (including virtual root hub drivers for host |
239 | * controllers) should ever call this. | 239 | * controllers) should ever call this. |
@@ -277,22 +277,22 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | |||
277 | * as stable: bus->busnum changes easily from modprobe order, | 277 | * as stable: bus->busnum changes easily from modprobe order, |
278 | * cardbus or pci hotplugging, and so on. | 278 | * cardbus or pci hotplugging, and so on. |
279 | */ | 279 | */ |
280 | if (unlikely (!parent)) { | 280 | if (unlikely(!parent)) { |
281 | dev->devpath [0] = '0'; | 281 | dev->devpath[0] = '0'; |
282 | 282 | ||
283 | dev->dev.parent = bus->controller; | 283 | dev->dev.parent = bus->controller; |
284 | sprintf (&dev->dev.bus_id[0], "usb%d", bus->busnum); | 284 | sprintf(&dev->dev.bus_id[0], "usb%d", bus->busnum); |
285 | } else { | 285 | } else { |
286 | /* match any labeling on the hubs; it's one-based */ | 286 | /* match any labeling on the hubs; it's one-based */ |
287 | if (parent->devpath [0] == '0') | 287 | if (parent->devpath[0] == '0') |
288 | snprintf (dev->devpath, sizeof dev->devpath, | 288 | snprintf(dev->devpath, sizeof dev->devpath, |
289 | "%d", port1); | 289 | "%d", port1); |
290 | else | 290 | else |
291 | snprintf (dev->devpath, sizeof dev->devpath, | 291 | snprintf(dev->devpath, sizeof dev->devpath, |
292 | "%s.%d", parent->devpath, port1); | 292 | "%s.%d", parent->devpath, port1); |
293 | 293 | ||
294 | dev->dev.parent = &parent->dev; | 294 | dev->dev.parent = &parent->dev; |
295 | sprintf (&dev->dev.bus_id[0], "%d-%s", | 295 | sprintf(&dev->dev.bus_id[0], "%d-%s", |
296 | bus->busnum, dev->devpath); | 296 | bus->busnum, dev->devpath); |
297 | 297 | ||
298 | /* hub driver sets up TT records */ | 298 | /* hub driver sets up TT records */ |
@@ -463,7 +463,7 @@ static struct usb_device *match_device(struct usb_device *dev, | |||
463 | /* see if this device matches */ | 463 | /* see if this device matches */ |
464 | if ((vendor_id == le16_to_cpu(dev->descriptor.idVendor)) && | 464 | if ((vendor_id == le16_to_cpu(dev->descriptor.idVendor)) && |
465 | (product_id == le16_to_cpu(dev->descriptor.idProduct))) { | 465 | (product_id == le16_to_cpu(dev->descriptor.idProduct))) { |
466 | dev_dbg (&dev->dev, "matched this device!\n"); | 466 | dev_dbg(&dev->dev, "matched this device!\n"); |
467 | ret_dev = usb_get_dev(dev); | 467 | ret_dev = usb_get_dev(dev); |
468 | goto exit; | 468 | goto exit; |
469 | } | 469 | } |
@@ -535,7 +535,7 @@ exit: | |||
535 | */ | 535 | */ |
536 | int usb_get_current_frame_number(struct usb_device *dev) | 536 | int usb_get_current_frame_number(struct usb_device *dev) |
537 | { | 537 | { |
538 | return usb_hcd_get_frame_number (dev); | 538 | return usb_hcd_get_frame_number(dev); |
539 | } | 539 | } |
540 | 540 | ||
541 | /*-------------------------------------------------------------------*/ | 541 | /*-------------------------------------------------------------------*/ |
@@ -593,7 +593,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size, | |||
593 | * | 593 | * |
594 | * When the buffer is no longer used, free it with usb_buffer_free(). | 594 | * When the buffer is no longer used, free it with usb_buffer_free(). |
595 | */ | 595 | */ |
596 | void *usb_buffer_alloc ( | 596 | void *usb_buffer_alloc( |
597 | struct usb_device *dev, | 597 | struct usb_device *dev, |
598 | size_t size, | 598 | size_t size, |
599 | gfp_t mem_flags, | 599 | gfp_t mem_flags, |
@@ -602,7 +602,7 @@ void *usb_buffer_alloc ( | |||
602 | { | 602 | { |
603 | if (!dev || !dev->bus) | 603 | if (!dev || !dev->bus) |
604 | return NULL; | 604 | return NULL; |
605 | return hcd_buffer_alloc (dev->bus, size, mem_flags, dma); | 605 | return hcd_buffer_alloc(dev->bus, size, mem_flags, dma); |
606 | } | 606 | } |
607 | 607 | ||
608 | /** | 608 | /** |
@@ -616,7 +616,7 @@ void *usb_buffer_alloc ( | |||
616 | * been allocated using usb_buffer_alloc(), and the parameters must match | 616 | * been allocated using usb_buffer_alloc(), and the parameters must match |
617 | * those provided in that allocation request. | 617 | * those provided in that allocation request. |
618 | */ | 618 | */ |
619 | void usb_buffer_free ( | 619 | void usb_buffer_free( |
620 | struct usb_device *dev, | 620 | struct usb_device *dev, |
621 | size_t size, | 621 | size_t size, |
622 | void *addr, | 622 | void *addr, |
@@ -627,7 +627,7 @@ void usb_buffer_free ( | |||
627 | return; | 627 | return; |
628 | if (!addr) | 628 | if (!addr) |
629 | return; | 629 | return; |
630 | hcd_buffer_free (dev->bus, size, addr, dma); | 630 | hcd_buffer_free(dev->bus, size, addr, dma); |
631 | } | 631 | } |
632 | 632 | ||
633 | /** | 633 | /** |
@@ -647,7 +647,7 @@ void usb_buffer_free ( | |||
647 | * Reverse the effect of this call with usb_buffer_unmap(). | 647 | * Reverse the effect of this call with usb_buffer_unmap(). |
648 | */ | 648 | */ |
649 | #if 0 | 649 | #if 0 |
650 | struct urb *usb_buffer_map (struct urb *urb) | 650 | struct urb *usb_buffer_map(struct urb *urb) |
651 | { | 651 | { |
652 | struct usb_bus *bus; | 652 | struct usb_bus *bus; |
653 | struct device *controller; | 653 | struct device *controller; |
@@ -659,14 +659,14 @@ struct urb *usb_buffer_map (struct urb *urb) | |||
659 | return NULL; | 659 | return NULL; |
660 | 660 | ||
661 | if (controller->dma_mask) { | 661 | if (controller->dma_mask) { |
662 | urb->transfer_dma = dma_map_single (controller, | 662 | urb->transfer_dma = dma_map_single(controller, |
663 | urb->transfer_buffer, urb->transfer_buffer_length, | 663 | urb->transfer_buffer, urb->transfer_buffer_length, |
664 | usb_pipein (urb->pipe) | 664 | usb_pipein(urb->pipe) |
665 | ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 665 | ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
666 | if (usb_pipecontrol (urb->pipe)) | 666 | if (usb_pipecontrol(urb->pipe)) |
667 | urb->setup_dma = dma_map_single (controller, | 667 | urb->setup_dma = dma_map_single(controller, |
668 | urb->setup_packet, | 668 | urb->setup_packet, |
669 | sizeof (struct usb_ctrlrequest), | 669 | sizeof(struct usb_ctrlrequest), |
670 | DMA_TO_DEVICE); | 670 | DMA_TO_DEVICE); |
671 | // FIXME generic api broken like pci, can't report errors | 671 | // FIXME generic api broken like pci, can't report errors |
672 | // if (urb->transfer_dma == DMA_ADDR_INVALID) return 0; | 672 | // if (urb->transfer_dma == DMA_ADDR_INVALID) return 0; |
@@ -689,7 +689,7 @@ struct urb *usb_buffer_map (struct urb *urb) | |||
689 | * usb_buffer_dmasync - synchronize DMA and CPU view of buffer(s) | 689 | * usb_buffer_dmasync - synchronize DMA and CPU view of buffer(s) |
690 | * @urb: urb whose transfer_buffer/setup_packet will be synchronized | 690 | * @urb: urb whose transfer_buffer/setup_packet will be synchronized |
691 | */ | 691 | */ |
692 | void usb_buffer_dmasync (struct urb *urb) | 692 | void usb_buffer_dmasync(struct urb *urb) |
693 | { | 693 | { |
694 | struct usb_bus *bus; | 694 | struct usb_bus *bus; |
695 | struct device *controller; | 695 | struct device *controller; |
@@ -702,14 +702,14 @@ void usb_buffer_dmasync (struct urb *urb) | |||
702 | return; | 702 | return; |
703 | 703 | ||
704 | if (controller->dma_mask) { | 704 | if (controller->dma_mask) { |
705 | dma_sync_single (controller, | 705 | dma_sync_single(controller, |
706 | urb->transfer_dma, urb->transfer_buffer_length, | 706 | urb->transfer_dma, urb->transfer_buffer_length, |
707 | usb_pipein (urb->pipe) | 707 | usb_pipein(urb->pipe) |
708 | ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 708 | ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
709 | if (usb_pipecontrol (urb->pipe)) | 709 | if (usb_pipecontrol(urb->pipe)) |
710 | dma_sync_single (controller, | 710 | dma_sync_single(controller, |
711 | urb->setup_dma, | 711 | urb->setup_dma, |
712 | sizeof (struct usb_ctrlrequest), | 712 | sizeof(struct usb_ctrlrequest), |
713 | DMA_TO_DEVICE); | 713 | DMA_TO_DEVICE); |
714 | } | 714 | } |
715 | } | 715 | } |
@@ -722,7 +722,7 @@ void usb_buffer_dmasync (struct urb *urb) | |||
722 | * Reverses the effect of usb_buffer_map(). | 722 | * Reverses the effect of usb_buffer_map(). |
723 | */ | 723 | */ |
724 | #if 0 | 724 | #if 0 |
725 | void usb_buffer_unmap (struct urb *urb) | 725 | void usb_buffer_unmap(struct urb *urb) |
726 | { | 726 | { |
727 | struct usb_bus *bus; | 727 | struct usb_bus *bus; |
728 | struct device *controller; | 728 | struct device *controller; |
@@ -735,14 +735,14 @@ void usb_buffer_unmap (struct urb *urb) | |||
735 | return; | 735 | return; |
736 | 736 | ||
737 | if (controller->dma_mask) { | 737 | if (controller->dma_mask) { |
738 | dma_unmap_single (controller, | 738 | dma_unmap_single(controller, |
739 | urb->transfer_dma, urb->transfer_buffer_length, | 739 | urb->transfer_dma, urb->transfer_buffer_length, |
740 | usb_pipein (urb->pipe) | 740 | usb_pipein(urb->pipe) |
741 | ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 741 | ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
742 | if (usb_pipecontrol (urb->pipe)) | 742 | if (usb_pipecontrol(urb->pipe)) |
743 | dma_unmap_single (controller, | 743 | dma_unmap_single(controller, |
744 | urb->setup_dma, | 744 | urb->setup_dma, |
745 | sizeof (struct usb_ctrlrequest), | 745 | sizeof(struct usb_ctrlrequest), |
746 | DMA_TO_DEVICE); | 746 | DMA_TO_DEVICE); |
747 | } | 747 | } |
748 | urb->transfer_flags &= ~(URB_NO_TRANSFER_DMA_MAP | 748 | urb->transfer_flags &= ~(URB_NO_TRANSFER_DMA_MAP |
@@ -783,15 +783,15 @@ int usb_buffer_map_sg(const struct usb_device *dev, unsigned pipe, | |||
783 | struct device *controller; | 783 | struct device *controller; |
784 | 784 | ||
785 | if (!dev | 785 | if (!dev |
786 | || usb_pipecontrol (pipe) | 786 | || usb_pipecontrol(pipe) |
787 | || !(bus = dev->bus) | 787 | || !(bus = dev->bus) |
788 | || !(controller = bus->controller) | 788 | || !(controller = bus->controller) |
789 | || !controller->dma_mask) | 789 | || !controller->dma_mask) |
790 | return -1; | 790 | return -1; |
791 | 791 | ||
792 | // FIXME generic api broken like pci, can't report errors | 792 | // FIXME generic api broken like pci, can't report errors |
793 | return dma_map_sg (controller, sg, nents, | 793 | return dma_map_sg(controller, sg, nents, |
794 | usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 794 | usb_pipein(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
795 | } | 795 | } |
796 | 796 | ||
797 | /* XXX DISABLED, no users currently. If you wish to re-enable this | 797 | /* XXX DISABLED, no users currently. If you wish to re-enable this |
@@ -823,8 +823,8 @@ void usb_buffer_dmasync_sg(const struct usb_device *dev, unsigned pipe, | |||
823 | || !controller->dma_mask) | 823 | || !controller->dma_mask) |
824 | return; | 824 | return; |
825 | 825 | ||
826 | dma_sync_sg (controller, sg, n_hw_ents, | 826 | dma_sync_sg(controller, sg, n_hw_ents, |
827 | usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 827 | usb_pipein(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
828 | } | 828 | } |
829 | #endif | 829 | #endif |
830 | 830 | ||
@@ -849,8 +849,8 @@ void usb_buffer_unmap_sg(const struct usb_device *dev, unsigned pipe, | |||
849 | || !controller->dma_mask) | 849 | || !controller->dma_mask) |
850 | return; | 850 | return; |
851 | 851 | ||
852 | dma_unmap_sg (controller, sg, n_hw_ents, | 852 | dma_unmap_sg(controller, sg, n_hw_ents, |
853 | usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 853 | usb_pipein(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
854 | } | 854 | } |
855 | 855 | ||
856 | /* format to disable USB on kernel command line is: nousb */ | 856 | /* format to disable USB on kernel command line is: nousb */ |
@@ -871,7 +871,7 @@ static int __init usb_init(void) | |||
871 | { | 871 | { |
872 | int retval; | 872 | int retval; |
873 | if (nousb) { | 873 | if (nousb) { |
874 | pr_info ("%s: USB support disabled\n", usbcore_name); | 874 | pr_info("%s: USB support disabled\n", usbcore_name); |
875 | return 0; | 875 | return 0; |
876 | } | 876 | } |
877 | 877 | ||
@@ -971,19 +971,19 @@ EXPORT_SYMBOL(__usb_get_extra_descriptor); | |||
971 | EXPORT_SYMBOL(usb_find_device); | 971 | EXPORT_SYMBOL(usb_find_device); |
972 | EXPORT_SYMBOL(usb_get_current_frame_number); | 972 | EXPORT_SYMBOL(usb_get_current_frame_number); |
973 | 973 | ||
974 | EXPORT_SYMBOL (usb_buffer_alloc); | 974 | EXPORT_SYMBOL(usb_buffer_alloc); |
975 | EXPORT_SYMBOL (usb_buffer_free); | 975 | EXPORT_SYMBOL(usb_buffer_free); |
976 | 976 | ||
977 | #if 0 | 977 | #if 0 |
978 | EXPORT_SYMBOL (usb_buffer_map); | 978 | EXPORT_SYMBOL(usb_buffer_map); |
979 | EXPORT_SYMBOL (usb_buffer_dmasync); | 979 | EXPORT_SYMBOL(usb_buffer_dmasync); |
980 | EXPORT_SYMBOL (usb_buffer_unmap); | 980 | EXPORT_SYMBOL(usb_buffer_unmap); |
981 | #endif | 981 | #endif |
982 | 982 | ||
983 | EXPORT_SYMBOL (usb_buffer_map_sg); | 983 | EXPORT_SYMBOL(usb_buffer_map_sg); |
984 | #if 0 | 984 | #if 0 |
985 | EXPORT_SYMBOL (usb_buffer_dmasync_sg); | 985 | EXPORT_SYMBOL(usb_buffer_dmasync_sg); |
986 | #endif | 986 | #endif |
987 | EXPORT_SYMBOL (usb_buffer_unmap_sg); | 987 | EXPORT_SYMBOL(usb_buffer_unmap_sg); |
988 | 988 | ||
989 | MODULE_LICENSE("GPL"); | 989 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 72f3db99ff94..f39050145f1f 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -39,18 +39,20 @@ | |||
39 | #include <linux/interrupt.h> | 39 | #include <linux/interrupt.h> |
40 | #include <linux/proc_fs.h> | 40 | #include <linux/proc_fs.h> |
41 | #include <linux/clk.h> | 41 | #include <linux/clk.h> |
42 | #include <linux/usb_ch9.h> | 42 | #include <linux/usb/ch9.h> |
43 | #include <linux/usb_gadget.h> | 43 | #include <linux/usb_gadget.h> |
44 | 44 | ||
45 | #include <asm/byteorder.h> | 45 | #include <asm/byteorder.h> |
46 | #include <asm/hardware.h> | ||
46 | #include <asm/io.h> | 47 | #include <asm/io.h> |
47 | #include <asm/irq.h> | 48 | #include <asm/irq.h> |
48 | #include <asm/system.h> | 49 | #include <asm/system.h> |
49 | #include <asm/mach-types.h> | 50 | #include <asm/mach-types.h> |
50 | 51 | ||
51 | #include <asm/arch/hardware.h> | ||
52 | #include <asm/arch/gpio.h> | 52 | #include <asm/arch/gpio.h> |
53 | #include <asm/arch/board.h> | 53 | #include <asm/arch/board.h> |
54 | #include <asm/arch/cpu.h> | ||
55 | #include <asm/arch/at91sam9261_matrix.h> | ||
54 | 56 | ||
55 | #include "at91_udc.h" | 57 | #include "at91_udc.h" |
56 | 58 | ||
@@ -78,27 +80,11 @@ | |||
78 | static const char driver_name [] = "at91_udc"; | 80 | static const char driver_name [] = "at91_udc"; |
79 | static const char ep0name[] = "ep0"; | 81 | static const char ep0name[] = "ep0"; |
80 | 82 | ||
81 | /*-------------------------------------------------------------------------*/ | ||
82 | |||
83 | /* | ||
84 | * Read from a UDP register. | ||
85 | */ | ||
86 | static inline unsigned long at91_udp_read(unsigned int reg) | ||
87 | { | ||
88 | void __iomem *udp_base = (void __iomem *)AT91_VA_BASE_UDP; | ||
89 | 83 | ||
90 | return __raw_readl(udp_base + reg); | 84 | #define at91_udp_read(dev, reg) \ |
91 | } | 85 | __raw_readl((dev)->udp_baseaddr + (reg)) |
92 | 86 | #define at91_udp_write(dev, reg, val) \ | |
93 | /* | 87 | __raw_writel((val), (dev)->udp_baseaddr + (reg)) |
94 | * Write to a UDP register. | ||
95 | */ | ||
96 | static inline void at91_udp_write(unsigned int reg, unsigned long value) | ||
97 | { | ||
98 | void __iomem *udp_base = (void __iomem *)AT91_VA_BASE_UDP; | ||
99 | |||
100 | __raw_writel(value, udp_base + reg); | ||
101 | } | ||
102 | 88 | ||
103 | /*-------------------------------------------------------------------------*/ | 89 | /*-------------------------------------------------------------------------*/ |
104 | 90 | ||
@@ -210,13 +196,13 @@ static int proc_udc_show(struct seq_file *s, void *unused) | |||
210 | return 0; | 196 | return 0; |
211 | } | 197 | } |
212 | 198 | ||
213 | tmp = at91_udp_read(AT91_UDP_FRM_NUM); | 199 | tmp = at91_udp_read(udc, AT91_UDP_FRM_NUM); |
214 | seq_printf(s, "frame %05x:%s%s frame=%d\n", tmp, | 200 | seq_printf(s, "frame %05x:%s%s frame=%d\n", tmp, |
215 | (tmp & AT91_UDP_FRM_OK) ? " ok" : "", | 201 | (tmp & AT91_UDP_FRM_OK) ? " ok" : "", |
216 | (tmp & AT91_UDP_FRM_ERR) ? " err" : "", | 202 | (tmp & AT91_UDP_FRM_ERR) ? " err" : "", |
217 | (tmp & AT91_UDP_NUM)); | 203 | (tmp & AT91_UDP_NUM)); |
218 | 204 | ||
219 | tmp = at91_udp_read(AT91_UDP_GLB_STAT); | 205 | tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT); |
220 | seq_printf(s, "glbstate %02x:%s" FOURBITS "\n", tmp, | 206 | seq_printf(s, "glbstate %02x:%s" FOURBITS "\n", tmp, |
221 | (tmp & AT91_UDP_RMWUPE) ? " rmwupe" : "", | 207 | (tmp & AT91_UDP_RMWUPE) ? " rmwupe" : "", |
222 | (tmp & AT91_UDP_RSMINPR) ? " rsminpr" : "", | 208 | (tmp & AT91_UDP_RSMINPR) ? " rsminpr" : "", |
@@ -224,13 +210,13 @@ static int proc_udc_show(struct seq_file *s, void *unused) | |||
224 | (tmp & AT91_UDP_CONFG) ? " confg" : "", | 210 | (tmp & AT91_UDP_CONFG) ? " confg" : "", |
225 | (tmp & AT91_UDP_FADDEN) ? " fadden" : ""); | 211 | (tmp & AT91_UDP_FADDEN) ? " fadden" : ""); |
226 | 212 | ||
227 | tmp = at91_udp_read(AT91_UDP_FADDR); | 213 | tmp = at91_udp_read(udc, AT91_UDP_FADDR); |
228 | seq_printf(s, "faddr %03x:%s fadd=%d\n", tmp, | 214 | seq_printf(s, "faddr %03x:%s fadd=%d\n", tmp, |
229 | (tmp & AT91_UDP_FEN) ? " fen" : "", | 215 | (tmp & AT91_UDP_FEN) ? " fen" : "", |
230 | (tmp & AT91_UDP_FADD)); | 216 | (tmp & AT91_UDP_FADD)); |
231 | 217 | ||
232 | proc_irq_show(s, "imr ", at91_udp_read(AT91_UDP_IMR)); | 218 | proc_irq_show(s, "imr ", at91_udp_read(udc, AT91_UDP_IMR)); |
233 | proc_irq_show(s, "isr ", at91_udp_read(AT91_UDP_ISR)); | 219 | proc_irq_show(s, "isr ", at91_udp_read(udc, AT91_UDP_ISR)); |
234 | 220 | ||
235 | if (udc->enabled && udc->vbus) { | 221 | if (udc->enabled && udc->vbus) { |
236 | proc_ep_show(s, &udc->ep[0]); | 222 | proc_ep_show(s, &udc->ep[0]); |
@@ -286,6 +272,7 @@ static inline void remove_debug_file(struct at91_udc *udc) {} | |||
286 | static void done(struct at91_ep *ep, struct at91_request *req, int status) | 272 | static void done(struct at91_ep *ep, struct at91_request *req, int status) |
287 | { | 273 | { |
288 | unsigned stopped = ep->stopped; | 274 | unsigned stopped = ep->stopped; |
275 | struct at91_udc *udc = ep->udc; | ||
289 | 276 | ||
290 | list_del_init(&req->queue); | 277 | list_del_init(&req->queue); |
291 | if (req->req.status == -EINPROGRESS) | 278 | if (req->req.status == -EINPROGRESS) |
@@ -301,7 +288,7 @@ static void done(struct at91_ep *ep, struct at91_request *req, int status) | |||
301 | 288 | ||
302 | /* ep0 is always ready; other endpoints need a non-empty queue */ | 289 | /* ep0 is always ready; other endpoints need a non-empty queue */ |
303 | if (list_empty(&ep->queue) && ep->int_mask != (1 << 0)) | 290 | if (list_empty(&ep->queue) && ep->int_mask != (1 << 0)) |
304 | at91_udp_write(AT91_UDP_IDR, ep->int_mask); | 291 | at91_udp_write(udc, AT91_UDP_IDR, ep->int_mask); |
305 | } | 292 | } |
306 | 293 | ||
307 | /*-------------------------------------------------------------------------*/ | 294 | /*-------------------------------------------------------------------------*/ |
@@ -554,8 +541,8 @@ ok: | |||
554 | * reset/init endpoint fifo. NOTE: leaves fifo_bank alone, | 541 | * reset/init endpoint fifo. NOTE: leaves fifo_bank alone, |
555 | * since endpoint resets don't reset hw pingpong state. | 542 | * since endpoint resets don't reset hw pingpong state. |
556 | */ | 543 | */ |
557 | at91_udp_write(AT91_UDP_RST_EP, ep->int_mask); | 544 | at91_udp_write(dev, AT91_UDP_RST_EP, ep->int_mask); |
558 | at91_udp_write(AT91_UDP_RST_EP, 0); | 545 | at91_udp_write(dev, AT91_UDP_RST_EP, 0); |
559 | 546 | ||
560 | local_irq_restore(flags); | 547 | local_irq_restore(flags); |
561 | return 0; | 548 | return 0; |
@@ -564,6 +551,7 @@ ok: | |||
564 | static int at91_ep_disable (struct usb_ep * _ep) | 551 | static int at91_ep_disable (struct usb_ep * _ep) |
565 | { | 552 | { |
566 | struct at91_ep *ep = container_of(_ep, struct at91_ep, ep); | 553 | struct at91_ep *ep = container_of(_ep, struct at91_ep, ep); |
554 | struct at91_udc *udc = ep->udc; | ||
567 | unsigned long flags; | 555 | unsigned long flags; |
568 | 556 | ||
569 | if (ep == &ep->udc->ep[0]) | 557 | if (ep == &ep->udc->ep[0]) |
@@ -579,8 +567,8 @@ static int at91_ep_disable (struct usb_ep * _ep) | |||
579 | 567 | ||
580 | /* reset fifos and endpoint */ | 568 | /* reset fifos and endpoint */ |
581 | if (ep->udc->clocked) { | 569 | if (ep->udc->clocked) { |
582 | at91_udp_write(AT91_UDP_RST_EP, ep->int_mask); | 570 | at91_udp_write(udc, AT91_UDP_RST_EP, ep->int_mask); |
583 | at91_udp_write(AT91_UDP_RST_EP, 0); | 571 | at91_udp_write(udc, AT91_UDP_RST_EP, 0); |
584 | __raw_writel(0, ep->creg); | 572 | __raw_writel(0, ep->creg); |
585 | } | 573 | } |
586 | 574 | ||
@@ -598,7 +586,7 @@ at91_ep_alloc_request(struct usb_ep *_ep, unsigned int gfp_flags) | |||
598 | { | 586 | { |
599 | struct at91_request *req; | 587 | struct at91_request *req; |
600 | 588 | ||
601 | req = kcalloc(1, sizeof (struct at91_request), gfp_flags); | 589 | req = kzalloc(sizeof (struct at91_request), gfp_flags); |
602 | if (!req) | 590 | if (!req) |
603 | return NULL; | 591 | return NULL; |
604 | 592 | ||
@@ -695,10 +683,10 @@ static int at91_ep_queue(struct usb_ep *_ep, | |||
695 | * reconfigures the endpoints. | 683 | * reconfigures the endpoints. |
696 | */ | 684 | */ |
697 | if (dev->wait_for_config_ack) { | 685 | if (dev->wait_for_config_ack) { |
698 | tmp = at91_udp_read(AT91_UDP_GLB_STAT); | 686 | tmp = at91_udp_read(dev, AT91_UDP_GLB_STAT); |
699 | tmp ^= AT91_UDP_CONFG; | 687 | tmp ^= AT91_UDP_CONFG; |
700 | VDBG("toggle config\n"); | 688 | VDBG("toggle config\n"); |
701 | at91_udp_write(AT91_UDP_GLB_STAT, tmp); | 689 | at91_udp_write(dev, AT91_UDP_GLB_STAT, tmp); |
702 | } | 690 | } |
703 | if (req->req.length == 0) { | 691 | if (req->req.length == 0) { |
704 | ep0_in_status: | 692 | ep0_in_status: |
@@ -727,7 +715,7 @@ ep0_in_status: | |||
727 | 715 | ||
728 | if (req && !status) { | 716 | if (req && !status) { |
729 | list_add_tail (&req->queue, &ep->queue); | 717 | list_add_tail (&req->queue, &ep->queue); |
730 | at91_udp_write(AT91_UDP_IER, ep->int_mask); | 718 | at91_udp_write(dev, AT91_UDP_IER, ep->int_mask); |
731 | } | 719 | } |
732 | done: | 720 | done: |
733 | local_irq_restore(flags); | 721 | local_irq_restore(flags); |
@@ -758,6 +746,7 @@ static int at91_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | |||
758 | static int at91_ep_set_halt(struct usb_ep *_ep, int value) | 746 | static int at91_ep_set_halt(struct usb_ep *_ep, int value) |
759 | { | 747 | { |
760 | struct at91_ep *ep = container_of(_ep, struct at91_ep, ep); | 748 | struct at91_ep *ep = container_of(_ep, struct at91_ep, ep); |
749 | struct at91_udc *udc = ep->udc; | ||
761 | u32 __iomem *creg; | 750 | u32 __iomem *creg; |
762 | u32 csr; | 751 | u32 csr; |
763 | unsigned long flags; | 752 | unsigned long flags; |
@@ -785,8 +774,8 @@ static int at91_ep_set_halt(struct usb_ep *_ep, int value) | |||
785 | csr |= AT91_UDP_FORCESTALL; | 774 | csr |= AT91_UDP_FORCESTALL; |
786 | VDBG("halt %s\n", ep->ep.name); | 775 | VDBG("halt %s\n", ep->ep.name); |
787 | } else { | 776 | } else { |
788 | at91_udp_write(AT91_UDP_RST_EP, ep->int_mask); | 777 | at91_udp_write(udc, AT91_UDP_RST_EP, ep->int_mask); |
789 | at91_udp_write(AT91_UDP_RST_EP, 0); | 778 | at91_udp_write(udc, AT91_UDP_RST_EP, 0); |
790 | csr &= ~AT91_UDP_FORCESTALL; | 779 | csr &= ~AT91_UDP_FORCESTALL; |
791 | } | 780 | } |
792 | __raw_writel(csr, creg); | 781 | __raw_writel(csr, creg); |
@@ -813,9 +802,11 @@ static struct usb_ep_ops at91_ep_ops = { | |||
813 | 802 | ||
814 | static int at91_get_frame(struct usb_gadget *gadget) | 803 | static int at91_get_frame(struct usb_gadget *gadget) |
815 | { | 804 | { |
805 | struct at91_udc *udc = to_udc(gadget); | ||
806 | |||
816 | if (!to_udc(gadget)->clocked) | 807 | if (!to_udc(gadget)->clocked) |
817 | return -EINVAL; | 808 | return -EINVAL; |
818 | return at91_udp_read(AT91_UDP_FRM_NUM) & AT91_UDP_NUM; | 809 | return at91_udp_read(udc, AT91_UDP_FRM_NUM) & AT91_UDP_NUM; |
819 | } | 810 | } |
820 | 811 | ||
821 | static int at91_wakeup(struct usb_gadget *gadget) | 812 | static int at91_wakeup(struct usb_gadget *gadget) |
@@ -833,11 +824,11 @@ static int at91_wakeup(struct usb_gadget *gadget) | |||
833 | 824 | ||
834 | /* NOTE: some "early versions" handle ESR differently ... */ | 825 | /* NOTE: some "early versions" handle ESR differently ... */ |
835 | 826 | ||
836 | glbstate = at91_udp_read(AT91_UDP_GLB_STAT); | 827 | glbstate = at91_udp_read(udc, AT91_UDP_GLB_STAT); |
837 | if (!(glbstate & AT91_UDP_ESR)) | 828 | if (!(glbstate & AT91_UDP_ESR)) |
838 | goto done; | 829 | goto done; |
839 | glbstate |= AT91_UDP_ESR; | 830 | glbstate |= AT91_UDP_ESR; |
840 | at91_udp_write(AT91_UDP_GLB_STAT, glbstate); | 831 | at91_udp_write(udc, AT91_UDP_GLB_STAT, glbstate); |
841 | 832 | ||
842 | done: | 833 | done: |
843 | local_irq_restore(flags); | 834 | local_irq_restore(flags); |
@@ -861,6 +852,7 @@ static void udc_reinit(struct at91_udc *udc) | |||
861 | ep->stopped = 0; | 852 | ep->stopped = 0; |
862 | ep->fifo_bank = 0; | 853 | ep->fifo_bank = 0; |
863 | ep->ep.maxpacket = ep->maxpacket; | 854 | ep->ep.maxpacket = ep->maxpacket; |
855 | ep->creg = (void __iomem *) udc->udp_baseaddr + AT91_UDP_CSR(i); | ||
864 | // initialiser une queue par endpoint | 856 | // initialiser une queue par endpoint |
865 | INIT_LIST_HEAD(&ep->queue); | 857 | INIT_LIST_HEAD(&ep->queue); |
866 | } | 858 | } |
@@ -915,14 +907,41 @@ static void pullup(struct at91_udc *udc, int is_on) | |||
915 | if (!udc->enabled || !udc->vbus) | 907 | if (!udc->enabled || !udc->vbus) |
916 | is_on = 0; | 908 | is_on = 0; |
917 | DBG("%sactive\n", is_on ? "" : "in"); | 909 | DBG("%sactive\n", is_on ? "" : "in"); |
910 | |||
918 | if (is_on) { | 911 | if (is_on) { |
919 | clk_on(udc); | 912 | clk_on(udc); |
920 | at91_udp_write(AT91_UDP_TXVC, 0); | 913 | at91_udp_write(udc, AT91_UDP_TXVC, 0); |
921 | at91_set_gpio_value(udc->board.pullup_pin, 1); | 914 | if (cpu_is_at91rm9200()) |
922 | } else { | 915 | at91_set_gpio_value(udc->board.pullup_pin, 1); |
916 | else if (cpu_is_at91sam9260()) { | ||
917 | u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); | ||
918 | |||
919 | txvc |= AT91_UDP_TXVC_PUON; | ||
920 | at91_udp_write(udc, AT91_UDP_TXVC, txvc); | ||
921 | } else if (cpu_is_at91sam9261()) { | ||
922 | u32 usbpucr; | ||
923 | |||
924 | usbpucr = at91_sys_read(AT91_MATRIX_USBPUCR); | ||
925 | usbpucr |= AT91_MATRIX_USBPUCR_PUON; | ||
926 | at91_sys_write(AT91_MATRIX_USBPUCR, usbpucr); | ||
927 | } | ||
928 | } else { | ||
923 | stop_activity(udc); | 929 | stop_activity(udc); |
924 | at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); | 930 | at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); |
925 | at91_set_gpio_value(udc->board.pullup_pin, 0); | 931 | if (cpu_is_at91rm9200()) |
932 | at91_set_gpio_value(udc->board.pullup_pin, 0); | ||
933 | else if (cpu_is_at91sam9260()) { | ||
934 | u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); | ||
935 | |||
936 | txvc &= ~AT91_UDP_TXVC_PUON; | ||
937 | at91_udp_write(udc, AT91_UDP_TXVC, txvc); | ||
938 | } else if (cpu_is_at91sam9261()) { | ||
939 | u32 usbpucr; | ||
940 | |||
941 | usbpucr = at91_sys_read(AT91_MATRIX_USBPUCR); | ||
942 | usbpucr &= ~AT91_MATRIX_USBPUCR_PUON; | ||
943 | at91_sys_write(AT91_MATRIX_USBPUCR, usbpucr); | ||
944 | } | ||
926 | clk_off(udc); | 945 | clk_off(udc); |
927 | } | 946 | } |
928 | } | 947 | } |
@@ -936,7 +955,10 @@ static int at91_vbus_session(struct usb_gadget *gadget, int is_active) | |||
936 | // VDBG("vbus %s\n", is_active ? "on" : "off"); | 955 | // VDBG("vbus %s\n", is_active ? "on" : "off"); |
937 | local_irq_save(flags); | 956 | local_irq_save(flags); |
938 | udc->vbus = (is_active != 0); | 957 | udc->vbus = (is_active != 0); |
939 | pullup(udc, is_active); | 958 | if (udc->driver) |
959 | pullup(udc, is_active); | ||
960 | else | ||
961 | pullup(udc, 0); | ||
940 | local_irq_restore(flags); | 962 | local_irq_restore(flags); |
941 | return 0; | 963 | return 0; |
942 | } | 964 | } |
@@ -1086,7 +1108,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) | |||
1086 | 1108 | ||
1087 | case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) | 1109 | case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) |
1088 | | USB_REQ_SET_CONFIGURATION: | 1110 | | USB_REQ_SET_CONFIGURATION: |
1089 | tmp = at91_udp_read(AT91_UDP_GLB_STAT) & AT91_UDP_CONFG; | 1111 | tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT) & AT91_UDP_CONFG; |
1090 | if (pkt.r.wValue) | 1112 | if (pkt.r.wValue) |
1091 | udc->wait_for_config_ack = (tmp == 0); | 1113 | udc->wait_for_config_ack = (tmp == 0); |
1092 | else | 1114 | else |
@@ -1103,7 +1125,7 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) | |||
1103 | case ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) | 1125 | case ((USB_DIR_IN|USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) |
1104 | | USB_REQ_GET_STATUS: | 1126 | | USB_REQ_GET_STATUS: |
1105 | tmp = (udc->selfpowered << USB_DEVICE_SELF_POWERED); | 1127 | tmp = (udc->selfpowered << USB_DEVICE_SELF_POWERED); |
1106 | if (at91_udp_read(AT91_UDP_GLB_STAT) & AT91_UDP_ESR) | 1128 | if (at91_udp_read(udc, AT91_UDP_GLB_STAT) & AT91_UDP_ESR) |
1107 | tmp |= (1 << USB_DEVICE_REMOTE_WAKEUP); | 1129 | tmp |= (1 << USB_DEVICE_REMOTE_WAKEUP); |
1108 | PACKET("get device status\n"); | 1130 | PACKET("get device status\n"); |
1109 | __raw_writeb(tmp, dreg); | 1131 | __raw_writeb(tmp, dreg); |
@@ -1114,17 +1136,17 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) | |||
1114 | | USB_REQ_SET_FEATURE: | 1136 | | USB_REQ_SET_FEATURE: |
1115 | if (w_value != USB_DEVICE_REMOTE_WAKEUP) | 1137 | if (w_value != USB_DEVICE_REMOTE_WAKEUP) |
1116 | goto stall; | 1138 | goto stall; |
1117 | tmp = at91_udp_read(AT91_UDP_GLB_STAT); | 1139 | tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT); |
1118 | tmp |= AT91_UDP_ESR; | 1140 | tmp |= AT91_UDP_ESR; |
1119 | at91_udp_write(AT91_UDP_GLB_STAT, tmp); | 1141 | at91_udp_write(udc, AT91_UDP_GLB_STAT, tmp); |
1120 | goto succeed; | 1142 | goto succeed; |
1121 | case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) | 1143 | case ((USB_TYPE_STANDARD|USB_RECIP_DEVICE) << 8) |
1122 | | USB_REQ_CLEAR_FEATURE: | 1144 | | USB_REQ_CLEAR_FEATURE: |
1123 | if (w_value != USB_DEVICE_REMOTE_WAKEUP) | 1145 | if (w_value != USB_DEVICE_REMOTE_WAKEUP) |
1124 | goto stall; | 1146 | goto stall; |
1125 | tmp = at91_udp_read(AT91_UDP_GLB_STAT); | 1147 | tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT); |
1126 | tmp &= ~AT91_UDP_ESR; | 1148 | tmp &= ~AT91_UDP_ESR; |
1127 | at91_udp_write(AT91_UDP_GLB_STAT, tmp); | 1149 | at91_udp_write(udc, AT91_UDP_GLB_STAT, tmp); |
1128 | goto succeed; | 1150 | goto succeed; |
1129 | 1151 | ||
1130 | /* | 1152 | /* |
@@ -1206,8 +1228,8 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) | |||
1206 | } else if (ep->is_in) | 1228 | } else if (ep->is_in) |
1207 | goto stall; | 1229 | goto stall; |
1208 | 1230 | ||
1209 | at91_udp_write(AT91_UDP_RST_EP, ep->int_mask); | 1231 | at91_udp_write(udc, AT91_UDP_RST_EP, ep->int_mask); |
1210 | at91_udp_write(AT91_UDP_RST_EP, 0); | 1232 | at91_udp_write(udc, AT91_UDP_RST_EP, 0); |
1211 | tmp = __raw_readl(ep->creg); | 1233 | tmp = __raw_readl(ep->creg); |
1212 | tmp |= CLR_FX; | 1234 | tmp |= CLR_FX; |
1213 | tmp &= ~(SET_FX | AT91_UDP_FORCESTALL); | 1235 | tmp &= ~(SET_FX | AT91_UDP_FORCESTALL); |
@@ -1222,7 +1244,10 @@ static void handle_setup(struct at91_udc *udc, struct at91_ep *ep, u32 csr) | |||
1222 | #undef w_length | 1244 | #undef w_length |
1223 | 1245 | ||
1224 | /* pass request up to the gadget driver */ | 1246 | /* pass request up to the gadget driver */ |
1225 | status = udc->driver->setup(&udc->gadget, &pkt.r); | 1247 | if (udc->driver) |
1248 | status = udc->driver->setup(&udc->gadget, &pkt.r); | ||
1249 | else | ||
1250 | status = -ENODEV; | ||
1226 | if (status < 0) { | 1251 | if (status < 0) { |
1227 | stall: | 1252 | stall: |
1228 | VDBG("req %02x.%02x protocol STALL; stat %d\n", | 1253 | VDBG("req %02x.%02x protocol STALL; stat %d\n", |
@@ -1300,13 +1325,13 @@ static void handle_ep0(struct at91_udc *udc) | |||
1300 | if (udc->wait_for_addr_ack) { | 1325 | if (udc->wait_for_addr_ack) { |
1301 | u32 tmp; | 1326 | u32 tmp; |
1302 | 1327 | ||
1303 | at91_udp_write(AT91_UDP_FADDR, | 1328 | at91_udp_write(udc, AT91_UDP_FADDR, |
1304 | AT91_UDP_FEN | udc->addr); | 1329 | AT91_UDP_FEN | udc->addr); |
1305 | tmp = at91_udp_read(AT91_UDP_GLB_STAT); | 1330 | tmp = at91_udp_read(udc, AT91_UDP_GLB_STAT); |
1306 | tmp &= ~AT91_UDP_FADDEN; | 1331 | tmp &= ~AT91_UDP_FADDEN; |
1307 | if (udc->addr) | 1332 | if (udc->addr) |
1308 | tmp |= AT91_UDP_FADDEN; | 1333 | tmp |= AT91_UDP_FADDEN; |
1309 | at91_udp_write(AT91_UDP_GLB_STAT, tmp); | 1334 | at91_udp_write(udc, AT91_UDP_GLB_STAT, tmp); |
1310 | 1335 | ||
1311 | udc->wait_for_addr_ack = 0; | 1336 | udc->wait_for_addr_ack = 0; |
1312 | VDBG("address %d\n", udc->addr); | 1337 | VDBG("address %d\n", udc->addr); |
@@ -1374,28 +1399,28 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc) | |||
1374 | while (rescans--) { | 1399 | while (rescans--) { |
1375 | u32 status; | 1400 | u32 status; |
1376 | 1401 | ||
1377 | status = at91_udp_read(AT91_UDP_ISR) | 1402 | status = at91_udp_read(udc, AT91_UDP_ISR) |
1378 | & at91_udp_read(AT91_UDP_IMR); | 1403 | & at91_udp_read(udc, AT91_UDP_IMR); |
1379 | if (!status) | 1404 | if (!status) |
1380 | break; | 1405 | break; |
1381 | 1406 | ||
1382 | /* USB reset irq: not maskable */ | 1407 | /* USB reset irq: not maskable */ |
1383 | if (status & AT91_UDP_ENDBUSRES) { | 1408 | if (status & AT91_UDP_ENDBUSRES) { |
1384 | at91_udp_write(AT91_UDP_IDR, ~MINIMUS_INTERRUPTUS); | 1409 | at91_udp_write(udc, AT91_UDP_IDR, ~MINIMUS_INTERRUPTUS); |
1385 | at91_udp_write(AT91_UDP_IER, MINIMUS_INTERRUPTUS); | 1410 | at91_udp_write(udc, AT91_UDP_IER, MINIMUS_INTERRUPTUS); |
1386 | /* Atmel code clears this irq twice */ | 1411 | /* Atmel code clears this irq twice */ |
1387 | at91_udp_write(AT91_UDP_ICR, AT91_UDP_ENDBUSRES); | 1412 | at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_ENDBUSRES); |
1388 | at91_udp_write(AT91_UDP_ICR, AT91_UDP_ENDBUSRES); | 1413 | at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_ENDBUSRES); |
1389 | VDBG("end bus reset\n"); | 1414 | VDBG("end bus reset\n"); |
1390 | udc->addr = 0; | 1415 | udc->addr = 0; |
1391 | stop_activity(udc); | 1416 | stop_activity(udc); |
1392 | 1417 | ||
1393 | /* enable ep0 */ | 1418 | /* enable ep0 */ |
1394 | at91_udp_write(AT91_UDP_CSR(0), | 1419 | at91_udp_write(udc, AT91_UDP_CSR(0), |
1395 | AT91_UDP_EPEDS | AT91_UDP_EPTYPE_CTRL); | 1420 | AT91_UDP_EPEDS | AT91_UDP_EPTYPE_CTRL); |
1396 | udc->gadget.speed = USB_SPEED_FULL; | 1421 | udc->gadget.speed = USB_SPEED_FULL; |
1397 | udc->suspended = 0; | 1422 | udc->suspended = 0; |
1398 | at91_udp_write(AT91_UDP_IER, AT91_UDP_EP(0)); | 1423 | at91_udp_write(udc, AT91_UDP_IER, AT91_UDP_EP(0)); |
1399 | 1424 | ||
1400 | /* | 1425 | /* |
1401 | * NOTE: this driver keeps clocks off unless the | 1426 | * NOTE: this driver keeps clocks off unless the |
@@ -1406,9 +1431,9 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc) | |||
1406 | 1431 | ||
1407 | /* host initiated suspend (3+ms bus idle) */ | 1432 | /* host initiated suspend (3+ms bus idle) */ |
1408 | } else if (status & AT91_UDP_RXSUSP) { | 1433 | } else if (status & AT91_UDP_RXSUSP) { |
1409 | at91_udp_write(AT91_UDP_IDR, AT91_UDP_RXSUSP); | 1434 | at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXSUSP); |
1410 | at91_udp_write(AT91_UDP_IER, AT91_UDP_RXRSM); | 1435 | at91_udp_write(udc, AT91_UDP_IER, AT91_UDP_RXRSM); |
1411 | at91_udp_write(AT91_UDP_ICR, AT91_UDP_RXSUSP); | 1436 | at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXSUSP); |
1412 | // VDBG("bus suspend\n"); | 1437 | // VDBG("bus suspend\n"); |
1413 | if (udc->suspended) | 1438 | if (udc->suspended) |
1414 | continue; | 1439 | continue; |
@@ -1425,9 +1450,9 @@ static irqreturn_t at91_udc_irq (int irq, void *_udc) | |||
1425 | 1450 | ||
1426 | /* host initiated resume */ | 1451 | /* host initiated resume */ |
1427 | } else if (status & AT91_UDP_RXRSM) { | 1452 | } else if (status & AT91_UDP_RXRSM) { |
1428 | at91_udp_write(AT91_UDP_IDR, AT91_UDP_RXRSM); | 1453 | at91_udp_write(udc, AT91_UDP_IDR, AT91_UDP_RXRSM); |
1429 | at91_udp_write(AT91_UDP_IER, AT91_UDP_RXSUSP); | 1454 | at91_udp_write(udc, AT91_UDP_IER, AT91_UDP_RXSUSP); |
1430 | at91_udp_write(AT91_UDP_ICR, AT91_UDP_RXRSM); | 1455 | at91_udp_write(udc, AT91_UDP_ICR, AT91_UDP_RXRSM); |
1431 | // VDBG("bus resume\n"); | 1456 | // VDBG("bus resume\n"); |
1432 | if (!udc->suspended) | 1457 | if (!udc->suspended) |
1433 | continue; | 1458 | continue; |
@@ -1485,8 +1510,6 @@ static struct at91_udc controller = { | |||
1485 | }, | 1510 | }, |
1486 | .udc = &controller, | 1511 | .udc = &controller, |
1487 | .maxpacket = 8, | 1512 | .maxpacket = 8, |
1488 | .creg = (void __iomem *)(AT91_VA_BASE_UDP | ||
1489 | + AT91_UDP_CSR(0)), | ||
1490 | .int_mask = 1 << 0, | 1513 | .int_mask = 1 << 0, |
1491 | }, | 1514 | }, |
1492 | .ep[1] = { | 1515 | .ep[1] = { |
@@ -1497,8 +1520,6 @@ static struct at91_udc controller = { | |||
1497 | .udc = &controller, | 1520 | .udc = &controller, |
1498 | .is_pingpong = 1, | 1521 | .is_pingpong = 1, |
1499 | .maxpacket = 64, | 1522 | .maxpacket = 64, |
1500 | .creg = (void __iomem *)(AT91_VA_BASE_UDP | ||
1501 | + AT91_UDP_CSR(1)), | ||
1502 | .int_mask = 1 << 1, | 1523 | .int_mask = 1 << 1, |
1503 | }, | 1524 | }, |
1504 | .ep[2] = { | 1525 | .ep[2] = { |
@@ -1509,8 +1530,6 @@ static struct at91_udc controller = { | |||
1509 | .udc = &controller, | 1530 | .udc = &controller, |
1510 | .is_pingpong = 1, | 1531 | .is_pingpong = 1, |
1511 | .maxpacket = 64, | 1532 | .maxpacket = 64, |
1512 | .creg = (void __iomem *)(AT91_VA_BASE_UDP | ||
1513 | + AT91_UDP_CSR(2)), | ||
1514 | .int_mask = 1 << 2, | 1533 | .int_mask = 1 << 2, |
1515 | }, | 1534 | }, |
1516 | .ep[3] = { | 1535 | .ep[3] = { |
@@ -1521,8 +1540,6 @@ static struct at91_udc controller = { | |||
1521 | }, | 1540 | }, |
1522 | .udc = &controller, | 1541 | .udc = &controller, |
1523 | .maxpacket = 8, | 1542 | .maxpacket = 8, |
1524 | .creg = (void __iomem *)(AT91_VA_BASE_UDP | ||
1525 | + AT91_UDP_CSR(3)), | ||
1526 | .int_mask = 1 << 3, | 1543 | .int_mask = 1 << 3, |
1527 | }, | 1544 | }, |
1528 | .ep[4] = { | 1545 | .ep[4] = { |
@@ -1533,8 +1550,6 @@ static struct at91_udc controller = { | |||
1533 | .udc = &controller, | 1550 | .udc = &controller, |
1534 | .is_pingpong = 1, | 1551 | .is_pingpong = 1, |
1535 | .maxpacket = 256, | 1552 | .maxpacket = 256, |
1536 | .creg = (void __iomem *)(AT91_VA_BASE_UDP | ||
1537 | + AT91_UDP_CSR(4)), | ||
1538 | .int_mask = 1 << 4, | 1553 | .int_mask = 1 << 4, |
1539 | }, | 1554 | }, |
1540 | .ep[5] = { | 1555 | .ep[5] = { |
@@ -1545,8 +1560,6 @@ static struct at91_udc controller = { | |||
1545 | .udc = &controller, | 1560 | .udc = &controller, |
1546 | .is_pingpong = 1, | 1561 | .is_pingpong = 1, |
1547 | .maxpacket = 256, | 1562 | .maxpacket = 256, |
1548 | .creg = (void __iomem *)(AT91_VA_BASE_UDP | ||
1549 | + AT91_UDP_CSR(5)), | ||
1550 | .int_mask = 1 << 5, | 1563 | .int_mask = 1 << 5, |
1551 | }, | 1564 | }, |
1552 | /* ep6 and ep7 are also reserved (custom silicon might use them) */ | 1565 | /* ep6 and ep7 are also reserved (custom silicon might use them) */ |
@@ -1572,9 +1585,8 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
1572 | int retval; | 1585 | int retval; |
1573 | 1586 | ||
1574 | if (!driver | 1587 | if (!driver |
1575 | || driver->speed != USB_SPEED_FULL | 1588 | || driver->speed < USB_SPEED_FULL |
1576 | || !driver->bind | 1589 | || !driver->bind |
1577 | || !driver->unbind | ||
1578 | || !driver->setup) { | 1590 | || !driver->setup) { |
1579 | DBG("bad parameter.\n"); | 1591 | DBG("bad parameter.\n"); |
1580 | return -EINVAL; | 1592 | return -EINVAL; |
@@ -1595,6 +1607,10 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
1595 | if (retval) { | 1607 | if (retval) { |
1596 | DBG("driver->bind() returned %d\n", retval); | 1608 | DBG("driver->bind() returned %d\n", retval); |
1597 | udc->driver = NULL; | 1609 | udc->driver = NULL; |
1610 | udc->gadget.dev.driver = NULL; | ||
1611 | udc->gadget.dev.driver_data = NULL; | ||
1612 | udc->enabled = 0; | ||
1613 | udc->selfpowered = 0; | ||
1598 | return retval; | 1614 | return retval; |
1599 | } | 1615 | } |
1600 | 1616 | ||
@@ -1611,12 +1627,12 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) | |||
1611 | { | 1627 | { |
1612 | struct at91_udc *udc = &controller; | 1628 | struct at91_udc *udc = &controller; |
1613 | 1629 | ||
1614 | if (!driver || driver != udc->driver) | 1630 | if (!driver || driver != udc->driver || !driver->unbind) |
1615 | return -EINVAL; | 1631 | return -EINVAL; |
1616 | 1632 | ||
1617 | local_irq_disable(); | 1633 | local_irq_disable(); |
1618 | udc->enabled = 0; | 1634 | udc->enabled = 0; |
1619 | at91_udp_write(AT91_UDP_IDR, ~0); | 1635 | at91_udp_write(udc, AT91_UDP_IDR, ~0); |
1620 | pullup(udc, 0); | 1636 | pullup(udc, 0); |
1621 | local_irq_enable(); | 1637 | local_irq_enable(); |
1622 | 1638 | ||
@@ -1641,6 +1657,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1641 | struct device *dev = &pdev->dev; | 1657 | struct device *dev = &pdev->dev; |
1642 | struct at91_udc *udc; | 1658 | struct at91_udc *udc; |
1643 | int retval; | 1659 | int retval; |
1660 | struct resource *res; | ||
1644 | 1661 | ||
1645 | if (!dev->platform_data) { | 1662 | if (!dev->platform_data) { |
1646 | /* small (so we copy it) but critical! */ | 1663 | /* small (so we copy it) but critical! */ |
@@ -1658,7 +1675,13 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1658 | return -ENODEV; | 1675 | return -ENODEV; |
1659 | } | 1676 | } |
1660 | 1677 | ||
1661 | if (!request_mem_region(AT91RM9200_BASE_UDP, SZ_16K, driver_name)) { | 1678 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1679 | if (!res) | ||
1680 | return -ENXIO; | ||
1681 | |||
1682 | if (!request_mem_region(res->start, | ||
1683 | res->end - res->start + 1, | ||
1684 | driver_name)) { | ||
1662 | DBG("someone's using UDC memory\n"); | 1685 | DBG("someone's using UDC memory\n"); |
1663 | return -EBUSY; | 1686 | return -EBUSY; |
1664 | } | 1687 | } |
@@ -1668,15 +1691,23 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1668 | udc->gadget.dev.parent = dev; | 1691 | udc->gadget.dev.parent = dev; |
1669 | udc->board = *(struct at91_udc_data *) dev->platform_data; | 1692 | udc->board = *(struct at91_udc_data *) dev->platform_data; |
1670 | udc->pdev = pdev; | 1693 | udc->pdev = pdev; |
1671 | udc_reinit(udc); | ||
1672 | udc->enabled = 0; | 1694 | udc->enabled = 0; |
1673 | 1695 | ||
1696 | udc->udp_baseaddr = ioremap(res->start, res->end - res->start + 1); | ||
1697 | if (!udc->udp_baseaddr) { | ||
1698 | release_mem_region(res->start, res->end - res->start + 1); | ||
1699 | return -ENOMEM; | ||
1700 | } | ||
1701 | |||
1702 | udc_reinit(udc); | ||
1703 | |||
1674 | /* get interface and function clocks */ | 1704 | /* get interface and function clocks */ |
1675 | udc->iclk = clk_get(dev, "udc_clk"); | 1705 | udc->iclk = clk_get(dev, "udc_clk"); |
1676 | udc->fclk = clk_get(dev, "udpck"); | 1706 | udc->fclk = clk_get(dev, "udpck"); |
1677 | if (IS_ERR(udc->iclk) || IS_ERR(udc->fclk)) { | 1707 | if (IS_ERR(udc->iclk) || IS_ERR(udc->fclk)) { |
1678 | DBG("clocks missing\n"); | 1708 | DBG("clocks missing\n"); |
1679 | return -ENODEV; | 1709 | retval = -ENODEV; |
1710 | goto fail0; | ||
1680 | } | 1711 | } |
1681 | 1712 | ||
1682 | retval = device_register(&udc->gadget.dev); | 1713 | retval = device_register(&udc->gadget.dev); |
@@ -1685,8 +1716,10 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1685 | 1716 | ||
1686 | /* don't do anything until we have both gadget driver and VBUS */ | 1717 | /* don't do anything until we have both gadget driver and VBUS */ |
1687 | clk_enable(udc->iclk); | 1718 | clk_enable(udc->iclk); |
1688 | at91_udp_write(AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); | 1719 | at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); |
1689 | at91_udp_write(AT91_UDP_IDR, 0xffffffff); | 1720 | at91_udp_write(udc, AT91_UDP_IDR, 0xffffffff); |
1721 | /* Clear all pending interrupts - UDP may be used by bootloader. */ | ||
1722 | at91_udp_write(udc, AT91_UDP_ICR, 0xffffffff); | ||
1690 | clk_disable(udc->iclk); | 1723 | clk_disable(udc->iclk); |
1691 | 1724 | ||
1692 | /* request UDC and maybe VBUS irqs */ | 1725 | /* request UDC and maybe VBUS irqs */ |
@@ -1698,6 +1731,11 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1698 | goto fail1; | 1731 | goto fail1; |
1699 | } | 1732 | } |
1700 | if (udc->board.vbus_pin > 0) { | 1733 | if (udc->board.vbus_pin > 0) { |
1734 | /* | ||
1735 | * Get the initial state of VBUS - we cannot expect | ||
1736 | * a pending interrupt. | ||
1737 | */ | ||
1738 | udc->vbus = at91_get_gpio_value(udc->board.vbus_pin); | ||
1701 | if (request_irq(udc->board.vbus_pin, at91_vbus_irq, | 1739 | if (request_irq(udc->board.vbus_pin, at91_vbus_irq, |
1702 | IRQF_DISABLED, driver_name, udc)) { | 1740 | IRQF_DISABLED, driver_name, udc)) { |
1703 | DBG("request vbus irq %d failed\n", | 1741 | DBG("request vbus irq %d failed\n", |
@@ -1720,7 +1758,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev) | |||
1720 | fail1: | 1758 | fail1: |
1721 | device_unregister(&udc->gadget.dev); | 1759 | device_unregister(&udc->gadget.dev); |
1722 | fail0: | 1760 | fail0: |
1723 | release_mem_region(AT91RM9200_BASE_UDP, SZ_16K); | 1761 | release_mem_region(res->start, res->end - res->start + 1); |
1724 | DBG("%s probe failed, %d\n", driver_name, retval); | 1762 | DBG("%s probe failed, %d\n", driver_name, retval); |
1725 | return retval; | 1763 | return retval; |
1726 | } | 1764 | } |
@@ -1728,13 +1766,14 @@ fail0: | |||
1728 | static int __devexit at91udc_remove(struct platform_device *pdev) | 1766 | static int __devexit at91udc_remove(struct platform_device *pdev) |
1729 | { | 1767 | { |
1730 | struct at91_udc *udc = platform_get_drvdata(pdev); | 1768 | struct at91_udc *udc = platform_get_drvdata(pdev); |
1769 | struct resource *res; | ||
1731 | 1770 | ||
1732 | DBG("remove\n"); | 1771 | DBG("remove\n"); |
1733 | 1772 | ||
1734 | pullup(udc, 0); | 1773 | if (udc->driver) |
1774 | return -EBUSY; | ||
1735 | 1775 | ||
1736 | if (udc->driver != 0) | 1776 | pullup(udc, 0); |
1737 | usb_gadget_unregister_driver(udc->driver); | ||
1738 | 1777 | ||
1739 | device_init_wakeup(&pdev->dev, 0); | 1778 | device_init_wakeup(&pdev->dev, 0); |
1740 | remove_debug_file(udc); | 1779 | remove_debug_file(udc); |
@@ -1742,7 +1781,10 @@ static int __devexit at91udc_remove(struct platform_device *pdev) | |||
1742 | free_irq(udc->board.vbus_pin, udc); | 1781 | free_irq(udc->board.vbus_pin, udc); |
1743 | free_irq(udc->udp_irq, udc); | 1782 | free_irq(udc->udp_irq, udc); |
1744 | device_unregister(&udc->gadget.dev); | 1783 | device_unregister(&udc->gadget.dev); |
1745 | release_mem_region(AT91RM9200_BASE_UDP, SZ_16K); | 1784 | |
1785 | iounmap(udc->udp_baseaddr); | ||
1786 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1787 | release_mem_region(res->start, res->end - res->start + 1); | ||
1746 | 1788 | ||
1747 | clk_put(udc->iclk); | 1789 | clk_put(udc->iclk); |
1748 | clk_put(udc->fclk); | 1790 | clk_put(udc->fclk); |
@@ -1765,16 +1807,13 @@ static int at91udc_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
1765 | || !wake | 1807 | || !wake |
1766 | || at91_suspend_entering_slow_clock()) { | 1808 | || at91_suspend_entering_slow_clock()) { |
1767 | pullup(udc, 0); | 1809 | pullup(udc, 0); |
1768 | disable_irq_wake(udc->udp_irq); | 1810 | wake = 0; |
1769 | } else | 1811 | } else |
1770 | enable_irq_wake(udc->udp_irq); | 1812 | enable_irq_wake(udc->udp_irq); |
1771 | 1813 | ||
1772 | if (udc->board.vbus_pin > 0) { | 1814 | udc->active_suspend = wake; |
1773 | if (wake) | 1815 | if (udc->board.vbus_pin > 0 && wake) |
1774 | enable_irq_wake(udc->board.vbus_pin); | 1816 | enable_irq_wake(udc->board.vbus_pin); |
1775 | else | ||
1776 | disable_irq_wake(udc->board.vbus_pin); | ||
1777 | } | ||
1778 | return 0; | 1817 | return 0; |
1779 | } | 1818 | } |
1780 | 1819 | ||
@@ -1782,8 +1821,14 @@ static int at91udc_resume(struct platform_device *pdev) | |||
1782 | { | 1821 | { |
1783 | struct at91_udc *udc = platform_get_drvdata(pdev); | 1822 | struct at91_udc *udc = platform_get_drvdata(pdev); |
1784 | 1823 | ||
1824 | if (udc->board.vbus_pin > 0 && udc->active_suspend) | ||
1825 | disable_irq_wake(udc->board.vbus_pin); | ||
1826 | |||
1785 | /* maybe reconnect to host; if so, clocks on */ | 1827 | /* maybe reconnect to host; if so, clocks on */ |
1786 | pullup(udc, 1); | 1828 | if (udc->active_suspend) |
1829 | disable_irq_wake(udc->udp_irq); | ||
1830 | else | ||
1831 | pullup(udc, 1); | ||
1787 | return 0; | 1832 | return 0; |
1788 | } | 1833 | } |
1789 | #else | 1834 | #else |
diff --git a/drivers/usb/gadget/at91_udc.h b/drivers/usb/gadget/at91_udc.h index 882af42e86cc..7e34e2f864f9 100644 --- a/drivers/usb/gadget/at91_udc.h +++ b/drivers/usb/gadget/at91_udc.h | |||
@@ -51,10 +51,10 @@ | |||
51 | #define AT91_UDP_EP(n) (1 << (n)) /* Endpoint Interrupt Status */ | 51 | #define AT91_UDP_EP(n) (1 << (n)) /* Endpoint Interrupt Status */ |
52 | #define AT91_UDP_RXSUSP (1 << 8) /* USB Suspend Interrupt Status */ | 52 | #define AT91_UDP_RXSUSP (1 << 8) /* USB Suspend Interrupt Status */ |
53 | #define AT91_UDP_RXRSM (1 << 9) /* USB Resume Interrupt Status */ | 53 | #define AT91_UDP_RXRSM (1 << 9) /* USB Resume Interrupt Status */ |
54 | #define AT91_UDP_EXTRSM (1 << 10) /* External Resume Interrupt Status */ | 54 | #define AT91_UDP_EXTRSM (1 << 10) /* External Resume Interrupt Status [AT91RM9200 only] */ |
55 | #define AT91_UDP_SOFINT (1 << 11) /* Start of Frame Interrupt Status */ | 55 | #define AT91_UDP_SOFINT (1 << 11) /* Start of Frame Interrupt Status */ |
56 | #define AT91_UDP_ENDBUSRES (1 << 12) /* End of Bus Reset Interrpt Status */ | 56 | #define AT91_UDP_ENDBUSRES (1 << 12) /* End of Bus Reset Interrpt Status */ |
57 | #define AT91_UDP_WAKEUP (1 << 13) /* USB Wakeup Interrupt Status */ | 57 | #define AT91_UDP_WAKEUP (1 << 13) /* USB Wakeup Interrupt Status [AT91RM9200 only] */ |
58 | 58 | ||
59 | #define AT91_UDP_ICR 0x20 /* Interrupt Clear Register */ | 59 | #define AT91_UDP_ICR 0x20 /* Interrupt Clear Register */ |
60 | #define AT91_UDP_RST_EP 0x28 /* Reset Endpoint Register */ | 60 | #define AT91_UDP_RST_EP 0x28 /* Reset Endpoint Register */ |
@@ -84,7 +84,7 @@ | |||
84 | 84 | ||
85 | #define AT91_UDP_TXVC 0x74 /* Transceiver Control Register */ | 85 | #define AT91_UDP_TXVC 0x74 /* Transceiver Control Register */ |
86 | #define AT91_UDP_TXVC_TXVDIS (1 << 8) /* Transceiver Disable */ | 86 | #define AT91_UDP_TXVC_TXVDIS (1 << 8) /* Transceiver Disable */ |
87 | 87 | #define AT91_UDP_TXVC_PUON (1 << 9) /* PullUp On [AT91SAM9260 only] */ | |
88 | 88 | ||
89 | /*-------------------------------------------------------------------------*/ | 89 | /*-------------------------------------------------------------------------*/ |
90 | 90 | ||
@@ -136,11 +136,13 @@ struct at91_udc { | |||
136 | unsigned wait_for_addr_ack:1; | 136 | unsigned wait_for_addr_ack:1; |
137 | unsigned wait_for_config_ack:1; | 137 | unsigned wait_for_config_ack:1; |
138 | unsigned selfpowered:1; | 138 | unsigned selfpowered:1; |
139 | unsigned active_suspend:1; | ||
139 | u8 addr; | 140 | u8 addr; |
140 | struct at91_udc_data board; | 141 | struct at91_udc_data board; |
141 | struct clk *iclk, *fclk; | 142 | struct clk *iclk, *fclk; |
142 | struct platform_device *pdev; | 143 | struct platform_device *pdev; |
143 | struct proc_dir_entry *pde; | 144 | struct proc_dir_entry *pde; |
145 | void __iomem *udp_baseaddr; | ||
144 | int udp_irq; | 146 | int udp_irq; |
145 | }; | 147 | }; |
146 | 148 | ||
diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c index 83b4866df9af..d18901b92cda 100644 --- a/drivers/usb/gadget/config.c +++ b/drivers/usb/gadget/config.c | |||
@@ -24,7 +24,7 @@ | |||
24 | #include <linux/string.h> | 24 | #include <linux/string.h> |
25 | #include <linux/device.h> | 25 | #include <linux/device.h> |
26 | 26 | ||
27 | #include <linux/usb_ch9.h> | 27 | #include <linux/usb/ch9.h> |
28 | #include <linux/usb_gadget.h> | 28 | #include <linux/usb_gadget.h> |
29 | 29 | ||
30 | 30 | ||
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index f1f32d7be5f9..3c2bc075ef4f 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -779,7 +779,7 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
779 | return -EINVAL; | 779 | return -EINVAL; |
780 | if (dum->driver) | 780 | if (dum->driver) |
781 | return -EBUSY; | 781 | return -EBUSY; |
782 | if (!driver->bind || !driver->unbind || !driver->setup | 782 | if (!driver->bind || !driver->setup |
783 | || driver->speed == USB_SPEED_UNKNOWN) | 783 | || driver->speed == USB_SPEED_UNKNOWN) |
784 | return -EINVAL; | 784 | return -EINVAL; |
785 | 785 | ||
@@ -837,7 +837,8 @@ usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
837 | err_bind_driver: | 837 | err_bind_driver: |
838 | driver_unregister (&driver->driver); | 838 | driver_unregister (&driver->driver); |
839 | err_register: | 839 | err_register: |
840 | driver->unbind (&dum->gadget); | 840 | if (driver->unbind) |
841 | driver->unbind (&dum->gadget); | ||
841 | spin_lock_irq (&dum->lock); | 842 | spin_lock_irq (&dum->lock); |
842 | dum->pullup = 0; | 843 | dum->pullup = 0; |
843 | set_link_state (dum); | 844 | set_link_state (dum); |
@@ -857,7 +858,7 @@ usb_gadget_unregister_driver (struct usb_gadget_driver *driver) | |||
857 | 858 | ||
858 | if (!dum) | 859 | if (!dum) |
859 | return -ENODEV; | 860 | return -ENODEV; |
860 | if (!driver || driver != dum->driver) | 861 | if (!driver || driver != dum->driver || !driver->unbind) |
861 | return -EINVAL; | 862 | return -EINVAL; |
862 | 863 | ||
863 | dev_dbg (udc_dev(dum), "unregister gadget driver '%s'\n", | 864 | dev_dbg (udc_dev(dum), "unregister gadget driver '%s'\n", |
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 53d584589c26..f28af06905a5 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #include <linux/ctype.h> | 27 | #include <linux/ctype.h> |
28 | #include <linux/string.h> | 28 | #include <linux/string.h> |
29 | 29 | ||
30 | #include <linux/usb_ch9.h> | 30 | #include <linux/usb/ch9.h> |
31 | #include <linux/usb_gadget.h> | 31 | #include <linux/usb_gadget.h> |
32 | 32 | ||
33 | #include "gadget_chips.h" | 33 | #include "gadget_chips.h" |
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index d15bf22b9a03..22e3c9443641 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c | |||
@@ -47,7 +47,7 @@ | |||
47 | #include <asm/uaccess.h> | 47 | #include <asm/uaccess.h> |
48 | #include <asm/unaligned.h> | 48 | #include <asm/unaligned.h> |
49 | 49 | ||
50 | #include <linux/usb_ch9.h> | 50 | #include <linux/usb/ch9.h> |
51 | #include <linux/usb/cdc.h> | 51 | #include <linux/usb/cdc.h> |
52 | #include <linux/usb_gadget.h> | 52 | #include <linux/usb_gadget.h> |
53 | 53 | ||
@@ -72,9 +72,18 @@ | |||
72 | * | 72 | * |
73 | * There's some hardware that can't talk CDC. We make that hardware | 73 | * There's some hardware that can't talk CDC. We make that hardware |
74 | * implement a "minimalist" vendor-agnostic CDC core: same framing, but | 74 | * implement a "minimalist" vendor-agnostic CDC core: same framing, but |
75 | * link-level setup only requires activating the configuration. | 75 | * link-level setup only requires activating the configuration. Only the |
76 | * Linux supports it, but other host operating systems may not. | 76 | * endpoint descriptors, and product/vendor IDs, are relevant; no control |
77 | * (This is a subset of CDC Ethernet.) | 77 | * operations are available. Linux supports it, but other host operating |
78 | * systems may not. (This is a subset of CDC Ethernet.) | ||
79 | * | ||
80 | * It turns out that if you add a few descriptors to that "CDC Subset", | ||
81 | * (Windows) host side drivers from MCCI can treat it as one submode of | ||
82 | * a proprietary scheme called "SAFE" ... without needing to know about | ||
83 | * specific product/vendor IDs. So we do that, making it easier to use | ||
84 | * those MS-Windows drivers. Those added descriptors make it resemble a | ||
85 | * CDC MDLM device, but they don't change device behavior at all. (See | ||
86 | * MCCI Engineering report 950198 "SAFE Networking Functions".) | ||
78 | * | 87 | * |
79 | * A third option is also in use. Rather than CDC Ethernet, or something | 88 | * A third option is also in use. Rather than CDC Ethernet, or something |
80 | * simpler, Microsoft pushes their own approach: RNDIS. The published | 89 | * simpler, Microsoft pushes their own approach: RNDIS. The published |
@@ -254,6 +263,10 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); | |||
254 | #define DEV_CONFIG_CDC | 263 | #define DEV_CONFIG_CDC |
255 | #endif | 264 | #endif |
256 | 265 | ||
266 | #ifdef CONFIG_USB_GADGET_S3C2410 | ||
267 | #define DEV_CONFIG_CDC | ||
268 | #endif | ||
269 | |||
257 | #ifdef CONFIG_USB_GADGET_AT91 | 270 | #ifdef CONFIG_USB_GADGET_AT91 |
258 | #define DEV_CONFIG_CDC | 271 | #define DEV_CONFIG_CDC |
259 | #endif | 272 | #endif |
@@ -266,6 +279,10 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); | |||
266 | #define DEV_CONFIG_CDC | 279 | #define DEV_CONFIG_CDC |
267 | #endif | 280 | #endif |
268 | 281 | ||
282 | #ifdef CONFIG_USB_GADGET_HUSB2DEV | ||
283 | #define DEV_CONFIG_CDC | ||
284 | #endif | ||
285 | |||
269 | 286 | ||
270 | /* For CDC-incapable hardware, choose the simple cdc subset. | 287 | /* For CDC-incapable hardware, choose the simple cdc subset. |
271 | * Anything that talks bulk (without notable bugs) can do this. | 288 | * Anything that talks bulk (without notable bugs) can do this. |
@@ -283,9 +300,6 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); | |||
283 | #define DEV_CONFIG_SUBSET | 300 | #define DEV_CONFIG_SUBSET |
284 | #endif | 301 | #endif |
285 | 302 | ||
286 | #ifdef CONFIG_USB_GADGET_S3C2410 | ||
287 | #define DEV_CONFIG_CDC | ||
288 | #endif | ||
289 | 303 | ||
290 | /*-------------------------------------------------------------------------*/ | 304 | /*-------------------------------------------------------------------------*/ |
291 | 305 | ||
@@ -487,8 +501,17 @@ rndis_config = { | |||
487 | * endpoint. Both have a "data" interface and two bulk endpoints. | 501 | * endpoint. Both have a "data" interface and two bulk endpoints. |
488 | * There are also differences in how control requests are handled. | 502 | * There are also differences in how control requests are handled. |
489 | * | 503 | * |
490 | * RNDIS shares a lot with CDC-Ethernet, since it's a variant of | 504 | * RNDIS shares a lot with CDC-Ethernet, since it's a variant of the |
491 | * the CDC-ACM (modem) spec. | 505 | * CDC-ACM (modem) spec. Unfortunately MSFT's RNDIS driver is buggy; it |
506 | * may hang or oops. Since bugfixes (or accurate specs, letting Linux | ||
507 | * work around those bugs) are unlikely to ever come from MSFT, you may | ||
508 | * wish to avoid using RNDIS. | ||
509 | * | ||
510 | * MCCI offers an alternative to RNDIS if you need to connect to Windows | ||
511 | * but have hardware that can't support CDC Ethernet. We add descriptors | ||
512 | * to present the CDC Subset as a (nonconformant) CDC MDLM variant called | ||
513 | * "SAFE". That borrows from both CDC Ethernet and CDC MDLM. You can | ||
514 | * get those drivers from MCCI, or bundled with various products. | ||
492 | */ | 515 | */ |
493 | 516 | ||
494 | #ifdef DEV_CONFIG_CDC | 517 | #ifdef DEV_CONFIG_CDC |
@@ -522,8 +545,6 @@ rndis_control_intf = { | |||
522 | }; | 545 | }; |
523 | #endif | 546 | #endif |
524 | 547 | ||
525 | #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) | ||
526 | |||
527 | static const struct usb_cdc_header_desc header_desc = { | 548 | static const struct usb_cdc_header_desc header_desc = { |
528 | .bLength = sizeof header_desc, | 549 | .bLength = sizeof header_desc, |
529 | .bDescriptorType = USB_DT_CS_INTERFACE, | 550 | .bDescriptorType = USB_DT_CS_INTERFACE, |
@@ -532,6 +553,8 @@ static const struct usb_cdc_header_desc header_desc = { | |||
532 | .bcdCDC = __constant_cpu_to_le16 (0x0110), | 553 | .bcdCDC = __constant_cpu_to_le16 (0x0110), |
533 | }; | 554 | }; |
534 | 555 | ||
556 | #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) | ||
557 | |||
535 | static const struct usb_cdc_union_desc union_desc = { | 558 | static const struct usb_cdc_union_desc union_desc = { |
536 | .bLength = sizeof union_desc, | 559 | .bLength = sizeof union_desc, |
537 | .bDescriptorType = USB_DT_CS_INTERFACE, | 560 | .bDescriptorType = USB_DT_CS_INTERFACE, |
@@ -564,7 +587,40 @@ static const struct usb_cdc_acm_descriptor acm_descriptor = { | |||
564 | 587 | ||
565 | #endif | 588 | #endif |
566 | 589 | ||
567 | #ifdef DEV_CONFIG_CDC | 590 | #ifndef DEV_CONFIG_CDC |
591 | |||
592 | /* "SAFE" loosely follows CDC WMC MDLM, violating the spec in various | ||
593 | * ways: data endpoints live in the control interface, there's no data | ||
594 | * interface, and it's not used to talk to a cell phone radio. | ||
595 | */ | ||
596 | |||
597 | static const struct usb_cdc_mdlm_desc mdlm_desc = { | ||
598 | .bLength = sizeof mdlm_desc, | ||
599 | .bDescriptorType = USB_DT_CS_INTERFACE, | ||
600 | .bDescriptorSubType = USB_CDC_MDLM_TYPE, | ||
601 | |||
602 | .bcdVersion = __constant_cpu_to_le16(0x0100), | ||
603 | .bGUID = { | ||
604 | 0x5d, 0x34, 0xcf, 0x66, 0x11, 0x18, 0x11, 0xd6, | ||
605 | 0xa2, 0x1a, 0x00, 0x01, 0x02, 0xca, 0x9a, 0x7f, | ||
606 | }, | ||
607 | }; | ||
608 | |||
609 | /* since "usb_cdc_mdlm_detail_desc" is a variable length structure, we | ||
610 | * can't really use its struct. All we do here is say that we're using | ||
611 | * the submode of "SAFE" which directly matches the CDC Subset. | ||
612 | */ | ||
613 | static const u8 mdlm_detail_desc[] = { | ||
614 | 6, | ||
615 | USB_DT_CS_INTERFACE, | ||
616 | USB_CDC_MDLM_DETAIL_TYPE, | ||
617 | |||
618 | 0, /* "SAFE" */ | ||
619 | 0, /* network control capabilities (none) */ | ||
620 | 0, /* network data capabilities ("raw" encapsulation) */ | ||
621 | }; | ||
622 | |||
623 | #endif | ||
568 | 624 | ||
569 | static const struct usb_cdc_ether_desc ether_desc = { | 625 | static const struct usb_cdc_ether_desc ether_desc = { |
570 | .bLength = sizeof ether_desc, | 626 | .bLength = sizeof ether_desc, |
@@ -579,7 +635,6 @@ static const struct usb_cdc_ether_desc ether_desc = { | |||
579 | .bNumberPowerFilters = 0, | 635 | .bNumberPowerFilters = 0, |
580 | }; | 636 | }; |
581 | 637 | ||
582 | #endif | ||
583 | 638 | ||
584 | #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) | 639 | #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) |
585 | 640 | ||
@@ -672,6 +727,9 @@ rndis_data_intf = { | |||
672 | /* | 727 | /* |
673 | * "Simple" CDC-subset option is a simple vendor-neutral model that most | 728 | * "Simple" CDC-subset option is a simple vendor-neutral model that most |
674 | * full speed controllers can handle: one interface, two bulk endpoints. | 729 | * full speed controllers can handle: one interface, two bulk endpoints. |
730 | * | ||
731 | * To assist host side drivers, we fancy it up a bit, and add descriptors | ||
732 | * so some host side drivers will understand it as a "SAFE" variant. | ||
675 | */ | 733 | */ |
676 | 734 | ||
677 | static const struct usb_interface_descriptor | 735 | static const struct usb_interface_descriptor |
@@ -682,8 +740,8 @@ subset_data_intf = { | |||
682 | .bInterfaceNumber = 0, | 740 | .bInterfaceNumber = 0, |
683 | .bAlternateSetting = 0, | 741 | .bAlternateSetting = 0, |
684 | .bNumEndpoints = 2, | 742 | .bNumEndpoints = 2, |
685 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | 743 | .bInterfaceClass = USB_CLASS_COMM, |
686 | .bInterfaceSubClass = 0, | 744 | .bInterfaceSubClass = USB_CDC_SUBCLASS_MDLM, |
687 | .bInterfaceProtocol = 0, | 745 | .bInterfaceProtocol = 0, |
688 | .iInterface = STRING_DATA, | 746 | .iInterface = STRING_DATA, |
689 | }; | 747 | }; |
@@ -731,10 +789,15 @@ static const struct usb_descriptor_header *fs_eth_function [11] = { | |||
731 | static inline void __init fs_subset_descriptors(void) | 789 | static inline void __init fs_subset_descriptors(void) |
732 | { | 790 | { |
733 | #ifdef DEV_CONFIG_SUBSET | 791 | #ifdef DEV_CONFIG_SUBSET |
792 | /* behavior is "CDC Subset"; extra descriptors say "SAFE" */ | ||
734 | fs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf; | 793 | fs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf; |
735 | fs_eth_function[2] = (struct usb_descriptor_header *) &fs_source_desc; | 794 | fs_eth_function[2] = (struct usb_descriptor_header *) &header_desc; |
736 | fs_eth_function[3] = (struct usb_descriptor_header *) &fs_sink_desc; | 795 | fs_eth_function[3] = (struct usb_descriptor_header *) &mdlm_desc; |
737 | fs_eth_function[4] = NULL; | 796 | fs_eth_function[4] = (struct usb_descriptor_header *) &mdlm_detail_desc; |
797 | fs_eth_function[5] = (struct usb_descriptor_header *) ðer_desc; | ||
798 | fs_eth_function[6] = (struct usb_descriptor_header *) &fs_source_desc; | ||
799 | fs_eth_function[7] = (struct usb_descriptor_header *) &fs_sink_desc; | ||
800 | fs_eth_function[8] = NULL; | ||
738 | #else | 801 | #else |
739 | fs_eth_function[1] = NULL; | 802 | fs_eth_function[1] = NULL; |
740 | #endif | 803 | #endif |
@@ -828,10 +891,15 @@ static const struct usb_descriptor_header *hs_eth_function [11] = { | |||
828 | static inline void __init hs_subset_descriptors(void) | 891 | static inline void __init hs_subset_descriptors(void) |
829 | { | 892 | { |
830 | #ifdef DEV_CONFIG_SUBSET | 893 | #ifdef DEV_CONFIG_SUBSET |
894 | /* behavior is "CDC Subset"; extra descriptors say "SAFE" */ | ||
831 | hs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf; | 895 | hs_eth_function[1] = (struct usb_descriptor_header *) &subset_data_intf; |
832 | hs_eth_function[2] = (struct usb_descriptor_header *) &fs_source_desc; | 896 | hs_eth_function[2] = (struct usb_descriptor_header *) &header_desc; |
833 | hs_eth_function[3] = (struct usb_descriptor_header *) &fs_sink_desc; | 897 | hs_eth_function[3] = (struct usb_descriptor_header *) &mdlm_desc; |
834 | hs_eth_function[4] = NULL; | 898 | hs_eth_function[4] = (struct usb_descriptor_header *) &mdlm_detail_desc; |
899 | hs_eth_function[5] = (struct usb_descriptor_header *) ðer_desc; | ||
900 | hs_eth_function[6] = (struct usb_descriptor_header *) &hs_source_desc; | ||
901 | hs_eth_function[7] = (struct usb_descriptor_header *) &hs_sink_desc; | ||
902 | hs_eth_function[8] = NULL; | ||
835 | #else | 903 | #else |
836 | hs_eth_function[1] = NULL; | 904 | hs_eth_function[1] = NULL; |
837 | #endif | 905 | #endif |
@@ -878,10 +946,8 @@ static char manufacturer [50]; | |||
878 | static char product_desc [40] = DRIVER_DESC; | 946 | static char product_desc [40] = DRIVER_DESC; |
879 | static char serial_number [20]; | 947 | static char serial_number [20]; |
880 | 948 | ||
881 | #ifdef DEV_CONFIG_CDC | ||
882 | /* address that the host will use ... usually assigned at random */ | 949 | /* address that the host will use ... usually assigned at random */ |
883 | static char ethaddr [2 * ETH_ALEN + 1]; | 950 | static char ethaddr [2 * ETH_ALEN + 1]; |
884 | #endif | ||
885 | 951 | ||
886 | /* static strings, in UTF-8 */ | 952 | /* static strings, in UTF-8 */ |
887 | static struct usb_string strings [] = { | 953 | static struct usb_string strings [] = { |
@@ -889,9 +955,9 @@ static struct usb_string strings [] = { | |||
889 | { STRING_PRODUCT, product_desc, }, | 955 | { STRING_PRODUCT, product_desc, }, |
890 | { STRING_SERIALNUMBER, serial_number, }, | 956 | { STRING_SERIALNUMBER, serial_number, }, |
891 | { STRING_DATA, "Ethernet Data", }, | 957 | { STRING_DATA, "Ethernet Data", }, |
958 | { STRING_ETHADDR, ethaddr, }, | ||
892 | #ifdef DEV_CONFIG_CDC | 959 | #ifdef DEV_CONFIG_CDC |
893 | { STRING_CDC, "CDC Ethernet", }, | 960 | { STRING_CDC, "CDC Ethernet", }, |
894 | { STRING_ETHADDR, ethaddr, }, | ||
895 | { STRING_CONTROL, "CDC Communications Control", }, | 961 | { STRING_CONTROL, "CDC Communications Control", }, |
896 | #endif | 962 | #endif |
897 | #ifdef DEV_CONFIG_SUBSET | 963 | #ifdef DEV_CONFIG_SUBSET |
@@ -986,10 +1052,10 @@ set_ether_config (struct eth_dev *dev, gfp_t gfp_flags) | |||
986 | } | 1052 | } |
987 | #endif | 1053 | #endif |
988 | 1054 | ||
989 | dev->in = ep_desc (dev->gadget, &hs_source_desc, &fs_source_desc); | 1055 | dev->in = ep_desc(gadget, &hs_source_desc, &fs_source_desc); |
990 | dev->in_ep->driver_data = dev; | 1056 | dev->in_ep->driver_data = dev; |
991 | 1057 | ||
992 | dev->out = ep_desc (dev->gadget, &hs_sink_desc, &fs_sink_desc); | 1058 | dev->out = ep_desc(gadget, &hs_sink_desc, &fs_sink_desc); |
993 | dev->out_ep->driver_data = dev; | 1059 | dev->out_ep->driver_data = dev; |
994 | 1060 | ||
995 | /* With CDC, the host isn't allowed to use these two data | 1061 | /* With CDC, the host isn't allowed to use these two data |
@@ -2278,10 +2344,10 @@ eth_bind (struct usb_gadget *gadget) | |||
2278 | "RNDIS/%s", driver_desc); | 2344 | "RNDIS/%s", driver_desc); |
2279 | 2345 | ||
2280 | /* CDC subset ... recognized by Linux since 2.4.10, but Windows | 2346 | /* CDC subset ... recognized by Linux since 2.4.10, but Windows |
2281 | * drivers aren't widely available. | 2347 | * drivers aren't widely available. (That may be improved by |
2348 | * supporting one submode of the "SAFE" variant of MDLM.) | ||
2282 | */ | 2349 | */ |
2283 | } else if (!cdc) { | 2350 | } else if (!cdc) { |
2284 | device_desc.bDeviceClass = USB_CLASS_VENDOR_SPEC; | ||
2285 | device_desc.idVendor = | 2351 | device_desc.idVendor = |
2286 | __constant_cpu_to_le16(SIMPLE_VENDOR_NUM); | 2352 | __constant_cpu_to_le16(SIMPLE_VENDOR_NUM); |
2287 | device_desc.idProduct = | 2353 | device_desc.idProduct = |
@@ -2352,6 +2418,10 @@ autoconf_fail: | |||
2352 | if (!cdc) { | 2418 | if (!cdc) { |
2353 | eth_config.bNumInterfaces = 1; | 2419 | eth_config.bNumInterfaces = 1; |
2354 | eth_config.iConfiguration = STRING_SUBSET; | 2420 | eth_config.iConfiguration = STRING_SUBSET; |
2421 | |||
2422 | /* use functions to set these up, in case we're built to work | ||
2423 | * with multiple controllers and must override CDC Ethernet. | ||
2424 | */ | ||
2355 | fs_subset_descriptors(); | 2425 | fs_subset_descriptors(); |
2356 | hs_subset_descriptors(); | 2426 | hs_subset_descriptors(); |
2357 | } | 2427 | } |
@@ -2415,22 +2485,20 @@ autoconf_fail: | |||
2415 | 2485 | ||
2416 | /* Module params for these addresses should come from ID proms. | 2486 | /* Module params for these addresses should come from ID proms. |
2417 | * The host side address is used with CDC and RNDIS, and commonly | 2487 | * The host side address is used with CDC and RNDIS, and commonly |
2418 | * ends up in a persistent config database. | 2488 | * ends up in a persistent config database. It's not clear if |
2489 | * host side code for the SAFE thing cares -- its original BLAN | ||
2490 | * thing didn't, Sharp never assigned those addresses on Zaurii. | ||
2419 | */ | 2491 | */ |
2420 | if (get_ether_addr(dev_addr, net->dev_addr)) | 2492 | if (get_ether_addr(dev_addr, net->dev_addr)) |
2421 | dev_warn(&gadget->dev, | 2493 | dev_warn(&gadget->dev, |
2422 | "using random %s ethernet address\n", "self"); | 2494 | "using random %s ethernet address\n", "self"); |
2423 | if (cdc || rndis) { | 2495 | if (get_ether_addr(host_addr, dev->host_mac)) |
2424 | if (get_ether_addr(host_addr, dev->host_mac)) | 2496 | dev_warn(&gadget->dev, |
2425 | dev_warn(&gadget->dev, | 2497 | "using random %s ethernet address\n", "host"); |
2426 | "using random %s ethernet address\n", "host"); | 2498 | snprintf (ethaddr, sizeof ethaddr, "%02X%02X%02X%02X%02X%02X", |
2427 | #ifdef DEV_CONFIG_CDC | 2499 | dev->host_mac [0], dev->host_mac [1], |
2428 | snprintf (ethaddr, sizeof ethaddr, "%02X%02X%02X%02X%02X%02X", | 2500 | dev->host_mac [2], dev->host_mac [3], |
2429 | dev->host_mac [0], dev->host_mac [1], | 2501 | dev->host_mac [4], dev->host_mac [5]); |
2430 | dev->host_mac [2], dev->host_mac [3], | ||
2431 | dev->host_mac [4], dev->host_mac [5]); | ||
2432 | #endif | ||
2433 | } | ||
2434 | 2502 | ||
2435 | if (rndis) { | 2503 | if (rndis) { |
2436 | status = rndis_init(); | 2504 | status = rndis_init(); |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index c98316ce8384..f04a29a46646 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -253,7 +253,7 @@ | |||
253 | #include <linux/freezer.h> | 253 | #include <linux/freezer.h> |
254 | #include <linux/utsname.h> | 254 | #include <linux/utsname.h> |
255 | 255 | ||
256 | #include <linux/usb_ch9.h> | 256 | #include <linux/usb/ch9.h> |
257 | #include <linux/usb_gadget.h> | 257 | #include <linux/usb_gadget.h> |
258 | 258 | ||
259 | #include "gadget_chips.h" | 259 | #include "gadget_chips.h" |
@@ -1148,7 +1148,7 @@ static int ep0_queue(struct fsg_dev *fsg) | |||
1148 | 1148 | ||
1149 | static void ep0_complete(struct usb_ep *ep, struct usb_request *req) | 1149 | static void ep0_complete(struct usb_ep *ep, struct usb_request *req) |
1150 | { | 1150 | { |
1151 | struct fsg_dev *fsg = (struct fsg_dev *) ep->driver_data; | 1151 | struct fsg_dev *fsg = ep->driver_data; |
1152 | 1152 | ||
1153 | if (req->actual > 0) | 1153 | if (req->actual > 0) |
1154 | dump_msg(fsg, fsg->ep0req_name, req->buf, req->actual); | 1154 | dump_msg(fsg, fsg->ep0req_name, req->buf, req->actual); |
@@ -1170,8 +1170,8 @@ static void ep0_complete(struct usb_ep *ep, struct usb_request *req) | |||
1170 | 1170 | ||
1171 | static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) | 1171 | static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) |
1172 | { | 1172 | { |
1173 | struct fsg_dev *fsg = (struct fsg_dev *) ep->driver_data; | 1173 | struct fsg_dev *fsg = ep->driver_data; |
1174 | struct fsg_buffhd *bh = (struct fsg_buffhd *) req->context; | 1174 | struct fsg_buffhd *bh = req->context; |
1175 | 1175 | ||
1176 | if (req->status || req->actual != req->length) | 1176 | if (req->status || req->actual != req->length) |
1177 | DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__, | 1177 | DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__, |
@@ -1190,8 +1190,8 @@ static void bulk_in_complete(struct usb_ep *ep, struct usb_request *req) | |||
1190 | 1190 | ||
1191 | static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) | 1191 | static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) |
1192 | { | 1192 | { |
1193 | struct fsg_dev *fsg = (struct fsg_dev *) ep->driver_data; | 1193 | struct fsg_dev *fsg = ep->driver_data; |
1194 | struct fsg_buffhd *bh = (struct fsg_buffhd *) req->context; | 1194 | struct fsg_buffhd *bh = req->context; |
1195 | 1195 | ||
1196 | dump_msg(fsg, "bulk-out", req->buf, req->actual); | 1196 | dump_msg(fsg, "bulk-out", req->buf, req->actual); |
1197 | if (req->status || req->actual != bh->bulk_out_intended_length) | 1197 | if (req->status || req->actual != bh->bulk_out_intended_length) |
@@ -1214,8 +1214,8 @@ static void bulk_out_complete(struct usb_ep *ep, struct usb_request *req) | |||
1214 | #ifdef CONFIG_USB_FILE_STORAGE_TEST | 1214 | #ifdef CONFIG_USB_FILE_STORAGE_TEST |
1215 | static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) | 1215 | static void intr_in_complete(struct usb_ep *ep, struct usb_request *req) |
1216 | { | 1216 | { |
1217 | struct fsg_dev *fsg = (struct fsg_dev *) ep->driver_data; | 1217 | struct fsg_dev *fsg = ep->driver_data; |
1218 | struct fsg_buffhd *bh = (struct fsg_buffhd *) req->context; | 1218 | struct fsg_buffhd *bh = req->context; |
1219 | 1219 | ||
1220 | if (req->status || req->actual != req->length) | 1220 | if (req->status || req->actual != req->length) |
1221 | DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__, | 1221 | DBG(fsg, "%s --> %d, %u/%u\n", __FUNCTION__, |
@@ -1909,10 +1909,10 @@ static int fsync_sub(struct lun *curlun) | |||
1909 | if (!filp->f_op->fsync) | 1909 | if (!filp->f_op->fsync) |
1910 | return -EINVAL; | 1910 | return -EINVAL; |
1911 | 1911 | ||
1912 | inode = filp->f_dentry->d_inode; | 1912 | inode = filp->f_path.dentry->d_inode; |
1913 | mutex_lock(&inode->i_mutex); | 1913 | mutex_lock(&inode->i_mutex); |
1914 | rc = filemap_fdatawrite(inode->i_mapping); | 1914 | rc = filemap_fdatawrite(inode->i_mapping); |
1915 | err = filp->f_op->fsync(filp, filp->f_dentry, 1); | 1915 | err = filp->f_op->fsync(filp, filp->f_path.dentry, 1); |
1916 | if (!rc) | 1916 | if (!rc) |
1917 | rc = err; | 1917 | rc = err; |
1918 | err = filemap_fdatawait(inode->i_mapping); | 1918 | err = filemap_fdatawait(inode->i_mapping); |
@@ -1950,7 +1950,7 @@ static int do_synchronize_cache(struct fsg_dev *fsg) | |||
1950 | static void invalidate_sub(struct lun *curlun) | 1950 | static void invalidate_sub(struct lun *curlun) |
1951 | { | 1951 | { |
1952 | struct file *filp = curlun->filp; | 1952 | struct file *filp = curlun->filp; |
1953 | struct inode *inode = filp->f_dentry->d_inode; | 1953 | struct inode *inode = filp->f_path.dentry->d_inode; |
1954 | unsigned long rc; | 1954 | unsigned long rc; |
1955 | 1955 | ||
1956 | rc = invalidate_inode_pages(inode->i_mapping); | 1956 | rc = invalidate_inode_pages(inode->i_mapping); |
@@ -2577,7 +2577,7 @@ static int send_status(struct fsg_dev *fsg) | |||
2577 | } | 2577 | } |
2578 | 2578 | ||
2579 | if (transport_is_bbb()) { | 2579 | if (transport_is_bbb()) { |
2580 | struct bulk_cs_wrap *csw = (struct bulk_cs_wrap *) bh->buf; | 2580 | struct bulk_cs_wrap *csw = bh->buf; |
2581 | 2581 | ||
2582 | /* Store and send the Bulk-only CSW */ | 2582 | /* Store and send the Bulk-only CSW */ |
2583 | csw->Signature = __constant_cpu_to_le32(USB_BULK_CS_SIG); | 2583 | csw->Signature = __constant_cpu_to_le32(USB_BULK_CS_SIG); |
@@ -2596,8 +2596,7 @@ static int send_status(struct fsg_dev *fsg) | |||
2596 | return 0; | 2596 | return 0; |
2597 | 2597 | ||
2598 | } else { // USB_PR_CBI | 2598 | } else { // USB_PR_CBI |
2599 | struct interrupt_data *buf = (struct interrupt_data *) | 2599 | struct interrupt_data *buf = bh->buf; |
2600 | bh->buf; | ||
2601 | 2600 | ||
2602 | /* Store and send the Interrupt data. UFI sends the ASC | 2601 | /* Store and send the Interrupt data. UFI sends the ASC |
2603 | * and ASCQ bytes. Everything else sends a Type (which | 2602 | * and ASCQ bytes. Everything else sends a Type (which |
@@ -2982,7 +2981,7 @@ static int do_scsi_command(struct fsg_dev *fsg) | |||
2982 | static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) | 2981 | static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) |
2983 | { | 2982 | { |
2984 | struct usb_request *req = bh->outreq; | 2983 | struct usb_request *req = bh->outreq; |
2985 | struct bulk_cb_wrap *cbw = (struct bulk_cb_wrap *) req->buf; | 2984 | struct bulk_cb_wrap *cbw = req->buf; |
2986 | 2985 | ||
2987 | /* Was this a real packet? */ | 2986 | /* Was this a real packet? */ |
2988 | if (req->status) | 2987 | if (req->status) |
@@ -3428,7 +3427,7 @@ static void handle_exception(struct fsg_dev *fsg) | |||
3428 | 3427 | ||
3429 | static int fsg_main_thread(void *fsg_) | 3428 | static int fsg_main_thread(void *fsg_) |
3430 | { | 3429 | { |
3431 | struct fsg_dev *fsg = (struct fsg_dev *) fsg_; | 3430 | struct fsg_dev *fsg = fsg_; |
3432 | 3431 | ||
3433 | /* Allow the thread to be killed by a signal, but set the signal mask | 3432 | /* Allow the thread to be killed by a signal, but set the signal mask |
3434 | * to block everything but INT, TERM, KILL, and USR1. */ | 3433 | * to block everything but INT, TERM, KILL, and USR1. */ |
@@ -3526,8 +3525,8 @@ static int open_backing_file(struct lun *curlun, const char *filename) | |||
3526 | if (!(filp->f_mode & FMODE_WRITE)) | 3525 | if (!(filp->f_mode & FMODE_WRITE)) |
3527 | ro = 1; | 3526 | ro = 1; |
3528 | 3527 | ||
3529 | if (filp->f_dentry) | 3528 | if (filp->f_path.dentry) |
3530 | inode = filp->f_dentry->d_inode; | 3529 | inode = filp->f_path.dentry->d_inode; |
3531 | if (inode && S_ISBLK(inode->i_mode)) { | 3530 | if (inode && S_ISBLK(inode->i_mode)) { |
3532 | if (bdev_read_only(inode->i_bdev)) | 3531 | if (bdev_read_only(inode->i_bdev)) |
3533 | ro = 1; | 3532 | ro = 1; |
@@ -3600,13 +3599,13 @@ static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char * | |||
3600 | static ssize_t show_file(struct device *dev, struct device_attribute *attr, char *buf) | 3599 | static ssize_t show_file(struct device *dev, struct device_attribute *attr, char *buf) |
3601 | { | 3600 | { |
3602 | struct lun *curlun = dev_to_lun(dev); | 3601 | struct lun *curlun = dev_to_lun(dev); |
3603 | struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); | 3602 | struct fsg_dev *fsg = dev_get_drvdata(dev); |
3604 | char *p; | 3603 | char *p; |
3605 | ssize_t rc; | 3604 | ssize_t rc; |
3606 | 3605 | ||
3607 | down_read(&fsg->filesem); | 3606 | down_read(&fsg->filesem); |
3608 | if (backing_file_is_open(curlun)) { // Get the complete pathname | 3607 | if (backing_file_is_open(curlun)) { // Get the complete pathname |
3609 | p = d_path(curlun->filp->f_dentry, curlun->filp->f_vfsmnt, | 3608 | p = d_path(curlun->filp->f_path.dentry, curlun->filp->f_path.mnt, |
3610 | buf, PAGE_SIZE - 1); | 3609 | buf, PAGE_SIZE - 1); |
3611 | if (IS_ERR(p)) | 3610 | if (IS_ERR(p)) |
3612 | rc = PTR_ERR(p); | 3611 | rc = PTR_ERR(p); |
@@ -3629,7 +3628,7 @@ static ssize_t store_ro(struct device *dev, struct device_attribute *attr, const | |||
3629 | { | 3628 | { |
3630 | ssize_t rc = count; | 3629 | ssize_t rc = count; |
3631 | struct lun *curlun = dev_to_lun(dev); | 3630 | struct lun *curlun = dev_to_lun(dev); |
3632 | struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); | 3631 | struct fsg_dev *fsg = dev_get_drvdata(dev); |
3633 | int i; | 3632 | int i; |
3634 | 3633 | ||
3635 | if (sscanf(buf, "%d", &i) != 1) | 3634 | if (sscanf(buf, "%d", &i) != 1) |
@@ -3652,7 +3651,7 @@ static ssize_t store_ro(struct device *dev, struct device_attribute *attr, const | |||
3652 | static ssize_t store_file(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 3651 | static ssize_t store_file(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
3653 | { | 3652 | { |
3654 | struct lun *curlun = dev_to_lun(dev); | 3653 | struct lun *curlun = dev_to_lun(dev); |
3655 | struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); | 3654 | struct fsg_dev *fsg = dev_get_drvdata(dev); |
3656 | int rc = 0; | 3655 | int rc = 0; |
3657 | 3656 | ||
3658 | if (curlun->prevent_medium_removal && backing_file_is_open(curlun)) { | 3657 | if (curlun->prevent_medium_removal && backing_file_is_open(curlun)) { |
@@ -3700,7 +3699,7 @@ static void fsg_release(struct kref *ref) | |||
3700 | 3699 | ||
3701 | static void lun_release(struct device *dev) | 3700 | static void lun_release(struct device *dev) |
3702 | { | 3701 | { |
3703 | struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); | 3702 | struct fsg_dev *fsg = dev_get_drvdata(dev); |
3704 | 3703 | ||
3705 | kref_put(&fsg->ref, fsg_release); | 3704 | kref_put(&fsg->ref, fsg_release); |
3706 | } | 3705 | } |
@@ -4030,8 +4029,8 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
4030 | if (backing_file_is_open(curlun)) { | 4029 | if (backing_file_is_open(curlun)) { |
4031 | p = NULL; | 4030 | p = NULL; |
4032 | if (pathbuf) { | 4031 | if (pathbuf) { |
4033 | p = d_path(curlun->filp->f_dentry, | 4032 | p = d_path(curlun->filp->f_path.dentry, |
4034 | curlun->filp->f_vfsmnt, | 4033 | curlun->filp->f_path.mnt, |
4035 | pathbuf, PATH_MAX); | 4034 | pathbuf, PATH_MAX); |
4036 | if (IS_ERR(p)) | 4035 | if (IS_ERR(p)) |
4037 | p = NULL; | 4036 | p = NULL; |
@@ -4100,7 +4099,7 @@ static struct usb_gadget_driver fsg_driver = { | |||
4100 | #endif | 4099 | #endif |
4101 | .function = (char *) longname, | 4100 | .function = (char *) longname, |
4102 | .bind = fsg_bind, | 4101 | .bind = fsg_bind, |
4103 | .unbind = __exit_p(fsg_unbind), | 4102 | .unbind = fsg_unbind, |
4104 | .disconnect = fsg_disconnect, | 4103 | .disconnect = fsg_disconnect, |
4105 | .setup = fsg_setup, | 4104 | .setup = fsg_setup, |
4106 | .suspend = fsg_suspend, | 4105 | .suspend = fsg_suspend, |
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index aa80f0910720..2e3d6620d216 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h | |||
@@ -75,6 +75,12 @@ | |||
75 | #define gadget_is_pxa27x(g) 0 | 75 | #define gadget_is_pxa27x(g) 0 |
76 | #endif | 76 | #endif |
77 | 77 | ||
78 | #ifdef CONFIG_USB_GADGET_HUSB2DEV | ||
79 | #define gadget_is_husb2dev(g) !strcmp("husb2_udc", (g)->name) | ||
80 | #else | ||
81 | #define gadget_is_husb2dev(g) 0 | ||
82 | #endif | ||
83 | |||
78 | #ifdef CONFIG_USB_GADGET_S3C2410 | 84 | #ifdef CONFIG_USB_GADGET_S3C2410 |
79 | #define gadget_is_s3c2410(g) !strcmp("s3c2410_udc", (g)->name) | 85 | #define gadget_is_s3c2410(g) !strcmp("s3c2410_udc", (g)->name) |
80 | #else | 86 | #else |
@@ -169,5 +175,7 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) | |||
169 | return 0x16; | 175 | return 0x16; |
170 | else if (gadget_is_mpc8272(gadget)) | 176 | else if (gadget_is_mpc8272(gadget)) |
171 | return 0x17; | 177 | return 0x17; |
178 | else if (gadget_is_husb2dev(gadget)) | ||
179 | return 0x18; | ||
172 | return -ENOENT; | 180 | return -ENOENT; |
173 | } | 181 | } |
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 31351826f2ba..d08a8d0e6427 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <sound/initval.h> | 35 | #include <sound/initval.h> |
36 | #include <sound/rawmidi.h> | 36 | #include <sound/rawmidi.h> |
37 | 37 | ||
38 | #include <linux/usb_ch9.h> | 38 | #include <linux/usb/ch9.h> |
39 | #include <linux/usb_gadget.h> | 39 | #include <linux/usb_gadget.h> |
40 | #include <linux/usb/audio.h> | 40 | #include <linux/usb/audio.h> |
41 | #include <linux/usb/midi.h> | 41 | #include <linux/usb/midi.h> |
@@ -123,7 +123,7 @@ struct gmidi_device { | |||
123 | struct usb_request *req; /* for control responses */ | 123 | struct usb_request *req; /* for control responses */ |
124 | u8 config; | 124 | u8 config; |
125 | struct usb_ep *in_ep, *out_ep; | 125 | struct usb_ep *in_ep, *out_ep; |
126 | struct snd_card *card; | 126 | struct snd_card *card; |
127 | struct snd_rawmidi *rmidi; | 127 | struct snd_rawmidi *rmidi; |
128 | struct snd_rawmidi_substream *in_substream; | 128 | struct snd_rawmidi_substream *in_substream; |
129 | struct snd_rawmidi_substream *out_substream; | 129 | struct snd_rawmidi_substream *out_substream; |
@@ -490,7 +490,7 @@ static void gmidi_complete(struct usb_ep *ep, struct usb_request *req) | |||
490 | int status = req->status; | 490 | int status = req->status; |
491 | 491 | ||
492 | switch (status) { | 492 | switch (status) { |
493 | case 0: /* normal completion */ | 493 | case 0: /* normal completion */ |
494 | if (ep == dev->out_ep) { | 494 | if (ep == dev->out_ep) { |
495 | /* we received stuff. | 495 | /* we received stuff. |
496 | req is queued again, below */ | 496 | req is queued again, below */ |
@@ -505,7 +505,7 @@ static void gmidi_complete(struct usb_ep *ep, struct usb_request *req) | |||
505 | break; | 505 | break; |
506 | 506 | ||
507 | /* this endpoint is normally active while we're configured */ | 507 | /* this endpoint is normally active while we're configured */ |
508 | case -ECONNABORTED: /* hardware forced ep reset */ | 508 | case -ECONNABORTED: /* hardware forced ep reset */ |
509 | case -ECONNRESET: /* request dequeued */ | 509 | case -ECONNRESET: /* request dequeued */ |
510 | case -ESHUTDOWN: /* disconnect from host */ | 510 | case -ESHUTDOWN: /* disconnect from host */ |
511 | VDBG(dev, "%s gone (%d), %d/%d\n", ep->name, status, | 511 | VDBG(dev, "%s gone (%d), %d/%d\n", ep->name, status, |
@@ -656,7 +656,7 @@ gmidi_set_config(struct gmidi_device *dev, unsigned number, gfp_t gfp_flags) | |||
656 | case USB_SPEED_LOW: speed = "low"; break; | 656 | case USB_SPEED_LOW: speed = "low"; break; |
657 | case USB_SPEED_FULL: speed = "full"; break; | 657 | case USB_SPEED_FULL: speed = "full"; break; |
658 | case USB_SPEED_HIGH: speed = "high"; break; | 658 | case USB_SPEED_HIGH: speed = "high"; break; |
659 | default: speed = "?"; break; | 659 | default: speed = "?"; break; |
660 | } | 660 | } |
661 | 661 | ||
662 | dev->config = number; | 662 | dev->config = number; |
@@ -1308,7 +1308,7 @@ static struct usb_gadget_driver gmidi_driver = { | |||
1308 | .speed = USB_SPEED_FULL, | 1308 | .speed = USB_SPEED_FULL, |
1309 | .function = (char *)longname, | 1309 | .function = (char *)longname, |
1310 | .bind = gmidi_bind, | 1310 | .bind = gmidi_bind, |
1311 | .unbind = __exit_p(gmidi_unbind), | 1311 | .unbind = gmidi_unbind, |
1312 | 1312 | ||
1313 | .setup = gmidi_setup, | 1313 | .setup = gmidi_setup, |
1314 | .disconnect = gmidi_disconnect, | 1314 | .disconnect = gmidi_disconnect, |
@@ -1316,7 +1316,7 @@ static struct usb_gadget_driver gmidi_driver = { | |||
1316 | .suspend = gmidi_suspend, | 1316 | .suspend = gmidi_suspend, |
1317 | .resume = gmidi_resume, | 1317 | .resume = gmidi_resume, |
1318 | 1318 | ||
1319 | .driver = { | 1319 | .driver = { |
1320 | .name = (char *)shortname, | 1320 | .name = (char *)shortname, |
1321 | .owner = THIS_MODULE, | 1321 | .owner = THIS_MODULE, |
1322 | }, | 1322 | }, |
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index 805a9826842d..e873cf488246 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -39,7 +39,7 @@ | |||
39 | #include <linux/interrupt.h> | 39 | #include <linux/interrupt.h> |
40 | #include <linux/proc_fs.h> | 40 | #include <linux/proc_fs.h> |
41 | #include <linux/device.h> | 41 | #include <linux/device.h> |
42 | #include <linux/usb_ch9.h> | 42 | #include <linux/usb/ch9.h> |
43 | #include <linux/usb_gadget.h> | 43 | #include <linux/usb_gadget.h> |
44 | 44 | ||
45 | #include <asm/byteorder.h> | 45 | #include <asm/byteorder.h> |
@@ -1432,7 +1432,6 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1432 | if (!driver | 1432 | if (!driver |
1433 | || driver->speed != USB_SPEED_FULL | 1433 | || driver->speed != USB_SPEED_FULL |
1434 | || !driver->bind | 1434 | || !driver->bind |
1435 | || !driver->unbind | ||
1436 | || !driver->disconnect | 1435 | || !driver->disconnect |
1437 | || !driver->setup) | 1436 | || !driver->setup) |
1438 | return -EINVAL; | 1437 | return -EINVAL; |
@@ -1495,7 +1494,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1495 | 1494 | ||
1496 | if (!dev) | 1495 | if (!dev) |
1497 | return -ENODEV; | 1496 | return -ENODEV; |
1498 | if (!driver || driver != dev->driver) | 1497 | if (!driver || driver != dev->driver || !driver->unbind) |
1499 | return -EINVAL; | 1498 | return -EINVAL; |
1500 | 1499 | ||
1501 | spin_lock_irqsave(&dev->lock, flags); | 1500 | spin_lock_irqsave(&dev->lock, flags); |
@@ -1808,13 +1807,8 @@ static void goku_remove(struct pci_dev *pdev) | |||
1808 | struct goku_udc *dev = pci_get_drvdata(pdev); | 1807 | struct goku_udc *dev = pci_get_drvdata(pdev); |
1809 | 1808 | ||
1810 | DBG(dev, "%s\n", __FUNCTION__); | 1809 | DBG(dev, "%s\n", __FUNCTION__); |
1811 | /* start with the driver above us */ | 1810 | |
1812 | if (dev->driver) { | 1811 | BUG_ON(dev->driver); |
1813 | /* should have been done already by driver model core */ | ||
1814 | WARN(dev, "pci remove, driver '%s' is still registered\n", | ||
1815 | dev->driver->driver.name); | ||
1816 | usb_gadget_unregister_driver(dev->driver); | ||
1817 | } | ||
1818 | 1812 | ||
1819 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES | 1813 | #ifdef CONFIG_USB_GADGET_DEBUG_FILES |
1820 | remove_proc_entry(proc_node_name, NULL); | 1814 | remove_proc_entry(proc_node_name, NULL); |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 3fb1044a4db0..34296e79edcf 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
@@ -20,7 +20,7 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | 22 | ||
23 | // #define DEBUG /* data to help fault diagnosis */ | 23 | // #define DEBUG /* data to help fault diagnosis */ |
24 | // #define VERBOSE /* extra debug messages (success too) */ | 24 | // #define VERBOSE /* extra debug messages (success too) */ |
25 | 25 | ||
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
@@ -59,11 +59,11 @@ | |||
59 | * may serve as a source of device events, used to handle all control | 59 | * may serve as a source of device events, used to handle all control |
60 | * requests other than basic enumeration. | 60 | * requests other than basic enumeration. |
61 | * | 61 | * |
62 | * - Then either immediately, or after a SET_CONFIGURATION control request, | 62 | * - Then, after a SET_CONFIGURATION control request, ep_config() is |
63 | * ep_config() is called when each /dev/gadget/ep* file is configured | 63 | * called when each /dev/gadget/ep* file is configured (by writing |
64 | * (by writing endpoint descriptors). Afterwards these files are used | 64 | * endpoint descriptors). Afterwards these files are used to write() |
65 | * to write() IN data or to read() OUT data. To halt the endpoint, a | 65 | * IN data or to read() OUT data. To halt the endpoint, a "wrong |
66 | * "wrong direction" request is issued (like reading an IN endpoint). | 66 | * direction" request is issued (like reading an IN endpoint). |
67 | * | 67 | * |
68 | * Unlike "usbfs" the only ioctl()s are for things that are rare, and maybe | 68 | * Unlike "usbfs" the only ioctl()s are for things that are rare, and maybe |
69 | * not possible on all hardware. For example, precise fault handling with | 69 | * not possible on all hardware. For example, precise fault handling with |
@@ -98,16 +98,16 @@ enum ep0_state { | |||
98 | * must always write descriptors to initialize the device, then | 98 | * must always write descriptors to initialize the device, then |
99 | * the device becomes UNCONNECTED until enumeration. | 99 | * the device becomes UNCONNECTED until enumeration. |
100 | */ | 100 | */ |
101 | STATE_OPENED, | 101 | STATE_DEV_OPENED, |
102 | 102 | ||
103 | /* From then on, ep0 fd is in either of two basic modes: | 103 | /* From then on, ep0 fd is in either of two basic modes: |
104 | * - (UN)CONNECTED: read usb_gadgetfs_event(s) from it | 104 | * - (UN)CONNECTED: read usb_gadgetfs_event(s) from it |
105 | * - SETUP: read/write will transfer control data and succeed; | 105 | * - SETUP: read/write will transfer control data and succeed; |
106 | * or if "wrong direction", performs protocol stall | 106 | * or if "wrong direction", performs protocol stall |
107 | */ | 107 | */ |
108 | STATE_UNCONNECTED, | 108 | STATE_DEV_UNCONNECTED, |
109 | STATE_CONNECTED, | 109 | STATE_DEV_CONNECTED, |
110 | STATE_SETUP, | 110 | STATE_DEV_SETUP, |
111 | 111 | ||
112 | /* UNBOUND means the driver closed ep0, so the device won't be | 112 | /* UNBOUND means the driver closed ep0, so the device won't be |
113 | * accessible again (DEV_DISABLED) until all fds are closed. | 113 | * accessible again (DEV_DISABLED) until all fds are closed. |
@@ -121,7 +121,7 @@ enum ep0_state { | |||
121 | struct dev_data { | 121 | struct dev_data { |
122 | spinlock_t lock; | 122 | spinlock_t lock; |
123 | atomic_t count; | 123 | atomic_t count; |
124 | enum ep0_state state; | 124 | enum ep0_state state; /* P: lock */ |
125 | struct usb_gadgetfs_event event [N_EVENT]; | 125 | struct usb_gadgetfs_event event [N_EVENT]; |
126 | unsigned ev_next; | 126 | unsigned ev_next; |
127 | struct fasync_struct *fasync; | 127 | struct fasync_struct *fasync; |
@@ -188,7 +188,6 @@ static struct dev_data *dev_new (void) | |||
188 | enum ep_state { | 188 | enum ep_state { |
189 | STATE_EP_DISABLED = 0, | 189 | STATE_EP_DISABLED = 0, |
190 | STATE_EP_READY, | 190 | STATE_EP_READY, |
191 | STATE_EP_DEFER_ENABLE, | ||
192 | STATE_EP_ENABLED, | 191 | STATE_EP_ENABLED, |
193 | STATE_EP_UNBOUND, | 192 | STATE_EP_UNBOUND, |
194 | }; | 193 | }; |
@@ -313,18 +312,10 @@ nonblock: | |||
313 | 312 | ||
314 | if ((val = down_interruptible (&epdata->lock)) < 0) | 313 | if ((val = down_interruptible (&epdata->lock)) < 0) |
315 | return val; | 314 | return val; |
316 | newstate: | 315 | |
317 | switch (epdata->state) { | 316 | switch (epdata->state) { |
318 | case STATE_EP_ENABLED: | 317 | case STATE_EP_ENABLED: |
319 | break; | 318 | break; |
320 | case STATE_EP_DEFER_ENABLE: | ||
321 | DBG (epdata->dev, "%s wait for host\n", epdata->name); | ||
322 | if ((val = wait_event_interruptible (epdata->wait, | ||
323 | epdata->state != STATE_EP_DEFER_ENABLE | ||
324 | || epdata->dev->state == STATE_DEV_UNBOUND | ||
325 | )) < 0) | ||
326 | goto fail; | ||
327 | goto newstate; | ||
328 | // case STATE_EP_DISABLED: /* "can't happen" */ | 319 | // case STATE_EP_DISABLED: /* "can't happen" */ |
329 | // case STATE_EP_READY: /* "can't happen" */ | 320 | // case STATE_EP_READY: /* "can't happen" */ |
330 | default: /* error! */ | 321 | default: /* error! */ |
@@ -333,7 +324,6 @@ newstate: | |||
333 | // FALLTHROUGH | 324 | // FALLTHROUGH |
334 | case STATE_EP_UNBOUND: /* clean disconnect */ | 325 | case STATE_EP_UNBOUND: /* clean disconnect */ |
335 | val = -ENODEV; | 326 | val = -ENODEV; |
336 | fail: | ||
337 | up (&epdata->lock); | 327 | up (&epdata->lock); |
338 | } | 328 | } |
339 | return val; | 329 | return val; |
@@ -565,29 +555,28 @@ static ssize_t ep_aio_read_retry(struct kiocb *iocb) | |||
565 | ssize_t len, total; | 555 | ssize_t len, total; |
566 | int i; | 556 | int i; |
567 | 557 | ||
568 | /* we "retry" to get the right mm context for this: */ | 558 | /* we "retry" to get the right mm context for this: */ |
569 | 559 | ||
570 | /* copy stuff into user buffers */ | 560 | /* copy stuff into user buffers */ |
571 | total = priv->actual; | 561 | total = priv->actual; |
572 | len = 0; | 562 | len = 0; |
573 | for (i=0; i < priv->nr_segs; i++) { | 563 | for (i=0; i < priv->nr_segs; i++) { |
574 | ssize_t this = min((ssize_t)(priv->iv[i].iov_len), total); | 564 | ssize_t this = min((ssize_t)(priv->iv[i].iov_len), total); |
575 | 565 | ||
576 | if (copy_to_user(priv->iv[i].iov_base, priv->buf, this)) { | 566 | if (copy_to_user(priv->iv[i].iov_base, priv->buf, this)) { |
577 | if (len == 0) | 567 | if (len == 0) |
578 | len = -EFAULT; | 568 | len = -EFAULT; |
579 | break; | 569 | break; |
580 | } | 570 | } |
581 | 571 | ||
582 | total -= this; | 572 | total -= this; |
583 | len += this; | 573 | len += this; |
584 | if (total == 0) | 574 | if (total == 0) |
585 | break; | 575 | break; |
586 | } | 576 | } |
587 | kfree(priv->buf); | 577 | kfree(priv->buf); |
588 | kfree(priv); | 578 | kfree(priv); |
589 | aio_put_req(iocb); | 579 | return len; |
590 | return len; | ||
591 | } | 580 | } |
592 | 581 | ||
593 | static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) | 582 | static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) |
@@ -600,18 +589,17 @@ static void ep_aio_complete(struct usb_ep *ep, struct usb_request *req) | |||
600 | spin_lock(&epdata->dev->lock); | 589 | spin_lock(&epdata->dev->lock); |
601 | priv->req = NULL; | 590 | priv->req = NULL; |
602 | priv->epdata = NULL; | 591 | priv->epdata = NULL; |
603 | if (priv->iv == NULL | 592 | |
604 | || unlikely(req->actual == 0) | 593 | /* if this was a write or a read returning no data then we |
605 | || unlikely(kiocbIsCancelled(iocb))) { | 594 | * don't need to copy anything to userspace, so we can |
595 | * complete the aio request immediately. | ||
596 | */ | ||
597 | if (priv->iv == NULL || unlikely(req->actual == 0)) { | ||
606 | kfree(req->buf); | 598 | kfree(req->buf); |
607 | kfree(priv); | 599 | kfree(priv); |
608 | iocb->private = NULL; | 600 | iocb->private = NULL; |
609 | /* aio_complete() reports bytes-transferred _and_ faults */ | 601 | /* aio_complete() reports bytes-transferred _and_ faults */ |
610 | if (unlikely(kiocbIsCancelled(iocb))) | 602 | aio_complete(iocb, req->actual ? req->actual : req->status, |
611 | aio_put_req(iocb); | ||
612 | else | ||
613 | aio_complete(iocb, | ||
614 | req->actual ? req->actual : req->status, | ||
615 | req->status); | 603 | req->status); |
616 | } else { | 604 | } else { |
617 | /* retry() won't report both; so we hide some faults */ | 605 | /* retry() won't report both; so we hide some faults */ |
@@ -636,7 +624,7 @@ ep_aio_rwtail( | |||
636 | size_t len, | 624 | size_t len, |
637 | struct ep_data *epdata, | 625 | struct ep_data *epdata, |
638 | const struct iovec *iv, | 626 | const struct iovec *iv, |
639 | unsigned long nr_segs | 627 | unsigned long nr_segs |
640 | ) | 628 | ) |
641 | { | 629 | { |
642 | struct kiocb_priv *priv; | 630 | struct kiocb_priv *priv; |
@@ -852,9 +840,9 @@ ep_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
852 | break; | 840 | break; |
853 | #endif | 841 | #endif |
854 | default: | 842 | default: |
855 | DBG (data->dev, "unconnected, %s init deferred\n", | 843 | DBG(data->dev, "unconnected, %s init abandoned\n", |
856 | data->name); | 844 | data->name); |
857 | data->state = STATE_EP_DEFER_ENABLE; | 845 | value = -EINVAL; |
858 | } | 846 | } |
859 | if (value == 0) { | 847 | if (value == 0) { |
860 | fd->f_op = &ep_io_operations; | 848 | fd->f_op = &ep_io_operations; |
@@ -943,22 +931,24 @@ static void clean_req (struct usb_ep *ep, struct usb_request *req) | |||
943 | static void ep0_complete (struct usb_ep *ep, struct usb_request *req) | 931 | static void ep0_complete (struct usb_ep *ep, struct usb_request *req) |
944 | { | 932 | { |
945 | struct dev_data *dev = ep->driver_data; | 933 | struct dev_data *dev = ep->driver_data; |
934 | unsigned long flags; | ||
946 | int free = 1; | 935 | int free = 1; |
947 | 936 | ||
948 | /* for control OUT, data must still get to userspace */ | 937 | /* for control OUT, data must still get to userspace */ |
938 | spin_lock_irqsave(&dev->lock, flags); | ||
949 | if (!dev->setup_in) { | 939 | if (!dev->setup_in) { |
950 | dev->setup_out_error = (req->status != 0); | 940 | dev->setup_out_error = (req->status != 0); |
951 | if (!dev->setup_out_error) | 941 | if (!dev->setup_out_error) |
952 | free = 0; | 942 | free = 0; |
953 | dev->setup_out_ready = 1; | 943 | dev->setup_out_ready = 1; |
954 | ep0_readable (dev); | 944 | ep0_readable (dev); |
955 | } else if (dev->state == STATE_SETUP) | 945 | } |
956 | dev->state = STATE_CONNECTED; | ||
957 | 946 | ||
958 | /* clean up as appropriate */ | 947 | /* clean up as appropriate */ |
959 | if (free && req->buf != &dev->rbuf) | 948 | if (free && req->buf != &dev->rbuf) |
960 | clean_req (ep, req); | 949 | clean_req (ep, req); |
961 | req->complete = epio_complete; | 950 | req->complete = epio_complete; |
951 | spin_unlock_irqrestore(&dev->lock, flags); | ||
962 | } | 952 | } |
963 | 953 | ||
964 | static int setup_req (struct usb_ep *ep, struct usb_request *req, u16 len) | 954 | static int setup_req (struct usb_ep *ep, struct usb_request *req, u16 len) |
@@ -998,13 +988,13 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) | |||
998 | } | 988 | } |
999 | 989 | ||
1000 | /* control DATA stage */ | 990 | /* control DATA stage */ |
1001 | if ((state = dev->state) == STATE_SETUP) { | 991 | if ((state = dev->state) == STATE_DEV_SETUP) { |
1002 | 992 | ||
1003 | if (dev->setup_in) { /* stall IN */ | 993 | if (dev->setup_in) { /* stall IN */ |
1004 | VDEBUG(dev, "ep0in stall\n"); | 994 | VDEBUG(dev, "ep0in stall\n"); |
1005 | (void) usb_ep_set_halt (dev->gadget->ep0); | 995 | (void) usb_ep_set_halt (dev->gadget->ep0); |
1006 | retval = -EL2HLT; | 996 | retval = -EL2HLT; |
1007 | dev->state = STATE_CONNECTED; | 997 | dev->state = STATE_DEV_CONNECTED; |
1008 | 998 | ||
1009 | } else if (len == 0) { /* ack SET_CONFIGURATION etc */ | 999 | } else if (len == 0) { /* ack SET_CONFIGURATION etc */ |
1010 | struct usb_ep *ep = dev->gadget->ep0; | 1000 | struct usb_ep *ep = dev->gadget->ep0; |
@@ -1012,7 +1002,7 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) | |||
1012 | 1002 | ||
1013 | if ((retval = setup_req (ep, req, 0)) == 0) | 1003 | if ((retval = setup_req (ep, req, 0)) == 0) |
1014 | retval = usb_ep_queue (ep, req, GFP_ATOMIC); | 1004 | retval = usb_ep_queue (ep, req, GFP_ATOMIC); |
1015 | dev->state = STATE_CONNECTED; | 1005 | dev->state = STATE_DEV_CONNECTED; |
1016 | 1006 | ||
1017 | /* assume that was SET_CONFIGURATION */ | 1007 | /* assume that was SET_CONFIGURATION */ |
1018 | if (dev->current_config) { | 1008 | if (dev->current_config) { |
@@ -1040,6 +1030,13 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) | |||
1040 | spin_lock_irq (&dev->lock); | 1030 | spin_lock_irq (&dev->lock); |
1041 | if (retval) | 1031 | if (retval) |
1042 | goto done; | 1032 | goto done; |
1033 | |||
1034 | if (dev->state != STATE_DEV_SETUP) { | ||
1035 | retval = -ECANCELED; | ||
1036 | goto done; | ||
1037 | } | ||
1038 | dev->state = STATE_DEV_CONNECTED; | ||
1039 | |||
1043 | if (dev->setup_out_error) | 1040 | if (dev->setup_out_error) |
1044 | retval = -EIO; | 1041 | retval = -EIO; |
1045 | else { | 1042 | else { |
@@ -1066,39 +1063,36 @@ scan: | |||
1066 | /* return queued events right away */ | 1063 | /* return queued events right away */ |
1067 | if (dev->ev_next != 0) { | 1064 | if (dev->ev_next != 0) { |
1068 | unsigned i, n; | 1065 | unsigned i, n; |
1069 | int tmp = dev->ev_next; | ||
1070 | 1066 | ||
1071 | len = min (len, tmp * sizeof (struct usb_gadgetfs_event)); | ||
1072 | n = len / sizeof (struct usb_gadgetfs_event); | 1067 | n = len / sizeof (struct usb_gadgetfs_event); |
1068 | if (dev->ev_next < n) | ||
1069 | n = dev->ev_next; | ||
1073 | 1070 | ||
1074 | /* ep0 can't deliver events when STATE_SETUP */ | 1071 | /* ep0 i/o has special semantics during STATE_DEV_SETUP */ |
1075 | for (i = 0; i < n; i++) { | 1072 | for (i = 0; i < n; i++) { |
1076 | if (dev->event [i].type == GADGETFS_SETUP) { | 1073 | if (dev->event [i].type == GADGETFS_SETUP) { |
1077 | len = i + 1; | 1074 | dev->state = STATE_DEV_SETUP; |
1078 | len *= sizeof (struct usb_gadgetfs_event); | 1075 | n = i + 1; |
1079 | n = 0; | ||
1080 | break; | 1076 | break; |
1081 | } | 1077 | } |
1082 | } | 1078 | } |
1083 | spin_unlock_irq (&dev->lock); | 1079 | spin_unlock_irq (&dev->lock); |
1080 | len = n * sizeof (struct usb_gadgetfs_event); | ||
1084 | if (copy_to_user (buf, &dev->event, len)) | 1081 | if (copy_to_user (buf, &dev->event, len)) |
1085 | retval = -EFAULT; | 1082 | retval = -EFAULT; |
1086 | else | 1083 | else |
1087 | retval = len; | 1084 | retval = len; |
1088 | if (len > 0) { | 1085 | if (len > 0) { |
1089 | len /= sizeof (struct usb_gadgetfs_event); | ||
1090 | |||
1091 | /* NOTE this doesn't guard against broken drivers; | 1086 | /* NOTE this doesn't guard against broken drivers; |
1092 | * concurrent ep0 readers may lose events. | 1087 | * concurrent ep0 readers may lose events. |
1093 | */ | 1088 | */ |
1094 | spin_lock_irq (&dev->lock); | 1089 | spin_lock_irq (&dev->lock); |
1095 | dev->ev_next -= len; | 1090 | if (dev->ev_next > n) { |
1096 | if (dev->ev_next != 0) | 1091 | memmove(&dev->event[0], &dev->event[n], |
1097 | memmove (&dev->event, &dev->event [len], | ||
1098 | sizeof (struct usb_gadgetfs_event) | 1092 | sizeof (struct usb_gadgetfs_event) |
1099 | * (tmp - len)); | 1093 | * (dev->ev_next - n)); |
1100 | if (n == 0) | 1094 | } |
1101 | dev->state = STATE_SETUP; | 1095 | dev->ev_next -= n; |
1102 | spin_unlock_irq (&dev->lock); | 1096 | spin_unlock_irq (&dev->lock); |
1103 | } | 1097 | } |
1104 | return retval; | 1098 | return retval; |
@@ -1113,8 +1107,8 @@ scan: | |||
1113 | DBG (dev, "fail %s, state %d\n", __FUNCTION__, state); | 1107 | DBG (dev, "fail %s, state %d\n", __FUNCTION__, state); |
1114 | retval = -ESRCH; | 1108 | retval = -ESRCH; |
1115 | break; | 1109 | break; |
1116 | case STATE_UNCONNECTED: | 1110 | case STATE_DEV_UNCONNECTED: |
1117 | case STATE_CONNECTED: | 1111 | case STATE_DEV_CONNECTED: |
1118 | spin_unlock_irq (&dev->lock); | 1112 | spin_unlock_irq (&dev->lock); |
1119 | DBG (dev, "%s wait\n", __FUNCTION__); | 1113 | DBG (dev, "%s wait\n", __FUNCTION__); |
1120 | 1114 | ||
@@ -1141,7 +1135,7 @@ next_event (struct dev_data *dev, enum usb_gadgetfs_event_type type) | |||
1141 | switch (type) { | 1135 | switch (type) { |
1142 | /* these events purge the queue */ | 1136 | /* these events purge the queue */ |
1143 | case GADGETFS_DISCONNECT: | 1137 | case GADGETFS_DISCONNECT: |
1144 | if (dev->state == STATE_SETUP) | 1138 | if (dev->state == STATE_DEV_SETUP) |
1145 | dev->setup_abort = 1; | 1139 | dev->setup_abort = 1; |
1146 | // FALL THROUGH | 1140 | // FALL THROUGH |
1147 | case GADGETFS_CONNECT: | 1141 | case GADGETFS_CONNECT: |
@@ -1153,7 +1147,7 @@ next_event (struct dev_data *dev, enum usb_gadgetfs_event_type type) | |||
1153 | for (i = 0; i != dev->ev_next; i++) { | 1147 | for (i = 0; i != dev->ev_next; i++) { |
1154 | if (dev->event [i].type != type) | 1148 | if (dev->event [i].type != type) |
1155 | continue; | 1149 | continue; |
1156 | DBG (dev, "discard old event %d\n", type); | 1150 | DBG(dev, "discard old event[%d] %d\n", i, type); |
1157 | dev->ev_next--; | 1151 | dev->ev_next--; |
1158 | if (i == dev->ev_next) | 1152 | if (i == dev->ev_next) |
1159 | break; | 1153 | break; |
@@ -1166,9 +1160,9 @@ next_event (struct dev_data *dev, enum usb_gadgetfs_event_type type) | |||
1166 | default: | 1160 | default: |
1167 | BUG (); | 1161 | BUG (); |
1168 | } | 1162 | } |
1163 | VDEBUG(dev, "event[%d] = %d\n", dev->ev_next, type); | ||
1169 | event = &dev->event [dev->ev_next++]; | 1164 | event = &dev->event [dev->ev_next++]; |
1170 | BUG_ON (dev->ev_next > N_EVENT); | 1165 | BUG_ON (dev->ev_next > N_EVENT); |
1171 | VDEBUG (dev, "ev %d, next %d\n", type, dev->ev_next); | ||
1172 | memset (event, 0, sizeof *event); | 1166 | memset (event, 0, sizeof *event); |
1173 | event->type = type; | 1167 | event->type = type; |
1174 | return event; | 1168 | return event; |
@@ -1188,12 +1182,13 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
1188 | retval = -EIDRM; | 1182 | retval = -EIDRM; |
1189 | 1183 | ||
1190 | /* data and/or status stage for control request */ | 1184 | /* data and/or status stage for control request */ |
1191 | } else if (dev->state == STATE_SETUP) { | 1185 | } else if (dev->state == STATE_DEV_SETUP) { |
1192 | 1186 | ||
1193 | /* IN DATA+STATUS caller makes len <= wLength */ | 1187 | /* IN DATA+STATUS caller makes len <= wLength */ |
1194 | if (dev->setup_in) { | 1188 | if (dev->setup_in) { |
1195 | retval = setup_req (dev->gadget->ep0, dev->req, len); | 1189 | retval = setup_req (dev->gadget->ep0, dev->req, len); |
1196 | if (retval == 0) { | 1190 | if (retval == 0) { |
1191 | dev->state = STATE_DEV_CONNECTED; | ||
1197 | spin_unlock_irq (&dev->lock); | 1192 | spin_unlock_irq (&dev->lock); |
1198 | if (copy_from_user (dev->req->buf, buf, len)) | 1193 | if (copy_from_user (dev->req->buf, buf, len)) |
1199 | retval = -EFAULT; | 1194 | retval = -EFAULT; |
@@ -1219,7 +1214,7 @@ ep0_write (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
1219 | VDEBUG(dev, "ep0out stall\n"); | 1214 | VDEBUG(dev, "ep0out stall\n"); |
1220 | (void) usb_ep_set_halt (dev->gadget->ep0); | 1215 | (void) usb_ep_set_halt (dev->gadget->ep0); |
1221 | retval = -EL2HLT; | 1216 | retval = -EL2HLT; |
1222 | dev->state = STATE_CONNECTED; | 1217 | dev->state = STATE_DEV_CONNECTED; |
1223 | } else { | 1218 | } else { |
1224 | DBG(dev, "bogus ep0out stall!\n"); | 1219 | DBG(dev, "bogus ep0out stall!\n"); |
1225 | } | 1220 | } |
@@ -1261,7 +1256,9 @@ dev_release (struct inode *inode, struct file *fd) | |||
1261 | put_dev (dev); | 1256 | put_dev (dev); |
1262 | 1257 | ||
1263 | /* other endpoints were all decoupled from this device */ | 1258 | /* other endpoints were all decoupled from this device */ |
1259 | spin_lock_irq(&dev->lock); | ||
1264 | dev->state = STATE_DEV_DISABLED; | 1260 | dev->state = STATE_DEV_DISABLED; |
1261 | spin_unlock_irq(&dev->lock); | ||
1265 | return 0; | 1262 | return 0; |
1266 | } | 1263 | } |
1267 | 1264 | ||
@@ -1282,7 +1279,7 @@ ep0_poll (struct file *fd, poll_table *wait) | |||
1282 | goto out; | 1279 | goto out; |
1283 | } | 1280 | } |
1284 | 1281 | ||
1285 | if (dev->state == STATE_SETUP) { | 1282 | if (dev->state == STATE_DEV_SETUP) { |
1286 | if (dev->setup_in || dev->setup_can_stall) | 1283 | if (dev->setup_in || dev->setup_can_stall) |
1287 | mask = POLLOUT; | 1284 | mask = POLLOUT; |
1288 | } else { | 1285 | } else { |
@@ -1392,52 +1389,29 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1392 | 1389 | ||
1393 | spin_lock (&dev->lock); | 1390 | spin_lock (&dev->lock); |
1394 | dev->setup_abort = 0; | 1391 | dev->setup_abort = 0; |
1395 | if (dev->state == STATE_UNCONNECTED) { | 1392 | if (dev->state == STATE_DEV_UNCONNECTED) { |
1396 | struct usb_ep *ep; | ||
1397 | struct ep_data *data; | ||
1398 | |||
1399 | dev->state = STATE_CONNECTED; | ||
1400 | dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket; | ||
1401 | |||
1402 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1393 | #ifdef CONFIG_USB_GADGET_DUALSPEED |
1403 | if (gadget->speed == USB_SPEED_HIGH && dev->hs_config == 0) { | 1394 | if (gadget->speed == USB_SPEED_HIGH && dev->hs_config == 0) { |
1395 | spin_unlock(&dev->lock); | ||
1404 | ERROR (dev, "no high speed config??\n"); | 1396 | ERROR (dev, "no high speed config??\n"); |
1405 | return -EINVAL; | 1397 | return -EINVAL; |
1406 | } | 1398 | } |
1407 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | 1399 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ |
1408 | 1400 | ||
1401 | dev->state = STATE_DEV_CONNECTED; | ||
1402 | dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket; | ||
1403 | |||
1409 | INFO (dev, "connected\n"); | 1404 | INFO (dev, "connected\n"); |
1410 | event = next_event (dev, GADGETFS_CONNECT); | 1405 | event = next_event (dev, GADGETFS_CONNECT); |
1411 | event->u.speed = gadget->speed; | 1406 | event->u.speed = gadget->speed; |
1412 | ep0_readable (dev); | 1407 | ep0_readable (dev); |
1413 | 1408 | ||
1414 | list_for_each_entry (ep, &gadget->ep_list, ep_list) { | ||
1415 | data = ep->driver_data; | ||
1416 | /* ... down_trylock (&data->lock) ... */ | ||
1417 | if (data->state != STATE_EP_DEFER_ENABLE) | ||
1418 | continue; | ||
1419 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
1420 | if (gadget->speed == USB_SPEED_HIGH) | ||
1421 | value = usb_ep_enable (ep, &data->hs_desc); | ||
1422 | else | ||
1423 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | ||
1424 | value = usb_ep_enable (ep, &data->desc); | ||
1425 | if (value) { | ||
1426 | ERROR (dev, "deferred %s enable --> %d\n", | ||
1427 | data->name, value); | ||
1428 | continue; | ||
1429 | } | ||
1430 | data->state = STATE_EP_ENABLED; | ||
1431 | wake_up (&data->wait); | ||
1432 | DBG (dev, "woke up %s waiters\n", data->name); | ||
1433 | } | ||
1434 | |||
1435 | /* host may have given up waiting for response. we can miss control | 1409 | /* host may have given up waiting for response. we can miss control |
1436 | * requests handled lower down (device/endpoint status and features); | 1410 | * requests handled lower down (device/endpoint status and features); |
1437 | * then ep0_{read,write} will report the wrong status. controller | 1411 | * then ep0_{read,write} will report the wrong status. controller |
1438 | * driver will have aborted pending i/o. | 1412 | * driver will have aborted pending i/o. |
1439 | */ | 1413 | */ |
1440 | } else if (dev->state == STATE_SETUP) | 1414 | } else if (dev->state == STATE_DEV_SETUP) |
1441 | dev->setup_abort = 1; | 1415 | dev->setup_abort = 1; |
1442 | 1416 | ||
1443 | req->buf = dev->rbuf; | 1417 | req->buf = dev->rbuf; |
@@ -1583,7 +1557,7 @@ delegate: | |||
1583 | } | 1557 | } |
1584 | 1558 | ||
1585 | /* proceed with data transfer and status phases? */ | 1559 | /* proceed with data transfer and status phases? */ |
1586 | if (value >= 0 && dev->state != STATE_SETUP) { | 1560 | if (value >= 0 && dev->state != STATE_DEV_SETUP) { |
1587 | req->length = value; | 1561 | req->length = value; |
1588 | req->zero = value < w_length; | 1562 | req->zero = value < w_length; |
1589 | value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC); | 1563 | value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC); |
@@ -1747,7 +1721,9 @@ gadgetfs_bind (struct usb_gadget *gadget) | |||
1747 | goto enomem; | 1721 | goto enomem; |
1748 | 1722 | ||
1749 | INFO (dev, "bound to %s driver\n", gadget->name); | 1723 | INFO (dev, "bound to %s driver\n", gadget->name); |
1750 | dev->state = STATE_UNCONNECTED; | 1724 | spin_lock_irq(&dev->lock); |
1725 | dev->state = STATE_DEV_UNCONNECTED; | ||
1726 | spin_unlock_irq(&dev->lock); | ||
1751 | get_dev (dev); | 1727 | get_dev (dev); |
1752 | return 0; | 1728 | return 0; |
1753 | 1729 | ||
@@ -1762,11 +1738,9 @@ gadgetfs_disconnect (struct usb_gadget *gadget) | |||
1762 | struct dev_data *dev = get_gadget_data (gadget); | 1738 | struct dev_data *dev = get_gadget_data (gadget); |
1763 | 1739 | ||
1764 | spin_lock (&dev->lock); | 1740 | spin_lock (&dev->lock); |
1765 | if (dev->state == STATE_UNCONNECTED) { | 1741 | if (dev->state == STATE_DEV_UNCONNECTED) |
1766 | DBG (dev, "already unconnected\n"); | ||
1767 | goto exit; | 1742 | goto exit; |
1768 | } | 1743 | dev->state = STATE_DEV_UNCONNECTED; |
1769 | dev->state = STATE_UNCONNECTED; | ||
1770 | 1744 | ||
1771 | INFO (dev, "disconnected\n"); | 1745 | INFO (dev, "disconnected\n"); |
1772 | next_event (dev, GADGETFS_DISCONNECT); | 1746 | next_event (dev, GADGETFS_DISCONNECT); |
@@ -1783,9 +1757,9 @@ gadgetfs_suspend (struct usb_gadget *gadget) | |||
1783 | INFO (dev, "suspended from state %d\n", dev->state); | 1757 | INFO (dev, "suspended from state %d\n", dev->state); |
1784 | spin_lock (&dev->lock); | 1758 | spin_lock (&dev->lock); |
1785 | switch (dev->state) { | 1759 | switch (dev->state) { |
1786 | case STATE_SETUP: // VERY odd... host died?? | 1760 | case STATE_DEV_SETUP: // VERY odd... host died?? |
1787 | case STATE_CONNECTED: | 1761 | case STATE_DEV_CONNECTED: |
1788 | case STATE_UNCONNECTED: | 1762 | case STATE_DEV_UNCONNECTED: |
1789 | next_event (dev, GADGETFS_SUSPEND); | 1763 | next_event (dev, GADGETFS_SUSPEND); |
1790 | ep0_readable (dev); | 1764 | ep0_readable (dev); |
1791 | /* FALLTHROUGH */ | 1765 | /* FALLTHROUGH */ |
@@ -1808,7 +1782,7 @@ static struct usb_gadget_driver gadgetfs_driver = { | |||
1808 | .disconnect = gadgetfs_disconnect, | 1782 | .disconnect = gadgetfs_disconnect, |
1809 | .suspend = gadgetfs_suspend, | 1783 | .suspend = gadgetfs_suspend, |
1810 | 1784 | ||
1811 | .driver = { | 1785 | .driver = { |
1812 | .name = (char *) shortname, | 1786 | .name = (char *) shortname, |
1813 | }, | 1787 | }, |
1814 | }; | 1788 | }; |
@@ -1829,7 +1803,7 @@ static struct usb_gadget_driver probe_driver = { | |||
1829 | .unbind = gadgetfs_nop, | 1803 | .unbind = gadgetfs_nop, |
1830 | .setup = (void *)gadgetfs_nop, | 1804 | .setup = (void *)gadgetfs_nop, |
1831 | .disconnect = gadgetfs_nop, | 1805 | .disconnect = gadgetfs_nop, |
1832 | .driver = { | 1806 | .driver = { |
1833 | .name = "nop", | 1807 | .name = "nop", |
1834 | }, | 1808 | }, |
1835 | }; | 1809 | }; |
@@ -1849,19 +1823,16 @@ static struct usb_gadget_driver probe_driver = { | |||
1849 | * . full/low speed config ... all wTotalLength bytes (with interface, | 1823 | * . full/low speed config ... all wTotalLength bytes (with interface, |
1850 | * class, altsetting, endpoint, and other descriptors) | 1824 | * class, altsetting, endpoint, and other descriptors) |
1851 | * . high speed config ... all descriptors, for high speed operation; | 1825 | * . high speed config ... all descriptors, for high speed operation; |
1852 | * this one's optional except for high-speed hardware | 1826 | * this one's optional except for high-speed hardware |
1853 | * . device descriptor | 1827 | * . device descriptor |
1854 | * | 1828 | * |
1855 | * Endpoints are not yet enabled. Drivers may want to immediately | 1829 | * Endpoints are not yet enabled. Drivers must wait until device |
1856 | * initialize them, using the /dev/gadget/ep* files that are available | 1830 | * configuration and interface altsetting changes create |
1857 | * as soon as the kernel sees the configuration, or they can wait | ||
1858 | * until device configuration and interface altsetting changes create | ||
1859 | * the need to configure (or unconfigure) them. | 1831 | * the need to configure (or unconfigure) them. |
1860 | * | 1832 | * |
1861 | * After initialization, the device stays active for as long as that | 1833 | * After initialization, the device stays active for as long as that |
1862 | * $CHIP file is open. Events may then be read from that descriptor, | 1834 | * $CHIP file is open. Events must then be read from that descriptor, |
1863 | * such as configuration notifications. More complex drivers will handle | 1835 | * such as configuration notifications. |
1864 | * some control requests in user space. | ||
1865 | */ | 1836 | */ |
1866 | 1837 | ||
1867 | static int is_valid_config (struct usb_config_descriptor *config) | 1838 | static int is_valid_config (struct usb_config_descriptor *config) |
@@ -1884,9 +1855,6 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) | |||
1884 | u32 tag; | 1855 | u32 tag; |
1885 | char *kbuf; | 1856 | char *kbuf; |
1886 | 1857 | ||
1887 | if (dev->state != STATE_OPENED) | ||
1888 | return -EEXIST; | ||
1889 | |||
1890 | if (len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) | 1858 | if (len < (USB_DT_CONFIG_SIZE + USB_DT_DEVICE_SIZE + 4)) |
1891 | return -EINVAL; | 1859 | return -EINVAL; |
1892 | 1860 | ||
@@ -1978,13 +1946,15 @@ dev_open (struct inode *inode, struct file *fd) | |||
1978 | struct dev_data *dev = inode->i_private; | 1946 | struct dev_data *dev = inode->i_private; |
1979 | int value = -EBUSY; | 1947 | int value = -EBUSY; |
1980 | 1948 | ||
1949 | spin_lock_irq(&dev->lock); | ||
1981 | if (dev->state == STATE_DEV_DISABLED) { | 1950 | if (dev->state == STATE_DEV_DISABLED) { |
1982 | dev->ev_next = 0; | 1951 | dev->ev_next = 0; |
1983 | dev->state = STATE_OPENED; | 1952 | dev->state = STATE_DEV_OPENED; |
1984 | fd->private_data = dev; | 1953 | fd->private_data = dev; |
1985 | get_dev (dev); | 1954 | get_dev (dev); |
1986 | value = 0; | 1955 | value = 0; |
1987 | } | 1956 | } |
1957 | spin_unlock_irq(&dev->lock); | ||
1988 | return value; | 1958 | return value; |
1989 | } | 1959 | } |
1990 | 1960 | ||
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c index 4a991564a03e..a0a73c08a344 100644 --- a/drivers/usb/gadget/lh7a40x_udc.c +++ b/drivers/usb/gadget/lh7a40x_udc.c | |||
@@ -422,9 +422,10 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
422 | DEBUG("%s: %s\n", __FUNCTION__, driver->driver.name); | 422 | DEBUG("%s: %s\n", __FUNCTION__, driver->driver.name); |
423 | 423 | ||
424 | if (!driver | 424 | if (!driver |
425 | || driver->speed != USB_SPEED_FULL | 425 | || driver->speed != USB_SPEED_FULL |
426 | || !driver->bind | 426 | || !driver->bind |
427 | || !driver->unbind || !driver->disconnect || !driver->setup) | 427 | || !driver->disconnect |
428 | || !driver->setup) | ||
428 | return -EINVAL; | 429 | return -EINVAL; |
429 | if (!dev) | 430 | if (!dev) |
430 | return -ENODEV; | 431 | return -ENODEV; |
@@ -471,7 +472,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
471 | 472 | ||
472 | if (!dev) | 473 | if (!dev) |
473 | return -ENODEV; | 474 | return -ENODEV; |
474 | if (!driver || driver != dev->driver) | 475 | if (!driver || driver != dev->driver || !driver->unbind) |
475 | return -EINVAL; | 476 | return -EINVAL; |
476 | 477 | ||
477 | spin_lock_irqsave(&dev->lock, flags); | 478 | spin_lock_irqsave(&dev->lock, flags); |
@@ -2125,9 +2126,11 @@ static int lh7a40x_udc_remove(struct platform_device *pdev) | |||
2125 | 2126 | ||
2126 | DEBUG("%s: %p\n", __FUNCTION__, pdev); | 2127 | DEBUG("%s: %p\n", __FUNCTION__, pdev); |
2127 | 2128 | ||
2129 | if (dev->driver) | ||
2130 | return -EBUSY; | ||
2131 | |||
2128 | udc_disable(dev); | 2132 | udc_disable(dev); |
2129 | remove_proc_files(); | 2133 | remove_proc_files(); |
2130 | usb_gadget_unregister_driver(dev->driver); | ||
2131 | 2134 | ||
2132 | free_irq(IRQ_USBINTR, dev); | 2135 | free_irq(IRQ_USBINTR, dev); |
2133 | 2136 | ||
diff --git a/drivers/usb/gadget/lh7a40x_udc.h b/drivers/usb/gadget/lh7a40x_udc.h index e3bb78524c88..b3fe197e1eeb 100644 --- a/drivers/usb/gadget/lh7a40x_udc.h +++ b/drivers/usb/gadget/lh7a40x_udc.h | |||
@@ -49,7 +49,7 @@ | |||
49 | #include <asm/unaligned.h> | 49 | #include <asm/unaligned.h> |
50 | #include <asm/hardware.h> | 50 | #include <asm/hardware.h> |
51 | 51 | ||
52 | #include <linux/usb_ch9.h> | 52 | #include <linux/usb/ch9.h> |
53 | #include <linux/usb_gadget.h> | 53 | #include <linux/usb_gadget.h> |
54 | 54 | ||
55 | /* | 55 | /* |
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 3024c679e38e..7617ff7bd5ac 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -63,7 +63,7 @@ | |||
63 | #include <linux/interrupt.h> | 63 | #include <linux/interrupt.h> |
64 | #include <linux/moduleparam.h> | 64 | #include <linux/moduleparam.h> |
65 | #include <linux/device.h> | 65 | #include <linux/device.h> |
66 | #include <linux/usb_ch9.h> | 66 | #include <linux/usb/ch9.h> |
67 | #include <linux/usb_gadget.h> | 67 | #include <linux/usb_gadget.h> |
68 | 68 | ||
69 | #include <asm/byteorder.h> | 69 | #include <asm/byteorder.h> |
@@ -2020,7 +2020,6 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
2020 | if (!driver | 2020 | if (!driver |
2021 | || driver->speed != USB_SPEED_HIGH | 2021 | || driver->speed != USB_SPEED_HIGH |
2022 | || !driver->bind | 2022 | || !driver->bind |
2023 | || !driver->unbind | ||
2024 | || !driver->setup) | 2023 | || !driver->setup) |
2025 | return -EINVAL; | 2024 | return -EINVAL; |
2026 | if (!dev) | 2025 | if (!dev) |
@@ -2107,7 +2106,7 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) | |||
2107 | 2106 | ||
2108 | if (!dev) | 2107 | if (!dev) |
2109 | return -ENODEV; | 2108 | return -ENODEV; |
2110 | if (!driver || driver != dev->driver) | 2109 | if (!driver || driver != dev->driver || !driver->unbind) |
2111 | return -EINVAL; | 2110 | return -EINVAL; |
2112 | 2111 | ||
2113 | spin_lock_irqsave (&dev->lock, flags); | 2112 | spin_lock_irqsave (&dev->lock, flags); |
@@ -2803,13 +2802,7 @@ static void net2280_remove (struct pci_dev *pdev) | |||
2803 | { | 2802 | { |
2804 | struct net2280 *dev = pci_get_drvdata (pdev); | 2803 | struct net2280 *dev = pci_get_drvdata (pdev); |
2805 | 2804 | ||
2806 | /* start with the driver above us */ | 2805 | BUG_ON(dev->driver); |
2807 | if (dev->driver) { | ||
2808 | /* should have been done already by driver model core */ | ||
2809 | WARN (dev, "pci remove, driver '%s' is still registered\n", | ||
2810 | dev->driver->driver.name); | ||
2811 | usb_gadget_unregister_driver (dev->driver); | ||
2812 | } | ||
2813 | 2806 | ||
2814 | /* then clean up the resources we allocated during probe() */ | 2807 | /* then clean up the resources we allocated during probe() */ |
2815 | net2280_led_shutdown (dev); | 2808 | net2280_led_shutdown (dev); |
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 030d87c28c2f..140104341db4 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c | |||
@@ -38,10 +38,11 @@ | |||
38 | #include <linux/mm.h> | 38 | #include <linux/mm.h> |
39 | #include <linux/moduleparam.h> | 39 | #include <linux/moduleparam.h> |
40 | #include <linux/platform_device.h> | 40 | #include <linux/platform_device.h> |
41 | #include <linux/usb_ch9.h> | 41 | #include <linux/usb/ch9.h> |
42 | #include <linux/usb_gadget.h> | 42 | #include <linux/usb_gadget.h> |
43 | #include <linux/usb/otg.h> | 43 | #include <linux/usb/otg.h> |
44 | #include <linux/dma-mapping.h> | 44 | #include <linux/dma-mapping.h> |
45 | #include <linux/clk.h> | ||
45 | 46 | ||
46 | #include <asm/byteorder.h> | 47 | #include <asm/byteorder.h> |
47 | #include <asm/io.h> | 48 | #include <asm/io.h> |
@@ -60,6 +61,11 @@ | |||
60 | /* bulk DMA seems to be behaving for both IN and OUT */ | 61 | /* bulk DMA seems to be behaving for both IN and OUT */ |
61 | #define USE_DMA | 62 | #define USE_DMA |
62 | 63 | ||
64 | /* FIXME: OMAP2 currently has some problem in DMA mode */ | ||
65 | #ifdef CONFIG_ARCH_OMAP2 | ||
66 | #undef USE_DMA | ||
67 | #endif | ||
68 | |||
63 | /* ISO too */ | 69 | /* ISO too */ |
64 | #define USE_ISO | 70 | #define USE_ISO |
65 | 71 | ||
@@ -99,7 +105,7 @@ static unsigned fifo_mode = 0; | |||
99 | * boot parameter "omap_udc:fifo_mode=42" | 105 | * boot parameter "omap_udc:fifo_mode=42" |
100 | */ | 106 | */ |
101 | module_param (fifo_mode, uint, 0); | 107 | module_param (fifo_mode, uint, 0); |
102 | MODULE_PARM_DESC (fifo_mode, "endpoint setup (0 == default)"); | 108 | MODULE_PARM_DESC (fifo_mode, "endpoint configuration"); |
103 | 109 | ||
104 | #ifdef USE_DMA | 110 | #ifdef USE_DMA |
105 | static unsigned use_dma = 1; | 111 | static unsigned use_dma = 1; |
@@ -122,7 +128,7 @@ static const char driver_desc [] = DRIVER_DESC; | |||
122 | /*-------------------------------------------------------------------------*/ | 128 | /*-------------------------------------------------------------------------*/ |
123 | 129 | ||
124 | /* there's a notion of "current endpoint" for modifying endpoint | 130 | /* there's a notion of "current endpoint" for modifying endpoint |
125 | * state, and PIO access to its FIFO. | 131 | * state, and PIO access to its FIFO. |
126 | */ | 132 | */ |
127 | 133 | ||
128 | static void use_ep(struct omap_ep *ep, u16 select) | 134 | static void use_ep(struct omap_ep *ep, u16 select) |
@@ -391,7 +397,7 @@ done(struct omap_ep *ep, struct omap_req *req, int status) | |||
391 | #define FIFO_EMPTY (UDC_NON_ISO_FIFO_EMPTY | UDC_ISO_FIFO_EMPTY) | 397 | #define FIFO_EMPTY (UDC_NON_ISO_FIFO_EMPTY | UDC_ISO_FIFO_EMPTY) |
392 | #define FIFO_UNREADABLE (UDC_EP_HALTED | FIFO_EMPTY) | 398 | #define FIFO_UNREADABLE (UDC_EP_HALTED | FIFO_EMPTY) |
393 | 399 | ||
394 | static inline int | 400 | static inline int |
395 | write_packet(u8 *buf, struct omap_req *req, unsigned max) | 401 | write_packet(u8 *buf, struct omap_req *req, unsigned max) |
396 | { | 402 | { |
397 | unsigned len; | 403 | unsigned len; |
@@ -456,7 +462,7 @@ static int write_fifo(struct omap_ep *ep, struct omap_req *req) | |||
456 | return is_last; | 462 | return is_last; |
457 | } | 463 | } |
458 | 464 | ||
459 | static inline int | 465 | static inline int |
460 | read_packet(u8 *buf, struct omap_req *req, unsigned avail) | 466 | read_packet(u8 *buf, struct omap_req *req, unsigned avail) |
461 | { | 467 | { |
462 | unsigned len; | 468 | unsigned len; |
@@ -542,9 +548,9 @@ static inline dma_addr_t dma_csac(unsigned lch) | |||
542 | /* omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is | 548 | /* omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is |
543 | * read before the DMA controller finished disabling the channel. | 549 | * read before the DMA controller finished disabling the channel. |
544 | */ | 550 | */ |
545 | csac = omap_readw(OMAP_DMA_CSAC(lch)); | 551 | csac = OMAP_DMA_CSAC_REG(lch); |
546 | if (csac == 0) | 552 | if (csac == 0) |
547 | csac = omap_readw(OMAP_DMA_CSAC(lch)); | 553 | csac = OMAP_DMA_CSAC_REG(lch); |
548 | return csac; | 554 | return csac; |
549 | } | 555 | } |
550 | 556 | ||
@@ -555,9 +561,9 @@ static inline dma_addr_t dma_cdac(unsigned lch) | |||
555 | /* omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is | 561 | /* omap 3.2/3.3 erratum: sometimes 0 is returned if CSAC/CDAC is |
556 | * read before the DMA controller finished disabling the channel. | 562 | * read before the DMA controller finished disabling the channel. |
557 | */ | 563 | */ |
558 | cdac = omap_readw(OMAP_DMA_CDAC(lch)); | 564 | cdac = OMAP_DMA_CDAC_REG(lch); |
559 | if (cdac == 0) | 565 | if (cdac == 0) |
560 | cdac = omap_readw(OMAP_DMA_CDAC(lch)); | 566 | cdac = OMAP_DMA_CDAC_REG(lch); |
561 | return cdac; | 567 | return cdac; |
562 | } | 568 | } |
563 | 569 | ||
@@ -582,7 +588,7 @@ static u16 dma_src_len(struct omap_ep *ep, dma_addr_t start) | |||
582 | } | 588 | } |
583 | 589 | ||
584 | #define DMA_DEST_LAST(x) (cpu_is_omap15xx() \ | 590 | #define DMA_DEST_LAST(x) (cpu_is_omap15xx() \ |
585 | ? omap_readw(OMAP_DMA_CSAC(x)) /* really: CPC */ \ | 591 | ? OMAP_DMA_CSAC_REG(x) /* really: CPC */ \ |
586 | : dma_cdac(x)) | 592 | : dma_cdac(x)) |
587 | 593 | ||
588 | static u16 dma_dest_len(struct omap_ep *ep, dma_addr_t start) | 594 | static u16 dma_dest_len(struct omap_ep *ep, dma_addr_t start) |
@@ -620,17 +626,19 @@ static void next_in_dma(struct omap_ep *ep, struct omap_req *req) | |||
620 | || (cpu_is_omap15xx() && length < ep->maxpacket)) { | 626 | || (cpu_is_omap15xx() && length < ep->maxpacket)) { |
621 | txdma_ctrl = UDC_TXN_EOT | length; | 627 | txdma_ctrl = UDC_TXN_EOT | length; |
622 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, | 628 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S8, |
623 | length, 1, sync_mode); | 629 | length, 1, sync_mode, 0, 0); |
624 | } else { | 630 | } else { |
625 | length = min(length / ep->maxpacket, | 631 | length = min(length / ep->maxpacket, |
626 | (unsigned) UDC_TXN_TSC + 1); | 632 | (unsigned) UDC_TXN_TSC + 1); |
627 | txdma_ctrl = length; | 633 | txdma_ctrl = length; |
628 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16, | 634 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16, |
629 | ep->ep.maxpacket >> 1, length, sync_mode); | 635 | ep->ep.maxpacket >> 1, length, sync_mode, |
636 | 0, 0); | ||
630 | length *= ep->maxpacket; | 637 | length *= ep->maxpacket; |
631 | } | 638 | } |
632 | omap_set_dma_src_params(ep->lch, OMAP_DMA_PORT_EMIFF, | 639 | omap_set_dma_src_params(ep->lch, OMAP_DMA_PORT_EMIFF, |
633 | OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual); | 640 | OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual, |
641 | 0, 0); | ||
634 | 642 | ||
635 | omap_start_dma(ep->lch); | 643 | omap_start_dma(ep->lch); |
636 | ep->dma_counter = dma_csac(ep->lch); | 644 | ep->dma_counter = dma_csac(ep->lch); |
@@ -675,9 +683,11 @@ static void next_out_dma(struct omap_ep *ep, struct omap_req *req) | |||
675 | req->dma_bytes = packets * ep->ep.maxpacket; | 683 | req->dma_bytes = packets * ep->ep.maxpacket; |
676 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16, | 684 | omap_set_dma_transfer_params(ep->lch, OMAP_DMA_DATA_TYPE_S16, |
677 | ep->ep.maxpacket >> 1, packets, | 685 | ep->ep.maxpacket >> 1, packets, |
678 | OMAP_DMA_SYNC_ELEMENT); | 686 | OMAP_DMA_SYNC_ELEMENT, |
687 | 0, 0); | ||
679 | omap_set_dma_dest_params(ep->lch, OMAP_DMA_PORT_EMIFF, | 688 | omap_set_dma_dest_params(ep->lch, OMAP_DMA_PORT_EMIFF, |
680 | OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual); | 689 | OMAP_DMA_AMODE_POST_INC, req->req.dma + req->req.actual, |
690 | 0, 0); | ||
681 | ep->dma_counter = DMA_DEST_LAST(ep->lch); | 691 | ep->dma_counter = DMA_DEST_LAST(ep->lch); |
682 | 692 | ||
683 | UDC_RXDMA_REG(ep->dma_channel) = UDC_RXN_STOP | (packets - 1); | 693 | UDC_RXDMA_REG(ep->dma_channel) = UDC_RXN_STOP | (packets - 1); |
@@ -820,7 +830,8 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) | |||
820 | omap_set_dma_dest_params(ep->lch, | 830 | omap_set_dma_dest_params(ep->lch, |
821 | OMAP_DMA_PORT_TIPB, | 831 | OMAP_DMA_PORT_TIPB, |
822 | OMAP_DMA_AMODE_CONSTANT, | 832 | OMAP_DMA_AMODE_CONSTANT, |
823 | (unsigned long) io_v2p((u32)&UDC_DATA_DMA_REG)); | 833 | (unsigned long) io_v2p((u32)&UDC_DATA_DMA_REG), |
834 | 0, 0); | ||
824 | } | 835 | } |
825 | } else { | 836 | } else { |
826 | status = omap_request_dma(OMAP_DMA_USB_W2FC_RX0 - 1 + channel, | 837 | status = omap_request_dma(OMAP_DMA_USB_W2FC_RX0 - 1 + channel, |
@@ -831,7 +842,8 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) | |||
831 | omap_set_dma_src_params(ep->lch, | 842 | omap_set_dma_src_params(ep->lch, |
832 | OMAP_DMA_PORT_TIPB, | 843 | OMAP_DMA_PORT_TIPB, |
833 | OMAP_DMA_AMODE_CONSTANT, | 844 | OMAP_DMA_AMODE_CONSTANT, |
834 | (unsigned long) io_v2p((u32)&UDC_DATA_DMA_REG)); | 845 | (unsigned long) io_v2p((u32)&UDC_DATA_DMA_REG), |
846 | 0, 0); | ||
835 | /* EMIFF */ | 847 | /* EMIFF */ |
836 | omap_set_dma_dest_burst_mode(ep->lch, | 848 | omap_set_dma_dest_burst_mode(ep->lch, |
837 | OMAP_DMA_DATA_BURST_4); | 849 | OMAP_DMA_DATA_BURST_4); |
@@ -846,7 +858,7 @@ static void dma_channel_claim(struct omap_ep *ep, unsigned channel) | |||
846 | 858 | ||
847 | /* channel type P: hw synch (fifo) */ | 859 | /* channel type P: hw synch (fifo) */ |
848 | if (!cpu_is_omap15xx()) | 860 | if (!cpu_is_omap15xx()) |
849 | omap_writew(2, OMAP_DMA_LCH_CTRL(ep->lch)); | 861 | OMAP1_DMA_LCH_CTRL_REG(ep->lch) = 2; |
850 | } | 862 | } |
851 | 863 | ||
852 | just_restart: | 864 | just_restart: |
@@ -893,7 +905,7 @@ static void dma_channel_release(struct omap_ep *ep) | |||
893 | else | 905 | else |
894 | req = NULL; | 906 | req = NULL; |
895 | 907 | ||
896 | active = ((1 << 7) & omap_readl(OMAP_DMA_CCR(ep->lch))) != 0; | 908 | active = ((1 << 7) & OMAP_DMA_CCR_REG(ep->lch)) != 0; |
897 | 909 | ||
898 | DBG("%s release %s %cxdma%d %p\n", ep->ep.name, | 910 | DBG("%s release %s %cxdma%d %p\n", ep->ep.name, |
899 | active ? "active" : "idle", | 911 | active ? "active" : "idle", |
@@ -1117,7 +1129,7 @@ static int omap_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | |||
1117 | */ | 1129 | */ |
1118 | dma_channel_release(ep); | 1130 | dma_channel_release(ep); |
1119 | dma_channel_claim(ep, channel); | 1131 | dma_channel_claim(ep, channel); |
1120 | } else | 1132 | } else |
1121 | done(ep, req, -ECONNRESET); | 1133 | done(ep, req, -ECONNRESET); |
1122 | spin_unlock_irqrestore(&ep->udc->lock, flags); | 1134 | spin_unlock_irqrestore(&ep->udc->lock, flags); |
1123 | return 0; | 1135 | return 0; |
@@ -1153,7 +1165,7 @@ static int omap_ep_set_halt(struct usb_ep *_ep, int value) | |||
1153 | 1165 | ||
1154 | /* IN endpoints must already be idle */ | 1166 | /* IN endpoints must already be idle */ |
1155 | if ((ep->bEndpointAddress & USB_DIR_IN) | 1167 | if ((ep->bEndpointAddress & USB_DIR_IN) |
1156 | && !list_empty(&ep->queue)) { | 1168 | && !list_empty(&ep->queue)) { |
1157 | status = -EAGAIN; | 1169 | status = -EAGAIN; |
1158 | goto done; | 1170 | goto done; |
1159 | } | 1171 | } |
@@ -1298,6 +1310,23 @@ static void pullup_disable(struct omap_udc *udc) | |||
1298 | UDC_SYSCON1_REG &= ~UDC_PULLUP_EN; | 1310 | UDC_SYSCON1_REG &= ~UDC_PULLUP_EN; |
1299 | } | 1311 | } |
1300 | 1312 | ||
1313 | static struct omap_udc *udc; | ||
1314 | |||
1315 | static void omap_udc_enable_clock(int enable) | ||
1316 | { | ||
1317 | if (udc == NULL || udc->dc_clk == NULL || udc->hhc_clk == NULL) | ||
1318 | return; | ||
1319 | |||
1320 | if (enable) { | ||
1321 | clk_enable(udc->dc_clk); | ||
1322 | clk_enable(udc->hhc_clk); | ||
1323 | udelay(100); | ||
1324 | } else { | ||
1325 | clk_disable(udc->hhc_clk); | ||
1326 | clk_disable(udc->dc_clk); | ||
1327 | } | ||
1328 | } | ||
1329 | |||
1301 | /* | 1330 | /* |
1302 | * Called by whatever detects VBUS sessions: external transceiver | 1331 | * Called by whatever detects VBUS sessions: external transceiver |
1303 | * driver, or maybe GPIO0 VBUS IRQ. May request 48 MHz clock. | 1332 | * driver, or maybe GPIO0 VBUS IRQ. May request 48 MHz clock. |
@@ -1318,10 +1347,22 @@ static int omap_vbus_session(struct usb_gadget *gadget, int is_active) | |||
1318 | else | 1347 | else |
1319 | FUNC_MUX_CTRL_0_REG &= ~VBUS_CTRL_1510; | 1348 | FUNC_MUX_CTRL_0_REG &= ~VBUS_CTRL_1510; |
1320 | } | 1349 | } |
1350 | if (udc->dc_clk != NULL && is_active) { | ||
1351 | if (!udc->clk_requested) { | ||
1352 | omap_udc_enable_clock(1); | ||
1353 | udc->clk_requested = 1; | ||
1354 | } | ||
1355 | } | ||
1321 | if (can_pullup(udc)) | 1356 | if (can_pullup(udc)) |
1322 | pullup_enable(udc); | 1357 | pullup_enable(udc); |
1323 | else | 1358 | else |
1324 | pullup_disable(udc); | 1359 | pullup_disable(udc); |
1360 | if (udc->dc_clk != NULL && !is_active) { | ||
1361 | if (udc->clk_requested) { | ||
1362 | omap_udc_enable_clock(0); | ||
1363 | udc->clk_requested = 0; | ||
1364 | } | ||
1365 | } | ||
1325 | spin_unlock_irqrestore(&udc->lock, flags); | 1366 | spin_unlock_irqrestore(&udc->lock, flags); |
1326 | return 0; | 1367 | return 0; |
1327 | } | 1368 | } |
@@ -1441,7 +1482,7 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) | |||
1441 | } | 1482 | } |
1442 | } | 1483 | } |
1443 | 1484 | ||
1444 | /* IN/OUT packets mean we're in the DATA or STATUS stage. | 1485 | /* IN/OUT packets mean we're in the DATA or STATUS stage. |
1445 | * This driver uses only uses protocol stalls (ep0 never halts), | 1486 | * This driver uses only uses protocol stalls (ep0 never halts), |
1446 | * and if we got this far the gadget driver already had a | 1487 | * and if we got this far the gadget driver already had a |
1447 | * chance to stall. Tries to be forgiving of host oddities. | 1488 | * chance to stall. Tries to be forgiving of host oddities. |
@@ -1509,7 +1550,7 @@ static void ep0_irq(struct omap_udc *udc, u16 irq_src) | |||
1509 | } else if (stat == 0) | 1550 | } else if (stat == 0) |
1510 | UDC_CTRL_REG = UDC_SET_FIFO_EN; | 1551 | UDC_CTRL_REG = UDC_SET_FIFO_EN; |
1511 | UDC_EP_NUM_REG = 0; | 1552 | UDC_EP_NUM_REG = 0; |
1512 | 1553 | ||
1513 | /* activate status stage */ | 1554 | /* activate status stage */ |
1514 | if (stat == 1) { | 1555 | if (stat == 1) { |
1515 | done(ep0, req, 0); | 1556 | done(ep0, req, 0); |
@@ -1866,7 +1907,7 @@ static void pio_out_timer(unsigned long _ep) | |||
1866 | 1907 | ||
1867 | spin_lock_irqsave(&ep->udc->lock, flags); | 1908 | spin_lock_irqsave(&ep->udc->lock, flags); |
1868 | if (!list_empty(&ep->queue) && ep->ackwait) { | 1909 | if (!list_empty(&ep->queue) && ep->ackwait) { |
1869 | use_ep(ep, 0); | 1910 | use_ep(ep, UDC_EP_SEL); |
1870 | stat_flg = UDC_STAT_FLG_REG; | 1911 | stat_flg = UDC_STAT_FLG_REG; |
1871 | 1912 | ||
1872 | if ((stat_flg & UDC_ACK) && (!(stat_flg & UDC_FIFO_EN) | 1913 | if ((stat_flg & UDC_ACK) && (!(stat_flg & UDC_FIFO_EN) |
@@ -1876,12 +1917,12 @@ static void pio_out_timer(unsigned long _ep) | |||
1876 | VDBG("%s: lose, %04x\n", ep->ep.name, stat_flg); | 1917 | VDBG("%s: lose, %04x\n", ep->ep.name, stat_flg); |
1877 | req = container_of(ep->queue.next, | 1918 | req = container_of(ep->queue.next, |
1878 | struct omap_req, queue); | 1919 | struct omap_req, queue); |
1879 | UDC_EP_NUM_REG = ep->bEndpointAddress | UDC_EP_SEL; | ||
1880 | (void) read_fifo(ep, req); | 1920 | (void) read_fifo(ep, req); |
1881 | UDC_EP_NUM_REG = ep->bEndpointAddress; | 1921 | UDC_EP_NUM_REG = ep->bEndpointAddress; |
1882 | UDC_CTRL_REG = UDC_SET_FIFO_EN; | 1922 | UDC_CTRL_REG = UDC_SET_FIFO_EN; |
1883 | ep->ackwait = 1 + ep->double_buf; | 1923 | ep->ackwait = 1 + ep->double_buf; |
1884 | } | 1924 | } else |
1925 | deselect_ep(); | ||
1885 | } | 1926 | } |
1886 | mod_timer(&ep->timer, PIO_OUT_TIMEOUT); | 1927 | mod_timer(&ep->timer, PIO_OUT_TIMEOUT); |
1887 | spin_unlock_irqrestore(&ep->udc->lock, flags); | 1928 | spin_unlock_irqrestore(&ep->udc->lock, flags); |
@@ -2028,7 +2069,17 @@ static irqreturn_t omap_udc_iso_irq(int irq, void *_dev) | |||
2028 | 2069 | ||
2029 | /*-------------------------------------------------------------------------*/ | 2070 | /*-------------------------------------------------------------------------*/ |
2030 | 2071 | ||
2031 | static struct omap_udc *udc; | 2072 | static inline int machine_needs_vbus_session(void) |
2073 | { | ||
2074 | return (machine_is_omap_innovator() | ||
2075 | || machine_is_omap_osk() | ||
2076 | || machine_is_omap_apollon() | ||
2077 | #ifndef CONFIG_MACH_OMAP_H4_OTG | ||
2078 | || machine_is_omap_h4() | ||
2079 | #endif | ||
2080 | || machine_is_sx1() | ||
2081 | ); | ||
2082 | } | ||
2032 | 2083 | ||
2033 | int usb_gadget_register_driver (struct usb_gadget_driver *driver) | 2084 | int usb_gadget_register_driver (struct usb_gadget_driver *driver) |
2034 | { | 2085 | { |
@@ -2043,7 +2094,6 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
2043 | // FIXME if otg, check: driver->is_otg | 2094 | // FIXME if otg, check: driver->is_otg |
2044 | || driver->speed < USB_SPEED_FULL | 2095 | || driver->speed < USB_SPEED_FULL |
2045 | || !driver->bind | 2096 | || !driver->bind |
2046 | || !driver->unbind | ||
2047 | || !driver->setup) | 2097 | || !driver->setup) |
2048 | return -EINVAL; | 2098 | return -EINVAL; |
2049 | 2099 | ||
@@ -2071,6 +2121,9 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
2071 | udc->gadget.dev.driver = &driver->driver; | 2121 | udc->gadget.dev.driver = &driver->driver; |
2072 | spin_unlock_irqrestore(&udc->lock, flags); | 2122 | spin_unlock_irqrestore(&udc->lock, flags); |
2073 | 2123 | ||
2124 | if (udc->dc_clk != NULL) | ||
2125 | omap_udc_enable_clock(1); | ||
2126 | |||
2074 | status = driver->bind (&udc->gadget); | 2127 | status = driver->bind (&udc->gadget); |
2075 | if (status) { | 2128 | if (status) { |
2076 | DBG("bind to %s --> %d\n", driver->driver.name, status); | 2129 | DBG("bind to %s --> %d\n", driver->driver.name, status); |
@@ -2087,9 +2140,11 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
2087 | status = otg_set_peripheral(udc->transceiver, &udc->gadget); | 2140 | status = otg_set_peripheral(udc->transceiver, &udc->gadget); |
2088 | if (status < 0) { | 2141 | if (status < 0) { |
2089 | ERR("can't bind to transceiver\n"); | 2142 | ERR("can't bind to transceiver\n"); |
2090 | driver->unbind (&udc->gadget); | 2143 | if (driver->unbind) { |
2091 | udc->gadget.dev.driver = NULL; | 2144 | driver->unbind (&udc->gadget); |
2092 | udc->driver = NULL; | 2145 | udc->gadget.dev.driver = NULL; |
2146 | udc->driver = NULL; | ||
2147 | } | ||
2093 | goto done; | 2148 | goto done; |
2094 | } | 2149 | } |
2095 | } else { | 2150 | } else { |
@@ -2102,10 +2157,12 @@ int usb_gadget_register_driver (struct usb_gadget_driver *driver) | |||
2102 | /* boards that don't have VBUS sensing can't autogate 48MHz; | 2157 | /* boards that don't have VBUS sensing can't autogate 48MHz; |
2103 | * can't enter deep sleep while a gadget driver is active. | 2158 | * can't enter deep sleep while a gadget driver is active. |
2104 | */ | 2159 | */ |
2105 | if (machine_is_omap_innovator() || machine_is_omap_osk()) | 2160 | if (machine_needs_vbus_session()) |
2106 | omap_vbus_session(&udc->gadget, 1); | 2161 | omap_vbus_session(&udc->gadget, 1); |
2107 | 2162 | ||
2108 | done: | 2163 | done: |
2164 | if (udc->dc_clk != NULL) | ||
2165 | omap_udc_enable_clock(0); | ||
2109 | return status; | 2166 | return status; |
2110 | } | 2167 | } |
2111 | EXPORT_SYMBOL(usb_gadget_register_driver); | 2168 | EXPORT_SYMBOL(usb_gadget_register_driver); |
@@ -2117,10 +2174,13 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) | |||
2117 | 2174 | ||
2118 | if (!udc) | 2175 | if (!udc) |
2119 | return -ENODEV; | 2176 | return -ENODEV; |
2120 | if (!driver || driver != udc->driver) | 2177 | if (!driver || driver != udc->driver || !driver->unbind) |
2121 | return -EINVAL; | 2178 | return -EINVAL; |
2122 | 2179 | ||
2123 | if (machine_is_omap_innovator() || machine_is_omap_osk()) | 2180 | if (udc->dc_clk != NULL) |
2181 | omap_udc_enable_clock(1); | ||
2182 | |||
2183 | if (machine_needs_vbus_session()) | ||
2124 | omap_vbus_session(&udc->gadget, 0); | 2184 | omap_vbus_session(&udc->gadget, 0); |
2125 | 2185 | ||
2126 | if (udc->transceiver) | 2186 | if (udc->transceiver) |
@@ -2136,6 +2196,8 @@ int usb_gadget_unregister_driver (struct usb_gadget_driver *driver) | |||
2136 | udc->gadget.dev.driver = NULL; | 2196 | udc->gadget.dev.driver = NULL; |
2137 | udc->driver = NULL; | 2197 | udc->driver = NULL; |
2138 | 2198 | ||
2199 | if (udc->dc_clk != NULL) | ||
2200 | omap_udc_enable_clock(0); | ||
2139 | DBG("unregistered driver '%s'\n", driver->driver.name); | 2201 | DBG("unregistered driver '%s'\n", driver->driver.name); |
2140 | return status; | 2202 | return status; |
2141 | } | 2203 | } |
@@ -2218,7 +2280,7 @@ static char *trx_mode(unsigned m, int enabled) | |||
2218 | case 0: return enabled ? "*6wire" : "unused"; | 2280 | case 0: return enabled ? "*6wire" : "unused"; |
2219 | case 1: return "4wire"; | 2281 | case 1: return "4wire"; |
2220 | case 2: return "3wire"; | 2282 | case 2: return "3wire"; |
2221 | case 3: return "6wire"; | 2283 | case 3: return "6wire"; |
2222 | default: return "unknown"; | 2284 | default: return "unknown"; |
2223 | } | 2285 | } |
2224 | } | 2286 | } |
@@ -2227,11 +2289,18 @@ static int proc_otg_show(struct seq_file *s) | |||
2227 | { | 2289 | { |
2228 | u32 tmp; | 2290 | u32 tmp; |
2229 | u32 trans; | 2291 | u32 trans; |
2292 | char *ctrl_name; | ||
2230 | 2293 | ||
2231 | tmp = OTG_REV_REG; | 2294 | tmp = OTG_REV_REG; |
2232 | trans = USB_TRANSCEIVER_CTRL_REG; | 2295 | if (cpu_is_omap24xx()) { |
2233 | seq_printf(s, "\nOTG rev %d.%d, transceiver_ctrl %05x\n", | 2296 | ctrl_name = "control_devconf"; |
2234 | tmp >> 4, tmp & 0xf, trans); | 2297 | trans = CONTROL_DEVCONF_REG; |
2298 | } else { | ||
2299 | ctrl_name = "tranceiver_ctrl"; | ||
2300 | trans = USB_TRANSCEIVER_CTRL_REG; | ||
2301 | } | ||
2302 | seq_printf(s, "\nOTG rev %d.%d, %s %05x\n", | ||
2303 | tmp >> 4, tmp & 0xf, ctrl_name, trans); | ||
2235 | tmp = OTG_SYSCON_1_REG; | 2304 | tmp = OTG_SYSCON_1_REG; |
2236 | seq_printf(s, "otg_syscon1 %08x usb2 %s, usb1 %s, usb0 %s," | 2305 | seq_printf(s, "otg_syscon1 %08x usb2 %s, usb1 %s, usb0 %s," |
2237 | FOURBITS "\n", tmp, | 2306 | FOURBITS "\n", tmp, |
@@ -2306,7 +2375,7 @@ static int proc_udc_show(struct seq_file *s, void *_) | |||
2306 | driver_desc, | 2375 | driver_desc, |
2307 | use_dma ? " (dma)" : ""); | 2376 | use_dma ? " (dma)" : ""); |
2308 | 2377 | ||
2309 | tmp = UDC_REV_REG & 0xff; | 2378 | tmp = UDC_REV_REG & 0xff; |
2310 | seq_printf(s, | 2379 | seq_printf(s, |
2311 | "UDC rev %d.%d, fifo mode %d, gadget %s\n" | 2380 | "UDC rev %d.%d, fifo mode %d, gadget %s\n" |
2312 | "hmc %d, transceiver %s\n", | 2381 | "hmc %d, transceiver %s\n", |
@@ -2314,11 +2383,16 @@ static int proc_udc_show(struct seq_file *s, void *_) | |||
2314 | fifo_mode, | 2383 | fifo_mode, |
2315 | udc->driver ? udc->driver->driver.name : "(none)", | 2384 | udc->driver ? udc->driver->driver.name : "(none)", |
2316 | HMC, | 2385 | HMC, |
2317 | udc->transceiver ? udc->transceiver->label : "(none)"); | 2386 | udc->transceiver |
2318 | seq_printf(s, "ULPD control %04x req %04x status %04x\n", | 2387 | ? udc->transceiver->label |
2319 | __REG16(ULPD_CLOCK_CTRL), | 2388 | : ((cpu_is_omap1710() || cpu_is_omap24xx()) |
2320 | __REG16(ULPD_SOFT_REQ), | 2389 | ? "external" : "(none)")); |
2321 | __REG16(ULPD_STATUS_REQ)); | 2390 | if (cpu_class_is_omap1()) { |
2391 | seq_printf(s, "ULPD control %04x req %04x status %04x\n", | ||
2392 | __REG16(ULPD_CLOCK_CTRL), | ||
2393 | __REG16(ULPD_SOFT_REQ), | ||
2394 | __REG16(ULPD_STATUS_REQ)); | ||
2395 | } | ||
2322 | 2396 | ||
2323 | /* OTG controller registers */ | 2397 | /* OTG controller registers */ |
2324 | if (!cpu_is_omap15xx()) | 2398 | if (!cpu_is_omap15xx()) |
@@ -2503,9 +2577,10 @@ omap_ep_setup(char *name, u8 addr, u8 type, | |||
2503 | dbuf = 1; | 2577 | dbuf = 1; |
2504 | } else { | 2578 | } else { |
2505 | /* double-buffering "not supported" on 15xx, | 2579 | /* double-buffering "not supported" on 15xx, |
2506 | * and ignored for PIO-IN on 16xx | 2580 | * and ignored for PIO-IN on newer chips |
2581 | * (for more reliable behavior) | ||
2507 | */ | 2582 | */ |
2508 | if (!use_dma || cpu_is_omap15xx()) | 2583 | if (!use_dma || cpu_is_omap15xx() || cpu_is_omap24xx()) |
2509 | dbuf = 0; | 2584 | dbuf = 0; |
2510 | 2585 | ||
2511 | switch (maxp) { | 2586 | switch (maxp) { |
@@ -2548,7 +2623,7 @@ omap_ep_setup(char *name, u8 addr, u8 type, | |||
2548 | ep->bEndpointAddress = addr; | 2623 | ep->bEndpointAddress = addr; |
2549 | ep->bmAttributes = type; | 2624 | ep->bmAttributes = type; |
2550 | ep->double_buf = dbuf; | 2625 | ep->double_buf = dbuf; |
2551 | ep->udc = udc; | 2626 | ep->udc = udc; |
2552 | 2627 | ||
2553 | ep->ep.name = ep->name; | 2628 | ep->ep.name = ep->name; |
2554 | ep->ep.ops = &omap_ep_ops; | 2629 | ep->ep.ops = &omap_ep_ops; |
@@ -2708,15 +2783,37 @@ static int __init omap_udc_probe(struct platform_device *pdev) | |||
2708 | struct otg_transceiver *xceiv = NULL; | 2783 | struct otg_transceiver *xceiv = NULL; |
2709 | const char *type = NULL; | 2784 | const char *type = NULL; |
2710 | struct omap_usb_config *config = pdev->dev.platform_data; | 2785 | struct omap_usb_config *config = pdev->dev.platform_data; |
2786 | struct clk *dc_clk; | ||
2787 | struct clk *hhc_clk; | ||
2711 | 2788 | ||
2712 | /* NOTE: "knows" the order of the resources! */ | 2789 | /* NOTE: "knows" the order of the resources! */ |
2713 | if (!request_mem_region(pdev->resource[0].start, | 2790 | if (!request_mem_region(pdev->resource[0].start, |
2714 | pdev->resource[0].end - pdev->resource[0].start + 1, | 2791 | pdev->resource[0].end - pdev->resource[0].start + 1, |
2715 | driver_name)) { | 2792 | driver_name)) { |
2716 | DBG("request_mem_region failed\n"); | 2793 | DBG("request_mem_region failed\n"); |
2717 | return -EBUSY; | 2794 | return -EBUSY; |
2718 | } | 2795 | } |
2719 | 2796 | ||
2797 | if (cpu_is_omap16xx()) { | ||
2798 | dc_clk = clk_get(&pdev->dev, "usb_dc_ck"); | ||
2799 | hhc_clk = clk_get(&pdev->dev, "usb_hhc_ck"); | ||
2800 | BUG_ON(IS_ERR(dc_clk) || IS_ERR(hhc_clk)); | ||
2801 | /* can't use omap_udc_enable_clock yet */ | ||
2802 | clk_enable(dc_clk); | ||
2803 | clk_enable(hhc_clk); | ||
2804 | udelay(100); | ||
2805 | } | ||
2806 | |||
2807 | if (cpu_is_omap24xx()) { | ||
2808 | dc_clk = clk_get(&pdev->dev, "usb_fck"); | ||
2809 | hhc_clk = clk_get(&pdev->dev, "usb_l4_ick"); | ||
2810 | BUG_ON(IS_ERR(dc_clk) || IS_ERR(hhc_clk)); | ||
2811 | /* can't use omap_udc_enable_clock yet */ | ||
2812 | clk_enable(dc_clk); | ||
2813 | clk_enable(hhc_clk); | ||
2814 | udelay(100); | ||
2815 | } | ||
2816 | |||
2720 | INFO("OMAP UDC rev %d.%d%s\n", | 2817 | INFO("OMAP UDC rev %d.%d%s\n", |
2721 | UDC_REV_REG >> 4, UDC_REV_REG & 0xf, | 2818 | UDC_REV_REG >> 4, UDC_REV_REG & 0xf, |
2722 | config->otg ? ", Mini-AB" : ""); | 2819 | config->otg ? ", Mini-AB" : ""); |
@@ -2726,7 +2823,7 @@ static int __init omap_udc_probe(struct platform_device *pdev) | |||
2726 | hmc = HMC_1510; | 2823 | hmc = HMC_1510; |
2727 | type = "(unknown)"; | 2824 | type = "(unknown)"; |
2728 | 2825 | ||
2729 | if (machine_is_omap_innovator()) { | 2826 | if (machine_is_omap_innovator() || machine_is_sx1()) { |
2730 | /* just set up software VBUS detect, and then | 2827 | /* just set up software VBUS detect, and then |
2731 | * later rig it so we always report VBUS. | 2828 | * later rig it so we always report VBUS. |
2732 | * FIXME without really sensing VBUS, we can't | 2829 | * FIXME without really sensing VBUS, we can't |
@@ -2755,6 +2852,15 @@ static int __init omap_udc_probe(struct platform_device *pdev) | |||
2755 | } | 2852 | } |
2756 | 2853 | ||
2757 | hmc = HMC_1610; | 2854 | hmc = HMC_1610; |
2855 | |||
2856 | if (cpu_is_omap24xx()) { | ||
2857 | /* this could be transceiverless in one of the | ||
2858 | * "we don't need to know" modes. | ||
2859 | */ | ||
2860 | type = "external"; | ||
2861 | goto known; | ||
2862 | } | ||
2863 | |||
2758 | switch (hmc) { | 2864 | switch (hmc) { |
2759 | case 0: /* POWERUP DEFAULT == 0 */ | 2865 | case 0: /* POWERUP DEFAULT == 0 */ |
2760 | case 4: | 2866 | case 4: |
@@ -2793,6 +2899,7 @@ bad_on_1710: | |||
2793 | goto cleanup0; | 2899 | goto cleanup0; |
2794 | } | 2900 | } |
2795 | } | 2901 | } |
2902 | known: | ||
2796 | INFO("hmc mode %d, %s transceiver\n", hmc, type); | 2903 | INFO("hmc mode %d, %s transceiver\n", hmc, type); |
2797 | 2904 | ||
2798 | /* a "gadget" abstracts/virtualizes the controller */ | 2905 | /* a "gadget" abstracts/virtualizes the controller */ |
@@ -2817,8 +2924,8 @@ bad_on_1710: | |||
2817 | status = request_irq(pdev->resource[1].start, omap_udc_irq, | 2924 | status = request_irq(pdev->resource[1].start, omap_udc_irq, |
2818 | IRQF_SAMPLE_RANDOM, driver_name, udc); | 2925 | IRQF_SAMPLE_RANDOM, driver_name, udc); |
2819 | if (status != 0) { | 2926 | if (status != 0) { |
2820 | ERR( "can't get irq %ld, err %d\n", | 2927 | ERR("can't get irq %d, err %d\n", |
2821 | pdev->resource[1].start, status); | 2928 | (int) pdev->resource[1].start, status); |
2822 | goto cleanup1; | 2929 | goto cleanup1; |
2823 | } | 2930 | } |
2824 | 2931 | ||
@@ -2826,24 +2933,41 @@ bad_on_1710: | |||
2826 | status = request_irq(pdev->resource[2].start, omap_udc_pio_irq, | 2933 | status = request_irq(pdev->resource[2].start, omap_udc_pio_irq, |
2827 | IRQF_SAMPLE_RANDOM, "omap_udc pio", udc); | 2934 | IRQF_SAMPLE_RANDOM, "omap_udc pio", udc); |
2828 | if (status != 0) { | 2935 | if (status != 0) { |
2829 | ERR( "can't get irq %ld, err %d\n", | 2936 | ERR("can't get irq %d, err %d\n", |
2830 | pdev->resource[2].start, status); | 2937 | (int) pdev->resource[2].start, status); |
2831 | goto cleanup2; | 2938 | goto cleanup2; |
2832 | } | 2939 | } |
2833 | #ifdef USE_ISO | 2940 | #ifdef USE_ISO |
2834 | status = request_irq(pdev->resource[3].start, omap_udc_iso_irq, | 2941 | status = request_irq(pdev->resource[3].start, omap_udc_iso_irq, |
2835 | IRQF_DISABLED, "omap_udc iso", udc); | 2942 | IRQF_DISABLED, "omap_udc iso", udc); |
2836 | if (status != 0) { | 2943 | if (status != 0) { |
2837 | ERR("can't get irq %ld, err %d\n", | 2944 | ERR("can't get irq %d, err %d\n", |
2838 | pdev->resource[3].start, status); | 2945 | (int) pdev->resource[3].start, status); |
2839 | goto cleanup3; | 2946 | goto cleanup3; |
2840 | } | 2947 | } |
2841 | #endif | 2948 | #endif |
2949 | if (cpu_is_omap16xx()) { | ||
2950 | udc->dc_clk = dc_clk; | ||
2951 | udc->hhc_clk = hhc_clk; | ||
2952 | clk_disable(hhc_clk); | ||
2953 | clk_disable(dc_clk); | ||
2954 | } | ||
2955 | |||
2956 | if (cpu_is_omap24xx()) { | ||
2957 | udc->dc_clk = dc_clk; | ||
2958 | udc->hhc_clk = hhc_clk; | ||
2959 | /* FIXME OMAP2 don't release hhc & dc clock */ | ||
2960 | #if 0 | ||
2961 | clk_disable(hhc_clk); | ||
2962 | clk_disable(dc_clk); | ||
2963 | #endif | ||
2964 | } | ||
2842 | 2965 | ||
2843 | create_proc_file(); | 2966 | create_proc_file(); |
2844 | device_add(&udc->gadget.dev); | 2967 | status = device_add(&udc->gadget.dev); |
2845 | return 0; | 2968 | if (!status) |
2846 | 2969 | return status; | |
2970 | /* If fail, fall through */ | ||
2847 | #ifdef USE_ISO | 2971 | #ifdef USE_ISO |
2848 | cleanup3: | 2972 | cleanup3: |
2849 | free_irq(pdev->resource[2].start, udc); | 2973 | free_irq(pdev->resource[2].start, udc); |
@@ -2859,8 +2983,17 @@ cleanup1: | |||
2859 | cleanup0: | 2983 | cleanup0: |
2860 | if (xceiv) | 2984 | if (xceiv) |
2861 | put_device(xceiv->dev); | 2985 | put_device(xceiv->dev); |
2986 | |||
2987 | if (cpu_is_omap16xx() || cpu_is_omap24xx()) { | ||
2988 | clk_disable(hhc_clk); | ||
2989 | clk_disable(dc_clk); | ||
2990 | clk_put(hhc_clk); | ||
2991 | clk_put(dc_clk); | ||
2992 | } | ||
2993 | |||
2862 | release_mem_region(pdev->resource[0].start, | 2994 | release_mem_region(pdev->resource[0].start, |
2863 | pdev->resource[0].end - pdev->resource[0].start + 1); | 2995 | pdev->resource[0].end - pdev->resource[0].start + 1); |
2996 | |||
2864 | return status; | 2997 | return status; |
2865 | } | 2998 | } |
2866 | 2999 | ||
@@ -2870,6 +3003,8 @@ static int __exit omap_udc_remove(struct platform_device *pdev) | |||
2870 | 3003 | ||
2871 | if (!udc) | 3004 | if (!udc) |
2872 | return -ENODEV; | 3005 | return -ENODEV; |
3006 | if (udc->driver) | ||
3007 | return -EBUSY; | ||
2873 | 3008 | ||
2874 | udc->done = &done; | 3009 | udc->done = &done; |
2875 | 3010 | ||
@@ -2888,6 +3023,13 @@ static int __exit omap_udc_remove(struct platform_device *pdev) | |||
2888 | free_irq(pdev->resource[2].start, udc); | 3023 | free_irq(pdev->resource[2].start, udc); |
2889 | free_irq(pdev->resource[1].start, udc); | 3024 | free_irq(pdev->resource[1].start, udc); |
2890 | 3025 | ||
3026 | if (udc->dc_clk) { | ||
3027 | if (udc->clk_requested) | ||
3028 | omap_udc_enable_clock(0); | ||
3029 | clk_put(udc->hhc_clk); | ||
3030 | clk_put(udc->dc_clk); | ||
3031 | } | ||
3032 | |||
2891 | release_mem_region(pdev->resource[0].start, | 3033 | release_mem_region(pdev->resource[0].start, |
2892 | pdev->resource[0].end - pdev->resource[0].start + 1); | 3034 | pdev->resource[0].end - pdev->resource[0].start + 1); |
2893 | 3035 | ||
diff --git a/drivers/usb/gadget/omap_udc.h b/drivers/usb/gadget/omap_udc.h index 652ee4627344..1dc398bb9ab2 100644 --- a/drivers/usb/gadget/omap_udc.h +++ b/drivers/usb/gadget/omap_udc.h | |||
@@ -175,6 +175,9 @@ struct omap_udc { | |||
175 | unsigned ep0_reset_config:1; | 175 | unsigned ep0_reset_config:1; |
176 | unsigned ep0_setup:1; | 176 | unsigned ep0_setup:1; |
177 | struct completion *done; | 177 | struct completion *done; |
178 | struct clk *dc_clk; | ||
179 | struct clk *hhc_clk; | ||
180 | unsigned clk_requested:1; | ||
178 | }; | 181 | }; |
179 | 182 | ||
180 | /*-------------------------------------------------------------------------*/ | 183 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 1ed506e95985..0d225369847d 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c | |||
@@ -56,7 +56,7 @@ | |||
56 | #include <asm/arch/pxa-regs.h> | 56 | #include <asm/arch/pxa-regs.h> |
57 | #endif | 57 | #endif |
58 | 58 | ||
59 | #include <linux/usb_ch9.h> | 59 | #include <linux/usb/ch9.h> |
60 | #include <linux/usb_gadget.h> | 60 | #include <linux/usb_gadget.h> |
61 | 61 | ||
62 | #include <asm/arch/udc.h> | 62 | #include <asm/arch/udc.h> |
@@ -1623,7 +1623,6 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1623 | if (!driver | 1623 | if (!driver |
1624 | || driver->speed < USB_SPEED_FULL | 1624 | || driver->speed < USB_SPEED_FULL |
1625 | || !driver->bind | 1625 | || !driver->bind |
1626 | || !driver->unbind | ||
1627 | || !driver->disconnect | 1626 | || !driver->disconnect |
1628 | || !driver->setup) | 1627 | || !driver->setup) |
1629 | return -EINVAL; | 1628 | return -EINVAL; |
@@ -1694,7 +1693,7 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1694 | 1693 | ||
1695 | if (!dev) | 1694 | if (!dev) |
1696 | return -ENODEV; | 1695 | return -ENODEV; |
1697 | if (!driver || driver != dev->driver) | 1696 | if (!driver || driver != dev->driver || !driver->unbind) |
1698 | return -EINVAL; | 1697 | return -EINVAL; |
1699 | 1698 | ||
1700 | local_irq_disable(); | 1699 | local_irq_disable(); |
@@ -2638,9 +2637,11 @@ static int __exit pxa2xx_udc_remove(struct platform_device *pdev) | |||
2638 | { | 2637 | { |
2639 | struct pxa2xx_udc *dev = platform_get_drvdata(pdev); | 2638 | struct pxa2xx_udc *dev = platform_get_drvdata(pdev); |
2640 | 2639 | ||
2640 | if (dev->driver) | ||
2641 | return -EBUSY; | ||
2642 | |||
2641 | udc_disable(dev); | 2643 | udc_disable(dev); |
2642 | remove_proc_files(); | 2644 | remove_proc_files(); |
2643 | usb_gadget_unregister_driver(dev->driver); | ||
2644 | 2645 | ||
2645 | if (dev->got_irq) { | 2646 | if (dev->got_irq) { |
2646 | free_irq(IRQ_USB, dev); | 2647 | free_irq(IRQ_USB, dev); |
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index 208e55a667ac..6c742a909225 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -43,7 +43,7 @@ | |||
43 | #include <asm/unaligned.h> | 43 | #include <asm/unaligned.h> |
44 | #include <asm/uaccess.h> | 44 | #include <asm/uaccess.h> |
45 | 45 | ||
46 | #include <linux/usb_ch9.h> | 46 | #include <linux/usb/ch9.h> |
47 | #include <linux/usb/cdc.h> | 47 | #include <linux/usb/cdc.h> |
48 | #include <linux/usb_gadget.h> | 48 | #include <linux/usb_gadget.h> |
49 | 49 | ||
@@ -200,7 +200,7 @@ static void gs_unthrottle(struct tty_struct * tty); | |||
200 | static void gs_break(struct tty_struct *tty, int break_state); | 200 | static void gs_break(struct tty_struct *tty, int break_state); |
201 | static int gs_ioctl(struct tty_struct *tty, struct file *file, | 201 | static int gs_ioctl(struct tty_struct *tty, struct file *file, |
202 | unsigned int cmd, unsigned long arg); | 202 | unsigned int cmd, unsigned long arg); |
203 | static void gs_set_termios(struct tty_struct *tty, struct termios *old); | 203 | static void gs_set_termios(struct tty_struct *tty, struct ktermios *old); |
204 | 204 | ||
205 | static int gs_send(struct gs_dev *dev); | 205 | static int gs_send(struct gs_dev *dev); |
206 | static int gs_send_packet(struct gs_dev *dev, char *packet, | 206 | static int gs_send_packet(struct gs_dev *dev, char *packet, |
@@ -296,7 +296,7 @@ static struct usb_gadget_driver gs_gadget_driver = { | |||
296 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | 296 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ |
297 | .function = GS_LONG_NAME, | 297 | .function = GS_LONG_NAME, |
298 | .bind = gs_bind, | 298 | .bind = gs_bind, |
299 | .unbind = __exit_p(gs_unbind), | 299 | .unbind = gs_unbind, |
300 | .setup = gs_setup, | 300 | .setup = gs_setup, |
301 | .disconnect = gs_disconnect, | 301 | .disconnect = gs_disconnect, |
302 | .driver = { | 302 | .driver = { |
@@ -1077,7 +1077,7 @@ static int gs_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, | |||
1077 | /* | 1077 | /* |
1078 | * gs_set_termios | 1078 | * gs_set_termios |
1079 | */ | 1079 | */ |
1080 | static void gs_set_termios(struct tty_struct *tty, struct termios *old) | 1080 | static void gs_set_termios(struct tty_struct *tty, struct ktermios *old) |
1081 | { | 1081 | { |
1082 | } | 1082 | } |
1083 | 1083 | ||
@@ -2195,7 +2195,7 @@ static struct gs_buf *gs_buf_alloc(unsigned int size, gfp_t kmalloc_flags) | |||
2195 | if (size == 0) | 2195 | if (size == 0) |
2196 | return NULL; | 2196 | return NULL; |
2197 | 2197 | ||
2198 | gb = (struct gs_buf *)kmalloc(sizeof(struct gs_buf), kmalloc_flags); | 2198 | gb = kmalloc(sizeof(struct gs_buf), kmalloc_flags); |
2199 | if (gb == NULL) | 2199 | if (gb == NULL) |
2200 | return NULL; | 2200 | return NULL; |
2201 | 2201 | ||
diff --git a/drivers/usb/gadget/usbstring.c b/drivers/usb/gadget/usbstring.c index b1735767660b..3459ea6c6c0b 100644 --- a/drivers/usb/gadget/usbstring.c +++ b/drivers/usb/gadget/usbstring.c | |||
@@ -14,7 +14,7 @@ | |||
14 | #include <linux/device.h> | 14 | #include <linux/device.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | 16 | ||
17 | #include <linux/usb_ch9.h> | 17 | #include <linux/usb/ch9.h> |
18 | #include <linux/usb_gadget.h> | 18 | #include <linux/usb_gadget.h> |
19 | 19 | ||
20 | #include <asm/unaligned.h> | 20 | #include <asm/unaligned.h> |
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index 40710ea1b490..ebe04e0d2879 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c | |||
@@ -84,7 +84,7 @@ | |||
84 | #include <asm/system.h> | 84 | #include <asm/system.h> |
85 | #include <asm/unaligned.h> | 85 | #include <asm/unaligned.h> |
86 | 86 | ||
87 | #include <linux/usb_ch9.h> | 87 | #include <linux/usb/ch9.h> |
88 | #include <linux/usb_gadget.h> | 88 | #include <linux/usb_gadget.h> |
89 | 89 | ||
90 | #include "gadget_chips.h" | 90 | #include "gadget_chips.h" |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index cc60759083bf..62711870f8ee 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -67,6 +67,11 @@ config USB_EHCI_TT_NEWSCHED | |||
67 | 67 | ||
68 | If unsure, say N. | 68 | If unsure, say N. |
69 | 69 | ||
70 | config USB_EHCI_BIG_ENDIAN_MMIO | ||
71 | bool | ||
72 | depends on USB_EHCI_HCD | ||
73 | default n | ||
74 | |||
70 | config USB_ISP116X_HCD | 75 | config USB_ISP116X_HCD |
71 | tristate "ISP116X HCD support" | 76 | tristate "ISP116X HCD support" |
72 | depends on USB | 77 | depends on USB |
@@ -101,21 +106,48 @@ config USB_OHCI_HCD_PPC_SOC | |||
101 | bool "OHCI support for on-chip PPC USB controller" | 106 | bool "OHCI support for on-chip PPC USB controller" |
102 | depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx) | 107 | depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx) |
103 | default y | 108 | default y |
104 | select USB_OHCI_BIG_ENDIAN | 109 | select USB_OHCI_BIG_ENDIAN_DESC |
110 | select USB_OHCI_BIG_ENDIAN_MMIO | ||
105 | ---help--- | 111 | ---help--- |
106 | Enables support for the USB controller on the MPC52xx or | 112 | Enables support for the USB controller on the MPC52xx or |
107 | STB03xxx processor chip. If unsure, say Y. | 113 | STB03xxx processor chip. If unsure, say Y. |
108 | 114 | ||
115 | config USB_OHCI_HCD_PPC_OF | ||
116 | bool "OHCI support for PPC USB controller on OF platform bus" | ||
117 | depends on USB_OHCI_HCD && PPC_OF | ||
118 | default y | ||
119 | ---help--- | ||
120 | Enables support for the USB controller PowerPC present on the | ||
121 | OpenFirmware platform bus. | ||
122 | |||
123 | config USB_OHCI_HCD_PPC_OF_BE | ||
124 | bool "Support big endian HC" | ||
125 | depends on USB_OHCI_HCD_PPC_OF | ||
126 | default y | ||
127 | select USB_OHCI_BIG_ENDIAN_DESC | ||
128 | select USB_OHCI_BIG_ENDIAN_MMIO | ||
129 | |||
130 | config USB_OHCI_HCD_PPC_OF_LE | ||
131 | bool "Support little endian HC" | ||
132 | depends on USB_OHCI_HCD_PPC_OF | ||
133 | default n | ||
134 | select USB_OHCI_LITTLE_ENDIAN | ||
135 | |||
109 | config USB_OHCI_HCD_PCI | 136 | config USB_OHCI_HCD_PCI |
110 | bool "OHCI support for PCI-bus USB controllers" | 137 | bool "OHCI support for PCI-bus USB controllers" |
111 | depends on USB_OHCI_HCD && PCI && (STB03xxx || PPC_MPC52xx) | 138 | depends on USB_OHCI_HCD && PCI && (STB03xxx || PPC_MPC52xx || USB_OHCI_HCD_PPC_OF) |
112 | default y | 139 | default y |
113 | select USB_OHCI_LITTLE_ENDIAN | 140 | select USB_OHCI_LITTLE_ENDIAN |
114 | ---help--- | 141 | ---help--- |
115 | Enables support for PCI-bus plug-in USB controller cards. | 142 | Enables support for PCI-bus plug-in USB controller cards. |
116 | If unsure, say Y. | 143 | If unsure, say Y. |
117 | 144 | ||
118 | config USB_OHCI_BIG_ENDIAN | 145 | config USB_OHCI_BIG_ENDIAN_DESC |
146 | bool | ||
147 | depends on USB_OHCI_HCD | ||
148 | default n | ||
149 | |||
150 | config USB_OHCI_BIG_ENDIAN_MMIO | ||
119 | bool | 151 | bool |
120 | depends on USB_OHCI_HCD | 152 | depends on USB_OHCI_HCD |
121 | default n | 153 | default n |
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 56349d21e6ea..246afea9e83b 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c | |||
@@ -43,7 +43,7 @@ | |||
43 | */ | 43 | */ |
44 | static void dbg_hcs_params (struct ehci_hcd *ehci, char *label) | 44 | static void dbg_hcs_params (struct ehci_hcd *ehci, char *label) |
45 | { | 45 | { |
46 | u32 params = readl (&ehci->caps->hcs_params); | 46 | u32 params = ehci_readl(ehci, &ehci->caps->hcs_params); |
47 | 47 | ||
48 | ehci_dbg (ehci, | 48 | ehci_dbg (ehci, |
49 | "%s hcs_params 0x%x dbg=%d%s cc=%d pcc=%d%s%s ports=%d\n", | 49 | "%s hcs_params 0x%x dbg=%d%s cc=%d pcc=%d%s%s ports=%d\n", |
@@ -87,7 +87,7 @@ static inline void dbg_hcs_params (struct ehci_hcd *ehci, char *label) {} | |||
87 | * */ | 87 | * */ |
88 | static void dbg_hcc_params (struct ehci_hcd *ehci, char *label) | 88 | static void dbg_hcc_params (struct ehci_hcd *ehci, char *label) |
89 | { | 89 | { |
90 | u32 params = readl (&ehci->caps->hcc_params); | 90 | u32 params = ehci_readl(ehci, &ehci->caps->hcc_params); |
91 | 91 | ||
92 | if (HCC_ISOC_CACHE (params)) { | 92 | if (HCC_ISOC_CACHE (params)) { |
93 | ehci_dbg (ehci, | 93 | ehci_dbg (ehci, |
@@ -653,7 +653,7 @@ show_registers (struct class_device *class_dev, char *buf) | |||
653 | } | 653 | } |
654 | 654 | ||
655 | /* Capability Registers */ | 655 | /* Capability Registers */ |
656 | i = HC_VERSION(readl (&ehci->caps->hc_capbase)); | 656 | i = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); |
657 | temp = scnprintf (next, size, | 657 | temp = scnprintf (next, size, |
658 | "bus %s, device %s (driver " DRIVER_VERSION ")\n" | 658 | "bus %s, device %s (driver " DRIVER_VERSION ")\n" |
659 | "%s\n" | 659 | "%s\n" |
@@ -673,7 +673,7 @@ show_registers (struct class_device *class_dev, char *buf) | |||
673 | unsigned count = 256/4; | 673 | unsigned count = 256/4; |
674 | 674 | ||
675 | pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); | 675 | pdev = to_pci_dev(ehci_to_hcd(ehci)->self.controller); |
676 | offset = HCC_EXT_CAPS (readl (&ehci->caps->hcc_params)); | 676 | offset = HCC_EXT_CAPS (ehci_readl(ehci, &ehci->caps->hcc_params)); |
677 | while (offset && count--) { | 677 | while (offset && count--) { |
678 | pci_read_config_dword (pdev, offset, &cap); | 678 | pci_read_config_dword (pdev, offset, &cap); |
679 | switch (cap & 0xff) { | 679 | switch (cap & 0xff) { |
@@ -704,50 +704,50 @@ show_registers (struct class_device *class_dev, char *buf) | |||
704 | #endif | 704 | #endif |
705 | 705 | ||
706 | // FIXME interpret both types of params | 706 | // FIXME interpret both types of params |
707 | i = readl (&ehci->caps->hcs_params); | 707 | i = ehci_readl(ehci, &ehci->caps->hcs_params); |
708 | temp = scnprintf (next, size, "structural params 0x%08x\n", i); | 708 | temp = scnprintf (next, size, "structural params 0x%08x\n", i); |
709 | size -= temp; | 709 | size -= temp; |
710 | next += temp; | 710 | next += temp; |
711 | 711 | ||
712 | i = readl (&ehci->caps->hcc_params); | 712 | i = ehci_readl(ehci, &ehci->caps->hcc_params); |
713 | temp = scnprintf (next, size, "capability params 0x%08x\n", i); | 713 | temp = scnprintf (next, size, "capability params 0x%08x\n", i); |
714 | size -= temp; | 714 | size -= temp; |
715 | next += temp; | 715 | next += temp; |
716 | 716 | ||
717 | /* Operational Registers */ | 717 | /* Operational Registers */ |
718 | temp = dbg_status_buf (scratch, sizeof scratch, label, | 718 | temp = dbg_status_buf (scratch, sizeof scratch, label, |
719 | readl (&ehci->regs->status)); | 719 | ehci_readl(ehci, &ehci->regs->status)); |
720 | temp = scnprintf (next, size, fmt, temp, scratch); | 720 | temp = scnprintf (next, size, fmt, temp, scratch); |
721 | size -= temp; | 721 | size -= temp; |
722 | next += temp; | 722 | next += temp; |
723 | 723 | ||
724 | temp = dbg_command_buf (scratch, sizeof scratch, label, | 724 | temp = dbg_command_buf (scratch, sizeof scratch, label, |
725 | readl (&ehci->regs->command)); | 725 | ehci_readl(ehci, &ehci->regs->command)); |
726 | temp = scnprintf (next, size, fmt, temp, scratch); | 726 | temp = scnprintf (next, size, fmt, temp, scratch); |
727 | size -= temp; | 727 | size -= temp; |
728 | next += temp; | 728 | next += temp; |
729 | 729 | ||
730 | temp = dbg_intr_buf (scratch, sizeof scratch, label, | 730 | temp = dbg_intr_buf (scratch, sizeof scratch, label, |
731 | readl (&ehci->regs->intr_enable)); | 731 | ehci_readl(ehci, &ehci->regs->intr_enable)); |
732 | temp = scnprintf (next, size, fmt, temp, scratch); | 732 | temp = scnprintf (next, size, fmt, temp, scratch); |
733 | size -= temp; | 733 | size -= temp; |
734 | next += temp; | 734 | next += temp; |
735 | 735 | ||
736 | temp = scnprintf (next, size, "uframe %04x\n", | 736 | temp = scnprintf (next, size, "uframe %04x\n", |
737 | readl (&ehci->regs->frame_index)); | 737 | ehci_readl(ehci, &ehci->regs->frame_index)); |
738 | size -= temp; | 738 | size -= temp; |
739 | next += temp; | 739 | next += temp; |
740 | 740 | ||
741 | for (i = 1; i <= HCS_N_PORTS (ehci->hcs_params); i++) { | 741 | for (i = 1; i <= HCS_N_PORTS (ehci->hcs_params); i++) { |
742 | temp = dbg_port_buf (scratch, sizeof scratch, label, i, | 742 | temp = dbg_port_buf (scratch, sizeof scratch, label, i, |
743 | readl (&ehci->regs->port_status [i - 1])); | 743 | ehci_readl(ehci, &ehci->regs->port_status [i - 1])); |
744 | temp = scnprintf (next, size, fmt, temp, scratch); | 744 | temp = scnprintf (next, size, fmt, temp, scratch); |
745 | size -= temp; | 745 | size -= temp; |
746 | next += temp; | 746 | next += temp; |
747 | if (i == HCS_DEBUG_PORT(ehci->hcs_params) && ehci->debug) { | 747 | if (i == HCS_DEBUG_PORT(ehci->hcs_params) && ehci->debug) { |
748 | temp = scnprintf (next, size, | 748 | temp = scnprintf (next, size, |
749 | " debug control %08x\n", | 749 | " debug control %08x\n", |
750 | readl (&ehci->debug->control)); | 750 | ehci_readl(ehci, &ehci->debug->control)); |
751 | size -= temp; | 751 | size -= temp; |
752 | next += temp; | 752 | next += temp; |
753 | } | 753 | } |
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 1a915e982c1c..a52480505f78 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c | |||
@@ -177,7 +177,7 @@ static void mpc83xx_setup_phy(struct ehci_hcd *ehci, | |||
177 | case FSL_USB2_PHY_NONE: | 177 | case FSL_USB2_PHY_NONE: |
178 | break; | 178 | break; |
179 | } | 179 | } |
180 | writel(portsc, &ehci->regs->port_status[port_offset]); | 180 | ehci_writel(ehci, portsc, &ehci->regs->port_status[port_offset]); |
181 | } | 181 | } |
182 | 182 | ||
183 | static void mpc83xx_usb_setup(struct usb_hcd *hcd) | 183 | static void mpc83xx_usb_setup(struct usb_hcd *hcd) |
@@ -214,7 +214,7 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd) | |||
214 | } | 214 | } |
215 | 215 | ||
216 | /* put controller in host mode. */ | 216 | /* put controller in host mode. */ |
217 | writel(0x00000003, non_ehci + FSL_SOC_USB_USBMODE); | 217 | ehci_writel(ehci, 0x00000003, non_ehci + FSL_SOC_USB_USBMODE); |
218 | out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c); | 218 | out_be32(non_ehci + FSL_SOC_USB_PRICTRL, 0x0000000c); |
219 | out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040); | 219 | out_be32(non_ehci + FSL_SOC_USB_AGECNTTHRSH, 0x00000040); |
220 | out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001); | 220 | out_be32(non_ehci + FSL_SOC_USB_SICTRL, 0x00000001); |
@@ -238,12 +238,12 @@ static int ehci_fsl_setup(struct usb_hcd *hcd) | |||
238 | /* EHCI registers start at offset 0x100 */ | 238 | /* EHCI registers start at offset 0x100 */ |
239 | ehci->caps = hcd->regs + 0x100; | 239 | ehci->caps = hcd->regs + 0x100; |
240 | ehci->regs = hcd->regs + 0x100 + | 240 | ehci->regs = hcd->regs + 0x100 + |
241 | HC_LENGTH(readl(&ehci->caps->hc_capbase)); | 241 | HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); |
242 | dbg_hcs_params(ehci, "reset"); | 242 | dbg_hcs_params(ehci, "reset"); |
243 | dbg_hcc_params(ehci, "reset"); | 243 | dbg_hcc_params(ehci, "reset"); |
244 | 244 | ||
245 | /* cache this readonly data; minimize chip reads */ | 245 | /* cache this readonly data; minimize chip reads */ |
246 | ehci->hcs_params = readl(&ehci->caps->hcs_params); | 246 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); |
247 | 247 | ||
248 | retval = ehci_halt(ehci); | 248 | retval = ehci_halt(ehci); |
249 | if (retval) | 249 | if (retval) |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 025d33313681..185721dba42b 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -157,12 +157,13 @@ MODULE_PARM_DESC (ignore_oc, "ignore bogus hardware overcurrent indications"); | |||
157 | * before driver shutdown. But it also seems to be caused by bugs in cardbus | 157 | * before driver shutdown. But it also seems to be caused by bugs in cardbus |
158 | * bridge shutdown: shutting down the bridge before the devices using it. | 158 | * bridge shutdown: shutting down the bridge before the devices using it. |
159 | */ | 159 | */ |
160 | static int handshake (void __iomem *ptr, u32 mask, u32 done, int usec) | 160 | static int handshake (struct ehci_hcd *ehci, void __iomem *ptr, |
161 | u32 mask, u32 done, int usec) | ||
161 | { | 162 | { |
162 | u32 result; | 163 | u32 result; |
163 | 164 | ||
164 | do { | 165 | do { |
165 | result = readl (ptr); | 166 | result = ehci_readl(ehci, ptr); |
166 | if (result == ~(u32)0) /* card removed */ | 167 | if (result == ~(u32)0) /* card removed */ |
167 | return -ENODEV; | 168 | return -ENODEV; |
168 | result &= mask; | 169 | result &= mask; |
@@ -177,18 +178,19 @@ static int handshake (void __iomem *ptr, u32 mask, u32 done, int usec) | |||
177 | /* force HC to halt state from unknown (EHCI spec section 2.3) */ | 178 | /* force HC to halt state from unknown (EHCI spec section 2.3) */ |
178 | static int ehci_halt (struct ehci_hcd *ehci) | 179 | static int ehci_halt (struct ehci_hcd *ehci) |
179 | { | 180 | { |
180 | u32 temp = readl (&ehci->regs->status); | 181 | u32 temp = ehci_readl(ehci, &ehci->regs->status); |
181 | 182 | ||
182 | /* disable any irqs left enabled by previous code */ | 183 | /* disable any irqs left enabled by previous code */ |
183 | writel (0, &ehci->regs->intr_enable); | 184 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); |
184 | 185 | ||
185 | if ((temp & STS_HALT) != 0) | 186 | if ((temp & STS_HALT) != 0) |
186 | return 0; | 187 | return 0; |
187 | 188 | ||
188 | temp = readl (&ehci->regs->command); | 189 | temp = ehci_readl(ehci, &ehci->regs->command); |
189 | temp &= ~CMD_RUN; | 190 | temp &= ~CMD_RUN; |
190 | writel (temp, &ehci->regs->command); | 191 | ehci_writel(ehci, temp, &ehci->regs->command); |
191 | return handshake (&ehci->regs->status, STS_HALT, STS_HALT, 16 * 125); | 192 | return handshake (ehci, &ehci->regs->status, |
193 | STS_HALT, STS_HALT, 16 * 125); | ||
192 | } | 194 | } |
193 | 195 | ||
194 | /* put TDI/ARC silicon into EHCI mode */ | 196 | /* put TDI/ARC silicon into EHCI mode */ |
@@ -198,23 +200,24 @@ static void tdi_reset (struct ehci_hcd *ehci) | |||
198 | u32 tmp; | 200 | u32 tmp; |
199 | 201 | ||
200 | reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + 0x68); | 202 | reg_ptr = (u32 __iomem *)(((u8 __iomem *)ehci->regs) + 0x68); |
201 | tmp = readl (reg_ptr); | 203 | tmp = ehci_readl(ehci, reg_ptr); |
202 | tmp |= 0x3; | 204 | tmp |= 0x3; |
203 | writel (tmp, reg_ptr); | 205 | ehci_writel(ehci, tmp, reg_ptr); |
204 | } | 206 | } |
205 | 207 | ||
206 | /* reset a non-running (STS_HALT == 1) controller */ | 208 | /* reset a non-running (STS_HALT == 1) controller */ |
207 | static int ehci_reset (struct ehci_hcd *ehci) | 209 | static int ehci_reset (struct ehci_hcd *ehci) |
208 | { | 210 | { |
209 | int retval; | 211 | int retval; |
210 | u32 command = readl (&ehci->regs->command); | 212 | u32 command = ehci_readl(ehci, &ehci->regs->command); |
211 | 213 | ||
212 | command |= CMD_RESET; | 214 | command |= CMD_RESET; |
213 | dbg_cmd (ehci, "reset", command); | 215 | dbg_cmd (ehci, "reset", command); |
214 | writel (command, &ehci->regs->command); | 216 | ehci_writel(ehci, command, &ehci->regs->command); |
215 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; | 217 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; |
216 | ehci->next_statechange = jiffies; | 218 | ehci->next_statechange = jiffies; |
217 | retval = handshake (&ehci->regs->command, CMD_RESET, 0, 250 * 1000); | 219 | retval = handshake (ehci, &ehci->regs->command, |
220 | CMD_RESET, 0, 250 * 1000); | ||
218 | 221 | ||
219 | if (retval) | 222 | if (retval) |
220 | return retval; | 223 | return retval; |
@@ -236,21 +239,21 @@ static void ehci_quiesce (struct ehci_hcd *ehci) | |||
236 | #endif | 239 | #endif |
237 | 240 | ||
238 | /* wait for any schedule enables/disables to take effect */ | 241 | /* wait for any schedule enables/disables to take effect */ |
239 | temp = readl (&ehci->regs->command) << 10; | 242 | temp = ehci_readl(ehci, &ehci->regs->command) << 10; |
240 | temp &= STS_ASS | STS_PSS; | 243 | temp &= STS_ASS | STS_PSS; |
241 | if (handshake (&ehci->regs->status, STS_ASS | STS_PSS, | 244 | if (handshake (ehci, &ehci->regs->status, STS_ASS | STS_PSS, |
242 | temp, 16 * 125) != 0) { | 245 | temp, 16 * 125) != 0) { |
243 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; | 246 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; |
244 | return; | 247 | return; |
245 | } | 248 | } |
246 | 249 | ||
247 | /* then disable anything that's still active */ | 250 | /* then disable anything that's still active */ |
248 | temp = readl (&ehci->regs->command); | 251 | temp = ehci_readl(ehci, &ehci->regs->command); |
249 | temp &= ~(CMD_ASE | CMD_IAAD | CMD_PSE); | 252 | temp &= ~(CMD_ASE | CMD_IAAD | CMD_PSE); |
250 | writel (temp, &ehci->regs->command); | 253 | ehci_writel(ehci, temp, &ehci->regs->command); |
251 | 254 | ||
252 | /* hardware can take 16 microframes to turn off ... */ | 255 | /* hardware can take 16 microframes to turn off ... */ |
253 | if (handshake (&ehci->regs->status, STS_ASS | STS_PSS, | 256 | if (handshake (ehci, &ehci->regs->status, STS_ASS | STS_PSS, |
254 | 0, 16 * 125) != 0) { | 257 | 0, 16 * 125) != 0) { |
255 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; | 258 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; |
256 | return; | 259 | return; |
@@ -277,11 +280,11 @@ static void ehci_watchdog (unsigned long param) | |||
277 | 280 | ||
278 | /* lost IAA irqs wedge things badly; seen with a vt8235 */ | 281 | /* lost IAA irqs wedge things badly; seen with a vt8235 */ |
279 | if (ehci->reclaim) { | 282 | if (ehci->reclaim) { |
280 | u32 status = readl (&ehci->regs->status); | 283 | u32 status = ehci_readl(ehci, &ehci->regs->status); |
281 | if (status & STS_IAA) { | 284 | if (status & STS_IAA) { |
282 | ehci_vdbg (ehci, "lost IAA\n"); | 285 | ehci_vdbg (ehci, "lost IAA\n"); |
283 | COUNT (ehci->stats.lost_iaa); | 286 | COUNT (ehci->stats.lost_iaa); |
284 | writel (STS_IAA, &ehci->regs->status); | 287 | ehci_writel(ehci, STS_IAA, &ehci->regs->status); |
285 | ehci->reclaim_ready = 1; | 288 | ehci->reclaim_ready = 1; |
286 | } | 289 | } |
287 | } | 290 | } |
@@ -309,7 +312,7 @@ ehci_shutdown (struct usb_hcd *hcd) | |||
309 | (void) ehci_halt (ehci); | 312 | (void) ehci_halt (ehci); |
310 | 313 | ||
311 | /* make BIOS/etc use companion controller during reboot */ | 314 | /* make BIOS/etc use companion controller during reboot */ |
312 | writel (0, &ehci->regs->configured_flag); | 315 | ehci_writel(ehci, 0, &ehci->regs->configured_flag); |
313 | } | 316 | } |
314 | 317 | ||
315 | static void ehci_port_power (struct ehci_hcd *ehci, int is_on) | 318 | static void ehci_port_power (struct ehci_hcd *ehci, int is_on) |
@@ -379,12 +382,13 @@ static void ehci_stop (struct usb_hcd *hcd) | |||
379 | ehci_quiesce (ehci); | 382 | ehci_quiesce (ehci); |
380 | 383 | ||
381 | ehci_reset (ehci); | 384 | ehci_reset (ehci); |
382 | writel (0, &ehci->regs->intr_enable); | 385 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); |
383 | spin_unlock_irq(&ehci->lock); | 386 | spin_unlock_irq(&ehci->lock); |
384 | 387 | ||
385 | /* let companion controllers work when we aren't */ | 388 | /* let companion controllers work when we aren't */ |
386 | writel (0, &ehci->regs->configured_flag); | 389 | ehci_writel(ehci, 0, &ehci->regs->configured_flag); |
387 | 390 | ||
391 | remove_companion_file(ehci); | ||
388 | remove_debug_files (ehci); | 392 | remove_debug_files (ehci); |
389 | 393 | ||
390 | /* root hub is shut down separately (first, when possible) */ | 394 | /* root hub is shut down separately (first, when possible) */ |
@@ -402,7 +406,8 @@ static void ehci_stop (struct usb_hcd *hcd) | |||
402 | ehci->stats.complete, ehci->stats.unlink); | 406 | ehci->stats.complete, ehci->stats.unlink); |
403 | #endif | 407 | #endif |
404 | 408 | ||
405 | dbg_status (ehci, "ehci_stop completed", readl (&ehci->regs->status)); | 409 | dbg_status (ehci, "ehci_stop completed", |
410 | ehci_readl(ehci, &ehci->regs->status)); | ||
406 | } | 411 | } |
407 | 412 | ||
408 | /* one-time init, only for memory state */ | 413 | /* one-time init, only for memory state */ |
@@ -428,7 +433,7 @@ static int ehci_init(struct usb_hcd *hcd) | |||
428 | return retval; | 433 | return retval; |
429 | 434 | ||
430 | /* controllers may cache some of the periodic schedule ... */ | 435 | /* controllers may cache some of the periodic schedule ... */ |
431 | hcc_params = readl(&ehci->caps->hcc_params); | 436 | hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params); |
432 | if (HCC_ISOC_CACHE(hcc_params)) // full frame cache | 437 | if (HCC_ISOC_CACHE(hcc_params)) // full frame cache |
433 | ehci->i_thresh = 8; | 438 | ehci->i_thresh = 8; |
434 | else // N microframes cached | 439 | else // N microframes cached |
@@ -496,13 +501,16 @@ static int ehci_run (struct usb_hcd *hcd) | |||
496 | u32 temp; | 501 | u32 temp; |
497 | u32 hcc_params; | 502 | u32 hcc_params; |
498 | 503 | ||
504 | hcd->uses_new_polling = 1; | ||
505 | hcd->poll_rh = 0; | ||
506 | |||
499 | /* EHCI spec section 4.1 */ | 507 | /* EHCI spec section 4.1 */ |
500 | if ((retval = ehci_reset(ehci)) != 0) { | 508 | if ((retval = ehci_reset(ehci)) != 0) { |
501 | ehci_mem_cleanup(ehci); | 509 | ehci_mem_cleanup(ehci); |
502 | return retval; | 510 | return retval; |
503 | } | 511 | } |
504 | writel(ehci->periodic_dma, &ehci->regs->frame_list); | 512 | ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list); |
505 | writel((u32)ehci->async->qh_dma, &ehci->regs->async_next); | 513 | ehci_writel(ehci, (u32)ehci->async->qh_dma, &ehci->regs->async_next); |
506 | 514 | ||
507 | /* | 515 | /* |
508 | * hcc_params controls whether ehci->regs->segment must (!!!) | 516 | * hcc_params controls whether ehci->regs->segment must (!!!) |
@@ -516,9 +524,9 @@ static int ehci_run (struct usb_hcd *hcd) | |||
516 | * Scsi_Host.highmem_io, and so forth. It's readonly to all | 524 | * Scsi_Host.highmem_io, and so forth. It's readonly to all |
517 | * host side drivers though. | 525 | * host side drivers though. |
518 | */ | 526 | */ |
519 | hcc_params = readl(&ehci->caps->hcc_params); | 527 | hcc_params = ehci_readl(ehci, &ehci->caps->hcc_params); |
520 | if (HCC_64BIT_ADDR(hcc_params)) { | 528 | if (HCC_64BIT_ADDR(hcc_params)) { |
521 | writel(0, &ehci->regs->segment); | 529 | ehci_writel(ehci, 0, &ehci->regs->segment); |
522 | #if 0 | 530 | #if 0 |
523 | // this is deeply broken on almost all architectures | 531 | // this is deeply broken on almost all architectures |
524 | if (!dma_set_mask(hcd->self.controller, DMA_64BIT_MASK)) | 532 | if (!dma_set_mask(hcd->self.controller, DMA_64BIT_MASK)) |
@@ -531,7 +539,7 @@ static int ehci_run (struct usb_hcd *hcd) | |||
531 | // root hub will detect new devices (why?); NEC doesn't | 539 | // root hub will detect new devices (why?); NEC doesn't |
532 | ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET); | 540 | ehci->command &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET); |
533 | ehci->command |= CMD_RUN; | 541 | ehci->command |= CMD_RUN; |
534 | writel (ehci->command, &ehci->regs->command); | 542 | ehci_writel(ehci, ehci->command, &ehci->regs->command); |
535 | dbg_cmd (ehci, "init", ehci->command); | 543 | dbg_cmd (ehci, "init", ehci->command); |
536 | 544 | ||
537 | /* | 545 | /* |
@@ -541,23 +549,25 @@ static int ehci_run (struct usb_hcd *hcd) | |||
541 | * and there's no companion controller unless maybe for USB OTG.) | 549 | * and there's no companion controller unless maybe for USB OTG.) |
542 | */ | 550 | */ |
543 | hcd->state = HC_STATE_RUNNING; | 551 | hcd->state = HC_STATE_RUNNING; |
544 | writel (FLAG_CF, &ehci->regs->configured_flag); | 552 | ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); |
545 | readl (&ehci->regs->command); /* unblock posted writes */ | 553 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ |
546 | 554 | ||
547 | temp = HC_VERSION(readl (&ehci->caps->hc_capbase)); | 555 | temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); |
548 | ehci_info (ehci, | 556 | ehci_info (ehci, |
549 | "USB %x.%x started, EHCI %x.%02x, driver %s%s\n", | 557 | "USB %x.%x started, EHCI %x.%02x, driver %s%s\n", |
550 | ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), | 558 | ((ehci->sbrn & 0xf0)>>4), (ehci->sbrn & 0x0f), |
551 | temp >> 8, temp & 0xff, DRIVER_VERSION, | 559 | temp >> 8, temp & 0xff, DRIVER_VERSION, |
552 | ignore_oc ? ", overcurrent ignored" : ""); | 560 | ignore_oc ? ", overcurrent ignored" : ""); |
553 | 561 | ||
554 | writel (INTR_MASK, &ehci->regs->intr_enable); /* Turn On Interrupts */ | 562 | ehci_writel(ehci, INTR_MASK, |
563 | &ehci->regs->intr_enable); /* Turn On Interrupts */ | ||
555 | 564 | ||
556 | /* GRR this is run-once init(), being done every time the HC starts. | 565 | /* GRR this is run-once init(), being done every time the HC starts. |
557 | * So long as they're part of class devices, we can't do it init() | 566 | * So long as they're part of class devices, we can't do it init() |
558 | * since the class device isn't created that early. | 567 | * since the class device isn't created that early. |
559 | */ | 568 | */ |
560 | create_debug_files(ehci); | 569 | create_debug_files(ehci); |
570 | create_companion_file(ehci); | ||
561 | 571 | ||
562 | return 0; | 572 | return 0; |
563 | } | 573 | } |
@@ -567,12 +577,12 @@ static int ehci_run (struct usb_hcd *hcd) | |||
567 | static irqreturn_t ehci_irq (struct usb_hcd *hcd) | 577 | static irqreturn_t ehci_irq (struct usb_hcd *hcd) |
568 | { | 578 | { |
569 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 579 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
570 | u32 status; | 580 | u32 status, pcd_status = 0; |
571 | int bh; | 581 | int bh; |
572 | 582 | ||
573 | spin_lock (&ehci->lock); | 583 | spin_lock (&ehci->lock); |
574 | 584 | ||
575 | status = readl (&ehci->regs->status); | 585 | status = ehci_readl(ehci, &ehci->regs->status); |
576 | 586 | ||
577 | /* e.g. cardbus physical eject */ | 587 | /* e.g. cardbus physical eject */ |
578 | if (status == ~(u32) 0) { | 588 | if (status == ~(u32) 0) { |
@@ -587,8 +597,8 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
587 | } | 597 | } |
588 | 598 | ||
589 | /* clear (just) interrupts */ | 599 | /* clear (just) interrupts */ |
590 | writel (status, &ehci->regs->status); | 600 | ehci_writel(ehci, status, &ehci->regs->status); |
591 | readl (&ehci->regs->command); /* unblock posted write */ | 601 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted write */ |
592 | bh = 0; | 602 | bh = 0; |
593 | 603 | ||
594 | #ifdef EHCI_VERBOSE_DEBUG | 604 | #ifdef EHCI_VERBOSE_DEBUG |
@@ -617,13 +627,15 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
617 | /* remote wakeup [4.3.1] */ | 627 | /* remote wakeup [4.3.1] */ |
618 | if (status & STS_PCD) { | 628 | if (status & STS_PCD) { |
619 | unsigned i = HCS_N_PORTS (ehci->hcs_params); | 629 | unsigned i = HCS_N_PORTS (ehci->hcs_params); |
630 | pcd_status = status; | ||
620 | 631 | ||
621 | /* resume root hub? */ | 632 | /* resume root hub? */ |
622 | if (!(readl(&ehci->regs->command) & CMD_RUN)) | 633 | if (!(ehci_readl(ehci, &ehci->regs->command) & CMD_RUN)) |
623 | usb_hcd_resume_root_hub(hcd); | 634 | usb_hcd_resume_root_hub(hcd); |
624 | 635 | ||
625 | while (i--) { | 636 | while (i--) { |
626 | int pstatus = readl (&ehci->regs->port_status [i]); | 637 | int pstatus = ehci_readl(ehci, |
638 | &ehci->regs->port_status [i]); | ||
627 | 639 | ||
628 | if (pstatus & PORT_OWNER) | 640 | if (pstatus & PORT_OWNER) |
629 | continue; | 641 | continue; |
@@ -643,14 +655,15 @@ static irqreturn_t ehci_irq (struct usb_hcd *hcd) | |||
643 | /* PCI errors [4.15.2.4] */ | 655 | /* PCI errors [4.15.2.4] */ |
644 | if (unlikely ((status & STS_FATAL) != 0)) { | 656 | if (unlikely ((status & STS_FATAL) != 0)) { |
645 | /* bogus "fatal" IRQs appear on some chips... why? */ | 657 | /* bogus "fatal" IRQs appear on some chips... why? */ |
646 | status = readl (&ehci->regs->status); | 658 | status = ehci_readl(ehci, &ehci->regs->status); |
647 | dbg_cmd (ehci, "fatal", readl (&ehci->regs->command)); | 659 | dbg_cmd (ehci, "fatal", ehci_readl(ehci, |
660 | &ehci->regs->command)); | ||
648 | dbg_status (ehci, "fatal", status); | 661 | dbg_status (ehci, "fatal", status); |
649 | if (status & STS_HALT) { | 662 | if (status & STS_HALT) { |
650 | ehci_err (ehci, "fatal error\n"); | 663 | ehci_err (ehci, "fatal error\n"); |
651 | dead: | 664 | dead: |
652 | ehci_reset (ehci); | 665 | ehci_reset (ehci); |
653 | writel (0, &ehci->regs->configured_flag); | 666 | ehci_writel(ehci, 0, &ehci->regs->configured_flag); |
654 | /* generic layer kills/unlinks all urbs, then | 667 | /* generic layer kills/unlinks all urbs, then |
655 | * uses ehci_stop to clean up the rest | 668 | * uses ehci_stop to clean up the rest |
656 | */ | 669 | */ |
@@ -661,6 +674,8 @@ dead: | |||
661 | if (bh) | 674 | if (bh) |
662 | ehci_work (ehci); | 675 | ehci_work (ehci); |
663 | spin_unlock (&ehci->lock); | 676 | spin_unlock (&ehci->lock); |
677 | if (pcd_status & STS_PCD) | ||
678 | usb_hcd_poll_rh_status(hcd); | ||
664 | return IRQ_HANDLED; | 679 | return IRQ_HANDLED; |
665 | } | 680 | } |
666 | 681 | ||
@@ -873,7 +888,8 @@ done: | |||
873 | static int ehci_get_frame (struct usb_hcd *hcd) | 888 | static int ehci_get_frame (struct usb_hcd *hcd) |
874 | { | 889 | { |
875 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 890 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
876 | return (readl (&ehci->regs->frame_index) >> 3) % ehci->periodic_size; | 891 | return (ehci_readl(ehci, &ehci->regs->frame_index) >> 3) % |
892 | ehci->periodic_size; | ||
877 | } | 893 | } |
878 | 894 | ||
879 | /*-------------------------------------------------------------------------*/ | 895 | /*-------------------------------------------------------------------------*/ |
@@ -899,7 +915,13 @@ MODULE_LICENSE ("GPL"); | |||
899 | #define PLATFORM_DRIVER ehci_hcd_au1xxx_driver | 915 | #define PLATFORM_DRIVER ehci_hcd_au1xxx_driver |
900 | #endif | 916 | #endif |
901 | 917 | ||
902 | #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) | 918 | #ifdef CONFIG_PPC_PS3 |
919 | #include "ehci-ps3.c" | ||
920 | #define PS3_SYSTEM_BUS_DRIVER ps3_ehci_sb_driver | ||
921 | #endif | ||
922 | |||
923 | #if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \ | ||
924 | !defined(PS3_SYSTEM_BUS_DRIVER) | ||
903 | #error "missing bus glue for ehci-hcd" | 925 | #error "missing bus glue for ehci-hcd" |
904 | #endif | 926 | #endif |
905 | 927 | ||
@@ -924,6 +946,20 @@ static int __init ehci_hcd_init(void) | |||
924 | #ifdef PLATFORM_DRIVER | 946 | #ifdef PLATFORM_DRIVER |
925 | platform_driver_unregister(&PLATFORM_DRIVER); | 947 | platform_driver_unregister(&PLATFORM_DRIVER); |
926 | #endif | 948 | #endif |
949 | return retval; | ||
950 | } | ||
951 | #endif | ||
952 | |||
953 | #ifdef PS3_SYSTEM_BUS_DRIVER | ||
954 | retval = ps3_system_bus_driver_register(&PS3_SYSTEM_BUS_DRIVER); | ||
955 | if (retval < 0) { | ||
956 | #ifdef PLATFORM_DRIVER | ||
957 | platform_driver_unregister(&PLATFORM_DRIVER); | ||
958 | #endif | ||
959 | #ifdef PCI_DRIVER | ||
960 | pci_unregister_driver(&PCI_DRIVER); | ||
961 | #endif | ||
962 | return retval; | ||
927 | } | 963 | } |
928 | #endif | 964 | #endif |
929 | 965 | ||
@@ -939,6 +975,9 @@ static void __exit ehci_hcd_cleanup(void) | |||
939 | #ifdef PCI_DRIVER | 975 | #ifdef PCI_DRIVER |
940 | pci_unregister_driver(&PCI_DRIVER); | 976 | pci_unregister_driver(&PCI_DRIVER); |
941 | #endif | 977 | #endif |
978 | #ifdef PS3_SYSTEM_BUS_DRIVER | ||
979 | ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); | ||
980 | #endif | ||
942 | } | 981 | } |
943 | module_exit(ehci_hcd_cleanup); | 982 | module_exit(ehci_hcd_cleanup); |
944 | 983 | ||
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index bfe5f307cba6..0d83c6df1a3b 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -47,7 +47,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
47 | ehci_quiesce (ehci); | 47 | ehci_quiesce (ehci); |
48 | hcd->state = HC_STATE_QUIESCING; | 48 | hcd->state = HC_STATE_QUIESCING; |
49 | } | 49 | } |
50 | ehci->command = readl (&ehci->regs->command); | 50 | ehci->command = ehci_readl(ehci, &ehci->regs->command); |
51 | if (ehci->reclaim) | 51 | if (ehci->reclaim) |
52 | ehci->reclaim_ready = 1; | 52 | ehci->reclaim_ready = 1; |
53 | ehci_work(ehci); | 53 | ehci_work(ehci); |
@@ -60,7 +60,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
60 | ehci->bus_suspended = 0; | 60 | ehci->bus_suspended = 0; |
61 | while (port--) { | 61 | while (port--) { |
62 | u32 __iomem *reg = &ehci->regs->port_status [port]; | 62 | u32 __iomem *reg = &ehci->regs->port_status [port]; |
63 | u32 t1 = readl (reg) & ~PORT_RWC_BITS; | 63 | u32 t1 = ehci_readl(ehci, reg) & ~PORT_RWC_BITS; |
64 | u32 t2 = t1; | 64 | u32 t2 = t1; |
65 | 65 | ||
66 | /* keep track of which ports we suspend */ | 66 | /* keep track of which ports we suspend */ |
@@ -79,7 +79,7 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
79 | if (t1 != t2) { | 79 | if (t1 != t2) { |
80 | ehci_vdbg (ehci, "port %d, %08x -> %08x\n", | 80 | ehci_vdbg (ehci, "port %d, %08x -> %08x\n", |
81 | port + 1, t1, t2); | 81 | port + 1, t1, t2); |
82 | writel (t2, reg); | 82 | ehci_writel(ehci, t2, reg); |
83 | } | 83 | } |
84 | } | 84 | } |
85 | 85 | ||
@@ -92,8 +92,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) | |||
92 | mask = INTR_MASK; | 92 | mask = INTR_MASK; |
93 | if (!device_may_wakeup(&hcd->self.root_hub->dev)) | 93 | if (!device_may_wakeup(&hcd->self.root_hub->dev)) |
94 | mask &= ~STS_PCD; | 94 | mask &= ~STS_PCD; |
95 | writel(mask, &ehci->regs->intr_enable); | 95 | ehci_writel(ehci, mask, &ehci->regs->intr_enable); |
96 | readl(&ehci->regs->intr_enable); | 96 | ehci_readl(ehci, &ehci->regs->intr_enable); |
97 | 97 | ||
98 | ehci->next_statechange = jiffies + msecs_to_jiffies(10); | 98 | ehci->next_statechange = jiffies + msecs_to_jiffies(10); |
99 | spin_unlock_irq (&ehci->lock); | 99 | spin_unlock_irq (&ehci->lock); |
@@ -118,26 +118,26 @@ static int ehci_bus_resume (struct usb_hcd *hcd) | |||
118 | * the last user of the controller, not reset/pm hardware keeping | 118 | * the last user of the controller, not reset/pm hardware keeping |
119 | * state we gave to it. | 119 | * state we gave to it. |
120 | */ | 120 | */ |
121 | temp = readl(&ehci->regs->intr_enable); | 121 | temp = ehci_readl(ehci, &ehci->regs->intr_enable); |
122 | ehci_dbg(ehci, "resume root hub%s\n", temp ? "" : " after power loss"); | 122 | ehci_dbg(ehci, "resume root hub%s\n", temp ? "" : " after power loss"); |
123 | 123 | ||
124 | /* at least some APM implementations will try to deliver | 124 | /* at least some APM implementations will try to deliver |
125 | * IRQs right away, so delay them until we're ready. | 125 | * IRQs right away, so delay them until we're ready. |
126 | */ | 126 | */ |
127 | writel(0, &ehci->regs->intr_enable); | 127 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); |
128 | 128 | ||
129 | /* re-init operational registers */ | 129 | /* re-init operational registers */ |
130 | writel(0, &ehci->regs->segment); | 130 | ehci_writel(ehci, 0, &ehci->regs->segment); |
131 | writel(ehci->periodic_dma, &ehci->regs->frame_list); | 131 | ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list); |
132 | writel((u32) ehci->async->qh_dma, &ehci->regs->async_next); | 132 | ehci_writel(ehci, (u32) ehci->async->qh_dma, &ehci->regs->async_next); |
133 | 133 | ||
134 | /* restore CMD_RUN, framelist size, and irq threshold */ | 134 | /* restore CMD_RUN, framelist size, and irq threshold */ |
135 | writel (ehci->command, &ehci->regs->command); | 135 | ehci_writel(ehci, ehci->command, &ehci->regs->command); |
136 | 136 | ||
137 | /* manually resume the ports we suspended during bus_suspend() */ | 137 | /* manually resume the ports we suspended during bus_suspend() */ |
138 | i = HCS_N_PORTS (ehci->hcs_params); | 138 | i = HCS_N_PORTS (ehci->hcs_params); |
139 | while (i--) { | 139 | while (i--) { |
140 | temp = readl (&ehci->regs->port_status [i]); | 140 | temp = ehci_readl(ehci, &ehci->regs->port_status [i]); |
141 | temp &= ~(PORT_RWC_BITS | 141 | temp &= ~(PORT_RWC_BITS |
142 | | PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E); | 142 | | PORT_WKOC_E | PORT_WKDISC_E | PORT_WKCONN_E); |
143 | if (test_bit(i, &ehci->bus_suspended) && | 143 | if (test_bit(i, &ehci->bus_suspended) && |
@@ -145,20 +145,20 @@ static int ehci_bus_resume (struct usb_hcd *hcd) | |||
145 | ehci->reset_done [i] = jiffies + msecs_to_jiffies (20); | 145 | ehci->reset_done [i] = jiffies + msecs_to_jiffies (20); |
146 | temp |= PORT_RESUME; | 146 | temp |= PORT_RESUME; |
147 | } | 147 | } |
148 | writel (temp, &ehci->regs->port_status [i]); | 148 | ehci_writel(ehci, temp, &ehci->regs->port_status [i]); |
149 | } | 149 | } |
150 | i = HCS_N_PORTS (ehci->hcs_params); | 150 | i = HCS_N_PORTS (ehci->hcs_params); |
151 | mdelay (20); | 151 | mdelay (20); |
152 | while (i--) { | 152 | while (i--) { |
153 | temp = readl (&ehci->regs->port_status [i]); | 153 | temp = ehci_readl(ehci, &ehci->regs->port_status [i]); |
154 | if (test_bit(i, &ehci->bus_suspended) && | 154 | if (test_bit(i, &ehci->bus_suspended) && |
155 | (temp & PORT_SUSPEND)) { | 155 | (temp & PORT_SUSPEND)) { |
156 | temp &= ~(PORT_RWC_BITS | PORT_RESUME); | 156 | temp &= ~(PORT_RWC_BITS | PORT_RESUME); |
157 | writel (temp, &ehci->regs->port_status [i]); | 157 | ehci_writel(ehci, temp, &ehci->regs->port_status [i]); |
158 | ehci_vdbg (ehci, "resumed port %d\n", i + 1); | 158 | ehci_vdbg (ehci, "resumed port %d\n", i + 1); |
159 | } | 159 | } |
160 | } | 160 | } |
161 | (void) readl (&ehci->regs->command); | 161 | (void) ehci_readl(ehci, &ehci->regs->command); |
162 | 162 | ||
163 | /* maybe re-activate the schedule(s) */ | 163 | /* maybe re-activate the schedule(s) */ |
164 | temp = 0; | 164 | temp = 0; |
@@ -168,14 +168,14 @@ static int ehci_bus_resume (struct usb_hcd *hcd) | |||
168 | temp |= CMD_PSE; | 168 | temp |= CMD_PSE; |
169 | if (temp) { | 169 | if (temp) { |
170 | ehci->command |= temp; | 170 | ehci->command |= temp; |
171 | writel (ehci->command, &ehci->regs->command); | 171 | ehci_writel(ehci, ehci->command, &ehci->regs->command); |
172 | } | 172 | } |
173 | 173 | ||
174 | ehci->next_statechange = jiffies + msecs_to_jiffies(5); | 174 | ehci->next_statechange = jiffies + msecs_to_jiffies(5); |
175 | hcd->state = HC_STATE_RUNNING; | 175 | hcd->state = HC_STATE_RUNNING; |
176 | 176 | ||
177 | /* Now we can safely re-enable irqs */ | 177 | /* Now we can safely re-enable irqs */ |
178 | writel(INTR_MASK, &ehci->regs->intr_enable); | 178 | ehci_writel(ehci, INTR_MASK, &ehci->regs->intr_enable); |
179 | 179 | ||
180 | spin_unlock_irq (&ehci->lock); | 180 | spin_unlock_irq (&ehci->lock); |
181 | return 0; | 181 | return 0; |
@@ -190,9 +190,107 @@ static int ehci_bus_resume (struct usb_hcd *hcd) | |||
190 | 190 | ||
191 | /*-------------------------------------------------------------------------*/ | 191 | /*-------------------------------------------------------------------------*/ |
192 | 192 | ||
193 | /* Display the ports dedicated to the companion controller */ | ||
194 | static ssize_t show_companion(struct class_device *class_dev, char *buf) | ||
195 | { | ||
196 | struct ehci_hcd *ehci; | ||
197 | int nports, index, n; | ||
198 | int count = PAGE_SIZE; | ||
199 | char *ptr = buf; | ||
200 | |||
201 | ehci = hcd_to_ehci(bus_to_hcd(class_get_devdata(class_dev))); | ||
202 | nports = HCS_N_PORTS(ehci->hcs_params); | ||
203 | |||
204 | for (index = 0; index < nports; ++index) { | ||
205 | if (test_bit(index, &ehci->companion_ports)) { | ||
206 | n = scnprintf(ptr, count, "%d\n", index + 1); | ||
207 | ptr += n; | ||
208 | count -= n; | ||
209 | } | ||
210 | } | ||
211 | return ptr - buf; | ||
212 | } | ||
213 | |||
214 | /* | ||
215 | * Dedicate or undedicate a port to the companion controller. | ||
216 | * Syntax is "[-]portnum", where a leading '-' sign means | ||
217 | * return control of the port to the EHCI controller. | ||
218 | */ | ||
219 | static ssize_t store_companion(struct class_device *class_dev, | ||
220 | const char *buf, size_t count) | ||
221 | { | ||
222 | struct ehci_hcd *ehci; | ||
223 | int portnum, new_owner, try; | ||
224 | u32 __iomem *status_reg; | ||
225 | u32 port_status; | ||
226 | |||
227 | ehci = hcd_to_ehci(bus_to_hcd(class_get_devdata(class_dev))); | ||
228 | new_owner = PORT_OWNER; /* Owned by companion */ | ||
229 | if (sscanf(buf, "%d", &portnum) != 1) | ||
230 | return -EINVAL; | ||
231 | if (portnum < 0) { | ||
232 | portnum = - portnum; | ||
233 | new_owner = 0; /* Owned by EHCI */ | ||
234 | } | ||
235 | if (portnum <= 0 || portnum > HCS_N_PORTS(ehci->hcs_params)) | ||
236 | return -ENOENT; | ||
237 | status_reg = &ehci->regs->port_status[--portnum]; | ||
238 | if (new_owner) | ||
239 | set_bit(portnum, &ehci->companion_ports); | ||
240 | else | ||
241 | clear_bit(portnum, &ehci->companion_ports); | ||
242 | |||
243 | /* | ||
244 | * The controller won't set the OWNER bit if the port is | ||
245 | * enabled, so this loop will sometimes require at least two | ||
246 | * iterations: one to disable the port and one to set OWNER. | ||
247 | */ | ||
248 | |||
249 | for (try = 4; try > 0; --try) { | ||
250 | spin_lock_irq(&ehci->lock); | ||
251 | port_status = ehci_readl(ehci, status_reg); | ||
252 | if ((port_status & PORT_OWNER) == new_owner | ||
253 | || (port_status & (PORT_OWNER | PORT_CONNECT)) | ||
254 | == 0) | ||
255 | try = 0; | ||
256 | else { | ||
257 | port_status ^= PORT_OWNER; | ||
258 | port_status &= ~(PORT_PE | PORT_RWC_BITS); | ||
259 | ehci_writel(ehci, port_status, status_reg); | ||
260 | } | ||
261 | spin_unlock_irq(&ehci->lock); | ||
262 | if (try > 1) | ||
263 | msleep(5); | ||
264 | } | ||
265 | return count; | ||
266 | } | ||
267 | static CLASS_DEVICE_ATTR(companion, 0644, show_companion, store_companion); | ||
268 | |||
269 | static inline void create_companion_file(struct ehci_hcd *ehci) | ||
270 | { | ||
271 | int i; | ||
272 | |||
273 | /* with integrated TT there is no companion! */ | ||
274 | if (!ehci_is_TDI(ehci)) | ||
275 | i = class_device_create_file(ehci_to_hcd(ehci)->self.class_dev, | ||
276 | &class_device_attr_companion); | ||
277 | } | ||
278 | |||
279 | static inline void remove_companion_file(struct ehci_hcd *ehci) | ||
280 | { | ||
281 | /* with integrated TT there is no companion! */ | ||
282 | if (!ehci_is_TDI(ehci)) | ||
283 | class_device_remove_file(ehci_to_hcd(ehci)->self.class_dev, | ||
284 | &class_device_attr_companion); | ||
285 | } | ||
286 | |||
287 | |||
288 | /*-------------------------------------------------------------------------*/ | ||
289 | |||
193 | static int check_reset_complete ( | 290 | static int check_reset_complete ( |
194 | struct ehci_hcd *ehci, | 291 | struct ehci_hcd *ehci, |
195 | int index, | 292 | int index, |
293 | u32 __iomem *status_reg, | ||
196 | int port_status | 294 | int port_status |
197 | ) { | 295 | ) { |
198 | if (!(port_status & PORT_CONNECT)) { | 296 | if (!(port_status & PORT_CONNECT)) { |
@@ -217,7 +315,7 @@ static int check_reset_complete ( | |||
217 | // what happens if HCS_N_CC(params) == 0 ? | 315 | // what happens if HCS_N_CC(params) == 0 ? |
218 | port_status |= PORT_OWNER; | 316 | port_status |= PORT_OWNER; |
219 | port_status &= ~PORT_RWC_BITS; | 317 | port_status &= ~PORT_RWC_BITS; |
220 | writel (port_status, &ehci->regs->port_status [index]); | 318 | ehci_writel(ehci, port_status, status_reg); |
221 | 319 | ||
222 | } else | 320 | } else |
223 | ehci_dbg (ehci, "port %d high speed\n", index + 1); | 321 | ehci_dbg (ehci, "port %d high speed\n", index + 1); |
@@ -268,22 +366,21 @@ ehci_hub_status_data (struct usb_hcd *hcd, char *buf) | |||
268 | /* port N changes (bit N)? */ | 366 | /* port N changes (bit N)? */ |
269 | spin_lock_irqsave (&ehci->lock, flags); | 367 | spin_lock_irqsave (&ehci->lock, flags); |
270 | for (i = 0; i < ports; i++) { | 368 | for (i = 0; i < ports; i++) { |
271 | temp = readl (&ehci->regs->port_status [i]); | 369 | temp = ehci_readl(ehci, &ehci->regs->port_status [i]); |
272 | if (temp & PORT_OWNER) { | 370 | |
273 | /* don't report this in GetPortStatus */ | 371 | /* |
274 | if (temp & PORT_CSC) { | 372 | * Return status information even for ports with OWNER set. |
275 | temp &= ~PORT_RWC_BITS; | 373 | * Otherwise khubd wouldn't see the disconnect event when a |
276 | temp |= PORT_CSC; | 374 | * high-speed device is switched over to the companion |
277 | writel (temp, &ehci->regs->port_status [i]); | 375 | * controller by the user. |
278 | } | 376 | */ |
279 | continue; | 377 | |
280 | } | ||
281 | if (!(temp & PORT_CONNECT)) | 378 | if (!(temp & PORT_CONNECT)) |
282 | ehci->reset_done [i] = 0; | 379 | ehci->reset_done [i] = 0; |
283 | if ((temp & mask) != 0 | 380 | if ((temp & mask) != 0 |
284 | || ((temp & PORT_RESUME) != 0 | 381 | || ((temp & PORT_RESUME) != 0 |
285 | && time_after (jiffies, | 382 | && time_after_eq(jiffies, |
286 | ehci->reset_done [i]))) { | 383 | ehci->reset_done[i]))) { |
287 | if (i < 7) | 384 | if (i < 7) |
288 | buf [0] |= 1 << (i + 1); | 385 | buf [0] |= 1 << (i + 1); |
289 | else | 386 | else |
@@ -345,6 +442,7 @@ static int ehci_hub_control ( | |||
345 | ) { | 442 | ) { |
346 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 443 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
347 | int ports = HCS_N_PORTS (ehci->hcs_params); | 444 | int ports = HCS_N_PORTS (ehci->hcs_params); |
445 | u32 __iomem *status_reg = &ehci->regs->port_status[wIndex - 1]; | ||
348 | u32 temp, status; | 446 | u32 temp, status; |
349 | unsigned long flags; | 447 | unsigned long flags; |
350 | int retval = 0; | 448 | int retval = 0; |
@@ -373,18 +471,22 @@ static int ehci_hub_control ( | |||
373 | if (!wIndex || wIndex > ports) | 471 | if (!wIndex || wIndex > ports) |
374 | goto error; | 472 | goto error; |
375 | wIndex--; | 473 | wIndex--; |
376 | temp = readl (&ehci->regs->port_status [wIndex]); | 474 | temp = ehci_readl(ehci, status_reg); |
377 | if (temp & PORT_OWNER) | 475 | |
378 | break; | 476 | /* |
477 | * Even if OWNER is set, so the port is owned by the | ||
478 | * companion controller, khubd needs to be able to clear | ||
479 | * the port-change status bits (especially | ||
480 | * USB_PORT_FEAT_C_CONNECTION). | ||
481 | */ | ||
379 | 482 | ||
380 | switch (wValue) { | 483 | switch (wValue) { |
381 | case USB_PORT_FEAT_ENABLE: | 484 | case USB_PORT_FEAT_ENABLE: |
382 | writel (temp & ~PORT_PE, | 485 | ehci_writel(ehci, temp & ~PORT_PE, status_reg); |
383 | &ehci->regs->port_status [wIndex]); | ||
384 | break; | 486 | break; |
385 | case USB_PORT_FEAT_C_ENABLE: | 487 | case USB_PORT_FEAT_C_ENABLE: |
386 | writel((temp & ~PORT_RWC_BITS) | PORT_PEC, | 488 | ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_PEC, |
387 | &ehci->regs->port_status [wIndex]); | 489 | status_reg); |
388 | break; | 490 | break; |
389 | case USB_PORT_FEAT_SUSPEND: | 491 | case USB_PORT_FEAT_SUSPEND: |
390 | if (temp & PORT_RESET) | 492 | if (temp & PORT_RESET) |
@@ -396,8 +498,8 @@ static int ehci_hub_control ( | |||
396 | goto error; | 498 | goto error; |
397 | /* resume signaling for 20 msec */ | 499 | /* resume signaling for 20 msec */ |
398 | temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); | 500 | temp &= ~(PORT_RWC_BITS | PORT_WAKE_BITS); |
399 | writel (temp | PORT_RESUME, | 501 | ehci_writel(ehci, temp | PORT_RESUME, |
400 | &ehci->regs->port_status [wIndex]); | 502 | status_reg); |
401 | ehci->reset_done [wIndex] = jiffies | 503 | ehci->reset_done [wIndex] = jiffies |
402 | + msecs_to_jiffies (20); | 504 | + msecs_to_jiffies (20); |
403 | } | 505 | } |
@@ -407,16 +509,17 @@ static int ehci_hub_control ( | |||
407 | break; | 509 | break; |
408 | case USB_PORT_FEAT_POWER: | 510 | case USB_PORT_FEAT_POWER: |
409 | if (HCS_PPC (ehci->hcs_params)) | 511 | if (HCS_PPC (ehci->hcs_params)) |
410 | writel (temp & ~(PORT_RWC_BITS | PORT_POWER), | 512 | ehci_writel(ehci, |
411 | &ehci->regs->port_status [wIndex]); | 513 | temp & ~(PORT_RWC_BITS | PORT_POWER), |
514 | status_reg); | ||
412 | break; | 515 | break; |
413 | case USB_PORT_FEAT_C_CONNECTION: | 516 | case USB_PORT_FEAT_C_CONNECTION: |
414 | writel((temp & ~PORT_RWC_BITS) | PORT_CSC, | 517 | ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_CSC, |
415 | &ehci->regs->port_status [wIndex]); | 518 | status_reg); |
416 | break; | 519 | break; |
417 | case USB_PORT_FEAT_C_OVER_CURRENT: | 520 | case USB_PORT_FEAT_C_OVER_CURRENT: |
418 | writel((temp & ~PORT_RWC_BITS) | PORT_OCC, | 521 | ehci_writel(ehci, (temp & ~PORT_RWC_BITS) | PORT_OCC, |
419 | &ehci->regs->port_status [wIndex]); | 522 | status_reg); |
420 | break; | 523 | break; |
421 | case USB_PORT_FEAT_C_RESET: | 524 | case USB_PORT_FEAT_C_RESET: |
422 | /* GetPortStatus clears reset */ | 525 | /* GetPortStatus clears reset */ |
@@ -424,7 +527,7 @@ static int ehci_hub_control ( | |||
424 | default: | 527 | default: |
425 | goto error; | 528 | goto error; |
426 | } | 529 | } |
427 | readl (&ehci->regs->command); /* unblock posted write */ | 530 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted write */ |
428 | break; | 531 | break; |
429 | case GetHubDescriptor: | 532 | case GetHubDescriptor: |
430 | ehci_hub_descriptor (ehci, (struct usb_hub_descriptor *) | 533 | ehci_hub_descriptor (ehci, (struct usb_hub_descriptor *) |
@@ -440,7 +543,7 @@ static int ehci_hub_control ( | |||
440 | goto error; | 543 | goto error; |
441 | wIndex--; | 544 | wIndex--; |
442 | status = 0; | 545 | status = 0; |
443 | temp = readl (&ehci->regs->port_status [wIndex]); | 546 | temp = ehci_readl(ehci, status_reg); |
444 | 547 | ||
445 | // wPortChange bits | 548 | // wPortChange bits |
446 | if (temp & PORT_CSC) | 549 | if (temp & PORT_CSC) |
@@ -451,42 +554,55 @@ static int ehci_hub_control ( | |||
451 | status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT; | 554 | status |= 1 << USB_PORT_FEAT_C_OVER_CURRENT; |
452 | 555 | ||
453 | /* whoever resumes must GetPortStatus to complete it!! */ | 556 | /* whoever resumes must GetPortStatus to complete it!! */ |
454 | if ((temp & PORT_RESUME) | 557 | if (temp & PORT_RESUME) { |
455 | && time_after (jiffies, | ||
456 | ehci->reset_done [wIndex])) { | ||
457 | status |= 1 << USB_PORT_FEAT_C_SUSPEND; | ||
458 | ehci->reset_done [wIndex] = 0; | ||
459 | 558 | ||
460 | /* stop resume signaling */ | 559 | /* Remote Wakeup received? */ |
461 | temp = readl (&ehci->regs->port_status [wIndex]); | 560 | if (!ehci->reset_done[wIndex]) { |
462 | writel (temp & ~(PORT_RWC_BITS | PORT_RESUME), | 561 | /* resume signaling for 20 msec */ |
463 | &ehci->regs->port_status [wIndex]); | 562 | ehci->reset_done[wIndex] = jiffies |
464 | retval = handshake ( | 563 | + msecs_to_jiffies(20); |
465 | &ehci->regs->port_status [wIndex], | 564 | /* check the port again */ |
466 | PORT_RESUME, 0, 2000 /* 2msec */); | 565 | mod_timer(&ehci_to_hcd(ehci)->rh_timer, |
467 | if (retval != 0) { | 566 | ehci->reset_done[wIndex]); |
468 | ehci_err (ehci, "port %d resume error %d\n", | 567 | } |
469 | wIndex + 1, retval); | 568 | |
470 | goto error; | 569 | /* resume completed? */ |
570 | else if (time_after_eq(jiffies, | ||
571 | ehci->reset_done[wIndex])) { | ||
572 | status |= 1 << USB_PORT_FEAT_C_SUSPEND; | ||
573 | ehci->reset_done[wIndex] = 0; | ||
574 | |||
575 | /* stop resume signaling */ | ||
576 | temp = ehci_readl(ehci, status_reg); | ||
577 | ehci_writel(ehci, | ||
578 | temp & ~(PORT_RWC_BITS | PORT_RESUME), | ||
579 | status_reg); | ||
580 | retval = handshake(ehci, status_reg, | ||
581 | PORT_RESUME, 0, 2000 /* 2msec */); | ||
582 | if (retval != 0) { | ||
583 | ehci_err(ehci, | ||
584 | "port %d resume error %d\n", | ||
585 | wIndex + 1, retval); | ||
586 | goto error; | ||
587 | } | ||
588 | temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10)); | ||
471 | } | 589 | } |
472 | temp &= ~(PORT_SUSPEND|PORT_RESUME|(3<<10)); | ||
473 | } | 590 | } |
474 | 591 | ||
475 | /* whoever resets must GetPortStatus to complete it!! */ | 592 | /* whoever resets must GetPortStatus to complete it!! */ |
476 | if ((temp & PORT_RESET) | 593 | if ((temp & PORT_RESET) |
477 | && time_after (jiffies, | 594 | && time_after_eq(jiffies, |
478 | ehci->reset_done [wIndex])) { | 595 | ehci->reset_done[wIndex])) { |
479 | status |= 1 << USB_PORT_FEAT_C_RESET; | 596 | status |= 1 << USB_PORT_FEAT_C_RESET; |
480 | ehci->reset_done [wIndex] = 0; | 597 | ehci->reset_done [wIndex] = 0; |
481 | 598 | ||
482 | /* force reset to complete */ | 599 | /* force reset to complete */ |
483 | writel (temp & ~(PORT_RWC_BITS | PORT_RESET), | 600 | ehci_writel(ehci, temp & ~(PORT_RWC_BITS | PORT_RESET), |
484 | &ehci->regs->port_status [wIndex]); | 601 | status_reg); |
485 | /* REVISIT: some hardware needs 550+ usec to clear | 602 | /* REVISIT: some hardware needs 550+ usec to clear |
486 | * this bit; seems too long to spin routinely... | 603 | * this bit; seems too long to spin routinely... |
487 | */ | 604 | */ |
488 | retval = handshake ( | 605 | retval = handshake(ehci, status_reg, |
489 | &ehci->regs->port_status [wIndex], | ||
490 | PORT_RESET, 0, 750); | 606 | PORT_RESET, 0, 750); |
491 | if (retval != 0) { | 607 | if (retval != 0) { |
492 | ehci_err (ehci, "port %d reset error %d\n", | 608 | ehci_err (ehci, "port %d reset error %d\n", |
@@ -495,28 +611,41 @@ static int ehci_hub_control ( | |||
495 | } | 611 | } |
496 | 612 | ||
497 | /* see what we found out */ | 613 | /* see what we found out */ |
498 | temp = check_reset_complete (ehci, wIndex, | 614 | temp = check_reset_complete (ehci, wIndex, status_reg, |
499 | readl (&ehci->regs->port_status [wIndex])); | 615 | ehci_readl(ehci, status_reg)); |
500 | } | 616 | } |
501 | 617 | ||
502 | // don't show wPortStatus if it's owned by a companion hc | 618 | /* transfer dedicated ports to the companion hc */ |
503 | if (!(temp & PORT_OWNER)) { | 619 | if ((temp & PORT_CONNECT) && |
504 | if (temp & PORT_CONNECT) { | 620 | test_bit(wIndex, &ehci->companion_ports)) { |
505 | status |= 1 << USB_PORT_FEAT_CONNECTION; | 621 | temp &= ~PORT_RWC_BITS; |
506 | // status may be from integrated TT | 622 | temp |= PORT_OWNER; |
507 | status |= ehci_port_speed(ehci, temp); | 623 | ehci_writel(ehci, temp, status_reg); |
508 | } | 624 | ehci_dbg(ehci, "port %d --> companion\n", wIndex + 1); |
509 | if (temp & PORT_PE) | 625 | temp = ehci_readl(ehci, status_reg); |
510 | status |= 1 << USB_PORT_FEAT_ENABLE; | 626 | } |
511 | if (temp & (PORT_SUSPEND|PORT_RESUME)) | 627 | |
512 | status |= 1 << USB_PORT_FEAT_SUSPEND; | 628 | /* |
513 | if (temp & PORT_OC) | 629 | * Even if OWNER is set, there's no harm letting khubd |
514 | status |= 1 << USB_PORT_FEAT_OVER_CURRENT; | 630 | * see the wPortStatus values (they should all be 0 except |
515 | if (temp & PORT_RESET) | 631 | * for PORT_POWER anyway). |
516 | status |= 1 << USB_PORT_FEAT_RESET; | 632 | */ |
517 | if (temp & PORT_POWER) | 633 | |
518 | status |= 1 << USB_PORT_FEAT_POWER; | 634 | if (temp & PORT_CONNECT) { |
635 | status |= 1 << USB_PORT_FEAT_CONNECTION; | ||
636 | // status may be from integrated TT | ||
637 | status |= ehci_port_speed(ehci, temp); | ||
519 | } | 638 | } |
639 | if (temp & PORT_PE) | ||
640 | status |= 1 << USB_PORT_FEAT_ENABLE; | ||
641 | if (temp & (PORT_SUSPEND|PORT_RESUME)) | ||
642 | status |= 1 << USB_PORT_FEAT_SUSPEND; | ||
643 | if (temp & PORT_OC) | ||
644 | status |= 1 << USB_PORT_FEAT_OVER_CURRENT; | ||
645 | if (temp & PORT_RESET) | ||
646 | status |= 1 << USB_PORT_FEAT_RESET; | ||
647 | if (temp & PORT_POWER) | ||
648 | status |= 1 << USB_PORT_FEAT_POWER; | ||
520 | 649 | ||
521 | #ifndef EHCI_VERBOSE_DEBUG | 650 | #ifndef EHCI_VERBOSE_DEBUG |
522 | if (status & ~0xffff) /* only if wPortChange is interesting */ | 651 | if (status & ~0xffff) /* only if wPortChange is interesting */ |
@@ -541,7 +670,7 @@ static int ehci_hub_control ( | |||
541 | if (!wIndex || wIndex > ports) | 670 | if (!wIndex || wIndex > ports) |
542 | goto error; | 671 | goto error; |
543 | wIndex--; | 672 | wIndex--; |
544 | temp = readl (&ehci->regs->port_status [wIndex]); | 673 | temp = ehci_readl(ehci, status_reg); |
545 | if (temp & PORT_OWNER) | 674 | if (temp & PORT_OWNER) |
546 | break; | 675 | break; |
547 | 676 | ||
@@ -555,13 +684,12 @@ static int ehci_hub_control ( | |||
555 | goto error; | 684 | goto error; |
556 | if (device_may_wakeup(&hcd->self.root_hub->dev)) | 685 | if (device_may_wakeup(&hcd->self.root_hub->dev)) |
557 | temp |= PORT_WAKE_BITS; | 686 | temp |= PORT_WAKE_BITS; |
558 | writel (temp | PORT_SUSPEND, | 687 | ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); |
559 | &ehci->regs->port_status [wIndex]); | ||
560 | break; | 688 | break; |
561 | case USB_PORT_FEAT_POWER: | 689 | case USB_PORT_FEAT_POWER: |
562 | if (HCS_PPC (ehci->hcs_params)) | 690 | if (HCS_PPC (ehci->hcs_params)) |
563 | writel (temp | PORT_POWER, | 691 | ehci_writel(ehci, temp | PORT_POWER, |
564 | &ehci->regs->port_status [wIndex]); | 692 | status_reg); |
565 | break; | 693 | break; |
566 | case USB_PORT_FEAT_RESET: | 694 | case USB_PORT_FEAT_RESET: |
567 | if (temp & PORT_RESUME) | 695 | if (temp & PORT_RESUME) |
@@ -589,7 +717,7 @@ static int ehci_hub_control ( | |||
589 | ehci->reset_done [wIndex] = jiffies | 717 | ehci->reset_done [wIndex] = jiffies |
590 | + msecs_to_jiffies (50); | 718 | + msecs_to_jiffies (50); |
591 | } | 719 | } |
592 | writel (temp, &ehci->regs->port_status [wIndex]); | 720 | ehci_writel(ehci, temp, status_reg); |
593 | break; | 721 | break; |
594 | 722 | ||
595 | /* For downstream facing ports (these): one hub port is put | 723 | /* For downstream facing ports (these): one hub port is put |
@@ -604,13 +732,13 @@ static int ehci_hub_control ( | |||
604 | ehci_quiesce(ehci); | 732 | ehci_quiesce(ehci); |
605 | ehci_halt(ehci); | 733 | ehci_halt(ehci); |
606 | temp |= selector << 16; | 734 | temp |= selector << 16; |
607 | writel (temp, &ehci->regs->port_status [wIndex]); | 735 | ehci_writel(ehci, temp, status_reg); |
608 | break; | 736 | break; |
609 | 737 | ||
610 | default: | 738 | default: |
611 | goto error; | 739 | goto error; |
612 | } | 740 | } |
613 | readl (&ehci->regs->command); /* unblock posted writes */ | 741 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ |
614 | break; | 742 | break; |
615 | 743 | ||
616 | default: | 744 | default: |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index 4bc7970ba3ef..12edc723ec73 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -38,7 +38,7 @@ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) | |||
38 | if ((temp & (3 << 13)) == (1 << 13)) { | 38 | if ((temp & (3 << 13)) == (1 << 13)) { |
39 | temp &= 0x1fff; | 39 | temp &= 0x1fff; |
40 | ehci->debug = ehci_to_hcd(ehci)->regs + temp; | 40 | ehci->debug = ehci_to_hcd(ehci)->regs + temp; |
41 | temp = readl(&ehci->debug->control); | 41 | temp = ehci_readl(ehci, &ehci->debug->control); |
42 | ehci_info(ehci, "debug port %d%s\n", | 42 | ehci_info(ehci, "debug port %d%s\n", |
43 | HCS_DEBUG_PORT(ehci->hcs_params), | 43 | HCS_DEBUG_PORT(ehci->hcs_params), |
44 | (temp & DBGP_ENABLED) | 44 | (temp & DBGP_ENABLED) |
@@ -71,8 +71,24 @@ static int ehci_pci_setup(struct usb_hcd *hcd) | |||
71 | u32 temp; | 71 | u32 temp; |
72 | int retval; | 72 | int retval; |
73 | 73 | ||
74 | switch (pdev->vendor) { | ||
75 | case PCI_VENDOR_ID_TOSHIBA_2: | ||
76 | /* celleb's companion chip */ | ||
77 | if (pdev->device == 0x01b5) { | ||
78 | #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO | ||
79 | ehci->big_endian_mmio = 1; | ||
80 | #else | ||
81 | ehci_warn(ehci, | ||
82 | "unsupported big endian Toshiba quirk\n"); | ||
83 | #endif | ||
84 | } | ||
85 | break; | ||
86 | } | ||
87 | |||
74 | ehci->caps = hcd->regs; | 88 | ehci->caps = hcd->regs; |
75 | ehci->regs = hcd->regs + HC_LENGTH(readl(&ehci->caps->hc_capbase)); | 89 | ehci->regs = hcd->regs + |
90 | HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase)); | ||
91 | |||
76 | dbg_hcs_params(ehci, "reset"); | 92 | dbg_hcs_params(ehci, "reset"); |
77 | dbg_hcc_params(ehci, "reset"); | 93 | dbg_hcc_params(ehci, "reset"); |
78 | 94 | ||
@@ -101,7 +117,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd) | |||
101 | } | 117 | } |
102 | 118 | ||
103 | /* cache this readonly data; minimize chip reads */ | 119 | /* cache this readonly data; minimize chip reads */ |
104 | ehci->hcs_params = readl(&ehci->caps->hcs_params); | 120 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); |
105 | 121 | ||
106 | retval = ehci_halt(ehci); | 122 | retval = ehci_halt(ehci); |
107 | if (retval) | 123 | if (retval) |
@@ -235,8 +251,8 @@ static int ehci_pci_suspend(struct usb_hcd *hcd, pm_message_t message) | |||
235 | rc = -EINVAL; | 251 | rc = -EINVAL; |
236 | goto bail; | 252 | goto bail; |
237 | } | 253 | } |
238 | writel (0, &ehci->regs->intr_enable); | 254 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); |
239 | (void)readl(&ehci->regs->intr_enable); | 255 | (void)ehci_readl(ehci, &ehci->regs->intr_enable); |
240 | 256 | ||
241 | /* make sure snapshot being resumed re-enumerates everything */ | 257 | /* make sure snapshot being resumed re-enumerates everything */ |
242 | if (message.event == PM_EVENT_PRETHAW) { | 258 | if (message.event == PM_EVENT_PRETHAW) { |
@@ -270,13 +286,13 @@ static int ehci_pci_resume(struct usb_hcd *hcd) | |||
270 | /* If CF is still set, we maintained PCI Vaux power. | 286 | /* If CF is still set, we maintained PCI Vaux power. |
271 | * Just undo the effect of ehci_pci_suspend(). | 287 | * Just undo the effect of ehci_pci_suspend(). |
272 | */ | 288 | */ |
273 | if (readl(&ehci->regs->configured_flag) == FLAG_CF) { | 289 | if (ehci_readl(ehci, &ehci->regs->configured_flag) == FLAG_CF) { |
274 | int mask = INTR_MASK; | 290 | int mask = INTR_MASK; |
275 | 291 | ||
276 | if (!device_may_wakeup(&hcd->self.root_hub->dev)) | 292 | if (!device_may_wakeup(&hcd->self.root_hub->dev)) |
277 | mask &= ~STS_PCD; | 293 | mask &= ~STS_PCD; |
278 | writel(mask, &ehci->regs->intr_enable); | 294 | ehci_writel(ehci, mask, &ehci->regs->intr_enable); |
279 | readl(&ehci->regs->intr_enable); | 295 | ehci_readl(ehci, &ehci->regs->intr_enable); |
280 | return 0; | 296 | return 0; |
281 | } | 297 | } |
282 | 298 | ||
@@ -300,9 +316,9 @@ static int ehci_pci_resume(struct usb_hcd *hcd) | |||
300 | /* here we "know" root ports should always stay powered */ | 316 | /* here we "know" root ports should always stay powered */ |
301 | ehci_port_power(ehci, 1); | 317 | ehci_port_power(ehci, 1); |
302 | 318 | ||
303 | writel(ehci->command, &ehci->regs->command); | 319 | ehci_writel(ehci, ehci->command, &ehci->regs->command); |
304 | writel(FLAG_CF, &ehci->regs->configured_flag); | 320 | ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); |
305 | readl(&ehci->regs->command); /* unblock posted writes */ | 321 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ |
306 | 322 | ||
307 | hcd->state = HC_STATE_SUSPENDED; | 323 | hcd->state = HC_STATE_SUSPENDED; |
308 | return 0; | 324 | return 0; |
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c new file mode 100644 index 000000000000..4d781a2a9807 --- /dev/null +++ b/drivers/usb/host/ehci-ps3.c | |||
@@ -0,0 +1,193 @@ | |||
1 | /* | ||
2 | * PS3 EHCI Host Controller driver | ||
3 | * | ||
4 | * Copyright (C) 2006 Sony Computer Entertainment Inc. | ||
5 | * Copyright 2006 Sony Corp. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <asm/ps3.h> | ||
22 | |||
23 | static int ps3_ehci_hc_reset(struct usb_hcd *hcd) | ||
24 | { | ||
25 | int result; | ||
26 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
27 | |||
28 | ehci->big_endian_mmio = 1; | ||
29 | |||
30 | ehci->caps = hcd->regs; | ||
31 | ehci->regs = hcd->regs + HC_LENGTH(ehci_readl(ehci, | ||
32 | &ehci->caps->hc_capbase)); | ||
33 | |||
34 | dbg_hcs_params(ehci, "reset"); | ||
35 | dbg_hcc_params(ehci, "reset"); | ||
36 | |||
37 | ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params); | ||
38 | |||
39 | result = ehci_halt(ehci); | ||
40 | |||
41 | if (result) | ||
42 | return result; | ||
43 | |||
44 | result = ehci_init(hcd); | ||
45 | |||
46 | if (result) | ||
47 | return result; | ||
48 | |||
49 | ehci_port_power(ehci, 0); | ||
50 | |||
51 | return result; | ||
52 | } | ||
53 | |||
54 | static const struct hc_driver ps3_ehci_hc_driver = { | ||
55 | .description = hcd_name, | ||
56 | .product_desc = "PS3 EHCI Host Controller", | ||
57 | .hcd_priv_size = sizeof(struct ehci_hcd), | ||
58 | .irq = ehci_irq, | ||
59 | .flags = HCD_MEMORY | HCD_USB2, | ||
60 | .reset = ps3_ehci_hc_reset, | ||
61 | .start = ehci_run, | ||
62 | .stop = ehci_stop, | ||
63 | .shutdown = ehci_shutdown, | ||
64 | .urb_enqueue = ehci_urb_enqueue, | ||
65 | .urb_dequeue = ehci_urb_dequeue, | ||
66 | .endpoint_disable = ehci_endpoint_disable, | ||
67 | .get_frame_number = ehci_get_frame, | ||
68 | .hub_status_data = ehci_hub_status_data, | ||
69 | .hub_control = ehci_hub_control, | ||
70 | #if defined(CONFIG_PM) | ||
71 | .bus_suspend = ehci_bus_suspend, | ||
72 | .bus_resume = ehci_bus_resume, | ||
73 | #endif | ||
74 | }; | ||
75 | |||
76 | #if !defined(DEBUG) | ||
77 | #undef dev_dbg | ||
78 | static inline int __attribute__ ((format (printf, 2, 3))) dev_dbg( | ||
79 | const struct device *_dev, const char *fmt, ...) {return 0;} | ||
80 | #endif | ||
81 | |||
82 | |||
83 | static int ps3_ehci_sb_probe(struct ps3_system_bus_device *dev) | ||
84 | { | ||
85 | int result; | ||
86 | struct usb_hcd *hcd; | ||
87 | unsigned int virq; | ||
88 | static u64 dummy_mask = DMA_32BIT_MASK; | ||
89 | |||
90 | if (usb_disabled()) { | ||
91 | result = -ENODEV; | ||
92 | goto fail_start; | ||
93 | } | ||
94 | |||
95 | result = ps3_mmio_region_create(dev->m_region); | ||
96 | |||
97 | if (result) { | ||
98 | dev_dbg(&dev->core, "%s:%d: ps3_map_mmio_region failed\n", | ||
99 | __func__, __LINE__); | ||
100 | result = -EPERM; | ||
101 | goto fail_mmio; | ||
102 | } | ||
103 | |||
104 | dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__, | ||
105 | __LINE__, dev->m_region->lpar_addr); | ||
106 | |||
107 | result = ps3_alloc_io_irq(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq); | ||
108 | |||
109 | if (result) { | ||
110 | dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n", | ||
111 | __func__, __LINE__, virq); | ||
112 | result = -EPERM; | ||
113 | goto fail_irq; | ||
114 | } | ||
115 | |||
116 | dev->core.power.power_state = PMSG_ON; | ||
117 | dev->core.dma_mask = &dummy_mask; /* FIXME: for improper usb code */ | ||
118 | |||
119 | hcd = usb_create_hcd(&ps3_ehci_hc_driver, &dev->core, dev->core.bus_id); | ||
120 | |||
121 | if (!hcd) { | ||
122 | dev_dbg(&dev->core, "%s:%d: usb_create_hcd failed\n", __func__, | ||
123 | __LINE__); | ||
124 | result = -ENOMEM; | ||
125 | goto fail_create_hcd; | ||
126 | } | ||
127 | |||
128 | hcd->rsrc_start = dev->m_region->lpar_addr; | ||
129 | hcd->rsrc_len = dev->m_region->len; | ||
130 | hcd->regs = ioremap(dev->m_region->lpar_addr, dev->m_region->len); | ||
131 | |||
132 | if (!hcd->regs) { | ||
133 | dev_dbg(&dev->core, "%s:%d: ioremap failed\n", __func__, | ||
134 | __LINE__); | ||
135 | result = -EPERM; | ||
136 | goto fail_ioremap; | ||
137 | } | ||
138 | |||
139 | dev_dbg(&dev->core, "%s:%d: hcd->rsrc_start %lxh\n", __func__, __LINE__, | ||
140 | (unsigned long)hcd->rsrc_start); | ||
141 | dev_dbg(&dev->core, "%s:%d: hcd->rsrc_len %lxh\n", __func__, __LINE__, | ||
142 | (unsigned long)hcd->rsrc_len); | ||
143 | dev_dbg(&dev->core, "%s:%d: hcd->regs %lxh\n", __func__, __LINE__, | ||
144 | (unsigned long)hcd->regs); | ||
145 | dev_dbg(&dev->core, "%s:%d: virq %lu\n", __func__, __LINE__, | ||
146 | (unsigned long)virq); | ||
147 | |||
148 | ps3_system_bus_set_driver_data(dev, hcd); | ||
149 | |||
150 | result = usb_add_hcd(hcd, virq, IRQF_DISABLED); | ||
151 | |||
152 | if (result) { | ||
153 | dev_dbg(&dev->core, "%s:%d: usb_add_hcd failed (%d)\n", | ||
154 | __func__, __LINE__, result); | ||
155 | goto fail_add_hcd; | ||
156 | } | ||
157 | |||
158 | return result; | ||
159 | |||
160 | fail_add_hcd: | ||
161 | iounmap(hcd->regs); | ||
162 | fail_ioremap: | ||
163 | usb_put_hcd(hcd); | ||
164 | fail_create_hcd: | ||
165 | ps3_free_io_irq(virq); | ||
166 | fail_irq: | ||
167 | ps3_free_mmio_region(dev->m_region); | ||
168 | fail_mmio: | ||
169 | fail_start: | ||
170 | return result; | ||
171 | } | ||
172 | |||
173 | static int ps3_ehci_sb_remove(struct ps3_system_bus_device *dev) | ||
174 | { | ||
175 | struct usb_hcd *hcd = | ||
176 | (struct usb_hcd *)ps3_system_bus_get_driver_data(dev); | ||
177 | |||
178 | usb_put_hcd(hcd); | ||
179 | ps3_system_bus_set_driver_data(dev, NULL); | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | |||
184 | MODULE_ALIAS("ps3-ehci"); | ||
185 | |||
186 | static struct ps3_system_bus_driver ps3_ehci_sb_driver = { | ||
187 | .match_id = PS3_MATCH_ID_EHCI, | ||
188 | .core = { | ||
189 | .name = "ps3-ehci-driver", | ||
190 | }, | ||
191 | .probe = ps3_ehci_sb_probe, | ||
192 | .remove = ps3_ehci_sb_remove, | ||
193 | }; | ||
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 62e46dc60e86..e7fbbd00e7cd 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -789,13 +789,14 @@ static void qh_link_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
789 | head = ehci->async; | 789 | head = ehci->async; |
790 | timer_action_done (ehci, TIMER_ASYNC_OFF); | 790 | timer_action_done (ehci, TIMER_ASYNC_OFF); |
791 | if (!head->qh_next.qh) { | 791 | if (!head->qh_next.qh) { |
792 | u32 cmd = readl (&ehci->regs->command); | 792 | u32 cmd = ehci_readl(ehci, &ehci->regs->command); |
793 | 793 | ||
794 | if (!(cmd & CMD_ASE)) { | 794 | if (!(cmd & CMD_ASE)) { |
795 | /* in case a clear of CMD_ASE didn't take yet */ | 795 | /* in case a clear of CMD_ASE didn't take yet */ |
796 | (void) handshake (&ehci->regs->status, STS_ASS, 0, 150); | 796 | (void)handshake(ehci, &ehci->regs->status, |
797 | STS_ASS, 0, 150); | ||
797 | cmd |= CMD_ASE | CMD_RUN; | 798 | cmd |= CMD_ASE | CMD_RUN; |
798 | writel (cmd, &ehci->regs->command); | 799 | ehci_writel(ehci, cmd, &ehci->regs->command); |
799 | ehci_to_hcd(ehci)->state = HC_STATE_RUNNING; | 800 | ehci_to_hcd(ehci)->state = HC_STATE_RUNNING; |
800 | /* posted write need not be known to HC yet ... */ | 801 | /* posted write need not be known to HC yet ... */ |
801 | } | 802 | } |
@@ -1007,7 +1008,7 @@ static void end_unlink_async (struct ehci_hcd *ehci) | |||
1007 | 1008 | ||
1008 | static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | 1009 | static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) |
1009 | { | 1010 | { |
1010 | int cmd = readl (&ehci->regs->command); | 1011 | int cmd = ehci_readl(ehci, &ehci->regs->command); |
1011 | struct ehci_qh *prev; | 1012 | struct ehci_qh *prev; |
1012 | 1013 | ||
1013 | #ifdef DEBUG | 1014 | #ifdef DEBUG |
@@ -1025,7 +1026,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
1025 | if (ehci_to_hcd(ehci)->state != HC_STATE_HALT | 1026 | if (ehci_to_hcd(ehci)->state != HC_STATE_HALT |
1026 | && !ehci->reclaim) { | 1027 | && !ehci->reclaim) { |
1027 | /* ... and CMD_IAAD clear */ | 1028 | /* ... and CMD_IAAD clear */ |
1028 | writel (cmd & ~CMD_ASE, &ehci->regs->command); | 1029 | ehci_writel(ehci, cmd & ~CMD_ASE, |
1030 | &ehci->regs->command); | ||
1029 | wmb (); | 1031 | wmb (); |
1030 | // handshake later, if we need to | 1032 | // handshake later, if we need to |
1031 | timer_action_done (ehci, TIMER_ASYNC_OFF); | 1033 | timer_action_done (ehci, TIMER_ASYNC_OFF); |
@@ -1054,8 +1056,8 @@ static void start_unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
1054 | 1056 | ||
1055 | ehci->reclaim_ready = 0; | 1057 | ehci->reclaim_ready = 0; |
1056 | cmd |= CMD_IAAD; | 1058 | cmd |= CMD_IAAD; |
1057 | writel (cmd, &ehci->regs->command); | 1059 | ehci_writel(ehci, cmd, &ehci->regs->command); |
1058 | (void) readl (&ehci->regs->command); | 1060 | (void)ehci_readl(ehci, &ehci->regs->command); |
1059 | timer_action (ehci, TIMER_IAA_WATCHDOG); | 1061 | timer_action (ehci, TIMER_IAA_WATCHDOG); |
1060 | } | 1062 | } |
1061 | 1063 | ||
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index 65c402a0fa7a..7b5ae7111f23 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -433,20 +433,20 @@ static int enable_periodic (struct ehci_hcd *ehci) | |||
433 | /* did clearing PSE did take effect yet? | 433 | /* did clearing PSE did take effect yet? |
434 | * takes effect only at frame boundaries... | 434 | * takes effect only at frame boundaries... |
435 | */ | 435 | */ |
436 | status = handshake (&ehci->regs->status, STS_PSS, 0, 9 * 125); | 436 | status = handshake(ehci, &ehci->regs->status, STS_PSS, 0, 9 * 125); |
437 | if (status != 0) { | 437 | if (status != 0) { |
438 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; | 438 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; |
439 | return status; | 439 | return status; |
440 | } | 440 | } |
441 | 441 | ||
442 | cmd = readl (&ehci->regs->command) | CMD_PSE; | 442 | cmd = ehci_readl(ehci, &ehci->regs->command) | CMD_PSE; |
443 | writel (cmd, &ehci->regs->command); | 443 | ehci_writel(ehci, cmd, &ehci->regs->command); |
444 | /* posted write ... PSS happens later */ | 444 | /* posted write ... PSS happens later */ |
445 | ehci_to_hcd(ehci)->state = HC_STATE_RUNNING; | 445 | ehci_to_hcd(ehci)->state = HC_STATE_RUNNING; |
446 | 446 | ||
447 | /* make sure ehci_work scans these */ | 447 | /* make sure ehci_work scans these */ |
448 | ehci->next_uframe = readl (&ehci->regs->frame_index) | 448 | ehci->next_uframe = ehci_readl(ehci, &ehci->regs->frame_index) |
449 | % (ehci->periodic_size << 3); | 449 | % (ehci->periodic_size << 3); |
450 | return 0; | 450 | return 0; |
451 | } | 451 | } |
452 | 452 | ||
@@ -458,14 +458,14 @@ static int disable_periodic (struct ehci_hcd *ehci) | |||
458 | /* did setting PSE not take effect yet? | 458 | /* did setting PSE not take effect yet? |
459 | * takes effect only at frame boundaries... | 459 | * takes effect only at frame boundaries... |
460 | */ | 460 | */ |
461 | status = handshake (&ehci->regs->status, STS_PSS, STS_PSS, 9 * 125); | 461 | status = handshake(ehci, &ehci->regs->status, STS_PSS, STS_PSS, 9 * 125); |
462 | if (status != 0) { | 462 | if (status != 0) { |
463 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; | 463 | ehci_to_hcd(ehci)->state = HC_STATE_HALT; |
464 | return status; | 464 | return status; |
465 | } | 465 | } |
466 | 466 | ||
467 | cmd = readl (&ehci->regs->command) & ~CMD_PSE; | 467 | cmd = ehci_readl(ehci, &ehci->regs->command) & ~CMD_PSE; |
468 | writel (cmd, &ehci->regs->command); | 468 | ehci_writel(ehci, cmd, &ehci->regs->command); |
469 | /* posted write ... */ | 469 | /* posted write ... */ |
470 | 470 | ||
471 | ehci->next_uframe = -1; | 471 | ehci->next_uframe = -1; |
@@ -1336,7 +1336,7 @@ iso_stream_schedule ( | |||
1336 | goto fail; | 1336 | goto fail; |
1337 | } | 1337 | } |
1338 | 1338 | ||
1339 | now = readl (&ehci->regs->frame_index) % mod; | 1339 | now = ehci_readl(ehci, &ehci->regs->frame_index) % mod; |
1340 | 1340 | ||
1341 | /* when's the last uframe this urb could start? */ | 1341 | /* when's the last uframe this urb could start? */ |
1342 | max = now + mod; | 1342 | max = now + mod; |
@@ -2088,7 +2088,7 @@ scan_periodic (struct ehci_hcd *ehci) | |||
2088 | */ | 2088 | */ |
2089 | now_uframe = ehci->next_uframe; | 2089 | now_uframe = ehci->next_uframe; |
2090 | if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) | 2090 | if (HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) |
2091 | clock = readl (&ehci->regs->frame_index); | 2091 | clock = ehci_readl(ehci, &ehci->regs->frame_index); |
2092 | else | 2092 | else |
2093 | clock = now_uframe + mod - 1; | 2093 | clock = now_uframe + mod - 1; |
2094 | clock %= mod; | 2094 | clock %= mod; |
@@ -2213,7 +2213,7 @@ restart: | |||
2213 | if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) | 2213 | if (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state)) |
2214 | break; | 2214 | break; |
2215 | ehci->next_uframe = now_uframe; | 2215 | ehci->next_uframe = now_uframe; |
2216 | now = readl (&ehci->regs->frame_index) % mod; | 2216 | now = ehci_readl(ehci, &ehci->regs->frame_index) % mod; |
2217 | if (now_uframe == now) | 2217 | if (now_uframe == now) |
2218 | break; | 2218 | break; |
2219 | 2219 | ||
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 74dbc6c8228f..46fa57a520d0 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -74,7 +74,11 @@ struct ehci_hcd { /* one per controller */ | |||
74 | 74 | ||
75 | /* per root hub port */ | 75 | /* per root hub port */ |
76 | unsigned long reset_done [EHCI_MAX_ROOT_PORTS]; | 76 | unsigned long reset_done [EHCI_MAX_ROOT_PORTS]; |
77 | unsigned long bus_suspended; | 77 | /* bit vectors (one bit per port) */ |
78 | unsigned long bus_suspended; /* which ports were | ||
79 | already suspended at the start of a bus suspend */ | ||
80 | unsigned long companion_ports; /* which ports are | ||
81 | dedicated to the companion controller */ | ||
78 | 82 | ||
79 | /* per-HC memory pools (could be per-bus, but ...) */ | 83 | /* per-HC memory pools (could be per-bus, but ...) */ |
80 | struct dma_pool *qh_pool; /* qh per active urb */ | 84 | struct dma_pool *qh_pool; /* qh per active urb */ |
@@ -92,6 +96,7 @@ struct ehci_hcd { /* one per controller */ | |||
92 | unsigned is_tdi_rh_tt:1; /* TDI roothub with TT */ | 96 | unsigned is_tdi_rh_tt:1; /* TDI roothub with TT */ |
93 | unsigned no_selective_suspend:1; | 97 | unsigned no_selective_suspend:1; |
94 | unsigned has_fsl_port_bug:1; /* FreeScale */ | 98 | unsigned has_fsl_port_bug:1; /* FreeScale */ |
99 | unsigned big_endian_mmio:1; | ||
95 | 100 | ||
96 | u8 sbrn; /* packed release number */ | 101 | u8 sbrn; /* packed release number */ |
97 | 102 | ||
@@ -651,6 +656,45 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc) | |||
651 | #define ehci_has_fsl_portno_bug(e) (0) | 656 | #define ehci_has_fsl_portno_bug(e) (0) |
652 | #endif | 657 | #endif |
653 | 658 | ||
659 | /* | ||
660 | * While most USB host controllers implement their registers in | ||
661 | * little-endian format, a minority (celleb companion chip) implement | ||
662 | * them in big endian format. | ||
663 | * | ||
664 | * This attempts to support either format at compile time without a | ||
665 | * runtime penalty, or both formats with the additional overhead | ||
666 | * of checking a flag bit. | ||
667 | */ | ||
668 | |||
669 | #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO | ||
670 | #define ehci_big_endian_mmio(e) ((e)->big_endian_mmio) | ||
671 | #else | ||
672 | #define ehci_big_endian_mmio(e) 0 | ||
673 | #endif | ||
674 | |||
675 | static inline unsigned int ehci_readl (const struct ehci_hcd *ehci, | ||
676 | __u32 __iomem * regs) | ||
677 | { | ||
678 | #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO | ||
679 | return ehci_big_endian_mmio(ehci) ? | ||
680 | readl_be(regs) : | ||
681 | readl(regs); | ||
682 | #else | ||
683 | return readl(regs); | ||
684 | #endif | ||
685 | } | ||
686 | |||
687 | static inline void ehci_writel (const struct ehci_hcd *ehci, | ||
688 | const unsigned int val, __u32 __iomem *regs) | ||
689 | { | ||
690 | #ifdef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO | ||
691 | ehci_big_endian_mmio(ehci) ? | ||
692 | writel_be(val, regs) : | ||
693 | writel(val, regs); | ||
694 | #else | ||
695 | writel(val, regs); | ||
696 | #endif | ||
697 | } | ||
654 | 698 | ||
655 | /*-------------------------------------------------------------------------*/ | 699 | /*-------------------------------------------------------------------------*/ |
656 | 700 | ||
diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c index 9325e46a68c0..282d82efc0b0 100644 --- a/drivers/usb/host/hc_crisv10.c +++ b/drivers/usb/host/hc_crisv10.c | |||
@@ -365,7 +365,7 @@ static inline struct urb *urb_list_first(int epid) | |||
365 | /* Adds an urb_entry last in the list for this epid. */ | 365 | /* Adds an urb_entry last in the list for this epid. */ |
366 | static inline void urb_list_add(struct urb *urb, int epid) | 366 | static inline void urb_list_add(struct urb *urb, int epid) |
367 | { | 367 | { |
368 | urb_entry_t *urb_entry = (urb_entry_t *)kmalloc(sizeof(urb_entry_t), KMALLOC_FLAG); | 368 | urb_entry_t *urb_entry = kmalloc(sizeof(urb_entry_t), KMALLOC_FLAG); |
369 | assert(urb_entry); | 369 | assert(urb_entry); |
370 | 370 | ||
371 | urb_entry->urb = urb; | 371 | urb_entry->urb = urb; |
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c index b466581beb4a..930346487278 100644 --- a/drivers/usb/host/ohci-at91.c +++ b/drivers/usb/host/ohci-at91.c | |||
@@ -170,7 +170,6 @@ static int usb_hcd_at91_remove(struct usb_hcd *hcd, | |||
170 | at91_stop_hc(pdev); | 170 | at91_stop_hc(pdev); |
171 | iounmap(hcd->regs); | 171 | iounmap(hcd->regs); |
172 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 172 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
173 | disable_irq_wake(hcd->irq); | ||
174 | 173 | ||
175 | clk_put(fclk); | 174 | clk_put(fclk); |
176 | clk_put(iclk); | 175 | clk_put(iclk); |
@@ -187,7 +186,6 @@ ohci_at91_start (struct usb_hcd *hcd) | |||
187 | { | 186 | { |
188 | struct at91_usbh_data *board = hcd->self.controller->platform_data; | 187 | struct at91_usbh_data *board = hcd->self.controller->platform_data; |
189 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 188 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
190 | struct usb_device *root = hcd->self.root_hub; | ||
191 | int ret; | 189 | int ret; |
192 | 190 | ||
193 | if ((ret = ohci_init(ohci)) < 0) | 191 | if ((ret = ohci_init(ohci)) < 0) |
@@ -221,7 +219,7 @@ static const struct hc_driver ohci_at91_hc_driver = { | |||
221 | */ | 219 | */ |
222 | .start = ohci_at91_start, | 220 | .start = ohci_at91_start, |
223 | .stop = ohci_stop, | 221 | .stop = ohci_stop, |
224 | .shutdown = ohci_shutdown, | 222 | .shutdown = ohci_shutdown, |
225 | 223 | ||
226 | /* | 224 | /* |
227 | * managing i/o requests and associated device resources | 225 | * managing i/o requests and associated device resources |
@@ -272,8 +270,6 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
272 | 270 | ||
273 | if (device_may_wakeup(&pdev->dev)) | 271 | if (device_may_wakeup(&pdev->dev)) |
274 | enable_irq_wake(hcd->irq); | 272 | enable_irq_wake(hcd->irq); |
275 | else | ||
276 | disable_irq_wake(hcd->irq); | ||
277 | 273 | ||
278 | /* | 274 | /* |
279 | * The integrated transceivers seem unable to notice disconnect, | 275 | * The integrated transceivers seem unable to notice disconnect, |
@@ -294,6 +290,11 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg) | |||
294 | 290 | ||
295 | static int ohci_hcd_at91_drv_resume(struct platform_device *pdev) | 291 | static int ohci_hcd_at91_drv_resume(struct platform_device *pdev) |
296 | { | 292 | { |
293 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
294 | |||
295 | if (device_may_wakeup(&pdev->dev)) | ||
296 | disable_irq_wake(hcd->irq); | ||
297 | |||
297 | if (!clocked) { | 298 | if (!clocked) { |
298 | clk_enable(iclk); | 299 | clk_enable(iclk); |
299 | clk_enable(fclk); | 300 | clk_enable(fclk); |
@@ -321,18 +322,3 @@ static struct platform_driver ohci_hcd_at91_driver = { | |||
321 | }, | 322 | }, |
322 | }; | 323 | }; |
323 | 324 | ||
324 | static int __init ohci_hcd_at91_init (void) | ||
325 | { | ||
326 | if (usb_disabled()) | ||
327 | return -ENODEV; | ||
328 | |||
329 | return platform_driver_register(&ohci_hcd_at91_driver); | ||
330 | } | ||
331 | |||
332 | static void __exit ohci_hcd_at91_cleanup (void) | ||
333 | { | ||
334 | platform_driver_unregister(&ohci_hcd_at91_driver); | ||
335 | } | ||
336 | |||
337 | module_init (ohci_hcd_at91_init); | ||
338 | module_exit (ohci_hcd_at91_cleanup); | ||
diff --git a/drivers/usb/host/ohci-au1xxx.c b/drivers/usb/host/ohci-au1xxx.c index 24e23c5783d8..663a0600b6e7 100644 --- a/drivers/usb/host/ohci-au1xxx.c +++ b/drivers/usb/host/ohci-au1xxx.c | |||
@@ -269,7 +269,7 @@ static const struct hc_driver ohci_au1xxx_hc_driver = { | |||
269 | */ | 269 | */ |
270 | .start = ohci_au1xxx_start, | 270 | .start = ohci_au1xxx_start, |
271 | .stop = ohci_stop, | 271 | .stop = ohci_stop, |
272 | .shutdown = ohci_shutdown, | 272 | .shutdown = ohci_shutdown, |
273 | 273 | ||
274 | /* | 274 | /* |
275 | * managing i/o requests and associated device resources | 275 | * managing i/o requests and associated device resources |
@@ -336,7 +336,7 @@ static int ohci_hcd_au1xxx_drv_resume(struct platform_device *dev) | |||
336 | static struct platform_driver ohci_hcd_au1xxx_driver = { | 336 | static struct platform_driver ohci_hcd_au1xxx_driver = { |
337 | .probe = ohci_hcd_au1xxx_drv_probe, | 337 | .probe = ohci_hcd_au1xxx_drv_probe, |
338 | .remove = ohci_hcd_au1xxx_drv_remove, | 338 | .remove = ohci_hcd_au1xxx_drv_remove, |
339 | .shutdown = usb_hcd_platform_shutdown, | 339 | .shutdown = usb_hcd_platform_shutdown, |
340 | /*.suspend = ohci_hcd_au1xxx_drv_suspend, */ | 340 | /*.suspend = ohci_hcd_au1xxx_drv_suspend, */ |
341 | /*.resume = ohci_hcd_au1xxx_drv_resume, */ | 341 | /*.resume = ohci_hcd_au1xxx_drv_resume, */ |
342 | .driver = { | 342 | .driver = { |
@@ -345,19 +345,3 @@ static struct platform_driver ohci_hcd_au1xxx_driver = { | |||
345 | }, | 345 | }, |
346 | }; | 346 | }; |
347 | 347 | ||
348 | static int __init ohci_hcd_au1xxx_init (void) | ||
349 | { | ||
350 | pr_debug (DRIVER_INFO " (Au1xxx)"); | ||
351 | pr_debug ("block sizes: ed %d td %d\n", | ||
352 | sizeof (struct ed), sizeof (struct td)); | ||
353 | |||
354 | return platform_driver_register(&ohci_hcd_au1xxx_driver); | ||
355 | } | ||
356 | |||
357 | static void __exit ohci_hcd_au1xxx_cleanup (void) | ||
358 | { | ||
359 | platform_driver_unregister(&ohci_hcd_au1xxx_driver); | ||
360 | } | ||
361 | |||
362 | module_init (ohci_hcd_au1xxx_init); | ||
363 | module_exit (ohci_hcd_au1xxx_cleanup); | ||
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index 0f47a57dac28..273d5ddb72be 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c | |||
@@ -16,7 +16,7 @@ | |||
16 | case PIPE_CONTROL: temp = "ctrl"; break; \ | 16 | case PIPE_CONTROL: temp = "ctrl"; break; \ |
17 | case PIPE_BULK: temp = "bulk"; break; \ | 17 | case PIPE_BULK: temp = "bulk"; break; \ |
18 | case PIPE_INTERRUPT: temp = "intr"; break; \ | 18 | case PIPE_INTERRUPT: temp = "intr"; break; \ |
19 | default: temp = "isoc"; break; \ | 19 | default: temp = "isoc"; break; \ |
20 | }; temp;}) | 20 | }; temp;}) |
21 | #define pipestring(pipe) edstring(usb_pipetype(pipe)) | 21 | #define pipestring(pipe) edstring(usb_pipetype(pipe)) |
22 | 22 | ||
@@ -205,13 +205,13 @@ ohci_dump_status (struct ohci_hcd *controller, char **next, unsigned *size) | |||
205 | (temp & RH_PS_PSSC) ? " PSSC" : "", \ | 205 | (temp & RH_PS_PSSC) ? " PSSC" : "", \ |
206 | (temp & RH_PS_PESC) ? " PESC" : "", \ | 206 | (temp & RH_PS_PESC) ? " PESC" : "", \ |
207 | (temp & RH_PS_CSC) ? " CSC" : "", \ | 207 | (temp & RH_PS_CSC) ? " CSC" : "", \ |
208 | \ | 208 | \ |
209 | (temp & RH_PS_LSDA) ? " LSDA" : "", \ | 209 | (temp & RH_PS_LSDA) ? " LSDA" : "", \ |
210 | (temp & RH_PS_PPS) ? " PPS" : "", \ | 210 | (temp & RH_PS_PPS) ? " PPS" : "", \ |
211 | (temp & RH_PS_PRS) ? " PRS" : "", \ | 211 | (temp & RH_PS_PRS) ? " PRS" : "", \ |
212 | (temp & RH_PS_POCI) ? " POCI" : "", \ | 212 | (temp & RH_PS_POCI) ? " POCI" : "", \ |
213 | (temp & RH_PS_PSS) ? " PSS" : "", \ | 213 | (temp & RH_PS_PSS) ? " PSS" : "", \ |
214 | \ | 214 | \ |
215 | (temp & RH_PS_PES) ? " PES" : "", \ | 215 | (temp & RH_PS_PES) ? " PES" : "", \ |
216 | (temp & RH_PS_CCS) ? " CCS" : "" \ | 216 | (temp & RH_PS_CCS) ? " CCS" : "" \ |
217 | ); | 217 | ); |
@@ -563,7 +563,7 @@ show_periodic (struct class_device *class_dev, char *buf) | |||
563 | (info & ED_SKIP) ? " K" : "", | 563 | (info & ED_SKIP) ? " K" : "", |
564 | (ed->hwHeadP & | 564 | (ed->hwHeadP & |
565 | cpu_to_hc32(ohci, ED_H)) ? | 565 | cpu_to_hc32(ohci, ED_H)) ? |
566 | " H" : ""); | 566 | " H" : ""); |
567 | size -= temp; | 567 | size -= temp; |
568 | next += temp; | 568 | next += temp; |
569 | 569 | ||
diff --git a/drivers/usb/host/ohci-ep93xx.c b/drivers/usb/host/ohci-ep93xx.c index 1bf5e7a4e735..44c60fba76e1 100644 --- a/drivers/usb/host/ohci-ep93xx.c +++ b/drivers/usb/host/ohci-ep93xx.c | |||
@@ -169,7 +169,7 @@ static int ohci_hcd_ep93xx_drv_remove(struct platform_device *pdev) | |||
169 | static int ohci_hcd_ep93xx_drv_suspend(struct platform_device *pdev, pm_message_t state) | 169 | static int ohci_hcd_ep93xx_drv_suspend(struct platform_device *pdev, pm_message_t state) |
170 | { | 170 | { |
171 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | 171 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
172 | struct ochi_hcd *ohci = hcd_to_ohci(hcd); | 172 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); |
173 | 173 | ||
174 | if (time_before(jiffies, ohci->next_statechange)) | 174 | if (time_before(jiffies, ohci->next_statechange)) |
175 | msleep(5); | 175 | msleep(5); |
@@ -204,7 +204,7 @@ static int ohci_hcd_ep93xx_drv_resume(struct platform_device *pdev) | |||
204 | static struct platform_driver ohci_hcd_ep93xx_driver = { | 204 | static struct platform_driver ohci_hcd_ep93xx_driver = { |
205 | .probe = ohci_hcd_ep93xx_drv_probe, | 205 | .probe = ohci_hcd_ep93xx_drv_probe, |
206 | .remove = ohci_hcd_ep93xx_drv_remove, | 206 | .remove = ohci_hcd_ep93xx_drv_remove, |
207 | .shutdown = usb_hcd_platform_shutdown, | 207 | .shutdown = usb_hcd_platform_shutdown, |
208 | #ifdef CONFIG_PM | 208 | #ifdef CONFIG_PM |
209 | .suspend = ohci_hcd_ep93xx_drv_suspend, | 209 | .suspend = ohci_hcd_ep93xx_drv_suspend, |
210 | .resume = ohci_hcd_ep93xx_drv_resume, | 210 | .resume = ohci_hcd_ep93xx_drv_resume, |
@@ -214,15 +214,3 @@ static struct platform_driver ohci_hcd_ep93xx_driver = { | |||
214 | }, | 214 | }, |
215 | }; | 215 | }; |
216 | 216 | ||
217 | static int __init ohci_hcd_ep93xx_init(void) | ||
218 | { | ||
219 | return platform_driver_register(&ohci_hcd_ep93xx_driver); | ||
220 | } | ||
221 | |||
222 | static void __exit ohci_hcd_ep93xx_cleanup(void) | ||
223 | { | ||
224 | platform_driver_unregister(&ohci_hcd_ep93xx_driver); | ||
225 | } | ||
226 | |||
227 | module_init(ohci_hcd_ep93xx_init); | ||
228 | module_exit(ohci_hcd_ep93xx_cleanup); | ||
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index b28a9b602066..fa6a7ceaa0db 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -3,77 +3,21 @@ | |||
3 | * | 3 | * |
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | 4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> |
5 | * (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net> | 5 | * (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net> |
6 | * | 6 | * |
7 | * [ Initialisation is based on Linus' ] | 7 | * [ Initialisation is based on Linus' ] |
8 | * [ uhci code and gregs ohci fragments ] | 8 | * [ uhci code and gregs ohci fragments ] |
9 | * [ (C) Copyright 1999 Linus Torvalds ] | 9 | * [ (C) Copyright 1999 Linus Torvalds ] |
10 | * [ (C) Copyright 1999 Gregory P. Smith] | 10 | * [ (C) Copyright 1999 Gregory P. Smith] |
11 | * | 11 | * |
12 | * | 12 | * |
13 | * OHCI is the main "non-Intel/VIA" standard for USB 1.1 host controller | 13 | * OHCI is the main "non-Intel/VIA" standard for USB 1.1 host controller |
14 | * interfaces (though some non-x86 Intel chips use it). It supports | 14 | * interfaces (though some non-x86 Intel chips use it). It supports |
15 | * smarter hardware than UHCI. A download link for the spec available | 15 | * smarter hardware than UHCI. A download link for the spec available |
16 | * through the http://www.usb.org website. | 16 | * through the http://www.usb.org website. |
17 | * | 17 | * |
18 | * History: | ||
19 | * | ||
20 | * 2004/03/24 LH7A404 support (Durgesh Pattamatta & Marc Singer) | ||
21 | * 2004/02/04 use generic dma_* functions instead of pci_* (dsaxena@plexity.net) | ||
22 | * 2003/02/24 show registers in sysfs (Kevin Brosius) | ||
23 | * | ||
24 | * 2002/09/03 get rid of ed hashtables, rework periodic scheduling and | ||
25 | * bandwidth accounting; if debugging, show schedules in driverfs | ||
26 | * 2002/07/19 fixes to management of ED and schedule state. | ||
27 | * 2002/06/09 SA-1111 support (Christopher Hoover) | ||
28 | * 2002/06/01 remember frame when HC won't see EDs any more; use that info | ||
29 | * to fix urb unlink races caused by interrupt latency assumptions; | ||
30 | * minor ED field and function naming updates | ||
31 | * 2002/01/18 package as a patch for 2.5.3; this should match the | ||
32 | * 2.4.17 kernel modulo some bugs being fixed. | ||
33 | * | ||
34 | * 2001/10/18 merge pmac cleanup (Benjamin Herrenschmidt) and bugfixes | ||
35 | * from post-2.4.5 patches. | ||
36 | * 2001/09/20 URB_ZERO_PACKET support; hcca_dma portability, OPTi warning | ||
37 | * 2001/09/07 match PCI PM changes, errnos from Linus' tree | ||
38 | * 2001/05/05 fork 2.4.5 version into "hcd" framework, cleanup, simplify; | ||
39 | * pbook pci quirks gone (please fix pbook pci sw!) (db) | ||
40 | * | ||
41 | * 2001/04/08 Identify version on module load (gb) | ||
42 | * 2001/03/24 td/ed hashing to remove bus_to_virt (Steve Longerbeam); | ||
43 | pci_map_single (db) | ||
44 | * 2001/03/21 td and dev/ed allocation uses new pci_pool API (db) | ||
45 | * 2001/03/07 hcca allocation uses pci_alloc_consistent (Steve Longerbeam) | ||
46 | * | ||
47 | * 2000/09/26 fixed races in removing the private portion of the urb | ||
48 | * 2000/09/07 disable bulk and control lists when unlinking the last | ||
49 | * endpoint descriptor in order to avoid unrecoverable errors on | ||
50 | * the Lucent chips. (rwc@sgi) | ||
51 | * 2000/08/29 use bandwidth claiming hooks (thanks Randy!), fix some | ||
52 | * urb unlink probs, indentation fixes | ||
53 | * 2000/08/11 various oops fixes mostly affecting iso and cleanup from | ||
54 | * device unplugs. | ||
55 | * 2000/06/28 use PCI hotplug framework, for better power management | ||
56 | * and for Cardbus support (David Brownell) | ||
57 | * 2000/earlier: fixes for NEC/Lucent chips; suspend/resume handling | ||
58 | * when the controller loses power; handle UE; cleanup; ... | ||
59 | * | ||
60 | * v5.2 1999/12/07 URB 3rd preview, | ||
61 | * v5.1 1999/11/30 URB 2nd preview, cpia, (usb-scsi) | ||
62 | * v5.0 1999/11/22 URB Technical preview, Paul Mackerras powerbook susp/resume | ||
63 | * i386: HUB, Keyboard, Mouse, Printer | ||
64 | * | ||
65 | * v4.3 1999/10/27 multiple HCs, bulk_request | ||
66 | * v4.2 1999/09/05 ISO API alpha, new dev alloc, neg Error-codes | ||
67 | * v4.1 1999/08/27 Randy Dunlap's - ISO API first impl. | ||
68 | * v4.0 1999/08/18 | ||
69 | * v3.0 1999/06/25 | ||
70 | * v2.1 1999/05/09 code clean up | ||
71 | * v2.0 1999/05/04 | ||
72 | * v1.0 1999/04/27 initial release | ||
73 | * | ||
74 | * This file is licenced under the GPL. | 18 | * This file is licenced under the GPL. |
75 | */ | 19 | */ |
76 | 20 | ||
77 | #include <linux/module.h> | 21 | #include <linux/module.h> |
78 | #include <linux/moduleparam.h> | 22 | #include <linux/moduleparam.h> |
79 | #include <linux/pci.h> | 23 | #include <linux/pci.h> |
@@ -89,7 +33,7 @@ | |||
89 | #include <linux/list.h> | 33 | #include <linux/list.h> |
90 | #include <linux/usb.h> | 34 | #include <linux/usb.h> |
91 | #include <linux/usb/otg.h> | 35 | #include <linux/usb/otg.h> |
92 | #include <linux/dma-mapping.h> | 36 | #include <linux/dma-mapping.h> |
93 | #include <linux/dmapool.h> | 37 | #include <linux/dmapool.h> |
94 | #include <linux/reboot.h> | 38 | #include <linux/reboot.h> |
95 | 39 | ||
@@ -183,11 +127,11 @@ static int ohci_urb_enqueue ( | |||
183 | int i, size = 0; | 127 | int i, size = 0; |
184 | unsigned long flags; | 128 | unsigned long flags; |
185 | int retval = 0; | 129 | int retval = 0; |
186 | 130 | ||
187 | #ifdef OHCI_VERBOSE_DEBUG | 131 | #ifdef OHCI_VERBOSE_DEBUG |
188 | urb_print (urb, "SUB", usb_pipein (pipe)); | 132 | urb_print (urb, "SUB", usb_pipein (pipe)); |
189 | #endif | 133 | #endif |
190 | 134 | ||
191 | /* every endpoint has a ed, locate and maybe (re)initialize it */ | 135 | /* every endpoint has a ed, locate and maybe (re)initialize it */ |
192 | if (! (ed = ed_get (ohci, ep, urb->dev, pipe, urb->interval))) | 136 | if (! (ed = ed_get (ohci, ep, urb->dev, pipe, urb->interval))) |
193 | return -ENOMEM; | 137 | return -ENOMEM; |
@@ -232,7 +176,7 @@ static int ohci_urb_enqueue ( | |||
232 | memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (struct td *)); | 176 | memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (struct td *)); |
233 | INIT_LIST_HEAD (&urb_priv->pending); | 177 | INIT_LIST_HEAD (&urb_priv->pending); |
234 | urb_priv->length = size; | 178 | urb_priv->length = size; |
235 | urb_priv->ed = ed; | 179 | urb_priv->ed = ed; |
236 | 180 | ||
237 | /* allocate the TDs (deferring hash chain updates) */ | 181 | /* allocate the TDs (deferring hash chain updates) */ |
238 | for (i = 0; i < size; i++) { | 182 | for (i = 0; i < size; i++) { |
@@ -242,7 +186,7 @@ static int ohci_urb_enqueue ( | |||
242 | urb_free_priv (ohci, urb_priv); | 186 | urb_free_priv (ohci, urb_priv); |
243 | return -ENOMEM; | 187 | return -ENOMEM; |
244 | } | 188 | } |
245 | } | 189 | } |
246 | 190 | ||
247 | spin_lock_irqsave (&ohci->lock, flags); | 191 | spin_lock_irqsave (&ohci->lock, flags); |
248 | 192 | ||
@@ -313,13 +257,13 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) | |||
313 | { | 257 | { |
314 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 258 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
315 | unsigned long flags; | 259 | unsigned long flags; |
316 | 260 | ||
317 | #ifdef OHCI_VERBOSE_DEBUG | 261 | #ifdef OHCI_VERBOSE_DEBUG |
318 | urb_print (urb, "UNLINK", 1); | 262 | urb_print (urb, "UNLINK", 1); |
319 | #endif | 263 | #endif |
320 | 264 | ||
321 | spin_lock_irqsave (&ohci->lock, flags); | 265 | spin_lock_irqsave (&ohci->lock, flags); |
322 | if (HC_IS_RUNNING(hcd->state)) { | 266 | if (HC_IS_RUNNING(hcd->state)) { |
323 | urb_priv_t *urb_priv; | 267 | urb_priv_t *urb_priv; |
324 | 268 | ||
325 | /* Unless an IRQ completed the unlink while it was being | 269 | /* Unless an IRQ completed the unlink while it was being |
@@ -512,11 +456,11 @@ static int ohci_init (struct ohci_hcd *ohci) | |||
512 | 456 | ||
513 | /* Start an OHCI controller, set the BUS operational | 457 | /* Start an OHCI controller, set the BUS operational |
514 | * resets USB and controller | 458 | * resets USB and controller |
515 | * enable interrupts | 459 | * enable interrupts |
516 | */ | 460 | */ |
517 | static int ohci_run (struct ohci_hcd *ohci) | 461 | static int ohci_run (struct ohci_hcd *ohci) |
518 | { | 462 | { |
519 | u32 mask, temp; | 463 | u32 mask, temp; |
520 | int first = ohci->fminterval == 0; | 464 | int first = ohci->fminterval == 0; |
521 | struct usb_hcd *hcd = ohci_to_hcd(ohci); | 465 | struct usb_hcd *hcd = ohci_to_hcd(ohci); |
522 | 466 | ||
@@ -534,7 +478,7 @@ static int ohci_run (struct ohci_hcd *ohci) | |||
534 | /* also: power/overcurrent flags in roothub.a */ | 478 | /* also: power/overcurrent flags in roothub.a */ |
535 | } | 479 | } |
536 | 480 | ||
537 | /* Reset USB nearly "by the book". RemoteWakeupConnected was | 481 | /* Reset USB nearly "by the book". RemoteWakeupConnected was |
538 | * saved if boot firmware (BIOS/SMM/...) told us it's connected, | 482 | * saved if boot firmware (BIOS/SMM/...) told us it's connected, |
539 | * or if bus glue did the same (e.g. for PCI add-in cards with | 483 | * or if bus glue did the same (e.g. for PCI add-in cards with |
540 | * PCI PM support). | 484 | * PCI PM support). |
@@ -765,9 +709,9 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
765 | dl_done_list (ohci); | 709 | dl_done_list (ohci); |
766 | spin_unlock (&ohci->lock); | 710 | spin_unlock (&ohci->lock); |
767 | if (HC_IS_RUNNING(hcd->state)) | 711 | if (HC_IS_RUNNING(hcd->state)) |
768 | ohci_writel (ohci, OHCI_INTR_WDH, ®s->intrenable); | 712 | ohci_writel (ohci, OHCI_INTR_WDH, ®s->intrenable); |
769 | } | 713 | } |
770 | 714 | ||
771 | /* could track INTR_SO to reduce available PCI/... bandwidth */ | 715 | /* could track INTR_SO to reduce available PCI/... bandwidth */ |
772 | 716 | ||
773 | /* handle any pending URB/ED unlinks, leaving INTR_SF enabled | 717 | /* handle any pending URB/ED unlinks, leaving INTR_SF enabled |
@@ -778,12 +722,12 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
778 | finish_unlinks (ohci, ohci_frame_no(ohci)); | 722 | finish_unlinks (ohci, ohci_frame_no(ohci)); |
779 | if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list | 723 | if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list |
780 | && HC_IS_RUNNING(hcd->state)) | 724 | && HC_IS_RUNNING(hcd->state)) |
781 | ohci_writel (ohci, OHCI_INTR_SF, ®s->intrdisable); | 725 | ohci_writel (ohci, OHCI_INTR_SF, ®s->intrdisable); |
782 | spin_unlock (&ohci->lock); | 726 | spin_unlock (&ohci->lock); |
783 | 727 | ||
784 | if (HC_IS_RUNNING(hcd->state)) { | 728 | if (HC_IS_RUNNING(hcd->state)) { |
785 | ohci_writel (ohci, ints, ®s->intrstatus); | 729 | ohci_writel (ohci, ints, ®s->intrstatus); |
786 | ohci_writel (ohci, OHCI_INTR_MIE, ®s->intrenable); | 730 | ohci_writel (ohci, OHCI_INTR_MIE, ®s->intrenable); |
787 | // flush those writes | 731 | // flush those writes |
788 | (void) ohci_readl (ohci, &ohci->regs->control); | 732 | (void) ohci_readl (ohci, &ohci->regs->control); |
789 | } | 733 | } |
@@ -794,7 +738,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
794 | /*-------------------------------------------------------------------------*/ | 738 | /*-------------------------------------------------------------------------*/ |
795 | 739 | ||
796 | static void ohci_stop (struct usb_hcd *hcd) | 740 | static void ohci_stop (struct usb_hcd *hcd) |
797 | { | 741 | { |
798 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 742 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
799 | 743 | ||
800 | ohci_dbg (ohci, "stop %s controller (state 0x%02x)\n", | 744 | ohci_dbg (ohci, "stop %s controller (state 0x%02x)\n", |
@@ -812,8 +756,8 @@ static void ohci_stop (struct usb_hcd *hcd) | |||
812 | remove_debug_files (ohci); | 756 | remove_debug_files (ohci); |
813 | ohci_mem_cleanup (ohci); | 757 | ohci_mem_cleanup (ohci); |
814 | if (ohci->hcca) { | 758 | if (ohci->hcca) { |
815 | dma_free_coherent (hcd->self.controller, | 759 | dma_free_coherent (hcd->self.controller, |
816 | sizeof *ohci->hcca, | 760 | sizeof *ohci->hcca, |
817 | ohci->hcca, ohci->hcca_dma); | 761 | ohci->hcca, ohci->hcca_dma); |
818 | ohci->hcca = NULL; | 762 | ohci->hcca = NULL; |
819 | ohci->hcca_dma = 0; | 763 | ohci->hcca_dma = 0; |
@@ -836,7 +780,7 @@ static int ohci_restart (struct ohci_hcd *ohci) | |||
836 | * recycle any "live" eds/tds (and urbs) right away. | 780 | * recycle any "live" eds/tds (and urbs) right away. |
837 | * later, khubd disconnect processing will recycle the other state, | 781 | * later, khubd disconnect processing will recycle the other state, |
838 | * (either as disconnect/reconnect, or maybe someday as a reset). | 782 | * (either as disconnect/reconnect, or maybe someday as a reset). |
839 | */ | 783 | */ |
840 | spin_lock_irq(&ohci->lock); | 784 | spin_lock_irq(&ohci->lock); |
841 | disable (ohci); | 785 | disable (ohci); |
842 | usb_root_hub_lost_power(ohci_to_hcd(ohci)->self.root_hub); | 786 | usb_root_hub_lost_power(ohci_to_hcd(ohci)->self.root_hub); |
@@ -875,11 +819,11 @@ static int ohci_restart (struct ohci_hcd *ohci) | |||
875 | /* empty the interrupt branches */ | 819 | /* empty the interrupt branches */ |
876 | for (i = 0; i < NUM_INTS; i++) ohci->load [i] = 0; | 820 | for (i = 0; i < NUM_INTS; i++) ohci->load [i] = 0; |
877 | for (i = 0; i < NUM_INTS; i++) ohci->hcca->int_table [i] = 0; | 821 | for (i = 0; i < NUM_INTS; i++) ohci->hcca->int_table [i] = 0; |
878 | 822 | ||
879 | /* no EDs to remove */ | 823 | /* no EDs to remove */ |
880 | ohci->ed_rm_list = NULL; | 824 | ohci->ed_rm_list = NULL; |
881 | 825 | ||
882 | /* empty control and bulk lists */ | 826 | /* empty control and bulk lists */ |
883 | ohci->ed_controltail = NULL; | 827 | ohci->ed_controltail = NULL; |
884 | ohci->ed_bulktail = NULL; | 828 | ohci->ed_bulktail = NULL; |
885 | 829 | ||
@@ -911,59 +855,167 @@ MODULE_LICENSE ("GPL"); | |||
911 | 855 | ||
912 | #ifdef CONFIG_PCI | 856 | #ifdef CONFIG_PCI |
913 | #include "ohci-pci.c" | 857 | #include "ohci-pci.c" |
858 | #define PCI_DRIVER ohci_pci_driver | ||
914 | #endif | 859 | #endif |
915 | 860 | ||
916 | #ifdef CONFIG_SA1111 | 861 | #ifdef CONFIG_SA1111 |
917 | #include "ohci-sa1111.c" | 862 | #include "ohci-sa1111.c" |
863 | #define SA1111_DRIVER ohci_hcd_sa1111_driver | ||
918 | #endif | 864 | #endif |
919 | 865 | ||
920 | #ifdef CONFIG_ARCH_S3C2410 | 866 | #ifdef CONFIG_ARCH_S3C2410 |
921 | #include "ohci-s3c2410.c" | 867 | #include "ohci-s3c2410.c" |
868 | #define PLATFORM_DRIVER ohci_hcd_s3c2410_driver | ||
922 | #endif | 869 | #endif |
923 | 870 | ||
924 | #ifdef CONFIG_ARCH_OMAP | 871 | #ifdef CONFIG_ARCH_OMAP |
925 | #include "ohci-omap.c" | 872 | #include "ohci-omap.c" |
873 | #define PLATFORM_DRIVER ohci_hcd_omap_driver | ||
926 | #endif | 874 | #endif |
927 | 875 | ||
928 | #ifdef CONFIG_ARCH_LH7A404 | 876 | #ifdef CONFIG_ARCH_LH7A404 |
929 | #include "ohci-lh7a404.c" | 877 | #include "ohci-lh7a404.c" |
878 | #define PLATFORM_DRIVER ohci_hcd_lh7a404_driver | ||
930 | #endif | 879 | #endif |
931 | 880 | ||
932 | #ifdef CONFIG_PXA27x | 881 | #ifdef CONFIG_PXA27x |
933 | #include "ohci-pxa27x.c" | 882 | #include "ohci-pxa27x.c" |
883 | #define PLATFORM_DRIVER ohci_hcd_pxa27x_driver | ||
934 | #endif | 884 | #endif |
935 | 885 | ||
936 | #ifdef CONFIG_ARCH_EP93XX | 886 | #ifdef CONFIG_ARCH_EP93XX |
937 | #include "ohci-ep93xx.c" | 887 | #include "ohci-ep93xx.c" |
888 | #define PLATFORM_DRIVER ohci_hcd_ep93xx_driver | ||
938 | #endif | 889 | #endif |
939 | 890 | ||
940 | #ifdef CONFIG_SOC_AU1X00 | 891 | #ifdef CONFIG_SOC_AU1X00 |
941 | #include "ohci-au1xxx.c" | 892 | #include "ohci-au1xxx.c" |
893 | #define PLATFORM_DRIVER ohci_hcd_au1xxx_driver | ||
894 | #endif | ||
895 | |||
896 | #ifdef CONFIG_PNX8550 | ||
897 | #include "ohci-pnx8550.c" | ||
898 | #define PLATFORM_DRIVER ohci_hcd_pnx8550_driver | ||
942 | #endif | 899 | #endif |
943 | 900 | ||
944 | #ifdef CONFIG_USB_OHCI_HCD_PPC_SOC | 901 | #ifdef CONFIG_USB_OHCI_HCD_PPC_SOC |
945 | #include "ohci-ppc-soc.c" | 902 | #include "ohci-ppc-soc.c" |
903 | #define PLATFORM_DRIVER ohci_hcd_ppc_soc_driver | ||
946 | #endif | 904 | #endif |
947 | 905 | ||
948 | #ifdef CONFIG_ARCH_AT91 | 906 | #ifdef CONFIG_ARCH_AT91 |
949 | #include "ohci-at91.c" | 907 | #include "ohci-at91.c" |
908 | #define PLATFORM_DRIVER ohci_hcd_at91_driver | ||
950 | #endif | 909 | #endif |
951 | 910 | ||
952 | #ifdef CONFIG_ARCH_PNX4008 | 911 | #ifdef CONFIG_ARCH_PNX4008 |
953 | #include "ohci-pnx4008.c" | 912 | #include "ohci-pnx4008.c" |
913 | #define PLATFORM_DRIVER usb_hcd_pnx4008_driver | ||
954 | #endif | 914 | #endif |
955 | 915 | ||
956 | #if !(defined(CONFIG_PCI) \ | 916 | |
957 | || defined(CONFIG_SA1111) \ | 917 | #ifdef CONFIG_USB_OHCI_HCD_PPC_OF |
958 | || defined(CONFIG_ARCH_S3C2410) \ | 918 | #include "ohci-ppc-of.c" |
959 | || defined(CONFIG_ARCH_OMAP) \ | 919 | #define OF_PLATFORM_DRIVER ohci_hcd_ppc_of_driver |
960 | || defined (CONFIG_ARCH_LH7A404) \ | 920 | #endif |
961 | || defined (CONFIG_PXA27x) \ | 921 | |
962 | || defined (CONFIG_ARCH_EP93XX) \ | 922 | #ifdef CONFIG_PPC_PS3 |
963 | || defined (CONFIG_SOC_AU1X00) \ | 923 | #include "ohci-ps3.c" |
964 | || defined (CONFIG_USB_OHCI_HCD_PPC_SOC) \ | 924 | #define PS3_SYSTEM_BUS_DRIVER ps3_ohci_sb_driver |
965 | || defined (CONFIG_ARCH_AT91) \ | 925 | #endif |
966 | || defined (CONFIG_ARCH_PNX4008) \ | 926 | |
967 | ) | 927 | #if !defined(PCI_DRIVER) && \ |
928 | !defined(PLATFORM_DRIVER) && \ | ||
929 | !defined(OF_PLATFORM_DRIVER) && \ | ||
930 | !defined(SA1111_DRIVER) && \ | ||
931 | !defined(PS3_SYSTEM_BUS_DRIVER) | ||
968 | #error "missing bus glue for ohci-hcd" | 932 | #error "missing bus glue for ohci-hcd" |
969 | #endif | 933 | #endif |
934 | |||
935 | static int __init ohci_hcd_mod_init(void) | ||
936 | { | ||
937 | int retval = 0; | ||
938 | |||
939 | if (usb_disabled()) | ||
940 | return -ENODEV; | ||
941 | |||
942 | printk (KERN_DEBUG "%s: " DRIVER_INFO "\n", hcd_name); | ||
943 | pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name, | ||
944 | sizeof (struct ed), sizeof (struct td)); | ||
945 | |||
946 | #ifdef PS3_SYSTEM_BUS_DRIVER | ||
947 | retval = ps3_system_bus_driver_register(&PS3_SYSTEM_BUS_DRIVER); | ||
948 | if (retval < 0) | ||
949 | goto error_ps3; | ||
950 | #endif | ||
951 | |||
952 | #ifdef PLATFORM_DRIVER | ||
953 | retval = platform_driver_register(&PLATFORM_DRIVER); | ||
954 | if (retval < 0) | ||
955 | goto error_platform; | ||
956 | #endif | ||
957 | |||
958 | #ifdef OF_PLATFORM_DRIVER | ||
959 | retval = of_register_platform_driver(&OF_PLATFORM_DRIVER); | ||
960 | if (retval < 0) | ||
961 | goto error_of_platform; | ||
962 | #endif | ||
963 | |||
964 | #ifdef SA1111_DRIVER | ||
965 | retval = sa1111_driver_register(&SA1111_DRIVER); | ||
966 | if (retval < 0) | ||
967 | goto error_sa1111; | ||
968 | #endif | ||
969 | |||
970 | #ifdef PCI_DRIVER | ||
971 | retval = pci_register_driver(&PCI_DRIVER); | ||
972 | if (retval < 0) | ||
973 | goto error_pci; | ||
974 | #endif | ||
975 | |||
976 | return retval; | ||
977 | |||
978 | /* Error path */ | ||
979 | #ifdef PCI_DRIVER | ||
980 | error_pci: | ||
981 | #endif | ||
982 | #ifdef SA1111_DRIVER | ||
983 | sa1111_driver_unregister(&SA1111_DRIVER); | ||
984 | error_sa1111: | ||
985 | #endif | ||
986 | #ifdef OF_PLATFORM_DRIVER | ||
987 | of_unregister_platform_driver(&OF_PLATFORM_DRIVER); | ||
988 | error_of_platform: | ||
989 | #endif | ||
990 | #ifdef PLATFORM_DRIVER | ||
991 | platform_driver_unregister(&PLATFORM_DRIVER); | ||
992 | error_platform: | ||
993 | #endif | ||
994 | #ifdef PS3_SYSTEM_BUS_DRIVER | ||
995 | ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); | ||
996 | error_ps3: | ||
997 | #endif | ||
998 | return retval; | ||
999 | } | ||
1000 | module_init(ohci_hcd_mod_init); | ||
1001 | |||
1002 | static void __exit ohci_hcd_mod_exit(void) | ||
1003 | { | ||
1004 | #ifdef PCI_DRIVER | ||
1005 | pci_unregister_driver(&PCI_DRIVER); | ||
1006 | #endif | ||
1007 | #ifdef SA1111_DRIVER | ||
1008 | sa1111_driver_unregister(&SA1111_DRIVER); | ||
1009 | #endif | ||
1010 | #ifdef OF_PLATFORM_DRIVER | ||
1011 | of_unregister_platform_driver(&OF_PLATFORM_DRIVER); | ||
1012 | #endif | ||
1013 | #ifdef PLATFORM_DRIVER | ||
1014 | platform_driver_unregister(&PLATFORM_DRIVER); | ||
1015 | #endif | ||
1016 | #ifdef PS3_SYSTEM_BUS_DRIVER | ||
1017 | ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); | ||
1018 | #endif | ||
1019 | } | ||
1020 | module_exit(ohci_hcd_mod_exit); | ||
1021 | |||
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index 2441642cb7b4..216c9c9d4d6d 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * OHCI HCD (Host Controller Driver) for USB. | 2 | * OHCI HCD (Host Controller Driver) for USB. |
3 | * | 3 | * |
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | 4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> |
5 | * (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net> | 5 | * (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net> |
6 | * | 6 | * |
7 | * This file is licenced under GPL | 7 | * This file is licenced under GPL |
8 | */ | 8 | */ |
9 | 9 | ||
@@ -23,13 +23,13 @@ | |||
23 | (temp & RH_PS_PSSC) ? " PSSC" : "", \ | 23 | (temp & RH_PS_PSSC) ? " PSSC" : "", \ |
24 | (temp & RH_PS_PESC) ? " PESC" : "", \ | 24 | (temp & RH_PS_PESC) ? " PESC" : "", \ |
25 | (temp & RH_PS_CSC) ? " CSC" : "", \ | 25 | (temp & RH_PS_CSC) ? " CSC" : "", \ |
26 | \ | 26 | \ |
27 | (temp & RH_PS_LSDA) ? " LSDA" : "", \ | 27 | (temp & RH_PS_LSDA) ? " LSDA" : "", \ |
28 | (temp & RH_PS_PPS) ? " PPS" : "", \ | 28 | (temp & RH_PS_PPS) ? " PPS" : "", \ |
29 | (temp & RH_PS_PRS) ? " PRS" : "", \ | 29 | (temp & RH_PS_PRS) ? " PRS" : "", \ |
30 | (temp & RH_PS_POCI) ? " POCI" : "", \ | 30 | (temp & RH_PS_POCI) ? " POCI" : "", \ |
31 | (temp & RH_PS_PSS) ? " PSS" : "", \ | 31 | (temp & RH_PS_PSS) ? " PSS" : "", \ |
32 | \ | 32 | \ |
33 | (temp & RH_PS_PES) ? " PES" : "", \ | 33 | (temp & RH_PS_PES) ? " PES" : "", \ |
34 | (temp & RH_PS_CCS) ? " CCS" : "" \ | 34 | (temp & RH_PS_CCS) ? " CCS" : "" \ |
35 | ); | 35 | ); |
@@ -484,7 +484,7 @@ ohci_hub_descriptor ( | |||
484 | temp = 0; | 484 | temp = 0; |
485 | if (rh & RH_A_NPS) /* no power switching? */ | 485 | if (rh & RH_A_NPS) /* no power switching? */ |
486 | temp |= 0x0002; | 486 | temp |= 0x0002; |
487 | if (rh & RH_A_PSM) /* per-port power switching? */ | 487 | if (rh & RH_A_PSM) /* per-port power switching? */ |
488 | temp |= 0x0001; | 488 | temp |= 0x0001; |
489 | if (rh & RH_A_NOCP) /* no overcurrent reporting? */ | 489 | if (rh & RH_A_NOCP) /* no overcurrent reporting? */ |
490 | temp |= 0x0010; | 490 | temp |= 0x0010; |
@@ -555,7 +555,7 @@ static void start_hnp(struct ohci_hcd *ohci); | |||
555 | #define tick_before(t1,t2) ((s16)(((s16)(t1))-((s16)(t2))) < 0) | 555 | #define tick_before(t1,t2) ((s16)(((s16)(t1))-((s16)(t2))) < 0) |
556 | 556 | ||
557 | /* called from some task, normally khubd */ | 557 | /* called from some task, normally khubd */ |
558 | static inline void root_port_reset (struct ohci_hcd *ohci, unsigned port) | 558 | static inline int root_port_reset (struct ohci_hcd *ohci, unsigned port) |
559 | { | 559 | { |
560 | __hc32 __iomem *portstat = &ohci->regs->roothub.portstatus [port]; | 560 | __hc32 __iomem *portstat = &ohci->regs->roothub.portstatus [port]; |
561 | u32 temp; | 561 | u32 temp; |
@@ -570,10 +570,13 @@ static inline void root_port_reset (struct ohci_hcd *ohci, unsigned port) | |||
570 | /* spin until any current reset finishes */ | 570 | /* spin until any current reset finishes */ |
571 | for (;;) { | 571 | for (;;) { |
572 | temp = ohci_readl (ohci, portstat); | 572 | temp = ohci_readl (ohci, portstat); |
573 | /* handle e.g. CardBus eject */ | ||
574 | if (temp == ~(u32)0) | ||
575 | return -ESHUTDOWN; | ||
573 | if (!(temp & RH_PS_PRS)) | 576 | if (!(temp & RH_PS_PRS)) |
574 | break; | 577 | break; |
575 | udelay (500); | 578 | udelay (500); |
576 | } | 579 | } |
577 | 580 | ||
578 | if (!(temp & RH_PS_CCS)) | 581 | if (!(temp & RH_PS_CCS)) |
579 | break; | 582 | break; |
@@ -586,6 +589,8 @@ static inline void root_port_reset (struct ohci_hcd *ohci, unsigned port) | |||
586 | now = ohci_readl(ohci, &ohci->regs->fmnumber); | 589 | now = ohci_readl(ohci, &ohci->regs->fmnumber); |
587 | } while (tick_before(now, reset_done)); | 590 | } while (tick_before(now, reset_done)); |
588 | /* caller synchronizes using PRSC */ | 591 | /* caller synchronizes using PRSC */ |
592 | |||
593 | return 0; | ||
589 | } | 594 | } |
590 | 595 | ||
591 | static int ohci_hub_control ( | 596 | static int ohci_hub_control ( |
@@ -702,7 +707,7 @@ static int ohci_hub_control ( | |||
702 | &ohci->regs->roothub.portstatus [wIndex]); | 707 | &ohci->regs->roothub.portstatus [wIndex]); |
703 | break; | 708 | break; |
704 | case USB_PORT_FEAT_RESET: | 709 | case USB_PORT_FEAT_RESET: |
705 | root_port_reset (ohci, wIndex); | 710 | retval = root_port_reset (ohci, wIndex); |
706 | break; | 711 | break; |
707 | default: | 712 | default: |
708 | goto error; | 713 | goto error; |
diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c index e121d97ed91c..4a043abd85ea 100644 --- a/drivers/usb/host/ohci-lh7a404.c +++ b/drivers/usb/host/ohci-lh7a404.c | |||
@@ -38,7 +38,7 @@ static void lh7a404_start_hc(struct platform_device *dev) | |||
38 | CSC_PWRCNT |= CSC_PWRCNT_USBH_EN; /* Enable clock */ | 38 | CSC_PWRCNT |= CSC_PWRCNT_USBH_EN; /* Enable clock */ |
39 | udelay(1000); | 39 | udelay(1000); |
40 | USBH_CMDSTATUS = OHCI_HCR; | 40 | USBH_CMDSTATUS = OHCI_HCR; |
41 | 41 | ||
42 | printk(KERN_DEBUG __FILE__ | 42 | printk(KERN_DEBUG __FILE__ |
43 | ": Clock to USB host has been enabled \n"); | 43 | ": Clock to USB host has been enabled \n"); |
44 | } | 44 | } |
@@ -89,7 +89,7 @@ int usb_hcd_lh7a404_probe (const struct hc_driver *driver, | |||
89 | retval = -EBUSY; | 89 | retval = -EBUSY; |
90 | goto err1; | 90 | goto err1; |
91 | } | 91 | } |
92 | 92 | ||
93 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | 93 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); |
94 | if (!hcd->regs) { | 94 | if (!hcd->regs) { |
95 | pr_debug("ioremap failed"); | 95 | pr_debug("ioremap failed"); |
@@ -174,7 +174,7 @@ static const struct hc_driver ohci_lh7a404_hc_driver = { | |||
174 | */ | 174 | */ |
175 | .start = ohci_lh7a404_start, | 175 | .start = ohci_lh7a404_start, |
176 | .stop = ohci_stop, | 176 | .stop = ohci_stop, |
177 | .shutdown = ohci_shutdown, | 177 | .shutdown = ohci_shutdown, |
178 | 178 | ||
179 | /* | 179 | /* |
180 | * managing i/o requests and associated device resources | 180 | * managing i/o requests and associated device resources |
@@ -242,7 +242,7 @@ static int ohci_hcd_lh7a404_drv_resume(struct platform_device *dev) | |||
242 | static struct platform_driver ohci_hcd_lh7a404_driver = { | 242 | static struct platform_driver ohci_hcd_lh7a404_driver = { |
243 | .probe = ohci_hcd_lh7a404_drv_probe, | 243 | .probe = ohci_hcd_lh7a404_drv_probe, |
244 | .remove = ohci_hcd_lh7a404_drv_remove, | 244 | .remove = ohci_hcd_lh7a404_drv_remove, |
245 | .shutdown = usb_hcd_platform_shutdown, | 245 | .shutdown = usb_hcd_platform_shutdown, |
246 | /*.suspend = ohci_hcd_lh7a404_drv_suspend, */ | 246 | /*.suspend = ohci_hcd_lh7a404_drv_suspend, */ |
247 | /*.resume = ohci_hcd_lh7a404_drv_resume, */ | 247 | /*.resume = ohci_hcd_lh7a404_drv_resume, */ |
248 | .driver = { | 248 | .driver = { |
@@ -251,19 +251,3 @@ static struct platform_driver ohci_hcd_lh7a404_driver = { | |||
251 | }, | 251 | }, |
252 | }; | 252 | }; |
253 | 253 | ||
254 | static int __init ohci_hcd_lh7a404_init (void) | ||
255 | { | ||
256 | pr_debug (DRIVER_INFO " (LH7A404)"); | ||
257 | pr_debug ("block sizes: ed %d td %d\n", | ||
258 | sizeof (struct ed), sizeof (struct td)); | ||
259 | |||
260 | return platform_driver_register(&ohci_hcd_lh7a404_driver); | ||
261 | } | ||
262 | |||
263 | static void __exit ohci_hcd_lh7a404_cleanup (void) | ||
264 | { | ||
265 | platform_driver_unregister(&ohci_hcd_lh7a404_driver); | ||
266 | } | ||
267 | |||
268 | module_init (ohci_hcd_lh7a404_init); | ||
269 | module_exit (ohci_hcd_lh7a404_cleanup); | ||
diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c index d976614eebd3..2f20d3dc895b 100644 --- a/drivers/usb/host/ohci-mem.c +++ b/drivers/usb/host/ohci-mem.c | |||
@@ -1,24 +1,24 @@ | |||
1 | /* | 1 | /* |
2 | * OHCI HCD (Host Controller Driver) for USB. | 2 | * OHCI HCD (Host Controller Driver) for USB. |
3 | * | 3 | * |
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | 4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> |
5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> | 5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> |
6 | * | 6 | * |
7 | * This file is licenced under the GPL. | 7 | * This file is licenced under the GPL. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | /*-------------------------------------------------------------------------*/ | 10 | /*-------------------------------------------------------------------------*/ |
11 | 11 | ||
12 | /* | 12 | /* |
13 | * There's basically three types of memory: | 13 | * OHCI deals with three types of memory: |
14 | * - data used only by the HCD ... kmalloc is fine | 14 | * - data used only by the HCD ... kmalloc is fine |
15 | * - async and periodic schedules, shared by HC and HCD ... these | 15 | * - async and periodic schedules, shared by HC and HCD ... these |
16 | * need to use dma_pool or dma_alloc_coherent | 16 | * need to use dma_pool or dma_alloc_coherent |
17 | * - driver buffers, read/written by HC ... the hcd glue or the | 17 | * - driver buffers, read/written by HC ... the hcd glue or the |
18 | * device driver provides us with dma addresses | 18 | * device driver provides us with dma addresses |
19 | * | 19 | * |
20 | * There's also PCI "register" data, which is memory mapped. | 20 | * There's also "register" data, which is memory mapped. |
21 | * No memory seen by this driver is pagable. | 21 | * No memory seen by this driver (or any HCD) may be paged out. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | /*-------------------------------------------------------------------------*/ | 24 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 9c02177de50a..5cfa3d1c4413 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c | |||
@@ -447,7 +447,7 @@ static const struct hc_driver ohci_omap_hc_driver = { | |||
447 | .reset = ohci_omap_init, | 447 | .reset = ohci_omap_init, |
448 | .start = ohci_omap_start, | 448 | .start = ohci_omap_start, |
449 | .stop = ohci_omap_stop, | 449 | .stop = ohci_omap_stop, |
450 | .shutdown = ohci_shutdown, | 450 | .shutdown = ohci_shutdown, |
451 | 451 | ||
452 | /* | 452 | /* |
453 | * managing i/o requests and associated device resources | 453 | * managing i/o requests and associated device resources |
@@ -533,7 +533,7 @@ static int ohci_omap_resume(struct platform_device *dev) | |||
533 | static struct platform_driver ohci_hcd_omap_driver = { | 533 | static struct platform_driver ohci_hcd_omap_driver = { |
534 | .probe = ohci_hcd_omap_drv_probe, | 534 | .probe = ohci_hcd_omap_drv_probe, |
535 | .remove = ohci_hcd_omap_drv_remove, | 535 | .remove = ohci_hcd_omap_drv_remove, |
536 | .shutdown = usb_hcd_platform_shutdown, | 536 | .shutdown = usb_hcd_platform_shutdown, |
537 | #ifdef CONFIG_PM | 537 | #ifdef CONFIG_PM |
538 | .suspend = ohci_omap_suspend, | 538 | .suspend = ohci_omap_suspend, |
539 | .resume = ohci_omap_resume, | 539 | .resume = ohci_omap_resume, |
@@ -544,22 +544,3 @@ static struct platform_driver ohci_hcd_omap_driver = { | |||
544 | }, | 544 | }, |
545 | }; | 545 | }; |
546 | 546 | ||
547 | static int __init ohci_hcd_omap_init (void) | ||
548 | { | ||
549 | printk (KERN_DEBUG "%s: " DRIVER_INFO " (OMAP)\n", hcd_name); | ||
550 | if (usb_disabled()) | ||
551 | return -ENODEV; | ||
552 | |||
553 | pr_debug("%s: block sizes: ed %Zd td %Zd\n", hcd_name, | ||
554 | sizeof (struct ed), sizeof (struct td)); | ||
555 | |||
556 | return platform_driver_register(&ohci_hcd_omap_driver); | ||
557 | } | ||
558 | |||
559 | static void __exit ohci_hcd_omap_cleanup (void) | ||
560 | { | ||
561 | platform_driver_unregister(&ohci_hcd_omap_driver); | ||
562 | } | ||
563 | |||
564 | module_init (ohci_hcd_omap_init); | ||
565 | module_exit (ohci_hcd_omap_cleanup); | ||
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 874418552789..b331ac4d0d62 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -3,96 +3,171 @@ | |||
3 | * | 3 | * |
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | 4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> |
5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> | 5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> |
6 | * | 6 | * |
7 | * [ Initialisation is based on Linus' ] | 7 | * [ Initialisation is based on Linus' ] |
8 | * [ uhci code and gregs ohci fragments ] | 8 | * [ uhci code and gregs ohci fragments ] |
9 | * [ (C) Copyright 1999 Linus Torvalds ] | 9 | * [ (C) Copyright 1999 Linus Torvalds ] |
10 | * [ (C) Copyright 1999 Gregory P. Smith] | 10 | * [ (C) Copyright 1999 Gregory P. Smith] |
11 | * | 11 | * |
12 | * PCI Bus Glue | 12 | * PCI Bus Glue |
13 | * | 13 | * |
14 | * This file is licenced under the GPL. | 14 | * This file is licenced under the GPL. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #ifndef CONFIG_PCI | 17 | #ifndef CONFIG_PCI |
18 | #error "This file is PCI bus glue. CONFIG_PCI must be defined." | 18 | #error "This file is PCI bus glue. CONFIG_PCI must be defined." |
19 | #endif | 19 | #endif |
20 | 20 | ||
21 | /*-------------------------------------------------------------------------*/ | 21 | /*-------------------------------------------------------------------------*/ |
22 | 22 | ||
23 | static int | 23 | /* AMD 756, for most chips (early revs), corrupts register |
24 | ohci_pci_reset (struct usb_hcd *hcd) | 24 | * values on read ... so enable the vendor workaround. |
25 | */ | ||
26 | static int __devinit ohci_quirk_amd756(struct usb_hcd *hcd) | ||
25 | { | 27 | { |
26 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 28 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
27 | 29 | ||
28 | ohci_hcd_init (ohci); | 30 | ohci->flags = OHCI_QUIRK_AMD756; |
29 | return ohci_init (ohci); | 31 | ohci_dbg (ohci, "AMD756 erratum 4 workaround\n"); |
32 | |||
33 | /* also erratum 10 (suspend/resume issues) */ | ||
34 | device_init_wakeup(&hcd->self.root_hub->dev, 0); | ||
35 | |||
36 | return 0; | ||
30 | } | 37 | } |
31 | 38 | ||
32 | static int __devinit | 39 | /* Apple's OHCI driver has a lot of bizarre workarounds |
33 | ohci_pci_start (struct usb_hcd *hcd) | 40 | * for this chip. Evidently control and bulk lists |
41 | * can get confused. (B&W G3 models, and ...) | ||
42 | */ | ||
43 | static int __devinit ohci_quirk_opti(struct usb_hcd *hcd) | ||
34 | { | 44 | { |
35 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 45 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
36 | int ret; | ||
37 | 46 | ||
38 | /* REVISIT this whole block should move to reset(), which handles | 47 | ohci_dbg (ohci, "WARNING: OPTi workarounds unavailable\n"); |
39 | * all the other one-time init. | 48 | |
49 | return 0; | ||
50 | } | ||
51 | |||
52 | /* Check for NSC87560. We have to look at the bridge (fn1) to | ||
53 | * identify the USB (fn2). This quirk might apply to more or | ||
54 | * even all NSC stuff. | ||
55 | */ | ||
56 | static int __devinit ohci_quirk_ns(struct usb_hcd *hcd) | ||
57 | { | ||
58 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | ||
59 | struct pci_dev *b; | ||
60 | |||
61 | b = pci_get_slot (pdev->bus, PCI_DEVFN (PCI_SLOT (pdev->devfn), 1)); | ||
62 | if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO | ||
63 | && b->vendor == PCI_VENDOR_ID_NS) { | ||
64 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
65 | |||
66 | ohci->flags |= OHCI_QUIRK_SUPERIO; | ||
67 | ohci_dbg (ohci, "Using NSC SuperIO setup\n"); | ||
68 | } | ||
69 | pci_dev_put(b); | ||
70 | |||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | /* Check for Compaq's ZFMicro chipset, which needs short | ||
75 | * delays before control or bulk queues get re-activated | ||
76 | * in finish_unlinks() | ||
77 | */ | ||
78 | static int __devinit ohci_quirk_zfmicro(struct usb_hcd *hcd) | ||
79 | { | ||
80 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
81 | |||
82 | ohci->flags |= OHCI_QUIRK_ZFMICRO; | ||
83 | ohci_dbg (ohci, "enabled Compaq ZFMicro chipset quirk\n"); | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | /* Check for Toshiba SCC OHCI which has big endian registers | ||
89 | * and little endian in memory data structures | ||
90 | */ | ||
91 | static int __devinit ohci_quirk_toshiba_scc(struct usb_hcd *hcd) | ||
92 | { | ||
93 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
94 | |||
95 | /* That chip is only present in the southbridge of some | ||
96 | * cell based platforms which are supposed to select | ||
97 | * CONFIG_USB_OHCI_BIG_ENDIAN_MMIO. We verify here if | ||
98 | * that was the case though. | ||
40 | */ | 99 | */ |
100 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO | ||
101 | ohci->flags |= OHCI_QUIRK_BE_MMIO; | ||
102 | ohci_dbg (ohci, "enabled big endian Toshiba quirk\n"); | ||
103 | return 0; | ||
104 | #else | ||
105 | ohci_err (ohci, "unsupported big endian Toshiba quirk\n"); | ||
106 | return -ENXIO; | ||
107 | #endif | ||
108 | } | ||
109 | |||
110 | /* List of quirks for OHCI */ | ||
111 | static const struct pci_device_id ohci_pci_quirks[] = { | ||
112 | { | ||
113 | PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x740c), | ||
114 | .driver_data = (unsigned long)ohci_quirk_amd756, | ||
115 | }, | ||
116 | { | ||
117 | PCI_DEVICE(PCI_VENDOR_ID_OPTI, 0xc861), | ||
118 | .driver_data = (unsigned long)ohci_quirk_opti, | ||
119 | }, | ||
120 | { | ||
121 | PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_ANY_ID), | ||
122 | .driver_data = (unsigned long)ohci_quirk_ns, | ||
123 | }, | ||
124 | { | ||
125 | PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xa0f8), | ||
126 | .driver_data = (unsigned long)ohci_quirk_zfmicro, | ||
127 | }, | ||
128 | { | ||
129 | PCI_DEVICE(PCI_VENDOR_ID_TOSHIBA_2, 0x01b6), | ||
130 | .driver_data = (unsigned long)ohci_quirk_toshiba_scc, | ||
131 | }, | ||
132 | /* FIXME for some of the early AMD 760 southbridges, OHCI | ||
133 | * won't work at all. blacklist them. | ||
134 | */ | ||
135 | |||
136 | {}, | ||
137 | }; | ||
138 | |||
139 | static int ohci_pci_reset (struct usb_hcd *hcd) | ||
140 | { | ||
141 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
142 | int ret = 0; | ||
143 | |||
41 | if (hcd->self.controller) { | 144 | if (hcd->self.controller) { |
42 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); | 145 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); |
146 | const struct pci_device_id *quirk_id; | ||
43 | 147 | ||
44 | /* AMD 756, for most chips (early revs), corrupts register | 148 | quirk_id = pci_match_id(ohci_pci_quirks, pdev); |
45 | * values on read ... so enable the vendor workaround. | 149 | if (quirk_id != NULL) { |
46 | */ | 150 | int (*quirk)(struct usb_hcd *ohci); |
47 | if (pdev->vendor == PCI_VENDOR_ID_AMD | 151 | quirk = (void *)quirk_id->driver_data; |
48 | && pdev->device == 0x740c) { | 152 | ret = quirk(hcd); |
49 | ohci->flags = OHCI_QUIRK_AMD756; | ||
50 | ohci_dbg (ohci, "AMD756 erratum 4 workaround\n"); | ||
51 | /* also erratum 10 (suspend/resume issues) */ | ||
52 | device_init_wakeup(&hcd->self.root_hub->dev, 0); | ||
53 | } | 153 | } |
154 | } | ||
155 | if (ret == 0) { | ||
156 | ohci_hcd_init (ohci); | ||
157 | return ohci_init (ohci); | ||
158 | } | ||
159 | return ret; | ||
160 | } | ||
54 | 161 | ||
55 | /* FIXME for some of the early AMD 760 southbridges, OHCI | ||
56 | * won't work at all. blacklist them. | ||
57 | */ | ||
58 | |||
59 | /* Apple's OHCI driver has a lot of bizarre workarounds | ||
60 | * for this chip. Evidently control and bulk lists | ||
61 | * can get confused. (B&W G3 models, and ...) | ||
62 | */ | ||
63 | else if (pdev->vendor == PCI_VENDOR_ID_OPTI | ||
64 | && pdev->device == 0xc861) { | ||
65 | ohci_dbg (ohci, | ||
66 | "WARNING: OPTi workarounds unavailable\n"); | ||
67 | } | ||
68 | 162 | ||
69 | /* Check for NSC87560. We have to look at the bridge (fn1) to | 163 | static int __devinit ohci_pci_start (struct usb_hcd *hcd) |
70 | * identify the USB (fn2). This quirk might apply to more or | 164 | { |
71 | * even all NSC stuff. | 165 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
72 | */ | 166 | int ret; |
73 | else if (pdev->vendor == PCI_VENDOR_ID_NS) { | ||
74 | struct pci_dev *b; | ||
75 | |||
76 | b = pci_get_slot (pdev->bus, | ||
77 | PCI_DEVFN (PCI_SLOT (pdev->devfn), 1)); | ||
78 | if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO | ||
79 | && b->vendor == PCI_VENDOR_ID_NS) { | ||
80 | ohci->flags |= OHCI_QUIRK_SUPERIO; | ||
81 | ohci_dbg (ohci, "Using NSC SuperIO setup\n"); | ||
82 | } | ||
83 | pci_dev_put(b); | ||
84 | } | ||
85 | 167 | ||
86 | /* Check for Compaq's ZFMicro chipset, which needs short | 168 | #ifdef CONFIG_PM /* avoid warnings about unused pdev */ |
87 | * delays before control or bulk queues get re-activated | 169 | if (hcd->self.controller) { |
88 | * in finish_unlinks() | 170 | struct pci_dev *pdev = to_pci_dev(hcd->self.controller); |
89 | */ | ||
90 | else if (pdev->vendor == PCI_VENDOR_ID_COMPAQ | ||
91 | && pdev->device == 0xa0f8) { | ||
92 | ohci->flags |= OHCI_QUIRK_ZFMICRO; | ||
93 | ohci_dbg (ohci, | ||
94 | "enabled Compaq ZFMicro chipset quirk\n"); | ||
95 | } | ||
96 | 171 | ||
97 | /* RWC may not be set for add-in PCI cards, since boot | 172 | /* RWC may not be set for add-in PCI cards, since boot |
98 | * firmware probably ignored them. This transfers PCI | 173 | * firmware probably ignored them. This transfers PCI |
@@ -101,16 +176,14 @@ ohci_pci_start (struct usb_hcd *hcd) | |||
101 | if (device_may_wakeup(&pdev->dev)) | 176 | if (device_may_wakeup(&pdev->dev)) |
102 | ohci->hc_control |= OHCI_CTRL_RWC; | 177 | ohci->hc_control |= OHCI_CTRL_RWC; |
103 | } | 178 | } |
179 | #endif /* CONFIG_PM */ | ||
104 | 180 | ||
105 | /* NOTE: there may have already been a first reset, to | 181 | ret = ohci_run (ohci); |
106 | * keep bios/smm irqs from making trouble | 182 | if (ret < 0) { |
107 | */ | ||
108 | if ((ret = ohci_run (ohci)) < 0) { | ||
109 | ohci_err (ohci, "can't start\n"); | 183 | ohci_err (ohci, "can't start\n"); |
110 | ohci_stop (hcd); | 184 | ohci_stop (hcd); |
111 | return ret; | ||
112 | } | 185 | } |
113 | return 0; | 186 | return ret; |
114 | } | 187 | } |
115 | 188 | ||
116 | #ifdef CONFIG_PM | 189 | #ifdef CONFIG_PM |
@@ -238,23 +311,3 @@ static struct pci_driver ohci_pci_driver = { | |||
238 | .shutdown = usb_hcd_pci_shutdown, | 311 | .shutdown = usb_hcd_pci_shutdown, |
239 | }; | 312 | }; |
240 | 313 | ||
241 | |||
242 | static int __init ohci_hcd_pci_init (void) | ||
243 | { | ||
244 | printk (KERN_DEBUG "%s: " DRIVER_INFO " (PCI)\n", hcd_name); | ||
245 | if (usb_disabled()) | ||
246 | return -ENODEV; | ||
247 | |||
248 | pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name, | ||
249 | sizeof (struct ed), sizeof (struct td)); | ||
250 | return pci_register_driver (&ohci_pci_driver); | ||
251 | } | ||
252 | module_init (ohci_hcd_pci_init); | ||
253 | |||
254 | /*-------------------------------------------------------------------------*/ | ||
255 | |||
256 | static void __exit ohci_hcd_pci_cleanup (void) | ||
257 | { | ||
258 | pci_unregister_driver (&ohci_pci_driver); | ||
259 | } | ||
260 | module_exit (ohci_hcd_pci_cleanup); | ||
diff --git a/drivers/usb/host/ohci-pnx4008.c b/drivers/usb/host/ohci-pnx4008.c index 7f26f9bdbaf1..893b172384da 100644 --- a/drivers/usb/host/ohci-pnx4008.c +++ b/drivers/usb/host/ohci-pnx4008.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * driver for Philips PNX4008 USB Host | 4 | * driver for Philips PNX4008 USB Host |
5 | * | 5 | * |
6 | * Authors: Dmitry Chigirev <source@mvista.com> | 6 | * Authors: Dmitry Chigirev <source@mvista.com> |
7 | * Vitaly Wool <vitalywool@gmail.com> | 7 | * Vitaly Wool <vitalywool@gmail.com> |
8 | * | 8 | * |
9 | * register initialization is based on code examples provided by Philips | 9 | * register initialization is based on code examples provided by Philips |
10 | * Copyright (c) 2005 Koninklijke Philips Electronics N.V. | 10 | * Copyright (c) 2005 Koninklijke Philips Electronics N.V. |
@@ -29,7 +29,7 @@ | |||
29 | #include <asm/arch/irqs.h> | 29 | #include <asm/arch/irqs.h> |
30 | #include <asm/arch/gpio.h> | 30 | #include <asm/arch/gpio.h> |
31 | 31 | ||
32 | #define USB_CTRL IO_ADDRESS(PNX4008_PWRMAN_BASE + 0x64) | 32 | #define USB_CTRL IO_ADDRESS(PNX4008_PWRMAN_BASE + 0x64) |
33 | 33 | ||
34 | /* USB_CTRL bit defines */ | 34 | /* USB_CTRL bit defines */ |
35 | #define USB_SLAVE_HCLK_EN (1 << 24) | 35 | #define USB_SLAVE_HCLK_EN (1 << 24) |
@@ -465,15 +465,3 @@ static struct platform_driver usb_hcd_pnx4008_driver = { | |||
465 | .remove = usb_hcd_pnx4008_remove, | 465 | .remove = usb_hcd_pnx4008_remove, |
466 | }; | 466 | }; |
467 | 467 | ||
468 | static int __init usb_hcd_pnx4008_init(void) | ||
469 | { | ||
470 | return platform_driver_register(&usb_hcd_pnx4008_driver); | ||
471 | } | ||
472 | |||
473 | static void __exit usb_hcd_pnx4008_cleanup(void) | ||
474 | { | ||
475 | return platform_driver_unregister(&usb_hcd_pnx4008_driver); | ||
476 | } | ||
477 | |||
478 | module_init(usb_hcd_pnx4008_init); | ||
479 | module_exit(usb_hcd_pnx4008_cleanup); | ||
diff --git a/drivers/usb/host/ohci-pnx8550.c b/drivers/usb/host/ohci-pnx8550.c new file mode 100644 index 000000000000..de45eb0051a7 --- /dev/null +++ b/drivers/usb/host/ohci-pnx8550.c | |||
@@ -0,0 +1,242 @@ | |||
1 | /* | ||
2 | * OHCI HCD (Host Controller Driver) for USB. | ||
3 | * | ||
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | ||
5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> | ||
6 | * (C) Copyright 2002 Hewlett-Packard Company | ||
7 | * (C) Copyright 2005 Embedded Alley Solutions, Inc. | ||
8 | * | ||
9 | * Bus Glue for PNX8550 | ||
10 | * | ||
11 | * Written by Christopher Hoover <ch@hpl.hp.com> | ||
12 | * Based on fragments of previous driver by Russell King et al. | ||
13 | * | ||
14 | * Modified for LH7A404 from ohci-sa1111.c | ||
15 | * by Durgesh Pattamatta <pattamattad@sharpsec.com> | ||
16 | * | ||
17 | * Modified for PNX8550 from ohci-sa1111.c and sa-omap.c | ||
18 | * by Vitaly Wool <vitalywool@gmail.com> | ||
19 | * | ||
20 | * This file is licenced under the GPL. | ||
21 | */ | ||
22 | |||
23 | #include <linux/device.h> | ||
24 | #include <linux/platform_device.h> | ||
25 | #include <asm/mach-pnx8550/usb.h> | ||
26 | #include <asm/mach-pnx8550/int.h> | ||
27 | #include <asm/mach-pnx8550/pci.h> | ||
28 | |||
29 | #ifndef CONFIG_PNX8550 | ||
30 | #error "This file is PNX8550 bus glue. CONFIG_PNX8550 must be defined." | ||
31 | #endif | ||
32 | |||
33 | extern int usb_disabled(void); | ||
34 | |||
35 | /*-------------------------------------------------------------------------*/ | ||
36 | |||
37 | static void pnx8550_start_hc(struct platform_device *dev) | ||
38 | { | ||
39 | /* | ||
40 | * Set register CLK48CTL to enable and 48MHz | ||
41 | */ | ||
42 | outl(0x00000003, PCI_BASE | 0x0004770c); | ||
43 | |||
44 | /* | ||
45 | * Set register CLK12CTL to enable and 48MHz | ||
46 | */ | ||
47 | outl(0x00000003, PCI_BASE | 0x00047710); | ||
48 | |||
49 | udelay(100); | ||
50 | } | ||
51 | |||
52 | static void pnx8550_stop_hc(struct platform_device *dev) | ||
53 | { | ||
54 | udelay(10); | ||
55 | } | ||
56 | |||
57 | |||
58 | /*-------------------------------------------------------------------------*/ | ||
59 | |||
60 | /* configure so an HC device and id are always provided */ | ||
61 | /* always called with process context; sleeping is OK */ | ||
62 | |||
63 | |||
64 | /** | ||
65 | * usb_hcd_pnx8550_probe - initialize pnx8550-based HCDs | ||
66 | * Context: !in_interrupt() | ||
67 | * | ||
68 | * Allocates basic resources for this USB host controller, and | ||
69 | * then invokes the start() method for the HCD associated with it | ||
70 | * through the hotplug entry's driver_data. | ||
71 | * | ||
72 | */ | ||
73 | int usb_hcd_pnx8550_probe (const struct hc_driver *driver, | ||
74 | struct platform_device *dev) | ||
75 | { | ||
76 | int retval; | ||
77 | struct usb_hcd *hcd; | ||
78 | |||
79 | if (dev->resource[0].flags != IORESOURCE_MEM || | ||
80 | dev->resource[1].flags != IORESOURCE_IRQ) { | ||
81 | dev_err (&dev->dev,"invalid resource type\n"); | ||
82 | return -ENOMEM; | ||
83 | } | ||
84 | |||
85 | hcd = usb_create_hcd (driver, &dev->dev, "pnx8550"); | ||
86 | if (!hcd) | ||
87 | return -ENOMEM; | ||
88 | hcd->rsrc_start = dev->resource[0].start; | ||
89 | hcd->rsrc_len = dev->resource[0].end - dev->resource[0].start + 1; | ||
90 | |||
91 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | ||
92 | dev_err(&dev->dev, "request_mem_region [0x%08llx, 0x%08llx] " | ||
93 | "failed\n", hcd->rsrc_start, hcd->rsrc_len); | ||
94 | retval = -EBUSY; | ||
95 | goto err1; | ||
96 | } | ||
97 | |||
98 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
99 | if (!hcd->regs) { | ||
100 | dev_err(&dev->dev, "ioremap [[0x%08llx, 0x%08llx] failed\n", | ||
101 | hcd->rsrc_start, hcd->rsrc_len); | ||
102 | retval = -ENOMEM; | ||
103 | goto err2; | ||
104 | } | ||
105 | |||
106 | pnx8550_start_hc(dev); | ||
107 | |||
108 | ohci_hcd_init(hcd_to_ohci(hcd)); | ||
109 | |||
110 | retval = usb_add_hcd(hcd, dev->resource[1].start, SA_INTERRUPT); | ||
111 | if (retval == 0) | ||
112 | return retval; | ||
113 | |||
114 | pnx8550_stop_hc(dev); | ||
115 | iounmap(hcd->regs); | ||
116 | err2: | ||
117 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
118 | err1: | ||
119 | usb_put_hcd(hcd); | ||
120 | return retval; | ||
121 | } | ||
122 | |||
123 | |||
124 | /* may be called without controller electrically present */ | ||
125 | /* may be called with controller, bus, and devices active */ | ||
126 | |||
127 | /** | ||
128 | * usb_hcd_pnx8550_remove - shutdown processing for pnx8550-based HCDs | ||
129 | * @dev: USB Host Controller being removed | ||
130 | * Context: !in_interrupt() | ||
131 | * | ||
132 | * Reverses the effect of usb_hcd_pnx8550_probe(), first invoking | ||
133 | * the HCD's stop() method. It is always called from a thread | ||
134 | * context, normally "rmmod", "apmd", or something similar. | ||
135 | * | ||
136 | */ | ||
137 | void usb_hcd_pnx8550_remove (struct usb_hcd *hcd, struct platform_device *dev) | ||
138 | { | ||
139 | usb_remove_hcd(hcd); | ||
140 | pnx8550_stop_hc(dev); | ||
141 | iounmap(hcd->regs); | ||
142 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
143 | usb_put_hcd(hcd); | ||
144 | } | ||
145 | |||
146 | /*-------------------------------------------------------------------------*/ | ||
147 | |||
148 | static int __devinit | ||
149 | ohci_pnx8550_start (struct usb_hcd *hcd) | ||
150 | { | ||
151 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
152 | int ret; | ||
153 | |||
154 | ohci_dbg (ohci, "ohci_pnx8550_start, ohci:%p", ohci); | ||
155 | |||
156 | if ((ret = ohci_init(ohci)) < 0) | ||
157 | return ret; | ||
158 | |||
159 | if ((ret = ohci_run (ohci)) < 0) { | ||
160 | err ("can't start %s", hcd->self.bus_name); | ||
161 | ohci_stop (hcd); | ||
162 | return ret; | ||
163 | } | ||
164 | |||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | /*-------------------------------------------------------------------------*/ | ||
169 | |||
170 | static const struct hc_driver ohci_pnx8550_hc_driver = { | ||
171 | .description = hcd_name, | ||
172 | .product_desc = "PNX8550 OHCI", | ||
173 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
174 | |||
175 | /* | ||
176 | * generic hardware linkage | ||
177 | */ | ||
178 | .irq = ohci_irq, | ||
179 | .flags = HCD_USB11 | HCD_MEMORY, | ||
180 | |||
181 | /* | ||
182 | * basic lifecycle operations | ||
183 | */ | ||
184 | .start = ohci_pnx8550_start, | ||
185 | .stop = ohci_stop, | ||
186 | |||
187 | /* | ||
188 | * managing i/o requests and associated device resources | ||
189 | */ | ||
190 | .urb_enqueue = ohci_urb_enqueue, | ||
191 | .urb_dequeue = ohci_urb_dequeue, | ||
192 | .endpoint_disable = ohci_endpoint_disable, | ||
193 | |||
194 | /* | ||
195 | * scheduling support | ||
196 | */ | ||
197 | .get_frame_number = ohci_get_frame, | ||
198 | |||
199 | /* | ||
200 | * root hub support | ||
201 | */ | ||
202 | .hub_status_data = ohci_hub_status_data, | ||
203 | .hub_control = ohci_hub_control, | ||
204 | .hub_irq_enable = ohci_rhsc_enable, | ||
205 | #ifdef CONFIG_PM | ||
206 | .bus_suspend = ohci_bus_suspend, | ||
207 | .bus_resume = ohci_bus_resume, | ||
208 | #endif | ||
209 | .start_port_reset = ohci_start_port_reset, | ||
210 | }; | ||
211 | |||
212 | /*-------------------------------------------------------------------------*/ | ||
213 | |||
214 | static int ohci_hcd_pnx8550_drv_probe(struct platform_device *pdev) | ||
215 | { | ||
216 | int ret; | ||
217 | |||
218 | if (usb_disabled()) | ||
219 | return -ENODEV; | ||
220 | |||
221 | ret = usb_hcd_pnx8550_probe(&ohci_pnx8550_hc_driver, pdev); | ||
222 | return ret; | ||
223 | } | ||
224 | |||
225 | static int ohci_hcd_pnx8550_drv_remove(struct platform_device *pdev) | ||
226 | { | ||
227 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | ||
228 | |||
229 | usb_hcd_pnx8550_remove(hcd, pdev); | ||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | MODULE_ALIAS("pnx8550-ohci"); | ||
234 | |||
235 | static struct platform_driver ohci_hcd_pnx8550_driver = { | ||
236 | .driver = { | ||
237 | .name = "pnx8550-ohci", | ||
238 | }, | ||
239 | .probe = ohci_hcd_pnx8550_drv_probe, | ||
240 | .remove = ohci_hcd_pnx8550_drv_remove, | ||
241 | }; | ||
242 | |||
diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c new file mode 100644 index 000000000000..08e237c7bc43 --- /dev/null +++ b/drivers/usb/host/ohci-ppc-of.c | |||
@@ -0,0 +1,232 @@ | |||
1 | /* | ||
2 | * OHCI HCD (Host Controller Driver) for USB. | ||
3 | * | ||
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | ||
5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> | ||
6 | * (C) Copyright 2002 Hewlett-Packard Company | ||
7 | * (C) Copyright 2006 Sylvain Munaut <tnt@246tNt.com> | ||
8 | * | ||
9 | * Bus glue for OHCI HC on the of_platform bus | ||
10 | * | ||
11 | * Modified for of_platform bus from ohci-sa1111.c | ||
12 | * | ||
13 | * This file is licenced under the GPL. | ||
14 | */ | ||
15 | |||
16 | #include <linux/signal.h> | ||
17 | |||
18 | #include <asm/of_platform.h> | ||
19 | #include <asm/prom.h> | ||
20 | |||
21 | |||
22 | static int __devinit | ||
23 | ohci_ppc_of_start(struct usb_hcd *hcd) | ||
24 | { | ||
25 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
26 | int ret; | ||
27 | |||
28 | if ((ret = ohci_init(ohci)) < 0) | ||
29 | return ret; | ||
30 | |||
31 | if ((ret = ohci_run(ohci)) < 0) { | ||
32 | err("can't start %s", ohci_to_hcd(ohci)->self.bus_name); | ||
33 | ohci_stop(hcd); | ||
34 | return ret; | ||
35 | } | ||
36 | |||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | static const struct hc_driver ohci_ppc_of_hc_driver = { | ||
41 | .description = hcd_name, | ||
42 | .product_desc = "OF OHCI", | ||
43 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
44 | |||
45 | /* | ||
46 | * generic hardware linkage | ||
47 | */ | ||
48 | .irq = ohci_irq, | ||
49 | .flags = HCD_USB11 | HCD_MEMORY, | ||
50 | |||
51 | /* | ||
52 | * basic lifecycle operations | ||
53 | */ | ||
54 | .start = ohci_ppc_of_start, | ||
55 | .stop = ohci_stop, | ||
56 | .shutdown = ohci_shutdown, | ||
57 | |||
58 | /* | ||
59 | * managing i/o requests and associated device resources | ||
60 | */ | ||
61 | .urb_enqueue = ohci_urb_enqueue, | ||
62 | .urb_dequeue = ohci_urb_dequeue, | ||
63 | .endpoint_disable = ohci_endpoint_disable, | ||
64 | |||
65 | /* | ||
66 | * scheduling support | ||
67 | */ | ||
68 | .get_frame_number = ohci_get_frame, | ||
69 | |||
70 | /* | ||
71 | * root hub support | ||
72 | */ | ||
73 | .hub_status_data = ohci_hub_status_data, | ||
74 | .hub_control = ohci_hub_control, | ||
75 | .hub_irq_enable = ohci_rhsc_enable, | ||
76 | #ifdef CONFIG_PM | ||
77 | .bus_suspend = ohci_bus_suspend, | ||
78 | .bus_resume = ohci_bus_resume, | ||
79 | #endif | ||
80 | .start_port_reset = ohci_start_port_reset, | ||
81 | }; | ||
82 | |||
83 | |||
84 | static int __devinit | ||
85 | ohci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match) | ||
86 | { | ||
87 | struct device_node *dn = op->node; | ||
88 | struct usb_hcd *hcd; | ||
89 | struct ohci_hcd *ohci; | ||
90 | struct resource res; | ||
91 | int irq; | ||
92 | |||
93 | int rv; | ||
94 | int is_bigendian; | ||
95 | |||
96 | if (usb_disabled()) | ||
97 | return -ENODEV; | ||
98 | |||
99 | is_bigendian = | ||
100 | device_is_compatible(dn, "ohci-bigendian") || | ||
101 | device_is_compatible(dn, "ohci-be"); | ||
102 | |||
103 | dev_dbg(&op->dev, "initializing PPC-OF USB Controller\n"); | ||
104 | |||
105 | rv = of_address_to_resource(dn, 0, &res); | ||
106 | if (rv) | ||
107 | return rv; | ||
108 | |||
109 | hcd = usb_create_hcd(&ohci_ppc_of_hc_driver, &op->dev, "PPC-OF USB"); | ||
110 | if (!hcd) | ||
111 | return -ENOMEM; | ||
112 | |||
113 | hcd->rsrc_start = res.start; | ||
114 | hcd->rsrc_len = res.end - res.start + 1; | ||
115 | |||
116 | if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { | ||
117 | printk(KERN_ERR __FILE__ ": request_mem_region failed\n"); | ||
118 | rv = -EBUSY; | ||
119 | goto err_rmr; | ||
120 | } | ||
121 | |||
122 | irq = irq_of_parse_and_map(dn, 0); | ||
123 | if (irq == NO_IRQ) { | ||
124 | printk(KERN_ERR __FILE__ ": irq_of_parse_and_map failed\n"); | ||
125 | rv = -EBUSY; | ||
126 | goto err_irq; | ||
127 | } | ||
128 | |||
129 | hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len); | ||
130 | if (!hcd->regs) { | ||
131 | printk(KERN_ERR __FILE__ ": ioremap failed\n"); | ||
132 | rv = -ENOMEM; | ||
133 | goto err_ioremap; | ||
134 | } | ||
135 | |||
136 | ohci = hcd_to_ohci(hcd); | ||
137 | if (is_bigendian) | ||
138 | ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; | ||
139 | |||
140 | ohci_hcd_init(ohci); | ||
141 | |||
142 | rv = usb_add_hcd(hcd, irq, 0); | ||
143 | if (rv == 0) | ||
144 | return 0; | ||
145 | |||
146 | iounmap(hcd->regs); | ||
147 | err_ioremap: | ||
148 | irq_dispose_mapping(irq); | ||
149 | err_irq: | ||
150 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
151 | err_rmr: | ||
152 | usb_put_hcd(hcd); | ||
153 | |||
154 | return rv; | ||
155 | } | ||
156 | |||
157 | static int ohci_hcd_ppc_of_remove(struct of_device *op) | ||
158 | { | ||
159 | struct usb_hcd *hcd = dev_get_drvdata(&op->dev); | ||
160 | dev_set_drvdata(&op->dev, NULL); | ||
161 | |||
162 | dev_dbg(&op->dev, "stopping PPC-OF USB Controller\n"); | ||
163 | |||
164 | usb_remove_hcd(hcd); | ||
165 | |||
166 | iounmap(hcd->regs); | ||
167 | irq_dispose_mapping(hcd->irq); | ||
168 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | ||
169 | |||
170 | usb_put_hcd(hcd); | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static int ohci_hcd_ppc_of_shutdown(struct of_device *op) | ||
176 | { | ||
177 | struct usb_hcd *hcd = dev_get_drvdata(&op->dev); | ||
178 | |||
179 | if (hcd->driver->shutdown) | ||
180 | hcd->driver->shutdown(hcd); | ||
181 | |||
182 | return 0; | ||
183 | } | ||
184 | |||
185 | |||
186 | static struct of_device_id ohci_hcd_ppc_of_match[] = { | ||
187 | #ifdef CONFIG_USB_OHCI_HCD_PPC_OF_BE | ||
188 | { | ||
189 | .name = "usb", | ||
190 | .compatible = "ohci-bigendian", | ||
191 | }, | ||
192 | { | ||
193 | .name = "usb", | ||
194 | .compatible = "ohci-be", | ||
195 | }, | ||
196 | #endif | ||
197 | #ifdef CONFIG_USB_OHCI_HCD_PPC_OF_LE | ||
198 | { | ||
199 | .name = "usb", | ||
200 | .compatible = "ohci-littledian", | ||
201 | }, | ||
202 | { | ||
203 | .name = "usb", | ||
204 | .compatible = "ohci-le", | ||
205 | }, | ||
206 | #endif | ||
207 | {}, | ||
208 | }; | ||
209 | MODULE_DEVICE_TABLE(of, ohci_hcd_ppc_of_match); | ||
210 | |||
211 | #if !defined(CONFIG_USB_OHCI_HCD_PPC_OF_BE) && \ | ||
212 | !defined(CONFIG_USB_OHCI_HCD_PPC_OF_LE) | ||
213 | #error "No endianess selected for ppc-of-ohci" | ||
214 | #endif | ||
215 | |||
216 | |||
217 | static struct of_platform_driver ohci_hcd_ppc_of_driver = { | ||
218 | .name = "ppc-of-ohci", | ||
219 | .match_table = ohci_hcd_ppc_of_match, | ||
220 | .probe = ohci_hcd_ppc_of_probe, | ||
221 | .remove = ohci_hcd_ppc_of_remove, | ||
222 | .shutdown = ohci_hcd_ppc_of_shutdown, | ||
223 | #ifdef CONFIG_PM | ||
224 | /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/ | ||
225 | /*.resume = ohci_hcd_ppc_soc_drv_resume,*/ | ||
226 | #endif | ||
227 | .driver = { | ||
228 | .name = "ppc-of-ohci", | ||
229 | .owner = THIS_MODULE, | ||
230 | }, | ||
231 | }; | ||
232 | |||
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c index d9d1ae236bd5..1a2e1777ca61 100644 --- a/drivers/usb/host/ohci-ppc-soc.c +++ b/drivers/usb/host/ohci-ppc-soc.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> | 5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> |
6 | * (C) Copyright 2002 Hewlett-Packard Company | 6 | * (C) Copyright 2002 Hewlett-Packard Company |
7 | * (C) Copyright 2003-2005 MontaVista Software Inc. | 7 | * (C) Copyright 2003-2005 MontaVista Software Inc. |
8 | * | 8 | * |
9 | * Bus Glue for PPC On-Chip OHCI driver | 9 | * Bus Glue for PPC On-Chip OHCI driver |
10 | * Tested on Freescale MPC5200 and IBM STB04xxx | 10 | * Tested on Freescale MPC5200 and IBM STB04xxx |
11 | * | 11 | * |
@@ -72,7 +72,7 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver, | |||
72 | } | 72 | } |
73 | 73 | ||
74 | ohci = hcd_to_ohci(hcd); | 74 | ohci = hcd_to_ohci(hcd); |
75 | ohci->flags |= OHCI_BIG_ENDIAN; | 75 | ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; |
76 | ohci_hcd_init(ohci); | 76 | ohci_hcd_init(ohci); |
77 | 77 | ||
78 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); | 78 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); |
@@ -85,7 +85,7 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver, | |||
85 | err2: | 85 | err2: |
86 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); | 86 | release_mem_region(hcd->rsrc_start, hcd->rsrc_len); |
87 | err1: | 87 | err1: |
88 | usb_put_hcd(hcd); | 88 | usb_put_hcd(hcd); |
89 | return retval; | 89 | return retval; |
90 | } | 90 | } |
91 | 91 | ||
@@ -148,7 +148,7 @@ static const struct hc_driver ohci_ppc_soc_hc_driver = { | |||
148 | */ | 148 | */ |
149 | .start = ohci_ppc_soc_start, | 149 | .start = ohci_ppc_soc_start, |
150 | .stop = ohci_stop, | 150 | .stop = ohci_stop, |
151 | .shutdown = ohci_shutdown, | 151 | .shutdown = ohci_shutdown, |
152 | 152 | ||
153 | /* | 153 | /* |
154 | * managing i/o requests and associated device resources | 154 | * managing i/o requests and associated device resources |
@@ -197,7 +197,7 @@ static int ohci_hcd_ppc_soc_drv_remove(struct platform_device *pdev) | |||
197 | static struct platform_driver ohci_hcd_ppc_soc_driver = { | 197 | static struct platform_driver ohci_hcd_ppc_soc_driver = { |
198 | .probe = ohci_hcd_ppc_soc_drv_probe, | 198 | .probe = ohci_hcd_ppc_soc_drv_probe, |
199 | .remove = ohci_hcd_ppc_soc_drv_remove, | 199 | .remove = ohci_hcd_ppc_soc_drv_remove, |
200 | .shutdown = usb_hcd_platform_shutdown, | 200 | .shutdown = usb_hcd_platform_shutdown, |
201 | #ifdef CONFIG_PM | 201 | #ifdef CONFIG_PM |
202 | /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/ | 202 | /*.suspend = ohci_hcd_ppc_soc_drv_suspend,*/ |
203 | /*.resume = ohci_hcd_ppc_soc_drv_resume,*/ | 203 | /*.resume = ohci_hcd_ppc_soc_drv_resume,*/ |
@@ -208,19 +208,3 @@ static struct platform_driver ohci_hcd_ppc_soc_driver = { | |||
208 | }, | 208 | }, |
209 | }; | 209 | }; |
210 | 210 | ||
211 | static int __init ohci_hcd_ppc_soc_init(void) | ||
212 | { | ||
213 | pr_debug(DRIVER_INFO " (PPC SOC)\n"); | ||
214 | pr_debug("block sizes: ed %d td %d\n", sizeof(struct ed), | ||
215 | sizeof(struct td)); | ||
216 | |||
217 | return platform_driver_register(&ohci_hcd_ppc_soc_driver); | ||
218 | } | ||
219 | |||
220 | static void __exit ohci_hcd_ppc_soc_cleanup(void) | ||
221 | { | ||
222 | platform_driver_unregister(&ohci_hcd_ppc_soc_driver); | ||
223 | } | ||
224 | |||
225 | module_init(ohci_hcd_ppc_soc_init); | ||
226 | module_exit(ohci_hcd_ppc_soc_cleanup); | ||
diff --git a/drivers/usb/host/ohci-ps3.c b/drivers/usb/host/ohci-ps3.c new file mode 100644 index 000000000000..62283a3926de --- /dev/null +++ b/drivers/usb/host/ohci-ps3.c | |||
@@ -0,0 +1,196 @@ | |||
1 | /* | ||
2 | * PS3 OHCI Host Controller driver | ||
3 | * | ||
4 | * Copyright (C) 2006 Sony Computer Entertainment Inc. | ||
5 | * Copyright 2006 Sony Corp. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <asm/ps3.h> | ||
22 | |||
23 | static int ps3_ohci_hc_reset(struct usb_hcd *hcd) | ||
24 | { | ||
25 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
26 | |||
27 | ohci->flags |= OHCI_QUIRK_BE_MMIO; | ||
28 | ohci_hcd_init(ohci); | ||
29 | return ohci_init(ohci); | ||
30 | } | ||
31 | |||
32 | static int __devinit ps3_ohci_hc_start(struct usb_hcd *hcd) | ||
33 | { | ||
34 | int result; | ||
35 | struct ohci_hcd *ohci = hcd_to_ohci(hcd); | ||
36 | |||
37 | /* Handle root hub init quirk in spider south bridge. */ | ||
38 | /* Also set PwrOn2PwrGood to 0x7f (254ms). */ | ||
39 | |||
40 | ohci_writel(ohci, 0x7f000000 | RH_A_PSM | RH_A_OCPM, | ||
41 | &ohci->regs->roothub.a); | ||
42 | ohci_writel(ohci, 0x00060000, &ohci->regs->roothub.b); | ||
43 | |||
44 | result = ohci_run(ohci); | ||
45 | |||
46 | if (result < 0) { | ||
47 | err("can't start %s", hcd->self.bus_name); | ||
48 | ohci_stop(hcd); | ||
49 | } | ||
50 | |||
51 | return result; | ||
52 | } | ||
53 | |||
54 | static const struct hc_driver ps3_ohci_hc_driver = { | ||
55 | .description = hcd_name, | ||
56 | .product_desc = "PS3 OHCI Host Controller", | ||
57 | .hcd_priv_size = sizeof(struct ohci_hcd), | ||
58 | .irq = ohci_irq, | ||
59 | .flags = HCD_MEMORY | HCD_USB11, | ||
60 | .reset = ps3_ohci_hc_reset, | ||
61 | .start = ps3_ohci_hc_start, | ||
62 | .stop = ohci_stop, | ||
63 | .shutdown = ohci_shutdown, | ||
64 | .urb_enqueue = ohci_urb_enqueue, | ||
65 | .urb_dequeue = ohci_urb_dequeue, | ||
66 | .endpoint_disable = ohci_endpoint_disable, | ||
67 | .get_frame_number = ohci_get_frame, | ||
68 | .hub_status_data = ohci_hub_status_data, | ||
69 | .hub_control = ohci_hub_control, | ||
70 | .hub_irq_enable = ohci_rhsc_enable, | ||
71 | .start_port_reset = ohci_start_port_reset, | ||
72 | #if defined(CONFIG_PM) | ||
73 | .bus_suspend = ohci_bus_suspend, | ||
74 | .bus_resume = ohci_bus_resume, | ||
75 | #endif | ||
76 | }; | ||
77 | |||
78 | /* redefine dev_dbg to do a syntax check */ | ||
79 | |||
80 | #if !defined(DEBUG) | ||
81 | #undef dev_dbg | ||
82 | static inline int __attribute__ ((format (printf, 2, 3))) dev_dbg( | ||
83 | const struct device *_dev, const char *fmt, ...) {return 0;} | ||
84 | #endif | ||
85 | |||
86 | static int ps3_ohci_sb_probe(struct ps3_system_bus_device *dev) | ||
87 | { | ||
88 | int result; | ||
89 | struct usb_hcd *hcd; | ||
90 | unsigned int virq; | ||
91 | static u64 dummy_mask = DMA_32BIT_MASK; | ||
92 | |||
93 | if (usb_disabled()) { | ||
94 | result = -ENODEV; | ||
95 | goto fail_start; | ||
96 | } | ||
97 | |||
98 | result = ps3_mmio_region_create(dev->m_region); | ||
99 | |||
100 | if (result) { | ||
101 | dev_dbg(&dev->core, "%s:%d: ps3_map_mmio_region failed\n", | ||
102 | __func__, __LINE__); | ||
103 | result = -EPERM; | ||
104 | goto fail_mmio; | ||
105 | } | ||
106 | |||
107 | dev_dbg(&dev->core, "%s:%d: mmio mapped_addr %lxh\n", __func__, | ||
108 | __LINE__, dev->m_region->lpar_addr); | ||
109 | |||
110 | result = ps3_alloc_io_irq(PS3_BINDING_CPU_ANY, dev->interrupt_id, &virq); | ||
111 | |||
112 | if (result) { | ||
113 | dev_dbg(&dev->core, "%s:%d: ps3_construct_io_irq(%d) failed.\n", | ||
114 | __func__, __LINE__, virq); | ||
115 | result = -EPERM; | ||
116 | goto fail_irq; | ||
117 | } | ||
118 | |||
119 | dev->core.power.power_state = PMSG_ON; | ||
120 | dev->core.dma_mask = &dummy_mask; /* FIXME: for improper usb code */ | ||
121 | |||
122 | hcd = usb_create_hcd(&ps3_ohci_hc_driver, &dev->core, dev->core.bus_id); | ||
123 | |||
124 | if (!hcd) { | ||
125 | dev_dbg(&dev->core, "%s:%d: usb_create_hcd failed\n", __func__, | ||
126 | __LINE__); | ||
127 | result = -ENOMEM; | ||
128 | goto fail_create_hcd; | ||
129 | } | ||
130 | |||
131 | hcd->rsrc_start = dev->m_region->lpar_addr; | ||
132 | hcd->rsrc_len = dev->m_region->len; | ||
133 | hcd->regs = ioremap(dev->m_region->lpar_addr, dev->m_region->len); | ||
134 | |||
135 | if (!hcd->regs) { | ||
136 | dev_dbg(&dev->core, "%s:%d: ioremap failed\n", __func__, | ||
137 | __LINE__); | ||
138 | result = -EPERM; | ||
139 | goto fail_ioremap; | ||
140 | } | ||
141 | |||
142 | dev_dbg(&dev->core, "%s:%d: hcd->rsrc_start %lxh\n", __func__, __LINE__, | ||
143 | (unsigned long)hcd->rsrc_start); | ||
144 | dev_dbg(&dev->core, "%s:%d: hcd->rsrc_len %lxh\n", __func__, __LINE__, | ||
145 | (unsigned long)hcd->rsrc_len); | ||
146 | dev_dbg(&dev->core, "%s:%d: hcd->regs %lxh\n", __func__, __LINE__, | ||
147 | (unsigned long)hcd->regs); | ||
148 | dev_dbg(&dev->core, "%s:%d: virq %lu\n", __func__, __LINE__, | ||
149 | (unsigned long)virq); | ||
150 | |||
151 | ps3_system_bus_set_driver_data(dev, hcd); | ||
152 | |||
153 | result = usb_add_hcd(hcd, virq, IRQF_DISABLED); | ||
154 | |||
155 | if (result) { | ||
156 | dev_dbg(&dev->core, "%s:%d: usb_add_hcd failed (%d)\n", | ||
157 | __func__, __LINE__, result); | ||
158 | goto fail_add_hcd; | ||
159 | } | ||
160 | |||
161 | return result; | ||
162 | |||
163 | fail_add_hcd: | ||
164 | iounmap(hcd->regs); | ||
165 | fail_ioremap: | ||
166 | usb_put_hcd(hcd); | ||
167 | fail_create_hcd: | ||
168 | ps3_free_io_irq(virq); | ||
169 | fail_irq: | ||
170 | ps3_free_mmio_region(dev->m_region); | ||
171 | fail_mmio: | ||
172 | fail_start: | ||
173 | return result; | ||
174 | } | ||
175 | |||
176 | static int ps3_ohci_sb_remove (struct ps3_system_bus_device *dev) | ||
177 | { | ||
178 | struct usb_hcd *hcd = | ||
179 | (struct usb_hcd *)ps3_system_bus_get_driver_data(dev); | ||
180 | |||
181 | usb_put_hcd(hcd); | ||
182 | ps3_system_bus_set_driver_data(dev, NULL); | ||
183 | |||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | MODULE_ALIAS("ps3-ohci"); | ||
188 | |||
189 | static struct ps3_system_bus_driver ps3_ohci_sb_driver = { | ||
190 | .match_id = PS3_MATCH_ID_OHCI, | ||
191 | .core = { | ||
192 | .name = "ps3-ohci-driver", | ||
193 | }, | ||
194 | .probe = ps3_ohci_sb_probe, | ||
195 | .remove = ps3_ohci_sb_remove, | ||
196 | }; | ||
diff --git a/drivers/usb/host/ohci-pxa27x.c b/drivers/usb/host/ohci-pxa27x.c index e176b04d7aeb..f1563dc319d3 100644 --- a/drivers/usb/host/ohci-pxa27x.c +++ b/drivers/usb/host/ohci-pxa27x.c | |||
@@ -47,7 +47,7 @@ static int pxa27x_ohci_select_pmm( int mode ) | |||
47 | switch ( mode ) { | 47 | switch ( mode ) { |
48 | case PMM_NPS_MODE: | 48 | case PMM_NPS_MODE: |
49 | UHCRHDA |= RH_A_NPS; | 49 | UHCRHDA |= RH_A_NPS; |
50 | break; | 50 | break; |
51 | case PMM_GLOBAL_MODE: | 51 | case PMM_GLOBAL_MODE: |
52 | UHCRHDA &= ~(RH_A_NPS & RH_A_PSM); | 52 | UHCRHDA &= ~(RH_A_NPS & RH_A_PSM); |
53 | break; | 53 | break; |
@@ -60,7 +60,7 @@ static int pxa27x_ohci_select_pmm( int mode ) | |||
60 | break; | 60 | break; |
61 | default: | 61 | default: |
62 | printk( KERN_ERR | 62 | printk( KERN_ERR |
63 | "Invalid mode %d, set to non-power switch mode.\n", | 63 | "Invalid mode %d, set to non-power switch mode.\n", |
64 | mode ); | 64 | mode ); |
65 | 65 | ||
66 | UHCRHDA |= RH_A_NPS; | 66 | UHCRHDA |= RH_A_NPS; |
@@ -270,7 +270,7 @@ static const struct hc_driver ohci_pxa27x_hc_driver = { | |||
270 | */ | 270 | */ |
271 | .start = ohci_pxa27x_start, | 271 | .start = ohci_pxa27x_start, |
272 | .stop = ohci_stop, | 272 | .stop = ohci_stop, |
273 | .shutdown = ohci_shutdown, | 273 | .shutdown = ohci_shutdown, |
274 | 274 | ||
275 | /* | 275 | /* |
276 | * managing i/o requests and associated device resources | 276 | * managing i/o requests and associated device resources |
@@ -359,9 +359,9 @@ static int ohci_hcd_pxa27x_drv_resume(struct platform_device *pdev) | |||
359 | static struct platform_driver ohci_hcd_pxa27x_driver = { | 359 | static struct platform_driver ohci_hcd_pxa27x_driver = { |
360 | .probe = ohci_hcd_pxa27x_drv_probe, | 360 | .probe = ohci_hcd_pxa27x_drv_probe, |
361 | .remove = ohci_hcd_pxa27x_drv_remove, | 361 | .remove = ohci_hcd_pxa27x_drv_remove, |
362 | .shutdown = usb_hcd_platform_shutdown, | 362 | .shutdown = usb_hcd_platform_shutdown, |
363 | #ifdef CONFIG_PM | 363 | #ifdef CONFIG_PM |
364 | .suspend = ohci_hcd_pxa27x_drv_suspend, | 364 | .suspend = ohci_hcd_pxa27x_drv_suspend, |
365 | .resume = ohci_hcd_pxa27x_drv_resume, | 365 | .resume = ohci_hcd_pxa27x_drv_resume, |
366 | #endif | 366 | #endif |
367 | .driver = { | 367 | .driver = { |
@@ -369,19 +369,3 @@ static struct platform_driver ohci_hcd_pxa27x_driver = { | |||
369 | }, | 369 | }, |
370 | }; | 370 | }; |
371 | 371 | ||
372 | static int __init ohci_hcd_pxa27x_init (void) | ||
373 | { | ||
374 | pr_debug (DRIVER_INFO " (pxa27x)"); | ||
375 | pr_debug ("block sizes: ed %d td %d\n", | ||
376 | sizeof (struct ed), sizeof (struct td)); | ||
377 | |||
378 | return platform_driver_register(&ohci_hcd_pxa27x_driver); | ||
379 | } | ||
380 | |||
381 | static void __exit ohci_hcd_pxa27x_cleanup (void) | ||
382 | { | ||
383 | platform_driver_unregister(&ohci_hcd_pxa27x_driver); | ||
384 | } | ||
385 | |||
386 | module_init (ohci_hcd_pxa27x_init); | ||
387 | module_exit (ohci_hcd_pxa27x_cleanup); | ||
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index fe1fe2f97cb5..830a3fe8615e 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * OHCI HCD (Host Controller Driver) for USB. | 2 | * OHCI HCD (Host Controller Driver) for USB. |
3 | * | 3 | * |
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | 4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> |
5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> | 5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> |
6 | * | 6 | * |
7 | * This file is licenced under the GPL. | 7 | * This file is licenced under the GPL. |
8 | */ | 8 | */ |
9 | 9 | ||
@@ -89,7 +89,7 @@ __acquires(ohci->lock) | |||
89 | 89 | ||
90 | /*-------------------------------------------------------------------------* | 90 | /*-------------------------------------------------------------------------* |
91 | * ED handling functions | 91 | * ED handling functions |
92 | *-------------------------------------------------------------------------*/ | 92 | *-------------------------------------------------------------------------*/ |
93 | 93 | ||
94 | /* search for the right schedule branch to use for a periodic ed. | 94 | /* search for the right schedule branch to use for a periodic ed. |
95 | * does some load balancing; returns the branch, or negative errno. | 95 | * does some load balancing; returns the branch, or negative errno. |
@@ -107,7 +107,6 @@ static int balance (struct ohci_hcd *ohci, int interval, int load) | |||
107 | */ | 107 | */ |
108 | for (i = 0; i < interval ; i++) { | 108 | for (i = 0; i < interval ; i++) { |
109 | if (branch < 0 || ohci->load [branch] > ohci->load [i]) { | 109 | if (branch < 0 || ohci->load [branch] > ohci->load [i]) { |
110 | #if 1 /* CONFIG_USB_BANDWIDTH */ | ||
111 | int j; | 110 | int j; |
112 | 111 | ||
113 | /* usb 1.1 says 90% of one frame */ | 112 | /* usb 1.1 says 90% of one frame */ |
@@ -117,8 +116,7 @@ static int balance (struct ohci_hcd *ohci, int interval, int load) | |||
117 | } | 116 | } |
118 | if (j < NUM_INTS) | 117 | if (j < NUM_INTS) |
119 | continue; | 118 | continue; |
120 | #endif | 119 | branch = i; |
121 | branch = i; | ||
122 | } | 120 | } |
123 | } | 121 | } |
124 | return branch; | 122 | return branch; |
@@ -171,7 +169,7 @@ static void periodic_link (struct ohci_hcd *ohci, struct ed *ed) | |||
171 | /* link an ed into one of the HC chains */ | 169 | /* link an ed into one of the HC chains */ |
172 | 170 | ||
173 | static int ed_schedule (struct ohci_hcd *ohci, struct ed *ed) | 171 | static int ed_schedule (struct ohci_hcd *ohci, struct ed *ed) |
174 | { | 172 | { |
175 | int branch; | 173 | int branch; |
176 | 174 | ||
177 | if (ohci_to_hcd(ohci)->state == HC_STATE_QUIESCING) | 175 | if (ohci_to_hcd(ohci)->state == HC_STATE_QUIESCING) |
@@ -248,7 +246,7 @@ static int ed_schedule (struct ohci_hcd *ohci, struct ed *ed) | |||
248 | } | 246 | } |
249 | ed->branch = branch; | 247 | ed->branch = branch; |
250 | periodic_link (ohci, ed); | 248 | periodic_link (ohci, ed); |
251 | } | 249 | } |
252 | 250 | ||
253 | /* the HC may not see the schedule updates yet, but if it does | 251 | /* the HC may not see the schedule updates yet, but if it does |
254 | * then they'll be properly ordered. | 252 | * then they'll be properly ordered. |
@@ -277,7 +275,7 @@ static void periodic_unlink (struct ohci_hcd *ohci, struct ed *ed) | |||
277 | *prev = ed->ed_next; | 275 | *prev = ed->ed_next; |
278 | } | 276 | } |
279 | ohci->load [i] -= ed->load; | 277 | ohci->load [i] -= ed->load; |
280 | } | 278 | } |
281 | ohci_to_hcd(ohci)->self.bandwidth_allocated -= ed->load / ed->interval; | 279 | ohci_to_hcd(ohci)->self.bandwidth_allocated -= ed->load / ed->interval; |
282 | 280 | ||
283 | ohci_vdbg (ohci, "unlink %sed %p branch %d [%dus.], interval %d\n", | 281 | ohci_vdbg (ohci, "unlink %sed %p branch %d [%dus.], interval %d\n", |
@@ -285,7 +283,7 @@ static void periodic_unlink (struct ohci_hcd *ohci, struct ed *ed) | |||
285 | ed, ed->branch, ed->load, ed->interval); | 283 | ed, ed->branch, ed->load, ed->interval); |
286 | } | 284 | } |
287 | 285 | ||
288 | /* unlink an ed from one of the HC chains. | 286 | /* unlink an ed from one of the HC chains. |
289 | * just the link to the ed is unlinked. | 287 | * just the link to the ed is unlinked. |
290 | * the link from the ed still points to another operational ed or 0 | 288 | * the link from the ed still points to another operational ed or 0 |
291 | * so the HC can eventually finish the processing of the unlinked ed | 289 | * so the HC can eventually finish the processing of the unlinked ed |
@@ -307,7 +305,7 @@ static void periodic_unlink (struct ohci_hcd *ohci, struct ed *ed) | |||
307 | * When finish_unlinks() runs later, after SOF interrupt, it will often | 305 | * When finish_unlinks() runs later, after SOF interrupt, it will often |
308 | * complete one or more URB unlinks before making that state change. | 306 | * complete one or more URB unlinks before making that state change. |
309 | */ | 307 | */ |
310 | static void ed_deschedule (struct ohci_hcd *ohci, struct ed *ed) | 308 | static void ed_deschedule (struct ohci_hcd *ohci, struct ed *ed) |
311 | { | 309 | { |
312 | ed->hwINFO |= cpu_to_hc32 (ohci, ED_SKIP); | 310 | ed->hwINFO |= cpu_to_hc32 (ohci, ED_SKIP); |
313 | wmb (); | 311 | wmb (); |
@@ -397,7 +395,7 @@ static struct ed *ed_get ( | |||
397 | unsigned int pipe, | 395 | unsigned int pipe, |
398 | int interval | 396 | int interval |
399 | ) { | 397 | ) { |
400 | struct ed *ed; | 398 | struct ed *ed; |
401 | unsigned long flags; | 399 | unsigned long flags; |
402 | 400 | ||
403 | spin_lock_irqsave (&ohci->lock, flags); | 401 | spin_lock_irqsave (&ohci->lock, flags); |
@@ -413,9 +411,9 @@ static struct ed *ed_get ( | |||
413 | goto done; | 411 | goto done; |
414 | } | 412 | } |
415 | 413 | ||
416 | /* dummy td; end of td list for ed */ | 414 | /* dummy td; end of td list for ed */ |
417 | td = td_alloc (ohci, GFP_ATOMIC); | 415 | td = td_alloc (ohci, GFP_ATOMIC); |
418 | if (!td) { | 416 | if (!td) { |
419 | /* out of memory */ | 417 | /* out of memory */ |
420 | ed_free (ohci, ed); | 418 | ed_free (ohci, ed); |
421 | ed = NULL; | 419 | ed = NULL; |
@@ -462,7 +460,7 @@ static struct ed *ed_get ( | |||
462 | 460 | ||
463 | done: | 461 | done: |
464 | spin_unlock_irqrestore (&ohci->lock, flags); | 462 | spin_unlock_irqrestore (&ohci->lock, flags); |
465 | return ed; | 463 | return ed; |
466 | } | 464 | } |
467 | 465 | ||
468 | /*-------------------------------------------------------------------------*/ | 466 | /*-------------------------------------------------------------------------*/ |
@@ -474,7 +472,7 @@ done: | |||
474 | * and that ed->state is ED_OPER | 472 | * and that ed->state is ED_OPER |
475 | */ | 473 | */ |
476 | static void start_ed_unlink (struct ohci_hcd *ohci, struct ed *ed) | 474 | static void start_ed_unlink (struct ohci_hcd *ohci, struct ed *ed) |
477 | { | 475 | { |
478 | ed->hwINFO |= cpu_to_hc32 (ohci, ED_DEQUEUE); | 476 | ed->hwINFO |= cpu_to_hc32 (ohci, ED_DEQUEUE); |
479 | ed_deschedule (ohci, ed); | 477 | ed_deschedule (ohci, ed); |
480 | 478 | ||
@@ -541,7 +539,7 @@ td_fill (struct ohci_hcd *ohci, u32 info, | |||
541 | td->ed = urb_priv->ed; | 539 | td->ed = urb_priv->ed; |
542 | td->next_dl_td = NULL; | 540 | td->next_dl_td = NULL; |
543 | td->index = index; | 541 | td->index = index; |
544 | td->urb = urb; | 542 | td->urb = urb; |
545 | td->data_dma = data; | 543 | td->data_dma = data; |
546 | if (!len) | 544 | if (!len) |
547 | data = 0; | 545 | data = 0; |
@@ -553,8 +551,8 @@ td_fill (struct ohci_hcd *ohci, u32 info, | |||
553 | (data & 0x0FFF) | 0xE000); | 551 | (data & 0x0FFF) | 0xE000); |
554 | td->ed->last_iso = info & 0xffff; | 552 | td->ed->last_iso = info & 0xffff; |
555 | } else { | 553 | } else { |
556 | td->hwCBP = cpu_to_hc32 (ohci, data); | 554 | td->hwCBP = cpu_to_hc32 (ohci, data); |
557 | } | 555 | } |
558 | if (data) | 556 | if (data) |
559 | td->hwBE = cpu_to_hc32 (ohci, data + len - 1); | 557 | td->hwBE = cpu_to_hc32 (ohci, data + len - 1); |
560 | else | 558 | else |
@@ -597,7 +595,7 @@ static void td_submit_urb ( | |||
597 | * use the device toggle bits for resetting, and rely on the fact | 595 | * use the device toggle bits for resetting, and rely on the fact |
598 | * that resetting toggle is meaningless if the endpoint is active. | 596 | * that resetting toggle is meaningless if the endpoint is active. |
599 | */ | 597 | */ |
600 | if (!usb_gettoggle (urb->dev, usb_pipeendpoint (urb->pipe), is_out)) { | 598 | if (!usb_gettoggle (urb->dev, usb_pipeendpoint (urb->pipe), is_out)) { |
601 | usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), | 599 | usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), |
602 | is_out, 1); | 600 | is_out, 1); |
603 | urb_priv->ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_C); | 601 | urb_priv->ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_C); |
@@ -721,16 +719,16 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td) | |||
721 | list_del (&td->td_list); | 719 | list_del (&td->td_list); |
722 | 720 | ||
723 | /* ISO ... drivers see per-TD length/status */ | 721 | /* ISO ... drivers see per-TD length/status */ |
724 | if (tdINFO & TD_ISO) { | 722 | if (tdINFO & TD_ISO) { |
725 | u16 tdPSW = ohci_hwPSW (ohci, td, 0); | 723 | u16 tdPSW = ohci_hwPSW (ohci, td, 0); |
726 | int dlen = 0; | 724 | int dlen = 0; |
727 | 725 | ||
728 | /* NOTE: assumes FC in tdINFO == 0, and that | 726 | /* NOTE: assumes FC in tdINFO == 0, and that |
729 | * only the first of 0..MAXPSW psws is used. | 727 | * only the first of 0..MAXPSW psws is used. |
730 | */ | 728 | */ |
731 | 729 | ||
732 | cc = (tdPSW >> 12) & 0xF; | 730 | cc = (tdPSW >> 12) & 0xF; |
733 | if (tdINFO & TD_CC) /* hc didn't touch? */ | 731 | if (tdINFO & TD_CC) /* hc didn't touch? */ |
734 | return; | 732 | return; |
735 | 733 | ||
736 | if (usb_pipeout (urb->pipe)) | 734 | if (usb_pipeout (urb->pipe)) |
@@ -758,7 +756,7 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td) | |||
758 | int type = usb_pipetype (urb->pipe); | 756 | int type = usb_pipetype (urb->pipe); |
759 | u32 tdBE = hc32_to_cpup (ohci, &td->hwBE); | 757 | u32 tdBE = hc32_to_cpup (ohci, &td->hwBE); |
760 | 758 | ||
761 | cc = TD_CC_GET (tdINFO); | 759 | cc = TD_CC_GET (tdINFO); |
762 | 760 | ||
763 | /* update packet status if needed (short is normally ok) */ | 761 | /* update packet status if needed (short is normally ok) */ |
764 | if (cc == TD_DATAUNDERRUN | 762 | if (cc == TD_DATAUNDERRUN |
@@ -787,7 +785,7 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td) | |||
787 | urb, td, 1 + td->index, cc, | 785 | urb, td, 1 + td->index, cc, |
788 | urb->actual_length, | 786 | urb->actual_length, |
789 | urb->transfer_buffer_length); | 787 | urb->transfer_buffer_length); |
790 | } | 788 | } |
791 | } | 789 | } |
792 | 790 | ||
793 | /*-------------------------------------------------------------------------*/ | 791 | /*-------------------------------------------------------------------------*/ |
@@ -795,7 +793,7 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td) | |||
795 | static inline struct td * | 793 | static inline struct td * |
796 | ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) | 794 | ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) |
797 | { | 795 | { |
798 | struct urb *urb = td->urb; | 796 | struct urb *urb = td->urb; |
799 | struct ed *ed = td->ed; | 797 | struct ed *ed = td->ed; |
800 | struct list_head *tmp = td->td_list.next; | 798 | struct list_head *tmp = td->td_list.next; |
801 | __hc32 toggle = ed->hwHeadP & cpu_to_hc32 (ohci, ED_C); | 799 | __hc32 toggle = ed->hwHeadP & cpu_to_hc32 (ohci, ED_C); |
@@ -805,7 +803,7 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) | |||
805 | */ | 803 | */ |
806 | ed->hwINFO |= cpu_to_hc32 (ohci, ED_SKIP); | 804 | ed->hwINFO |= cpu_to_hc32 (ohci, ED_SKIP); |
807 | wmb (); | 805 | wmb (); |
808 | ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_H); | 806 | ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_H); |
809 | 807 | ||
810 | /* put any later tds from this urb onto the donelist, after 'td', | 808 | /* put any later tds from this urb onto the donelist, after 'td', |
811 | * order won't matter here: no errors, and nothing was transferred. | 809 | * order won't matter here: no errors, and nothing was transferred. |
@@ -833,7 +831,7 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) | |||
833 | info &= ~cpu_to_hc32 (ohci, TD_CC); | 831 | info &= ~cpu_to_hc32 (ohci, TD_CC); |
834 | next->hwINFO = info; | 832 | next->hwINFO = info; |
835 | 833 | ||
836 | next->next_dl_td = rev; | 834 | next->next_dl_td = rev; |
837 | rev = next; | 835 | rev = next; |
838 | 836 | ||
839 | ed->hwHeadP = next->hwNextTD | toggle; | 837 | ed->hwHeadP = next->hwNextTD | toggle; |
@@ -881,8 +879,8 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci) | |||
881 | /* get TD from hc's singly linked list, and | 879 | /* get TD from hc's singly linked list, and |
882 | * prepend to ours. ed->td_list changes later. | 880 | * prepend to ours. ed->td_list changes later. |
883 | */ | 881 | */ |
884 | while (td_dma) { | 882 | while (td_dma) { |
885 | int cc; | 883 | int cc; |
886 | 884 | ||
887 | td = dma_to_td (ohci, td_dma); | 885 | td = dma_to_td (ohci, td_dma); |
888 | if (!td) { | 886 | if (!td) { |
@@ -901,10 +899,10 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci) | |||
901 | && (td->ed->hwHeadP & cpu_to_hc32 (ohci, ED_H))) | 899 | && (td->ed->hwHeadP & cpu_to_hc32 (ohci, ED_H))) |
902 | td_rev = ed_halted (ohci, td, cc, td_rev); | 900 | td_rev = ed_halted (ohci, td, cc, td_rev); |
903 | 901 | ||
904 | td->next_dl_td = td_rev; | 902 | td->next_dl_td = td_rev; |
905 | td_rev = td; | 903 | td_rev = td; |
906 | td_dma = hc32_to_cpup (ohci, &td->hwNextTD); | 904 | td_dma = hc32_to_cpup (ohci, &td->hwNextTD); |
907 | } | 905 | } |
908 | return td_rev; | 906 | return td_rev; |
909 | } | 907 | } |
910 | 908 | ||
@@ -1013,9 +1011,9 @@ rescan_this: | |||
1013 | 1011 | ||
1014 | if (modified) | 1012 | if (modified) |
1015 | goto rescan_all; | 1013 | goto rescan_all; |
1016 | } | 1014 | } |
1017 | 1015 | ||
1018 | /* maybe reenable control and bulk lists */ | 1016 | /* maybe reenable control and bulk lists */ |
1019 | if (HC_IS_RUNNING(ohci_to_hcd(ohci)->state) | 1017 | if (HC_IS_RUNNING(ohci_to_hcd(ohci)->state) |
1020 | && ohci_to_hcd(ohci)->state != HC_STATE_QUIESCING | 1018 | && ohci_to_hcd(ohci)->state != HC_STATE_QUIESCING |
1021 | && !ohci->ed_rm_list) { | 1019 | && !ohci->ed_rm_list) { |
@@ -1041,20 +1039,20 @@ rescan_this: | |||
1041 | &ohci->regs->ed_bulkcurrent); | 1039 | &ohci->regs->ed_bulkcurrent); |
1042 | } | 1040 | } |
1043 | } | 1041 | } |
1044 | 1042 | ||
1045 | /* CLE/BLE to enable, CLF/BLF to (maybe) kickstart */ | 1043 | /* CLE/BLE to enable, CLF/BLF to (maybe) kickstart */ |
1046 | if (control) { | 1044 | if (control) { |
1047 | ohci->hc_control |= control; | 1045 | ohci->hc_control |= control; |
1048 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) | 1046 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) |
1049 | mdelay(1); | 1047 | mdelay(1); |
1050 | ohci_writel (ohci, ohci->hc_control, | 1048 | ohci_writel (ohci, ohci->hc_control, |
1051 | &ohci->regs->control); | 1049 | &ohci->regs->control); |
1052 | } | 1050 | } |
1053 | if (command) { | 1051 | if (command) { |
1054 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) | 1052 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) |
1055 | mdelay(1); | 1053 | mdelay(1); |
1056 | ohci_writel (ohci, command, &ohci->regs->cmdstatus); | 1054 | ohci_writel (ohci, command, &ohci->regs->cmdstatus); |
1057 | } | 1055 | } |
1058 | } | 1056 | } |
1059 | } | 1057 | } |
1060 | 1058 | ||
@@ -1074,19 +1072,19 @@ dl_done_list (struct ohci_hcd *ohci) | |||
1074 | { | 1072 | { |
1075 | struct td *td = dl_reverse_done_list (ohci); | 1073 | struct td *td = dl_reverse_done_list (ohci); |
1076 | 1074 | ||
1077 | while (td) { | 1075 | while (td) { |
1078 | struct td *td_next = td->next_dl_td; | 1076 | struct td *td_next = td->next_dl_td; |
1079 | struct urb *urb = td->urb; | 1077 | struct urb *urb = td->urb; |
1080 | urb_priv_t *urb_priv = urb->hcpriv; | 1078 | urb_priv_t *urb_priv = urb->hcpriv; |
1081 | struct ed *ed = td->ed; | 1079 | struct ed *ed = td->ed; |
1082 | 1080 | ||
1083 | /* update URB's length and status from TD */ | 1081 | /* update URB's length and status from TD */ |
1084 | td_done (ohci, urb, td); | 1082 | td_done (ohci, urb, td); |
1085 | urb_priv->td_cnt++; | 1083 | urb_priv->td_cnt++; |
1086 | 1084 | ||
1087 | /* If all this urb's TDs are done, call complete() */ | 1085 | /* If all this urb's TDs are done, call complete() */ |
1088 | if (urb_priv->td_cnt == urb_priv->length) | 1086 | if (urb_priv->td_cnt == urb_priv->length) |
1089 | finish_urb (ohci, urb); | 1087 | finish_urb (ohci, urb); |
1090 | 1088 | ||
1091 | /* clean schedule: unlink EDs that are no longer busy */ | 1089 | /* clean schedule: unlink EDs that are no longer busy */ |
1092 | if (list_empty (&ed->td_list)) { | 1090 | if (list_empty (&ed->td_list)) { |
@@ -1094,25 +1092,26 @@ dl_done_list (struct ohci_hcd *ohci) | |||
1094 | start_ed_unlink (ohci, ed); | 1092 | start_ed_unlink (ohci, ed); |
1095 | 1093 | ||
1096 | /* ... reenabling halted EDs only after fault cleanup */ | 1094 | /* ... reenabling halted EDs only after fault cleanup */ |
1097 | } else if ((ed->hwINFO & cpu_to_hc32 (ohci, ED_SKIP | ED_DEQUEUE)) | 1095 | } else if ((ed->hwINFO & cpu_to_hc32 (ohci, |
1096 | ED_SKIP | ED_DEQUEUE)) | ||
1098 | == cpu_to_hc32 (ohci, ED_SKIP)) { | 1097 | == cpu_to_hc32 (ohci, ED_SKIP)) { |
1099 | td = list_entry (ed->td_list.next, struct td, td_list); | 1098 | td = list_entry (ed->td_list.next, struct td, td_list); |
1100 | if (!(td->hwINFO & cpu_to_hc32 (ohci, TD_DONE))) { | 1099 | if (!(td->hwINFO & cpu_to_hc32 (ohci, TD_DONE))) { |
1101 | ed->hwINFO &= ~cpu_to_hc32 (ohci, ED_SKIP); | 1100 | ed->hwINFO &= ~cpu_to_hc32 (ohci, ED_SKIP); |
1102 | /* ... hc may need waking-up */ | 1101 | /* ... hc may need waking-up */ |
1103 | switch (ed->type) { | 1102 | switch (ed->type) { |
1104 | case PIPE_CONTROL: | 1103 | case PIPE_CONTROL: |
1105 | ohci_writel (ohci, OHCI_CLF, | 1104 | ohci_writel (ohci, OHCI_CLF, |
1106 | &ohci->regs->cmdstatus); | 1105 | &ohci->regs->cmdstatus); |
1107 | break; | 1106 | break; |
1108 | case PIPE_BULK: | 1107 | case PIPE_BULK: |
1109 | ohci_writel (ohci, OHCI_BLF, | 1108 | ohci_writel (ohci, OHCI_BLF, |
1110 | &ohci->regs->cmdstatus); | 1109 | &ohci->regs->cmdstatus); |
1111 | break; | 1110 | break; |
1112 | } | 1111 | } |
1113 | } | 1112 | } |
1114 | } | 1113 | } |
1115 | 1114 | ||
1116 | td = td_next; | 1115 | td = td_next; |
1117 | } | 1116 | } |
1118 | } | 1117 | } |
diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 59e436424d41..6829814b7aaf 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c | |||
@@ -447,7 +447,7 @@ static const struct hc_driver ohci_s3c2410_hc_driver = { | |||
447 | */ | 447 | */ |
448 | .start = ohci_s3c2410_start, | 448 | .start = ohci_s3c2410_start, |
449 | .stop = ohci_stop, | 449 | .stop = ohci_stop, |
450 | .shutdown = ohci_shutdown, | 450 | .shutdown = ohci_shutdown, |
451 | 451 | ||
452 | /* | 452 | /* |
453 | * managing i/o requests and associated device resources | 453 | * managing i/o requests and associated device resources |
@@ -492,7 +492,7 @@ static int ohci_hcd_s3c2410_drv_remove(struct platform_device *pdev) | |||
492 | static struct platform_driver ohci_hcd_s3c2410_driver = { | 492 | static struct platform_driver ohci_hcd_s3c2410_driver = { |
493 | .probe = ohci_hcd_s3c2410_drv_probe, | 493 | .probe = ohci_hcd_s3c2410_drv_probe, |
494 | .remove = ohci_hcd_s3c2410_drv_remove, | 494 | .remove = ohci_hcd_s3c2410_drv_remove, |
495 | .shutdown = usb_hcd_platform_shutdown, | 495 | .shutdown = usb_hcd_platform_shutdown, |
496 | /*.suspend = ohci_hcd_s3c2410_drv_suspend, */ | 496 | /*.suspend = ohci_hcd_s3c2410_drv_suspend, */ |
497 | /*.resume = ohci_hcd_s3c2410_drv_resume, */ | 497 | /*.resume = ohci_hcd_s3c2410_drv_resume, */ |
498 | .driver = { | 498 | .driver = { |
@@ -501,15 +501,3 @@ static struct platform_driver ohci_hcd_s3c2410_driver = { | |||
501 | }, | 501 | }, |
502 | }; | 502 | }; |
503 | 503 | ||
504 | static int __init ohci_hcd_s3c2410_init (void) | ||
505 | { | ||
506 | return platform_driver_register(&ohci_hcd_s3c2410_driver); | ||
507 | } | ||
508 | |||
509 | static void __exit ohci_hcd_s3c2410_cleanup (void) | ||
510 | { | ||
511 | platform_driver_unregister(&ohci_hcd_s3c2410_driver); | ||
512 | } | ||
513 | |||
514 | module_init (ohci_hcd_s3c2410_init); | ||
515 | module_exit (ohci_hcd_s3c2410_cleanup); | ||
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c index 71371de32ada..0f48f2d99226 100644 --- a/drivers/usb/host/ohci-sa1111.c +++ b/drivers/usb/host/ohci-sa1111.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | 4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> |
5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> | 5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> |
6 | * (C) Copyright 2002 Hewlett-Packard Company | 6 | * (C) Copyright 2002 Hewlett-Packard Company |
7 | * | 7 | * |
8 | * SA1111 Bus Glue | 8 | * SA1111 Bus Glue |
9 | * | 9 | * |
10 | * Written by Christopher Hoover <ch@hpl.hp.com> | 10 | * Written by Christopher Hoover <ch@hpl.hp.com> |
@@ -12,7 +12,7 @@ | |||
12 | * | 12 | * |
13 | * This file is licenced under the GPL. | 13 | * This file is licenced under the GPL. |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <asm/hardware.h> | 16 | #include <asm/hardware.h> |
17 | #include <asm/mach-types.h> | 17 | #include <asm/mach-types.h> |
18 | #include <asm/arch/assabet.h> | 18 | #include <asm/arch/assabet.h> |
@@ -31,7 +31,7 @@ static void sa1111_start_hc(struct sa1111_dev *dev) | |||
31 | { | 31 | { |
32 | unsigned int usb_rst = 0; | 32 | unsigned int usb_rst = 0; |
33 | 33 | ||
34 | printk(KERN_DEBUG __FILE__ | 34 | printk(KERN_DEBUG __FILE__ |
35 | ": starting SA-1111 OHCI USB Controller\n"); | 35 | ": starting SA-1111 OHCI USB Controller\n"); |
36 | 36 | ||
37 | #ifdef CONFIG_SA1100_BADGE4 | 37 | #ifdef CONFIG_SA1100_BADGE4 |
@@ -65,7 +65,7 @@ static void sa1111_start_hc(struct sa1111_dev *dev) | |||
65 | static void sa1111_stop_hc(struct sa1111_dev *dev) | 65 | static void sa1111_stop_hc(struct sa1111_dev *dev) |
66 | { | 66 | { |
67 | unsigned int usb_rst; | 67 | unsigned int usb_rst; |
68 | printk(KERN_DEBUG __FILE__ | 68 | printk(KERN_DEBUG __FILE__ |
69 | ": stopping SA-1111 OHCI USB Controller\n"); | 69 | ": stopping SA-1111 OHCI USB Controller\n"); |
70 | 70 | ||
71 | /* | 71 | /* |
@@ -269,19 +269,3 @@ static struct sa1111_driver ohci_hcd_sa1111_driver = { | |||
269 | .remove = ohci_hcd_sa1111_drv_remove, | 269 | .remove = ohci_hcd_sa1111_drv_remove, |
270 | }; | 270 | }; |
271 | 271 | ||
272 | static int __init ohci_hcd_sa1111_init (void) | ||
273 | { | ||
274 | dbg (DRIVER_INFO " (SA-1111)"); | ||
275 | dbg ("block sizes: ed %d td %d", | ||
276 | sizeof (struct ed), sizeof (struct td)); | ||
277 | |||
278 | return sa1111_driver_register(&ohci_hcd_sa1111_driver); | ||
279 | } | ||
280 | |||
281 | static void __exit ohci_hcd_sa1111_cleanup (void) | ||
282 | { | ||
283 | sa1111_driver_unregister(&ohci_hcd_sa1111_driver); | ||
284 | } | ||
285 | |||
286 | module_init (ohci_hcd_sa1111_init); | ||
287 | module_exit (ohci_hcd_sa1111_cleanup); | ||
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index a2f42a2f47c6..c2b5ecfe5e9f 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * OHCI HCD (Host Controller Driver) for USB. | 2 | * OHCI HCD (Host Controller Driver) for USB. |
3 | * | 3 | * |
4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> | 4 | * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at> |
5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> | 5 | * (C) Copyright 2000-2002 David Brownell <dbrownell@users.sourceforge.net> |
6 | * | 6 | * |
7 | * This file is licenced under the GPL. | 7 | * This file is licenced under the GPL. |
8 | */ | 8 | */ |
9 | 9 | ||
@@ -14,7 +14,7 @@ | |||
14 | */ | 14 | */ |
15 | typedef __u32 __bitwise __hc32; | 15 | typedef __u32 __bitwise __hc32; |
16 | typedef __u16 __bitwise __hc16; | 16 | typedef __u16 __bitwise __hc16; |
17 | 17 | ||
18 | /* | 18 | /* |
19 | * OHCI Endpoint Descriptor (ED) ... holds TD queue | 19 | * OHCI Endpoint Descriptor (ED) ... holds TD queue |
20 | * See OHCI spec, section 4.2 | 20 | * See OHCI spec, section 4.2 |
@@ -24,7 +24,7 @@ typedef __u16 __bitwise __hc16; | |||
24 | */ | 24 | */ |
25 | struct ed { | 25 | struct ed { |
26 | /* first fields are hardware-specified */ | 26 | /* first fields are hardware-specified */ |
27 | __hc32 hwINFO; /* endpoint config bitmap */ | 27 | __hc32 hwINFO; /* endpoint config bitmap */ |
28 | /* info bits defined by hcd */ | 28 | /* info bits defined by hcd */ |
29 | #define ED_DEQUEUE (1 << 27) | 29 | #define ED_DEQUEUE (1 << 27) |
30 | /* info bits defined by the hardware */ | 30 | /* info bits defined by the hardware */ |
@@ -52,11 +52,11 @@ struct ed { | |||
52 | * usually: OPER --> UNLINK --> (IDLE | OPER) --> ... | 52 | * usually: OPER --> UNLINK --> (IDLE | OPER) --> ... |
53 | */ | 53 | */ |
54 | u8 state; /* ED_{IDLE,UNLINK,OPER} */ | 54 | u8 state; /* ED_{IDLE,UNLINK,OPER} */ |
55 | #define ED_IDLE 0x00 /* NOT linked to HC */ | 55 | #define ED_IDLE 0x00 /* NOT linked to HC */ |
56 | #define ED_UNLINK 0x01 /* being unlinked from hc */ | 56 | #define ED_UNLINK 0x01 /* being unlinked from hc */ |
57 | #define ED_OPER 0x02 /* IS linked to hc */ | 57 | #define ED_OPER 0x02 /* IS linked to hc */ |
58 | 58 | ||
59 | u8 type; /* PIPE_{BULK,...} */ | 59 | u8 type; /* PIPE_{BULK,...} */ |
60 | 60 | ||
61 | /* periodic scheduling params (for intr and iso) */ | 61 | /* periodic scheduling params (for intr and iso) */ |
62 | u8 branch; | 62 | u8 branch; |
@@ -70,7 +70,7 @@ struct ed { | |||
70 | 70 | ||
71 | #define ED_MASK ((u32)~0x0f) /* strip hw status in low addr bits */ | 71 | #define ED_MASK ((u32)~0x0f) /* strip hw status in low addr bits */ |
72 | 72 | ||
73 | 73 | ||
74 | /* | 74 | /* |
75 | * OHCI Transfer Descriptor (TD) ... one per transfer segment | 75 | * OHCI Transfer Descriptor (TD) ... one per transfer segment |
76 | * See OHCI spec, sections 4.3.1 (general = control/bulk/interrupt) | 76 | * See OHCI spec, sections 4.3.1 (general = control/bulk/interrupt) |
@@ -107,22 +107,22 @@ struct td { | |||
107 | 107 | ||
108 | /* (no hwINFO #defines yet for iso tds) */ | 108 | /* (no hwINFO #defines yet for iso tds) */ |
109 | 109 | ||
110 | __hc32 hwCBP; /* Current Buffer Pointer (or 0) */ | 110 | __hc32 hwCBP; /* Current Buffer Pointer (or 0) */ |
111 | __hc32 hwNextTD; /* Next TD Pointer */ | 111 | __hc32 hwNextTD; /* Next TD Pointer */ |
112 | __hc32 hwBE; /* Memory Buffer End Pointer */ | 112 | __hc32 hwBE; /* Memory Buffer End Pointer */ |
113 | 113 | ||
114 | /* PSW is only for ISO. Only 1 PSW entry is used, but on | 114 | /* PSW is only for ISO. Only 1 PSW entry is used, but on |
115 | * big-endian PPC hardware that's the second entry. | 115 | * big-endian PPC hardware that's the second entry. |
116 | */ | 116 | */ |
117 | #define MAXPSW 2 | 117 | #define MAXPSW 2 |
118 | __hc16 hwPSW [MAXPSW]; | 118 | __hc16 hwPSW [MAXPSW]; |
119 | 119 | ||
120 | /* rest are purely for the driver's use */ | 120 | /* rest are purely for the driver's use */ |
121 | __u8 index; | 121 | __u8 index; |
122 | struct ed *ed; | 122 | struct ed *ed; |
123 | struct td *td_hash; /* dma-->td hashtable */ | 123 | struct td *td_hash; /* dma-->td hashtable */ |
124 | struct td *next_dl_td; | 124 | struct td *next_dl_td; |
125 | struct urb *urb; | 125 | struct urb *urb; |
126 | 126 | ||
127 | dma_addr_t td_dma; /* addr of this TD */ | 127 | dma_addr_t td_dma; /* addr of this TD */ |
128 | dma_addr_t data_dma; /* addr of data it points to */ | 128 | dma_addr_t data_dma; /* addr of data it points to */ |
@@ -152,8 +152,8 @@ struct td { | |||
152 | #define TD_NOTACCESSED 0x0F | 152 | #define TD_NOTACCESSED 0x0F |
153 | 153 | ||
154 | 154 | ||
155 | /* map OHCI TD status codes (CC) to errno values */ | 155 | /* map OHCI TD status codes (CC) to errno values */ |
156 | static const int cc_to_error [16] = { | 156 | static const int cc_to_error [16] = { |
157 | /* No Error */ 0, | 157 | /* No Error */ 0, |
158 | /* CRC Error */ -EILSEQ, | 158 | /* CRC Error */ -EILSEQ, |
159 | /* Bit Stuff */ -EPROTO, | 159 | /* Bit Stuff */ -EPROTO, |
@@ -169,7 +169,7 @@ static const int cc_to_error [16] = { | |||
169 | /* BufferOver */ -ECOMM, | 169 | /* BufferOver */ -ECOMM, |
170 | /* BuffUnder */ -ENOSR, | 170 | /* BuffUnder */ -ENOSR, |
171 | /* (for HCD) */ -EALREADY, | 171 | /* (for HCD) */ -EALREADY, |
172 | /* (for HCD) */ -EALREADY | 172 | /* (for HCD) */ -EALREADY |
173 | }; | 173 | }; |
174 | 174 | ||
175 | 175 | ||
@@ -182,7 +182,7 @@ struct ohci_hcca { | |||
182 | #define NUM_INTS 32 | 182 | #define NUM_INTS 32 |
183 | __hc32 int_table [NUM_INTS]; /* periodic schedule */ | 183 | __hc32 int_table [NUM_INTS]; /* periodic schedule */ |
184 | 184 | ||
185 | /* | 185 | /* |
186 | * OHCI defines u16 frame_no, followed by u16 zero pad. | 186 | * OHCI defines u16 frame_no, followed by u16 zero pad. |
187 | * Since some processors can't do 16 bit bus accesses, | 187 | * Since some processors can't do 16 bit bus accesses, |
188 | * portable access must be a 32 bits wide. | 188 | * portable access must be a 32 bits wide. |
@@ -262,10 +262,10 @@ struct ohci_regs { | |||
262 | * HcCommandStatus (cmdstatus) register masks | 262 | * HcCommandStatus (cmdstatus) register masks |
263 | */ | 263 | */ |
264 | #define OHCI_HCR (1 << 0) /* host controller reset */ | 264 | #define OHCI_HCR (1 << 0) /* host controller reset */ |
265 | #define OHCI_CLF (1 << 1) /* control list filled */ | 265 | #define OHCI_CLF (1 << 1) /* control list filled */ |
266 | #define OHCI_BLF (1 << 2) /* bulk list filled */ | 266 | #define OHCI_BLF (1 << 2) /* bulk list filled */ |
267 | #define OHCI_OCR (1 << 3) /* ownership change request */ | 267 | #define OHCI_OCR (1 << 3) /* ownership change request */ |
268 | #define OHCI_SOC (3 << 16) /* scheduling overrun count */ | 268 | #define OHCI_SOC (3 << 16) /* scheduling overrun count */ |
269 | 269 | ||
270 | /* | 270 | /* |
271 | * masks used with interrupt registers: | 271 | * masks used with interrupt registers: |
@@ -285,20 +285,20 @@ struct ohci_regs { | |||
285 | 285 | ||
286 | 286 | ||
287 | /* OHCI ROOT HUB REGISTER MASKS */ | 287 | /* OHCI ROOT HUB REGISTER MASKS */ |
288 | 288 | ||
289 | /* roothub.portstatus [i] bits */ | 289 | /* roothub.portstatus [i] bits */ |
290 | #define RH_PS_CCS 0x00000001 /* current connect status */ | 290 | #define RH_PS_CCS 0x00000001 /* current connect status */ |
291 | #define RH_PS_PES 0x00000002 /* port enable status*/ | 291 | #define RH_PS_PES 0x00000002 /* port enable status*/ |
292 | #define RH_PS_PSS 0x00000004 /* port suspend status */ | 292 | #define RH_PS_PSS 0x00000004 /* port suspend status */ |
293 | #define RH_PS_POCI 0x00000008 /* port over current indicator */ | 293 | #define RH_PS_POCI 0x00000008 /* port over current indicator */ |
294 | #define RH_PS_PRS 0x00000010 /* port reset status */ | 294 | #define RH_PS_PRS 0x00000010 /* port reset status */ |
295 | #define RH_PS_PPS 0x00000100 /* port power status */ | 295 | #define RH_PS_PPS 0x00000100 /* port power status */ |
296 | #define RH_PS_LSDA 0x00000200 /* low speed device attached */ | 296 | #define RH_PS_LSDA 0x00000200 /* low speed device attached */ |
297 | #define RH_PS_CSC 0x00010000 /* connect status change */ | 297 | #define RH_PS_CSC 0x00010000 /* connect status change */ |
298 | #define RH_PS_PESC 0x00020000 /* port enable status change */ | 298 | #define RH_PS_PESC 0x00020000 /* port enable status change */ |
299 | #define RH_PS_PSSC 0x00040000 /* port suspend status change */ | 299 | #define RH_PS_PSSC 0x00040000 /* port suspend status change */ |
300 | #define RH_PS_OCIC 0x00080000 /* over current indicator change */ | 300 | #define RH_PS_OCIC 0x00080000 /* over current indicator change */ |
301 | #define RH_PS_PRSC 0x00100000 /* port reset status change */ | 301 | #define RH_PS_PRSC 0x00100000 /* port reset status change */ |
302 | 302 | ||
303 | /* roothub.status bits */ | 303 | /* roothub.status bits */ |
304 | #define RH_HS_LPS 0x00000001 /* local power status */ | 304 | #define RH_HS_LPS 0x00000001 /* local power status */ |
@@ -333,7 +333,7 @@ typedef struct urb_priv { | |||
333 | } urb_priv_t; | 333 | } urb_priv_t; |
334 | 334 | ||
335 | #define TD_HASH_SIZE 64 /* power'o'two */ | 335 | #define TD_HASH_SIZE 64 /* power'o'two */ |
336 | // sizeof (struct td) ~= 64 == 2^6 ... | 336 | // sizeof (struct td) ~= 64 == 2^6 ... |
337 | #define TD_HASH_FUNC(td_dma) ((td_dma ^ (td_dma >> 6)) % TD_HASH_SIZE) | 337 | #define TD_HASH_FUNC(td_dma) ((td_dma ^ (td_dma >> 6)) % TD_HASH_SIZE) |
338 | 338 | ||
339 | 339 | ||
@@ -364,11 +364,11 @@ struct ohci_hcd { | |||
364 | 364 | ||
365 | struct ed *ed_bulktail; /* last in bulk list */ | 365 | struct ed *ed_bulktail; /* last in bulk list */ |
366 | struct ed *ed_controltail; /* last in ctrl list */ | 366 | struct ed *ed_controltail; /* last in ctrl list */ |
367 | struct ed *periodic [NUM_INTS]; /* shadow int_table */ | 367 | struct ed *periodic [NUM_INTS]; /* shadow int_table */ |
368 | 368 | ||
369 | /* | 369 | /* |
370 | * OTG controllers and transceivers need software interaction; | 370 | * OTG controllers and transceivers need software interaction; |
371 | * other external transceivers should be software-transparent | 371 | * other external transceivers should be software-transparent |
372 | */ | 372 | */ |
373 | struct otg_transceiver *transceiver; | 373 | struct otg_transceiver *transceiver; |
374 | 374 | ||
@@ -385,7 +385,7 @@ struct ohci_hcd { | |||
385 | */ | 385 | */ |
386 | int num_ports; | 386 | int num_ports; |
387 | int load [NUM_INTS]; | 387 | int load [NUM_INTS]; |
388 | u32 hc_control; /* copy of hc control reg */ | 388 | u32 hc_control; /* copy of hc control reg */ |
389 | unsigned long next_statechange; /* suspend/resume */ | 389 | unsigned long next_statechange; /* suspend/resume */ |
390 | u32 fminterval; /* saved register */ | 390 | u32 fminterval; /* saved register */ |
391 | unsigned autostop:1; /* rh auto stopping/stopped */ | 391 | unsigned autostop:1; /* rh auto stopping/stopped */ |
@@ -394,8 +394,9 @@ struct ohci_hcd { | |||
394 | #define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */ | 394 | #define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */ |
395 | #define OHCI_QUIRK_SUPERIO 0x02 /* natsemi */ | 395 | #define OHCI_QUIRK_SUPERIO 0x02 /* natsemi */ |
396 | #define OHCI_QUIRK_INITRESET 0x04 /* SiS, OPTi, ... */ | 396 | #define OHCI_QUIRK_INITRESET 0x04 /* SiS, OPTi, ... */ |
397 | #define OHCI_BIG_ENDIAN 0x08 /* big endian HC */ | 397 | #define OHCI_QUIRK_BE_DESC 0x08 /* BE descriptors */ |
398 | #define OHCI_QUIRK_ZFMICRO 0x10 /* Compaq ZFMicro chipset*/ | 398 | #define OHCI_QUIRK_BE_MMIO 0x10 /* BE registers */ |
399 | #define OHCI_QUIRK_ZFMICRO 0x20 /* Compaq ZFMicro chipset*/ | ||
399 | // there are also chip quirks/bugs in init logic | 400 | // there are also chip quirks/bugs in init logic |
400 | 401 | ||
401 | }; | 402 | }; |
@@ -439,117 +440,164 @@ static inline struct usb_hcd *ohci_to_hcd (const struct ohci_hcd *ohci) | |||
439 | * a minority (notably the IBM STB04XXX and the Motorola MPC5200 | 440 | * a minority (notably the IBM STB04XXX and the Motorola MPC5200 |
440 | * processors) implement them in big endian format. | 441 | * processors) implement them in big endian format. |
441 | * | 442 | * |
443 | * In addition some more exotic implementations like the Toshiba | ||
444 | * Spider (aka SCC) cell southbridge are "mixed" endian, that is, | ||
445 | * they have a different endianness for registers vs. in-memory | ||
446 | * descriptors. | ||
447 | * | ||
442 | * This attempts to support either format at compile time without a | 448 | * This attempts to support either format at compile time without a |
443 | * runtime penalty, or both formats with the additional overhead | 449 | * runtime penalty, or both formats with the additional overhead |
444 | * of checking a flag bit. | 450 | * of checking a flag bit. |
451 | * | ||
452 | * That leads to some tricky Kconfig rules howevber. There are | ||
453 | * different defaults based on some arch/ppc platforms, though | ||
454 | * the basic rules are: | ||
455 | * | ||
456 | * Controller type Kconfig options needed | ||
457 | * --------------- ---------------------- | ||
458 | * little endian CONFIG_USB_OHCI_LITTLE_ENDIAN | ||
459 | * | ||
460 | * fully big endian CONFIG_USB_OHCI_BIG_ENDIAN_DESC _and_ | ||
461 | * CONFIG_USB_OHCI_BIG_ENDIAN_MMIO | ||
462 | * | ||
463 | * mixed endian CONFIG_USB_OHCI_LITTLE_ENDIAN _and_ | ||
464 | * CONFIG_USB_OHCI_BIG_ENDIAN_{MMIO,DESC} | ||
465 | * | ||
466 | * (If you have a mixed endian controller, you -must- also define | ||
467 | * CONFIG_USB_OHCI_LITTLE_ENDIAN or things will not work when building | ||
468 | * both your mixed endian and a fully big endian controller support in | ||
469 | * the same kernel image). | ||
445 | */ | 470 | */ |
446 | 471 | ||
447 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN | 472 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_DESC |
473 | #ifdef CONFIG_USB_OHCI_LITTLE_ENDIAN | ||
474 | #define big_endian_desc(ohci) (ohci->flags & OHCI_QUIRK_BE_DESC) | ||
475 | #else | ||
476 | #define big_endian_desc(ohci) 1 /* only big endian */ | ||
477 | #endif | ||
478 | #else | ||
479 | #define big_endian_desc(ohci) 0 /* only little endian */ | ||
480 | #endif | ||
448 | 481 | ||
482 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO | ||
449 | #ifdef CONFIG_USB_OHCI_LITTLE_ENDIAN | 483 | #ifdef CONFIG_USB_OHCI_LITTLE_ENDIAN |
450 | #define big_endian(ohci) (ohci->flags & OHCI_BIG_ENDIAN) /* either */ | 484 | #define big_endian_mmio(ohci) (ohci->flags & OHCI_QUIRK_BE_MMIO) |
485 | #else | ||
486 | #define big_endian_mmio(ohci) 1 /* only big endian */ | ||
487 | #endif | ||
451 | #else | 488 | #else |
452 | #define big_endian(ohci) 1 /* only big endian */ | 489 | #define big_endian_mmio(ohci) 0 /* only little endian */ |
453 | #endif | 490 | #endif |
454 | 491 | ||
455 | /* | 492 | /* |
456 | * Big-endian read/write functions are arch-specific. | 493 | * Big-endian read/write functions are arch-specific. |
457 | * Other arches can be added if/when they're needed. | 494 | * Other arches can be added if/when they're needed. |
495 | * | ||
496 | * REVISIT: arch/powerpc now has readl/writel_be, so the | ||
497 | * definition below can die once the STB04xxx support is | ||
498 | * finally ported over. | ||
458 | */ | 499 | */ |
459 | #if defined(CONFIG_PPC) | 500 | #if defined(CONFIG_PPC) && !defined(CONFIG_PPC_MERGE) |
460 | #define readl_be(addr) in_be32((__force unsigned *)addr) | 501 | #define readl_be(addr) in_be32((__force unsigned *)addr) |
461 | #define writel_be(val, addr) out_be32((__force unsigned *)addr, val) | 502 | #define writel_be(val, addr) out_be32((__force unsigned *)addr, val) |
462 | #endif | 503 | #endif |
463 | 504 | ||
464 | static inline unsigned int ohci_readl (const struct ohci_hcd *ohci, | 505 | static inline unsigned int _ohci_readl (const struct ohci_hcd *ohci, |
465 | __hc32 __iomem * regs) | 506 | __hc32 __iomem * regs) |
466 | { | 507 | { |
467 | return big_endian(ohci) ? readl_be (regs) : readl ((__force u32 *)regs); | 508 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO |
509 | return big_endian_mmio(ohci) ? | ||
510 | readl_be (regs) : | ||
511 | readl (regs); | ||
512 | #else | ||
513 | return readl (regs); | ||
514 | #endif | ||
468 | } | 515 | } |
469 | 516 | ||
470 | static inline void ohci_writel (const struct ohci_hcd *ohci, | 517 | static inline void _ohci_writel (const struct ohci_hcd *ohci, |
471 | const unsigned int val, __hc32 __iomem *regs) | 518 | const unsigned int val, __hc32 __iomem *regs) |
472 | { | 519 | { |
473 | big_endian(ohci) ? writel_be (val, regs) : | 520 | #ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO |
474 | writel (val, (__force u32 *)regs); | 521 | big_endian_mmio(ohci) ? |
522 | writel_be (val, regs) : | ||
523 | writel (val, regs); | ||
524 | #else | ||
525 | writel (val, regs); | ||
526 | #endif | ||
475 | } | 527 | } |
476 | 528 | ||
477 | #else /* !CONFIG_USB_OHCI_BIG_ENDIAN */ | ||
478 | |||
479 | #define big_endian(ohci) 0 /* only little endian */ | ||
480 | |||
481 | #ifdef CONFIG_ARCH_LH7A404 | 529 | #ifdef CONFIG_ARCH_LH7A404 |
482 | /* Marc Singer: at the time this code was written, the LH7A404 | 530 | /* Marc Singer: at the time this code was written, the LH7A404 |
483 | * had a problem reading the USB host registers. This | 531 | * had a problem reading the USB host registers. This |
484 | * implementation of the ohci_readl function performs the read | 532 | * implementation of the ohci_readl function performs the read |
485 | * twice as a work-around. | 533 | * twice as a work-around. |
486 | */ | 534 | */ |
487 | static inline unsigned int | 535 | #define ohci_readl(o,r) (_ohci_readl(o,r),_ohci_readl(o,r)) |
488 | ohci_readl (const struct ohci_hcd *ohci, const __hc32 *regs) | 536 | #define ohci_writel(o,v,r) _ohci_writel(o,v,r) |
489 | { | ||
490 | *(volatile __force unsigned int*) regs; | ||
491 | return *(volatile __force unsigned int*) regs; | ||
492 | } | ||
493 | #else | 537 | #else |
494 | /* Standard version of ohci_readl uses standard, platform | 538 | #define ohci_readl(o,r) _ohci_readl(o,r) |
495 | * specific implementation. */ | 539 | #define ohci_writel(o,v,r) _ohci_writel(o,v,r) |
496 | static inline unsigned int | ||
497 | ohci_readl (const struct ohci_hcd *ohci, __hc32 __iomem * regs) | ||
498 | { | ||
499 | return readl(regs); | ||
500 | } | ||
501 | #endif | 540 | #endif |
502 | 541 | ||
503 | static inline void ohci_writel (const struct ohci_hcd *ohci, | ||
504 | const unsigned int val, __hc32 __iomem *regs) | ||
505 | { | ||
506 | writel (val, regs); | ||
507 | } | ||
508 | |||
509 | #endif /* !CONFIG_USB_OHCI_BIG_ENDIAN */ | ||
510 | 542 | ||
511 | /*-------------------------------------------------------------------------*/ | 543 | /*-------------------------------------------------------------------------*/ |
512 | 544 | ||
513 | /* cpu to ohci */ | 545 | /* cpu to ohci */ |
514 | static inline __hc16 cpu_to_hc16 (const struct ohci_hcd *ohci, const u16 x) | 546 | static inline __hc16 cpu_to_hc16 (const struct ohci_hcd *ohci, const u16 x) |
515 | { | 547 | { |
516 | return big_endian(ohci) ? (__force __hc16)cpu_to_be16(x) : (__force __hc16)cpu_to_le16(x); | 548 | return big_endian_desc(ohci) ? |
549 | (__force __hc16)cpu_to_be16(x) : | ||
550 | (__force __hc16)cpu_to_le16(x); | ||
517 | } | 551 | } |
518 | 552 | ||
519 | static inline __hc16 cpu_to_hc16p (const struct ohci_hcd *ohci, const u16 *x) | 553 | static inline __hc16 cpu_to_hc16p (const struct ohci_hcd *ohci, const u16 *x) |
520 | { | 554 | { |
521 | return big_endian(ohci) ? cpu_to_be16p(x) : cpu_to_le16p(x); | 555 | return big_endian_desc(ohci) ? |
556 | cpu_to_be16p(x) : | ||
557 | cpu_to_le16p(x); | ||
522 | } | 558 | } |
523 | 559 | ||
524 | static inline __hc32 cpu_to_hc32 (const struct ohci_hcd *ohci, const u32 x) | 560 | static inline __hc32 cpu_to_hc32 (const struct ohci_hcd *ohci, const u32 x) |
525 | { | 561 | { |
526 | return big_endian(ohci) ? (__force __hc32)cpu_to_be32(x) : (__force __hc32)cpu_to_le32(x); | 562 | return big_endian_desc(ohci) ? |
563 | (__force __hc32)cpu_to_be32(x) : | ||
564 | (__force __hc32)cpu_to_le32(x); | ||
527 | } | 565 | } |
528 | 566 | ||
529 | static inline __hc32 cpu_to_hc32p (const struct ohci_hcd *ohci, const u32 *x) | 567 | static inline __hc32 cpu_to_hc32p (const struct ohci_hcd *ohci, const u32 *x) |
530 | { | 568 | { |
531 | return big_endian(ohci) ? cpu_to_be32p(x) : cpu_to_le32p(x); | 569 | return big_endian_desc(ohci) ? |
570 | cpu_to_be32p(x) : | ||
571 | cpu_to_le32p(x); | ||
532 | } | 572 | } |
533 | 573 | ||
534 | /* ohci to cpu */ | 574 | /* ohci to cpu */ |
535 | static inline u16 hc16_to_cpu (const struct ohci_hcd *ohci, const __hc16 x) | 575 | static inline u16 hc16_to_cpu (const struct ohci_hcd *ohci, const __hc16 x) |
536 | { | 576 | { |
537 | return big_endian(ohci) ? be16_to_cpu((__force __be16)x) : le16_to_cpu((__force __le16)x); | 577 | return big_endian_desc(ohci) ? |
578 | be16_to_cpu((__force __be16)x) : | ||
579 | le16_to_cpu((__force __le16)x); | ||
538 | } | 580 | } |
539 | 581 | ||
540 | static inline u16 hc16_to_cpup (const struct ohci_hcd *ohci, const __hc16 *x) | 582 | static inline u16 hc16_to_cpup (const struct ohci_hcd *ohci, const __hc16 *x) |
541 | { | 583 | { |
542 | return big_endian(ohci) ? be16_to_cpup((__force __be16 *)x) : le16_to_cpup((__force __le16 *)x); | 584 | return big_endian_desc(ohci) ? |
585 | be16_to_cpup((__force __be16 *)x) : | ||
586 | le16_to_cpup((__force __le16 *)x); | ||
543 | } | 587 | } |
544 | 588 | ||
545 | static inline u32 hc32_to_cpu (const struct ohci_hcd *ohci, const __hc32 x) | 589 | static inline u32 hc32_to_cpu (const struct ohci_hcd *ohci, const __hc32 x) |
546 | { | 590 | { |
547 | return big_endian(ohci) ? be32_to_cpu((__force __be32)x) : le32_to_cpu((__force __le32)x); | 591 | return big_endian_desc(ohci) ? |
592 | be32_to_cpu((__force __be32)x) : | ||
593 | le32_to_cpu((__force __le32)x); | ||
548 | } | 594 | } |
549 | 595 | ||
550 | static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) | 596 | static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) |
551 | { | 597 | { |
552 | return big_endian(ohci) ? be32_to_cpup((__force __be32 *)x) : le32_to_cpup((__force __le32 *)x); | 598 | return big_endian_desc(ohci) ? |
599 | be32_to_cpup((__force __be32 *)x) : | ||
600 | le32_to_cpup((__force __le32 *)x); | ||
553 | } | 601 | } |
554 | 602 | ||
555 | /*-------------------------------------------------------------------------*/ | 603 | /*-------------------------------------------------------------------------*/ |
@@ -557,6 +605,9 @@ static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) | |||
557 | /* HCCA frame number is 16 bits, but is accessed as 32 bits since not all | 605 | /* HCCA frame number is 16 bits, but is accessed as 32 bits since not all |
558 | * hardware handles 16 bit reads. That creates a different confusion on | 606 | * hardware handles 16 bit reads. That creates a different confusion on |
559 | * some big-endian SOC implementations. Same thing happens with PSW access. | 607 | * some big-endian SOC implementations. Same thing happens with PSW access. |
608 | * | ||
609 | * FIXME: Deal with that as a runtime quirk when STB03xxx is ported over | ||
610 | * to arch/powerpc | ||
560 | */ | 611 | */ |
561 | 612 | ||
562 | #ifdef CONFIG_STB03xxx | 613 | #ifdef CONFIG_STB03xxx |
@@ -568,7 +619,7 @@ static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) | |||
568 | static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) | 619 | static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) |
569 | { | 620 | { |
570 | u32 tmp; | 621 | u32 tmp; |
571 | if (big_endian(ohci)) { | 622 | if (big_endian_desc(ohci)) { |
572 | tmp = be32_to_cpup((__force __be32 *)&ohci->hcca->frame_no); | 623 | tmp = be32_to_cpup((__force __be32 *)&ohci->hcca->frame_no); |
573 | tmp >>= OHCI_BE_FRAME_NO_SHIFT; | 624 | tmp >>= OHCI_BE_FRAME_NO_SHIFT; |
574 | } else | 625 | } else |
@@ -580,7 +631,7 @@ static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) | |||
580 | static inline __hc16 *ohci_hwPSWp(const struct ohci_hcd *ohci, | 631 | static inline __hc16 *ohci_hwPSWp(const struct ohci_hcd *ohci, |
581 | const struct td *td, int index) | 632 | const struct td *td, int index) |
582 | { | 633 | { |
583 | return (__hc16 *)(big_endian(ohci) ? | 634 | return (__hc16 *)(big_endian_desc(ohci) ? |
584 | &td->hwPSW[index ^ 1] : &td->hwPSW[index]); | 635 | &td->hwPSW[index ^ 1] : &td->hwPSW[index]); |
585 | } | 636 | } |
586 | 637 | ||
@@ -598,11 +649,11 @@ static inline void disable (struct ohci_hcd *ohci) | |||
598 | } | 649 | } |
599 | 650 | ||
600 | #define FI 0x2edf /* 12000 bits per frame (-1) */ | 651 | #define FI 0x2edf /* 12000 bits per frame (-1) */ |
601 | #define FSMP(fi) (0x7fff & ((6 * ((fi) - 210)) / 7)) | 652 | #define FSMP(fi) (0x7fff & ((6 * ((fi) - 210)) / 7)) |
602 | #define FIT (1 << 31) | 653 | #define FIT (1 << 31) |
603 | #define LSTHRESH 0x628 /* lowspeed bit threshold */ | 654 | #define LSTHRESH 0x628 /* lowspeed bit threshold */ |
604 | 655 | ||
605 | static void periodic_reinit (struct ohci_hcd *ohci) | 656 | static inline void periodic_reinit (struct ohci_hcd *ohci) |
606 | { | 657 | { |
607 | u32 fi = ohci->fminterval & 0x03fff; | 658 | u32 fi = ohci->fminterval & 0x03fff; |
608 | u32 fit = ohci_readl(ohci, &ohci->regs->fminterval) & FIT; | 659 | u32 fit = ohci_readl(ohci, &ohci->regs->fminterval) & FIT; |
@@ -626,11 +677,11 @@ static void periodic_reinit (struct ohci_hcd *ohci) | |||
626 | temp = ohci_readl (hc, &hc->regs->roothub.register); \ | 677 | temp = ohci_readl (hc, &hc->regs->roothub.register); \ |
627 | temp; }) | 678 | temp; }) |
628 | 679 | ||
629 | static u32 roothub_a (struct ohci_hcd *hc) | 680 | static inline u32 roothub_a (struct ohci_hcd *hc) |
630 | { return read_roothub (hc, a, 0xfc0fe000); } | 681 | { return read_roothub (hc, a, 0xfc0fe000); } |
631 | static inline u32 roothub_b (struct ohci_hcd *hc) | 682 | static inline u32 roothub_b (struct ohci_hcd *hc) |
632 | { return ohci_readl (hc, &hc->regs->roothub.b); } | 683 | { return ohci_readl (hc, &hc->regs->roothub.b); } |
633 | static inline u32 roothub_status (struct ohci_hcd *hc) | 684 | static inline u32 roothub_status (struct ohci_hcd *hc) |
634 | { return ohci_readl (hc, &hc->regs->roothub.status); } | 685 | { return ohci_readl (hc, &hc->regs->roothub.status); } |
635 | static u32 roothub_portstatus (struct ohci_hcd *hc, int i) | 686 | static inline u32 roothub_portstatus (struct ohci_hcd *hc, int i) |
636 | { return read_roothub (hc, portstatus [i], 0xffe0fce0); } | 687 | { return read_roothub (hc, portstatus [i], 0xffe0fce0); } |
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index a9d7119e3176..a7fa0d75567d 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/moduleparam.h> | 40 | #include <linux/moduleparam.h> |
41 | #include <linux/delay.h> | 41 | #include <linux/delay.h> |
42 | #include <linux/ioport.h> | 42 | #include <linux/ioport.h> |
43 | #include <linux/pci_ids.h> | ||
43 | #include <linux/sched.h> | 44 | #include <linux/sched.h> |
44 | #include <linux/slab.h> | 45 | #include <linux/slab.h> |
45 | #include <linux/smp_lock.h> | 46 | #include <linux/smp_lock.h> |
@@ -210,15 +211,16 @@ struct u132 { | |||
210 | * these cannot be inlines because we need the structure offset!! | 211 | * these cannot be inlines because we need the structure offset!! |
211 | * Does anyone have a better way????? | 212 | * Does anyone have a better way????? |
212 | */ | 213 | */ |
214 | #define ftdi_read_pcimem(pdev, member, data) usb_ftdi_elan_read_pcimem(pdev, \ | ||
215 | offsetof(struct ohci_regs, member), 0, data); | ||
216 | #define ftdi_write_pcimem(pdev, member, data) usb_ftdi_elan_write_pcimem(pdev, \ | ||
217 | offsetof(struct ohci_regs, member), 0, data); | ||
213 | #define u132_read_pcimem(u132, member, data) \ | 218 | #define u132_read_pcimem(u132, member, data) \ |
214 | usb_ftdi_elan_read_pcimem(u132->platform_dev, offsetof(struct \ | 219 | usb_ftdi_elan_read_pcimem(u132->platform_dev, offsetof(struct \ |
215 | ohci_regs, member), 0, data); | 220 | ohci_regs, member), 0, data); |
216 | #define u132_write_pcimem(u132, member, data) \ | 221 | #define u132_write_pcimem(u132, member, data) \ |
217 | usb_ftdi_elan_write_pcimem(u132->platform_dev, offsetof(struct \ | 222 | usb_ftdi_elan_write_pcimem(u132->platform_dev, offsetof(struct \ |
218 | ohci_regs, member), 0, data); | 223 | ohci_regs, member), 0, data); |
219 | #define u132_write_pcimem_byte(u132, member, data) \ | ||
220 | usb_ftdi_elan_write_pcimem(u132->platform_dev, offsetof(struct \ | ||
221 | ohci_regs, member), 0x0e, data); | ||
222 | static inline struct u132 *udev_to_u132(struct u132_udev *udev) | 224 | static inline struct u132 *udev_to_u132(struct u132_udev *udev) |
223 | { | 225 | { |
224 | u8 udev_number = udev->udev_number; | 226 | u8 udev_number = udev->udev_number; |
@@ -1574,59 +1576,12 @@ static char *hcfs2string(int state) | |||
1574 | return "?"; | 1576 | return "?"; |
1575 | } | 1577 | } |
1576 | 1578 | ||
1577 | static int u132_usb_reset(struct u132 *u132) | ||
1578 | { | ||
1579 | int retval; | ||
1580 | retval = u132_read_pcimem(u132, control, &u132->hc_control); | ||
1581 | if (retval) | ||
1582 | return retval; | ||
1583 | u132->hc_control &= OHCI_CTRL_RWC; | ||
1584 | retval = u132_write_pcimem(u132, control, u132->hc_control); | ||
1585 | if (retval) | ||
1586 | return retval; | ||
1587 | return 0; | ||
1588 | } | ||
1589 | |||
1590 | static int u132_init(struct u132 *u132) | 1579 | static int u132_init(struct u132 *u132) |
1591 | { | 1580 | { |
1592 | int retval; | 1581 | int retval; |
1593 | u32 control; | 1582 | u32 control; |
1594 | u132_disable(u132); | 1583 | u132_disable(u132); |
1595 | u132->next_statechange = | 1584 | u132->next_statechange = jiffies; |
1596 | jiffies; /* SMM owns the HC? not for long! */ { | ||
1597 | u32 control; | ||
1598 | retval = u132_read_pcimem(u132, control, &control); | ||
1599 | if (retval) | ||
1600 | return retval; | ||
1601 | if (control & OHCI_CTRL_IR) { | ||
1602 | u32 temp = 50; | ||
1603 | retval = u132_write_pcimem(u132, intrenable, | ||
1604 | OHCI_INTR_OC); | ||
1605 | if (retval) | ||
1606 | return retval; | ||
1607 | retval = u132_write_pcimem_byte(u132, cmdstatus, | ||
1608 | OHCI_OCR); | ||
1609 | if (retval) | ||
1610 | return retval; | ||
1611 | check:{ | ||
1612 | retval = u132_read_pcimem(u132, control, | ||
1613 | &control); | ||
1614 | if (retval) | ||
1615 | return retval; | ||
1616 | } | ||
1617 | if (control & OHCI_CTRL_IR) { | ||
1618 | msleep(10); | ||
1619 | if (--temp == 0) { | ||
1620 | dev_err(&u132->platform_dev->dev, "USB " | ||
1621 | "HC takeover failed!(BIOS/SMM b" | ||
1622 | "ug) control=%08X\n", control); | ||
1623 | return -EBUSY; | ||
1624 | } | ||
1625 | goto check; | ||
1626 | } | ||
1627 | u132_usb_reset(u132); | ||
1628 | } | ||
1629 | } | ||
1630 | retval = u132_write_pcimem(u132, intrdisable, OHCI_INTR_MIE); | 1585 | retval = u132_write_pcimem(u132, intrdisable, OHCI_INTR_MIE); |
1631 | if (retval) | 1586 | if (retval) |
1632 | return retval; | 1587 | return retval; |
@@ -1725,7 +1680,7 @@ static int u132_run(struct u132 *u132) | |||
1725 | retry:retval = u132_read_pcimem(u132, cmdstatus, &status); | 1680 | retry:retval = u132_read_pcimem(u132, cmdstatus, &status); |
1726 | if (retval) | 1681 | if (retval) |
1727 | return retval; | 1682 | return retval; |
1728 | retval = u132_write_pcimem_byte(u132, cmdstatus, OHCI_HCR); | 1683 | retval = u132_write_pcimem(u132, cmdstatus, OHCI_HCR); |
1729 | if (retval) | 1684 | if (retval) |
1730 | return retval; | 1685 | return retval; |
1731 | extra:{ | 1686 | extra:{ |
@@ -1782,7 +1737,7 @@ static int u132_run(struct u132 *u132) | |||
1782 | retval = u132_write_pcimem(u132, control, u132->hc_control); | 1737 | retval = u132_write_pcimem(u132, control, u132->hc_control); |
1783 | if (retval) | 1738 | if (retval) |
1784 | return retval; | 1739 | return retval; |
1785 | retval = u132_write_pcimem_byte(u132, cmdstatus, OHCI_BLF); | 1740 | retval = u132_write_pcimem(u132, cmdstatus, OHCI_BLF); |
1786 | if (retval) | 1741 | if (retval) |
1787 | return retval; | 1742 | return retval; |
1788 | retval = u132_read_pcimem(u132, cmdstatus, &cmdstatus); | 1743 | retval = u132_read_pcimem(u132, cmdstatus, &cmdstatus); |
@@ -1839,8 +1794,8 @@ static void u132_hcd_stop(struct usb_hcd *hcd) | |||
1839 | { | 1794 | { |
1840 | struct u132 *u132 = hcd_to_u132(hcd); | 1795 | struct u132 *u132 = hcd_to_u132(hcd); |
1841 | if (u132->going > 1) { | 1796 | if (u132->going > 1) { |
1842 | dev_err(&u132->platform_dev->dev, "device has been removed %d\n" | 1797 | dev_err(&u132->platform_dev->dev, "u132 device %p(hcd=%p) has b" |
1843 | , u132->going); | 1798 | "een removed %d\n", u132, hcd, u132->going); |
1844 | } else if (u132->going > 0) { | 1799 | } else if (u132->going > 0) { |
1845 | dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov" | 1800 | dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov" |
1846 | "ed\n", hcd); | 1801 | "ed\n", hcd); |
@@ -2545,8 +2500,9 @@ static void u132_endpoint_disable(struct usb_hcd *hcd, | |||
2545 | { | 2500 | { |
2546 | struct u132 *u132 = hcd_to_u132(hcd); | 2501 | struct u132 *u132 = hcd_to_u132(hcd); |
2547 | if (u132->going > 2) { | 2502 | if (u132->going > 2) { |
2548 | dev_err(&u132->platform_dev->dev, "device has been removed %d\n" | 2503 | dev_err(&u132->platform_dev->dev, "u132 device %p(hcd=%p hep=%p" |
2549 | , u132->going); | 2504 | ") has been removed %d\n", u132, hcd, hep, |
2505 | u132->going); | ||
2550 | } else { | 2506 | } else { |
2551 | struct u132_endp *endp = hep->hcpriv; | 2507 | struct u132_endp *endp = hep->hcpriv; |
2552 | if (endp) | 2508 | if (endp) |
@@ -2790,7 +2746,6 @@ static int u132_hub_status_data(struct usb_hcd *hcd, char *buf) | |||
2790 | } else if (u132->going > 0) { | 2746 | } else if (u132->going > 0) { |
2791 | dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov" | 2747 | dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov" |
2792 | "ed\n", hcd); | 2748 | "ed\n", hcd); |
2793 | dump_stack(); | ||
2794 | return -ESHUTDOWN; | 2749 | return -ESHUTDOWN; |
2795 | } else { | 2750 | } else { |
2796 | int i, changed = 0, length = 1; | 2751 | int i, changed = 0, length = 1; |
@@ -3034,12 +2989,15 @@ static int __devexit u132_remove(struct platform_device *pdev) | |||
3034 | struct usb_hcd *hcd = platform_get_drvdata(pdev); | 2989 | struct usb_hcd *hcd = platform_get_drvdata(pdev); |
3035 | if (hcd) { | 2990 | if (hcd) { |
3036 | struct u132 *u132 = hcd_to_u132(hcd); | 2991 | struct u132 *u132 = hcd_to_u132(hcd); |
3037 | dump_stack(); | ||
3038 | if (u132->going++ > 1) { | 2992 | if (u132->going++ > 1) { |
2993 | dev_err(&u132->platform_dev->dev, "already being remove" | ||
2994 | "d\n"); | ||
3039 | return -ENODEV; | 2995 | return -ENODEV; |
3040 | } else { | 2996 | } else { |
3041 | int rings = MAX_U132_RINGS; | 2997 | int rings = MAX_U132_RINGS; |
3042 | int endps = MAX_U132_ENDPS; | 2998 | int endps = MAX_U132_ENDPS; |
2999 | dev_err(&u132->platform_dev->dev, "removing device u132" | ||
3000 | ".%d\n", u132->sequence_num); | ||
3043 | msleep(100); | 3001 | msleep(100); |
3044 | down(&u132->sw_lock); | 3002 | down(&u132->sw_lock); |
3045 | u132_monitor_cancel_work(u132); | 3003 | u132_monitor_cancel_work(u132); |
@@ -3121,10 +3079,24 @@ static void u132_initialise(struct u132 *u132, struct platform_device *pdev) | |||
3121 | static int __devinit u132_probe(struct platform_device *pdev) | 3079 | static int __devinit u132_probe(struct platform_device *pdev) |
3122 | { | 3080 | { |
3123 | struct usb_hcd *hcd; | 3081 | struct usb_hcd *hcd; |
3082 | int retval; | ||
3083 | u32 control; | ||
3084 | u32 rh_a = -1; | ||
3085 | u32 num_ports; | ||
3124 | msleep(100); | 3086 | msleep(100); |
3125 | if (u132_exiting > 0) { | 3087 | if (u132_exiting > 0) { |
3126 | return -ENODEV; | 3088 | return -ENODEV; |
3127 | } /* refuse to confuse usbcore */ | 3089 | } |
3090 | retval = ftdi_write_pcimem(pdev, intrdisable, OHCI_INTR_MIE); | ||
3091 | if (retval) | ||
3092 | return retval; | ||
3093 | retval = ftdi_read_pcimem(pdev, control, &control); | ||
3094 | if (retval) | ||
3095 | return retval; | ||
3096 | retval = ftdi_read_pcimem(pdev, roothub.a, &rh_a); | ||
3097 | if (retval) | ||
3098 | return retval; | ||
3099 | num_ports = rh_a & RH_A_NDP; /* refuse to confuse usbcore */ | ||
3128 | if (pdev->dev.dma_mask) { | 3100 | if (pdev->dev.dma_mask) { |
3129 | return -EINVAL; | 3101 | return -EINVAL; |
3130 | } | 3102 | } |
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index e345f15b7d87..5d6c06bc4524 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c | |||
@@ -168,9 +168,13 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) | |||
168 | space, "", qh, qtype, | 168 | space, "", qh, qtype, |
169 | le32_to_cpu(qh->link), le32_to_cpu(element)); | 169 | le32_to_cpu(qh->link), le32_to_cpu(element)); |
170 | if (qh->type == USB_ENDPOINT_XFER_ISOC) | 170 | if (qh->type == USB_ENDPOINT_XFER_ISOC) |
171 | out += sprintf(out, "%*s period %d frame %x desc [%p]\n", | 171 | out += sprintf(out, "%*s period %d phase %d load %d us, " |
172 | space, "", qh->period, qh->iso_frame, | 172 | "frame %x desc [%p]\n", |
173 | qh->iso_packet_desc); | 173 | space, "", qh->period, qh->phase, qh->load, |
174 | qh->iso_frame, qh->iso_packet_desc); | ||
175 | else if (qh->type == USB_ENDPOINT_XFER_INT) | ||
176 | out += sprintf(out, "%*s period %d phase %d load %d us\n", | ||
177 | space, "", qh->period, qh->phase, qh->load); | ||
174 | 178 | ||
175 | if (element & UHCI_PTR_QH) | 179 | if (element & UHCI_PTR_QH) |
176 | out += sprintf(out, "%*s Element points to QH (bug?)\n", space, ""); | 180 | out += sprintf(out, "%*s Element points to QH (bug?)\n", space, ""); |
@@ -208,7 +212,7 @@ static int uhci_show_qh(struct uhci_qh *qh, char *buf, int len, int space) | |||
208 | space, "", nurbs); | 212 | space, "", nurbs); |
209 | } | 213 | } |
210 | 214 | ||
211 | if (qh->udev) { | 215 | if (qh->dummy_td) { |
212 | out += sprintf(out, "%*s Dummy TD\n", space, ""); | 216 | out += sprintf(out, "%*s Dummy TD\n", space, ""); |
213 | out += uhci_show_td(qh->dummy_td, out, len - (out - buf), 0); | 217 | out += uhci_show_td(qh->dummy_td, out, len - (out - buf), 0); |
214 | } | 218 | } |
@@ -347,31 +351,80 @@ static int uhci_sprint_schedule(struct uhci_hcd *uhci, char *buf, int len) | |||
347 | struct uhci_qh *qh; | 351 | struct uhci_qh *qh; |
348 | struct uhci_td *td; | 352 | struct uhci_td *td; |
349 | struct list_head *tmp, *head; | 353 | struct list_head *tmp, *head; |
354 | int nframes, nerrs; | ||
350 | 355 | ||
351 | out += uhci_show_root_hub_state(uhci, out, len - (out - buf)); | 356 | out += uhci_show_root_hub_state(uhci, out, len - (out - buf)); |
352 | out += sprintf(out, "HC status\n"); | 357 | out += sprintf(out, "HC status\n"); |
353 | out += uhci_show_status(uhci, out, len - (out - buf)); | 358 | out += uhci_show_status(uhci, out, len - (out - buf)); |
359 | |||
360 | out += sprintf(out, "Periodic load table\n"); | ||
361 | for (i = 0; i < MAX_PHASE; ++i) { | ||
362 | out += sprintf(out, "\t%d", uhci->load[i]); | ||
363 | if (i % 8 == 7) | ||
364 | *out++ = '\n'; | ||
365 | } | ||
366 | out += sprintf(out, "Total: %d, #INT: %d, #ISO: %d\n", | ||
367 | uhci->total_load, | ||
368 | uhci_to_hcd(uhci)->self.bandwidth_int_reqs, | ||
369 | uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs); | ||
354 | if (debug <= 1) | 370 | if (debug <= 1) |
355 | return out - buf; | 371 | return out - buf; |
356 | 372 | ||
357 | out += sprintf(out, "Frame List\n"); | 373 | out += sprintf(out, "Frame List\n"); |
374 | nframes = 10; | ||
375 | nerrs = 0; | ||
358 | for (i = 0; i < UHCI_NUMFRAMES; ++i) { | 376 | for (i = 0; i < UHCI_NUMFRAMES; ++i) { |
377 | __le32 link, qh_dma; | ||
378 | |||
379 | j = 0; | ||
359 | td = uhci->frame_cpu[i]; | 380 | td = uhci->frame_cpu[i]; |
381 | link = uhci->frame[i]; | ||
360 | if (!td) | 382 | if (!td) |
361 | continue; | 383 | goto check_link; |
362 | 384 | ||
363 | out += sprintf(out, "- Frame %d\n", i); \ | 385 | if (nframes > 0) { |
364 | if (td->dma_handle != (dma_addr_t)uhci->frame[i]) | 386 | out += sprintf(out, "- Frame %d -> (%08x)\n", |
365 | out += sprintf(out, " frame list does not match td->dma_handle!\n"); | 387 | i, le32_to_cpu(link)); |
388 | j = 1; | ||
389 | } | ||
366 | 390 | ||
367 | head = &td->fl_list; | 391 | head = &td->fl_list; |
368 | tmp = head; | 392 | tmp = head; |
369 | do { | 393 | do { |
370 | td = list_entry(tmp, struct uhci_td, fl_list); | 394 | td = list_entry(tmp, struct uhci_td, fl_list); |
371 | tmp = tmp->next; | 395 | tmp = tmp->next; |
372 | out += uhci_show_td(td, out, len - (out - buf), 4); | 396 | if (cpu_to_le32(td->dma_handle) != link) { |
397 | if (nframes > 0) | ||
398 | out += sprintf(out, " link does " | ||
399 | "not match list entry!\n"); | ||
400 | else | ||
401 | ++nerrs; | ||
402 | } | ||
403 | if (nframes > 0) | ||
404 | out += uhci_show_td(td, out, | ||
405 | len - (out - buf), 4); | ||
406 | link = td->link; | ||
373 | } while (tmp != head); | 407 | } while (tmp != head); |
408 | |||
409 | check_link: | ||
410 | qh_dma = uhci_frame_skel_link(uhci, i); | ||
411 | if (link != qh_dma) { | ||
412 | if (nframes > 0) { | ||
413 | if (!j) { | ||
414 | out += sprintf(out, | ||
415 | "- Frame %d -> (%08x)\n", | ||
416 | i, le32_to_cpu(link)); | ||
417 | j = 1; | ||
418 | } | ||
419 | out += sprintf(out, " link does not match " | ||
420 | "QH (%08x)!\n", le32_to_cpu(qh_dma)); | ||
421 | } else | ||
422 | ++nerrs; | ||
423 | } | ||
424 | nframes -= j; | ||
374 | } | 425 | } |
426 | if (nerrs > 0) | ||
427 | out += sprintf(out, "Skipped %d bad links\n", nerrs); | ||
375 | 428 | ||
376 | out += sprintf(out, "Skeleton QHs\n"); | 429 | out += sprintf(out, "Skeleton QHs\n"); |
377 | 430 | ||
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index e87692c31be4..49b9d390b95f 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -60,6 +60,11 @@ Randy Dunlap, Georg Acher, Deti Fliegl, Thomas Sailer, Roman Weissgaerber, \ | |||
60 | Alan Stern" | 60 | Alan Stern" |
61 | #define DRIVER_DESC "USB Universal Host Controller Interface driver" | 61 | #define DRIVER_DESC "USB Universal Host Controller Interface driver" |
62 | 62 | ||
63 | /* for flakey hardware, ignore overcurrent indicators */ | ||
64 | static int ignore_oc; | ||
65 | module_param(ignore_oc, bool, S_IRUGO); | ||
66 | MODULE_PARM_DESC(ignore_oc, "ignore hardware overcurrent indications"); | ||
67 | |||
63 | /* | 68 | /* |
64 | * debug = 0, no debugging messages | 69 | * debug = 0, no debugging messages |
65 | * debug = 1, dump failed URBs except for stalls | 70 | * debug = 1, dump failed URBs except for stalls |
@@ -87,6 +92,34 @@ static void suspend_rh(struct uhci_hcd *uhci, enum uhci_rh_state new_state); | |||
87 | static void wakeup_rh(struct uhci_hcd *uhci); | 92 | static void wakeup_rh(struct uhci_hcd *uhci); |
88 | static void uhci_get_current_frame_number(struct uhci_hcd *uhci); | 93 | static void uhci_get_current_frame_number(struct uhci_hcd *uhci); |
89 | 94 | ||
95 | /* | ||
96 | * Calculate the link pointer DMA value for the first Skeleton QH in a frame. | ||
97 | */ | ||
98 | static __le32 uhci_frame_skel_link(struct uhci_hcd *uhci, int frame) | ||
99 | { | ||
100 | int skelnum; | ||
101 | |||
102 | /* | ||
103 | * The interrupt queues will be interleaved as evenly as possible. | ||
104 | * There's not much to be done about period-1 interrupts; they have | ||
105 | * to occur in every frame. But we can schedule period-2 interrupts | ||
106 | * in odd-numbered frames, period-4 interrupts in frames congruent | ||
107 | * to 2 (mod 4), and so on. This way each frame only has two | ||
108 | * interrupt QHs, which will help spread out bandwidth utilization. | ||
109 | * | ||
110 | * ffs (Find First bit Set) does exactly what we need: | ||
111 | * 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[8], | ||
112 | * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[7], etc. | ||
113 | * ffs >= 7 => not on any high-period queue, so use | ||
114 | * skel_int1_qh = skelqh[9]. | ||
115 | * Add in UHCI_NUMFRAMES to insure at least one bit is set. | ||
116 | */ | ||
117 | skelnum = 8 - (int) __ffs(frame | UHCI_NUMFRAMES); | ||
118 | if (skelnum <= 1) | ||
119 | skelnum = 9; | ||
120 | return UHCI_PTR_QH | cpu_to_le32(uhci->skelqh[skelnum]->dma_handle); | ||
121 | } | ||
122 | |||
90 | #include "uhci-debug.c" | 123 | #include "uhci-debug.c" |
91 | #include "uhci-q.c" | 124 | #include "uhci-q.c" |
92 | #include "uhci-hub.c" | 125 | #include "uhci-hub.c" |
@@ -169,6 +202,11 @@ static int resume_detect_interrupts_are_broken(struct uhci_hcd *uhci) | |||
169 | { | 202 | { |
170 | int port; | 203 | int port; |
171 | 204 | ||
205 | /* If we have to ignore overcurrent events then almost by definition | ||
206 | * we can't depend on resume-detect interrupts. */ | ||
207 | if (ignore_oc) | ||
208 | return 1; | ||
209 | |||
172 | switch (to_pci_dev(uhci_dev(uhci))->vendor) { | 210 | switch (to_pci_dev(uhci_dev(uhci))->vendor) { |
173 | default: | 211 | default: |
174 | break; | 212 | break; |
@@ -199,24 +237,16 @@ static int resume_detect_interrupts_are_broken(struct uhci_hcd *uhci) | |||
199 | 237 | ||
200 | static int remote_wakeup_is_broken(struct uhci_hcd *uhci) | 238 | static int remote_wakeup_is_broken(struct uhci_hcd *uhci) |
201 | { | 239 | { |
202 | static struct dmi_system_id broken_wakeup_table[] = { | ||
203 | { | ||
204 | .ident = "Asus A7V8X", | ||
205 | .matches = { | ||
206 | DMI_MATCH(DMI_BOARD_VENDOR, "ASUSTeK"), | ||
207 | DMI_MATCH(DMI_BOARD_NAME, "A7V8X"), | ||
208 | DMI_MATCH(DMI_BOARD_VERSION, "REV 1.xx"), | ||
209 | } | ||
210 | }, | ||
211 | { } | ||
212 | }; | ||
213 | int port; | 240 | int port; |
241 | char *sys_info; | ||
242 | static char bad_Asus_board[] = "A7V8X"; | ||
214 | 243 | ||
215 | /* One of Asus's motherboards has a bug which causes it to | 244 | /* One of Asus's motherboards has a bug which causes it to |
216 | * wake up immediately from suspend-to-RAM if any of the ports | 245 | * wake up immediately from suspend-to-RAM if any of the ports |
217 | * are connected. In such cases we will not set EGSM. | 246 | * are connected. In such cases we will not set EGSM. |
218 | */ | 247 | */ |
219 | if (dmi_check_system(broken_wakeup_table)) { | 248 | sys_info = dmi_get_system_info(DMI_BOARD_NAME); |
249 | if (sys_info && !strcmp(sys_info, bad_Asus_board)) { | ||
220 | for (port = 0; port < uhci->rh_numports; ++port) { | 250 | for (port = 0; port < uhci->rh_numports; ++port) { |
221 | if (inw(uhci->io_addr + USBPORTSC1 + port * 2) & | 251 | if (inw(uhci->io_addr + USBPORTSC1 + port * 2) & |
222 | USBPORTSC_CCS) | 252 | USBPORTSC_CCS) |
@@ -255,7 +285,9 @@ __acquires(uhci->lock) | |||
255 | int_enable = USBINTR_RESUME; | 285 | int_enable = USBINTR_RESUME; |
256 | if (remote_wakeup_is_broken(uhci)) | 286 | if (remote_wakeup_is_broken(uhci)) |
257 | egsm_enable = 0; | 287 | egsm_enable = 0; |
258 | if (resume_detect_interrupts_are_broken(uhci) || !egsm_enable) | 288 | if (resume_detect_interrupts_are_broken(uhci) || !egsm_enable || |
289 | !device_may_wakeup( | ||
290 | &uhci_to_hcd(uhci)->self.root_hub->dev)) | ||
259 | uhci->working_RD = int_enable = 0; | 291 | uhci->working_RD = int_enable = 0; |
260 | 292 | ||
261 | outw(int_enable, uhci->io_addr + USBINTR); | 293 | outw(int_enable, uhci->io_addr + USBINTR); |
@@ -627,32 +659,11 @@ static int uhci_start(struct usb_hcd *hcd) | |||
627 | /* | 659 | /* |
628 | * Fill the frame list: make all entries point to the proper | 660 | * Fill the frame list: make all entries point to the proper |
629 | * interrupt queue. | 661 | * interrupt queue. |
630 | * | ||
631 | * The interrupt queues will be interleaved as evenly as possible. | ||
632 | * There's not much to be done about period-1 interrupts; they have | ||
633 | * to occur in every frame. But we can schedule period-2 interrupts | ||
634 | * in odd-numbered frames, period-4 interrupts in frames congruent | ||
635 | * to 2 (mod 4), and so on. This way each frame only has two | ||
636 | * interrupt QHs, which will help spread out bandwidth utilization. | ||
637 | */ | 662 | */ |
638 | for (i = 0; i < UHCI_NUMFRAMES; i++) { | 663 | for (i = 0; i < UHCI_NUMFRAMES; i++) { |
639 | int irq; | ||
640 | |||
641 | /* | ||
642 | * ffs (Find First bit Set) does exactly what we need: | ||
643 | * 1,3,5,... => ffs = 0 => use skel_int2_qh = skelqh[8], | ||
644 | * 2,6,10,... => ffs = 1 => use skel_int4_qh = skelqh[7], etc. | ||
645 | * ffs >= 7 => not on any high-period queue, so use | ||
646 | * skel_int1_qh = skelqh[9]. | ||
647 | * Add UHCI_NUMFRAMES to insure at least one bit is set. | ||
648 | */ | ||
649 | irq = 8 - (int) __ffs(i + UHCI_NUMFRAMES); | ||
650 | if (irq <= 1) | ||
651 | irq = 9; | ||
652 | 664 | ||
653 | /* Only place we don't use the frame list routines */ | 665 | /* Only place we don't use the frame list routines */ |
654 | uhci->frame[i] = UHCI_PTR_QH | | 666 | uhci->frame[i] = uhci_frame_skel_link(uhci, i); |
655 | cpu_to_le32(uhci->skelqh[irq]->dma_handle); | ||
656 | } | 667 | } |
657 | 668 | ||
658 | /* | 669 | /* |
@@ -921,7 +932,8 @@ static int __init uhci_hcd_init(void) | |||
921 | { | 932 | { |
922 | int retval = -ENOMEM; | 933 | int retval = -ENOMEM; |
923 | 934 | ||
924 | printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION "\n"); | 935 | printk(KERN_INFO DRIVER_DESC " " DRIVER_VERSION "%s\n", |
936 | ignore_oc ? ", overcurrent ignored" : ""); | ||
925 | 937 | ||
926 | if (usb_disabled()) | 938 | if (usb_disabled()) |
927 | return -ENODEV; | 939 | return -ENODEV; |
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 108e3de2dc26..74469b5bcb61 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h | |||
@@ -83,6 +83,7 @@ | |||
83 | #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ | 83 | #define UHCI_MAX_SOF_NUMBER 2047 /* in an SOF packet */ |
84 | #define CAN_SCHEDULE_FRAMES 1000 /* how far in the future frames | 84 | #define CAN_SCHEDULE_FRAMES 1000 /* how far in the future frames |
85 | * can be scheduled */ | 85 | * can be scheduled */ |
86 | #define MAX_PHASE 32 /* Periodic scheduling length */ | ||
86 | 87 | ||
87 | /* When no queues need Full-Speed Bandwidth Reclamation, | 88 | /* When no queues need Full-Speed Bandwidth Reclamation, |
88 | * delay this long before turning FSBR off */ | 89 | * delay this long before turning FSBR off */ |
@@ -141,6 +142,8 @@ struct uhci_qh { | |||
141 | unsigned long advance_jiffies; /* Time of last queue advance */ | 142 | unsigned long advance_jiffies; /* Time of last queue advance */ |
142 | unsigned int unlink_frame; /* When the QH was unlinked */ | 143 | unsigned int unlink_frame; /* When the QH was unlinked */ |
143 | unsigned int period; /* For Interrupt and Isochronous QHs */ | 144 | unsigned int period; /* For Interrupt and Isochronous QHs */ |
145 | short phase; /* Between 0 and period-1 */ | ||
146 | short load; /* Periodic time requirement, in us */ | ||
144 | unsigned int iso_frame; /* Frame # for iso_packet_desc */ | 147 | unsigned int iso_frame; /* Frame # for iso_packet_desc */ |
145 | int iso_status; /* Status for Isochronous URBs */ | 148 | int iso_status; /* Status for Isochronous URBs */ |
146 | 149 | ||
@@ -153,6 +156,8 @@ struct uhci_qh { | |||
153 | unsigned int needs_fixup:1; /* Must fix the TD toggle values */ | 156 | unsigned int needs_fixup:1; /* Must fix the TD toggle values */ |
154 | unsigned int is_stopped:1; /* Queue was stopped by error/unlink */ | 157 | unsigned int is_stopped:1; /* Queue was stopped by error/unlink */ |
155 | unsigned int wait_expired:1; /* QH_WAIT_TIMEOUT has expired */ | 158 | unsigned int wait_expired:1; /* QH_WAIT_TIMEOUT has expired */ |
159 | unsigned int bandwidth_reserved:1; /* Periodic bandwidth has | ||
160 | * been allocated */ | ||
156 | } __attribute__((aligned(16))); | 161 | } __attribute__((aligned(16))); |
157 | 162 | ||
158 | /* | 163 | /* |
@@ -414,6 +419,9 @@ struct uhci_hcd { | |||
414 | 419 | ||
415 | wait_queue_head_t waitqh; /* endpoint_disable waiters */ | 420 | wait_queue_head_t waitqh; /* endpoint_disable waiters */ |
416 | int num_waiting; /* Number of waiters */ | 421 | int num_waiting; /* Number of waiters */ |
422 | |||
423 | int total_load; /* Sum of array values */ | ||
424 | short load[MAX_PHASE]; /* Periodic allocations */ | ||
417 | }; | 425 | }; |
418 | 426 | ||
419 | /* Convert between a usb_hcd pointer and the corresponding uhci_hcd */ | 427 | /* Convert between a usb_hcd pointer and the corresponding uhci_hcd */ |
diff --git a/drivers/usb/host/uhci-hub.c b/drivers/usb/host/uhci-hub.c index f8347f1a10b6..bacc25c53ba3 100644 --- a/drivers/usb/host/uhci-hub.c +++ b/drivers/usb/host/uhci-hub.c | |||
@@ -52,10 +52,20 @@ static int any_ports_active(struct uhci_hcd *uhci) | |||
52 | static inline int get_hub_status_data(struct uhci_hcd *uhci, char *buf) | 52 | static inline int get_hub_status_data(struct uhci_hcd *uhci, char *buf) |
53 | { | 53 | { |
54 | int port; | 54 | int port; |
55 | int mask = RWC_BITS; | ||
56 | |||
57 | /* Some boards (both VIA and Intel apparently) report bogus | ||
58 | * overcurrent indications, causing massive log spam unless | ||
59 | * we completely ignore them. This doesn't seem to be a problem | ||
60 | * with the chipset so much as with the way it is connected on | ||
61 | * the motherboard; if the overcurrent input is left to float | ||
62 | * then it may constantly register false positives. */ | ||
63 | if (ignore_oc) | ||
64 | mask &= ~USBPORTSC_OCC; | ||
55 | 65 | ||
56 | *buf = 0; | 66 | *buf = 0; |
57 | for (port = 0; port < uhci->rh_numports; ++port) { | 67 | for (port = 0; port < uhci->rh_numports; ++port) { |
58 | if ((inw(uhci->io_addr + USBPORTSC1 + port * 2) & RWC_BITS) || | 68 | if ((inw(uhci->io_addr + USBPORTSC1 + port * 2) & mask) || |
59 | test_bit(port, &uhci->port_c_suspend)) | 69 | test_bit(port, &uhci->port_c_suspend)) |
60 | *buf |= (1 << (port + 1)); | 70 | *buf |= (1 << (port + 1)); |
61 | } | 71 | } |
@@ -263,7 +273,7 @@ static int uhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
263 | wPortChange |= USB_PORT_STAT_C_CONNECTION; | 273 | wPortChange |= USB_PORT_STAT_C_CONNECTION; |
264 | if (status & USBPORTSC_PEC) | 274 | if (status & USBPORTSC_PEC) |
265 | wPortChange |= USB_PORT_STAT_C_ENABLE; | 275 | wPortChange |= USB_PORT_STAT_C_ENABLE; |
266 | if (status & USBPORTSC_OCC) | 276 | if ((status & USBPORTSC_OCC) && !ignore_oc) |
267 | wPortChange |= USB_PORT_STAT_C_OVERCURRENT; | 277 | wPortChange |= USB_PORT_STAT_C_OVERCURRENT; |
268 | 278 | ||
269 | if (test_bit(port, &uhci->port_c_suspend)) { | 279 | if (test_bit(port, &uhci->port_c_suspend)) { |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 30b88459ac7d..2cbb239e63f8 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
@@ -248,16 +248,26 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci, | |||
248 | INIT_LIST_HEAD(&qh->node); | 248 | INIT_LIST_HEAD(&qh->node); |
249 | 249 | ||
250 | if (udev) { /* Normal QH */ | 250 | if (udev) { /* Normal QH */ |
251 | qh->dummy_td = uhci_alloc_td(uhci); | 251 | qh->type = hep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; |
252 | if (!qh->dummy_td) { | 252 | if (qh->type != USB_ENDPOINT_XFER_ISOC) { |
253 | dma_pool_free(uhci->qh_pool, qh, dma_handle); | 253 | qh->dummy_td = uhci_alloc_td(uhci); |
254 | return NULL; | 254 | if (!qh->dummy_td) { |
255 | dma_pool_free(uhci->qh_pool, qh, dma_handle); | ||
256 | return NULL; | ||
257 | } | ||
255 | } | 258 | } |
256 | qh->state = QH_STATE_IDLE; | 259 | qh->state = QH_STATE_IDLE; |
257 | qh->hep = hep; | 260 | qh->hep = hep; |
258 | qh->udev = udev; | 261 | qh->udev = udev; |
259 | hep->hcpriv = qh; | 262 | hep->hcpriv = qh; |
260 | qh->type = hep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; | 263 | |
264 | if (qh->type == USB_ENDPOINT_XFER_INT || | ||
265 | qh->type == USB_ENDPOINT_XFER_ISOC) | ||
266 | qh->load = usb_calc_bus_time(udev->speed, | ||
267 | usb_endpoint_dir_in(&hep->desc), | ||
268 | qh->type == USB_ENDPOINT_XFER_ISOC, | ||
269 | le16_to_cpu(hep->desc.wMaxPacketSize)) | ||
270 | / 1000 + 1; | ||
261 | 271 | ||
262 | } else { /* Skeleton QH */ | 272 | } else { /* Skeleton QH */ |
263 | qh->state = QH_STATE_ACTIVE; | 273 | qh->state = QH_STATE_ACTIVE; |
@@ -275,7 +285,8 @@ static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
275 | list_del(&qh->node); | 285 | list_del(&qh->node); |
276 | if (qh->udev) { | 286 | if (qh->udev) { |
277 | qh->hep->hcpriv = NULL; | 287 | qh->hep->hcpriv = NULL; |
278 | uhci_free_td(uhci, qh->dummy_td); | 288 | if (qh->dummy_td) |
289 | uhci_free_td(uhci, qh->dummy_td); | ||
279 | } | 290 | } |
280 | dma_pool_free(uhci->qh_pool, qh, qh->dma_handle); | 291 | dma_pool_free(uhci->qh_pool, qh, qh->dma_handle); |
281 | } | 292 | } |
@@ -327,7 +338,7 @@ static int uhci_cleanup_queue(struct uhci_hcd *uhci, struct uhci_qh *qh, | |||
327 | goto done; | 338 | goto done; |
328 | qh->element = UHCI_PTR_TERM; | 339 | qh->element = UHCI_PTR_TERM; |
329 | 340 | ||
330 | /* Control pipes have to worry about toggles */ | 341 | /* Control pipes don't have to worry about toggles */ |
331 | if (qh->type == USB_ENDPOINT_XFER_CONTROL) | 342 | if (qh->type == USB_ENDPOINT_XFER_CONTROL) |
332 | goto done; | 343 | goto done; |
333 | 344 | ||
@@ -493,6 +504,121 @@ static void uhci_make_qh_idle(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
493 | wake_up_all(&uhci->waitqh); | 504 | wake_up_all(&uhci->waitqh); |
494 | } | 505 | } |
495 | 506 | ||
507 | /* | ||
508 | * Find the highest existing bandwidth load for a given phase and period. | ||
509 | */ | ||
510 | static int uhci_highest_load(struct uhci_hcd *uhci, int phase, int period) | ||
511 | { | ||
512 | int highest_load = uhci->load[phase]; | ||
513 | |||
514 | for (phase += period; phase < MAX_PHASE; phase += period) | ||
515 | highest_load = max_t(int, highest_load, uhci->load[phase]); | ||
516 | return highest_load; | ||
517 | } | ||
518 | |||
519 | /* | ||
520 | * Set qh->phase to the optimal phase for a periodic transfer and | ||
521 | * check whether the bandwidth requirement is acceptable. | ||
522 | */ | ||
523 | static int uhci_check_bandwidth(struct uhci_hcd *uhci, struct uhci_qh *qh) | ||
524 | { | ||
525 | int minimax_load; | ||
526 | |||
527 | /* Find the optimal phase (unless it is already set) and get | ||
528 | * its load value. */ | ||
529 | if (qh->phase >= 0) | ||
530 | minimax_load = uhci_highest_load(uhci, qh->phase, qh->period); | ||
531 | else { | ||
532 | int phase, load; | ||
533 | int max_phase = min_t(int, MAX_PHASE, qh->period); | ||
534 | |||
535 | qh->phase = 0; | ||
536 | minimax_load = uhci_highest_load(uhci, qh->phase, qh->period); | ||
537 | for (phase = 1; phase < max_phase; ++phase) { | ||
538 | load = uhci_highest_load(uhci, phase, qh->period); | ||
539 | if (load < minimax_load) { | ||
540 | minimax_load = load; | ||
541 | qh->phase = phase; | ||
542 | } | ||
543 | } | ||
544 | } | ||
545 | |||
546 | /* Maximum allowable periodic bandwidth is 90%, or 900 us per frame */ | ||
547 | if (minimax_load + qh->load > 900) { | ||
548 | dev_dbg(uhci_dev(uhci), "bandwidth allocation failed: " | ||
549 | "period %d, phase %d, %d + %d us\n", | ||
550 | qh->period, qh->phase, minimax_load, qh->load); | ||
551 | return -ENOSPC; | ||
552 | } | ||
553 | return 0; | ||
554 | } | ||
555 | |||
556 | /* | ||
557 | * Reserve a periodic QH's bandwidth in the schedule | ||
558 | */ | ||
559 | static void uhci_reserve_bandwidth(struct uhci_hcd *uhci, struct uhci_qh *qh) | ||
560 | { | ||
561 | int i; | ||
562 | int load = qh->load; | ||
563 | char *p = "??"; | ||
564 | |||
565 | for (i = qh->phase; i < MAX_PHASE; i += qh->period) { | ||
566 | uhci->load[i] += load; | ||
567 | uhci->total_load += load; | ||
568 | } | ||
569 | uhci_to_hcd(uhci)->self.bandwidth_allocated = | ||
570 | uhci->total_load / MAX_PHASE; | ||
571 | switch (qh->type) { | ||
572 | case USB_ENDPOINT_XFER_INT: | ||
573 | ++uhci_to_hcd(uhci)->self.bandwidth_int_reqs; | ||
574 | p = "INT"; | ||
575 | break; | ||
576 | case USB_ENDPOINT_XFER_ISOC: | ||
577 | ++uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs; | ||
578 | p = "ISO"; | ||
579 | break; | ||
580 | } | ||
581 | qh->bandwidth_reserved = 1; | ||
582 | dev_dbg(uhci_dev(uhci), | ||
583 | "%s dev %d ep%02x-%s, period %d, phase %d, %d us\n", | ||
584 | "reserve", qh->udev->devnum, | ||
585 | qh->hep->desc.bEndpointAddress, p, | ||
586 | qh->period, qh->phase, load); | ||
587 | } | ||
588 | |||
589 | /* | ||
590 | * Release a periodic QH's bandwidth reservation | ||
591 | */ | ||
592 | static void uhci_release_bandwidth(struct uhci_hcd *uhci, struct uhci_qh *qh) | ||
593 | { | ||
594 | int i; | ||
595 | int load = qh->load; | ||
596 | char *p = "??"; | ||
597 | |||
598 | for (i = qh->phase; i < MAX_PHASE; i += qh->period) { | ||
599 | uhci->load[i] -= load; | ||
600 | uhci->total_load -= load; | ||
601 | } | ||
602 | uhci_to_hcd(uhci)->self.bandwidth_allocated = | ||
603 | uhci->total_load / MAX_PHASE; | ||
604 | switch (qh->type) { | ||
605 | case USB_ENDPOINT_XFER_INT: | ||
606 | --uhci_to_hcd(uhci)->self.bandwidth_int_reqs; | ||
607 | p = "INT"; | ||
608 | break; | ||
609 | case USB_ENDPOINT_XFER_ISOC: | ||
610 | --uhci_to_hcd(uhci)->self.bandwidth_isoc_reqs; | ||
611 | p = "ISO"; | ||
612 | break; | ||
613 | } | ||
614 | qh->bandwidth_reserved = 0; | ||
615 | dev_dbg(uhci_dev(uhci), | ||
616 | "%s dev %d ep%02x-%s, period %d, phase %d, %d us\n", | ||
617 | "release", qh->udev->devnum, | ||
618 | qh->hep->desc.bEndpointAddress, p, | ||
619 | qh->period, qh->phase, load); | ||
620 | } | ||
621 | |||
496 | static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, | 622 | static inline struct urb_priv *uhci_alloc_urb_priv(struct uhci_hcd *uhci, |
497 | struct urb *urb) | 623 | struct urb *urb) |
498 | { | 624 | { |
@@ -796,7 +922,6 @@ static int uhci_submit_common(struct uhci_hcd *uhci, struct urb *urb, | |||
796 | wmb(); | 922 | wmb(); |
797 | qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE); | 923 | qh->dummy_td->status |= __constant_cpu_to_le32(TD_CTRL_ACTIVE); |
798 | qh->dummy_td = td; | 924 | qh->dummy_td = td; |
799 | qh->period = urb->interval; | ||
800 | 925 | ||
801 | usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), | 926 | usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), |
802 | usb_pipeout(urb->pipe), toggle); | 927 | usb_pipeout(urb->pipe), toggle); |
@@ -827,28 +952,42 @@ static inline int uhci_submit_bulk(struct uhci_hcd *uhci, struct urb *urb, | |||
827 | static int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb, | 952 | static int uhci_submit_interrupt(struct uhci_hcd *uhci, struct urb *urb, |
828 | struct uhci_qh *qh) | 953 | struct uhci_qh *qh) |
829 | { | 954 | { |
830 | int exponent; | 955 | int ret; |
831 | 956 | ||
832 | /* USB 1.1 interrupt transfers only involve one packet per interval. | 957 | /* USB 1.1 interrupt transfers only involve one packet per interval. |
833 | * Drivers can submit URBs of any length, but longer ones will need | 958 | * Drivers can submit URBs of any length, but longer ones will need |
834 | * multiple intervals to complete. | 959 | * multiple intervals to complete. |
835 | */ | 960 | */ |
836 | 961 | ||
837 | /* Figure out which power-of-two queue to use */ | 962 | if (!qh->bandwidth_reserved) { |
838 | for (exponent = 7; exponent >= 0; --exponent) { | 963 | int exponent; |
839 | if ((1 << exponent) <= urb->interval) | ||
840 | break; | ||
841 | } | ||
842 | if (exponent < 0) | ||
843 | return -EINVAL; | ||
844 | urb->interval = 1 << exponent; | ||
845 | 964 | ||
846 | if (qh->period == 0) | 965 | /* Figure out which power-of-two queue to use */ |
966 | for (exponent = 7; exponent >= 0; --exponent) { | ||
967 | if ((1 << exponent) <= urb->interval) | ||
968 | break; | ||
969 | } | ||
970 | if (exponent < 0) | ||
971 | return -EINVAL; | ||
972 | qh->period = 1 << exponent; | ||
847 | qh->skel = uhci->skelqh[UHCI_SKEL_INDEX(exponent)]; | 973 | qh->skel = uhci->skelqh[UHCI_SKEL_INDEX(exponent)]; |
848 | else if (qh->period != urb->interval) | ||
849 | return -EINVAL; /* Can't change the period */ | ||
850 | 974 | ||
851 | return uhci_submit_common(uhci, urb, qh); | 975 | /* For now, interrupt phase is fixed by the layout |
976 | * of the QH lists. */ | ||
977 | qh->phase = (qh->period / 2) & (MAX_PHASE - 1); | ||
978 | ret = uhci_check_bandwidth(uhci, qh); | ||
979 | if (ret) | ||
980 | return ret; | ||
981 | } else if (qh->period > urb->interval) | ||
982 | return -EINVAL; /* Can't decrease the period */ | ||
983 | |||
984 | ret = uhci_submit_common(uhci, urb, qh); | ||
985 | if (ret == 0) { | ||
986 | urb->interval = qh->period; | ||
987 | if (!qh->bandwidth_reserved) | ||
988 | uhci_reserve_bandwidth(uhci, qh); | ||
989 | } | ||
990 | return ret; | ||
852 | } | 991 | } |
853 | 992 | ||
854 | /* | 993 | /* |
@@ -995,15 +1134,32 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, | |||
995 | return -EFBIG; | 1134 | return -EFBIG; |
996 | 1135 | ||
997 | /* Check the period and figure out the starting frame number */ | 1136 | /* Check the period and figure out the starting frame number */ |
998 | if (qh->period == 0) { | 1137 | if (!qh->bandwidth_reserved) { |
1138 | qh->period = urb->interval; | ||
999 | if (urb->transfer_flags & URB_ISO_ASAP) { | 1139 | if (urb->transfer_flags & URB_ISO_ASAP) { |
1140 | qh->phase = -1; /* Find the best phase */ | ||
1141 | i = uhci_check_bandwidth(uhci, qh); | ||
1142 | if (i) | ||
1143 | return i; | ||
1144 | |||
1145 | /* Allow a little time to allocate the TDs */ | ||
1000 | uhci_get_current_frame_number(uhci); | 1146 | uhci_get_current_frame_number(uhci); |
1001 | urb->start_frame = uhci->frame_number + 10; | 1147 | frame = uhci->frame_number + 10; |
1148 | |||
1149 | /* Move forward to the first frame having the | ||
1150 | * correct phase */ | ||
1151 | urb->start_frame = frame + ((qh->phase - frame) & | ||
1152 | (qh->period - 1)); | ||
1002 | } else { | 1153 | } else { |
1003 | i = urb->start_frame - uhci->last_iso_frame; | 1154 | i = urb->start_frame - uhci->last_iso_frame; |
1004 | if (i <= 0 || i >= UHCI_NUMFRAMES) | 1155 | if (i <= 0 || i >= UHCI_NUMFRAMES) |
1005 | return -EINVAL; | 1156 | return -EINVAL; |
1157 | qh->phase = urb->start_frame & (qh->period - 1); | ||
1158 | i = uhci_check_bandwidth(uhci, qh); | ||
1159 | if (i) | ||
1160 | return i; | ||
1006 | } | 1161 | } |
1162 | |||
1007 | } else if (qh->period != urb->interval) { | 1163 | } else if (qh->period != urb->interval) { |
1008 | return -EINVAL; /* Can't change the period */ | 1164 | return -EINVAL; /* Can't change the period */ |
1009 | 1165 | ||
@@ -1049,9 +1205,6 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, | |||
1049 | /* Set the interrupt-on-completion flag on the last packet. */ | 1205 | /* Set the interrupt-on-completion flag on the last packet. */ |
1050 | td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); | 1206 | td->status |= __constant_cpu_to_le32(TD_CTRL_IOC); |
1051 | 1207 | ||
1052 | qh->skel = uhci->skel_iso_qh; | ||
1053 | qh->period = urb->interval; | ||
1054 | |||
1055 | /* Add the TDs to the frame list */ | 1208 | /* Add the TDs to the frame list */ |
1056 | frame = urb->start_frame; | 1209 | frame = urb->start_frame; |
1057 | list_for_each_entry(td, &urbp->td_list, list) { | 1210 | list_for_each_entry(td, &urbp->td_list, list) { |
@@ -1065,6 +1218,9 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, | |||
1065 | qh->iso_status = 0; | 1218 | qh->iso_status = 0; |
1066 | } | 1219 | } |
1067 | 1220 | ||
1221 | qh->skel = uhci->skel_iso_qh; | ||
1222 | if (!qh->bandwidth_reserved) | ||
1223 | uhci_reserve_bandwidth(uhci, qh); | ||
1068 | return 0; | 1224 | return 0; |
1069 | } | 1225 | } |
1070 | 1226 | ||
@@ -1119,7 +1275,6 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd, | |||
1119 | unsigned long flags; | 1275 | unsigned long flags; |
1120 | struct urb_priv *urbp; | 1276 | struct urb_priv *urbp; |
1121 | struct uhci_qh *qh; | 1277 | struct uhci_qh *qh; |
1122 | int bustime; | ||
1123 | 1278 | ||
1124 | spin_lock_irqsave(&uhci->lock, flags); | 1279 | spin_lock_irqsave(&uhci->lock, flags); |
1125 | 1280 | ||
@@ -1149,35 +1304,11 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd, | |||
1149 | ret = uhci_submit_bulk(uhci, urb, qh); | 1304 | ret = uhci_submit_bulk(uhci, urb, qh); |
1150 | break; | 1305 | break; |
1151 | case USB_ENDPOINT_XFER_INT: | 1306 | case USB_ENDPOINT_XFER_INT: |
1152 | if (list_empty(&qh->queue)) { | 1307 | ret = uhci_submit_interrupt(uhci, urb, qh); |
1153 | bustime = usb_check_bandwidth(urb->dev, urb); | ||
1154 | if (bustime < 0) | ||
1155 | ret = bustime; | ||
1156 | else { | ||
1157 | ret = uhci_submit_interrupt(uhci, urb, qh); | ||
1158 | if (ret == 0) | ||
1159 | usb_claim_bandwidth(urb->dev, urb, bustime, 0); | ||
1160 | } | ||
1161 | } else { /* inherit from parent */ | ||
1162 | struct urb_priv *eurbp; | ||
1163 | |||
1164 | eurbp = list_entry(qh->queue.prev, struct urb_priv, | ||
1165 | node); | ||
1166 | urb->bandwidth = eurbp->urb->bandwidth; | ||
1167 | ret = uhci_submit_interrupt(uhci, urb, qh); | ||
1168 | } | ||
1169 | break; | 1308 | break; |
1170 | case USB_ENDPOINT_XFER_ISOC: | 1309 | case USB_ENDPOINT_XFER_ISOC: |
1171 | urb->error_count = 0; | 1310 | urb->error_count = 0; |
1172 | bustime = usb_check_bandwidth(urb->dev, urb); | ||
1173 | if (bustime < 0) { | ||
1174 | ret = bustime; | ||
1175 | break; | ||
1176 | } | ||
1177 | |||
1178 | ret = uhci_submit_isochronous(uhci, urb, qh); | 1311 | ret = uhci_submit_isochronous(uhci, urb, qh); |
1179 | if (ret == 0) | ||
1180 | usb_claim_bandwidth(urb->dev, urb, bustime, 1); | ||
1181 | break; | 1312 | break; |
1182 | } | 1313 | } |
1183 | if (ret != 0) | 1314 | if (ret != 0) |
@@ -1274,24 +1405,6 @@ __acquires(uhci->lock) | |||
1274 | 1405 | ||
1275 | uhci_free_urb_priv(uhci, urbp); | 1406 | uhci_free_urb_priv(uhci, urbp); |
1276 | 1407 | ||
1277 | switch (qh->type) { | ||
1278 | case USB_ENDPOINT_XFER_ISOC: | ||
1279 | /* Release bandwidth for Interrupt or Isoc. transfers */ | ||
1280 | if (urb->bandwidth) | ||
1281 | usb_release_bandwidth(urb->dev, urb, 1); | ||
1282 | break; | ||
1283 | case USB_ENDPOINT_XFER_INT: | ||
1284 | /* Release bandwidth for Interrupt or Isoc. transfers */ | ||
1285 | /* Make sure we don't release if we have a queued URB */ | ||
1286 | if (list_empty(&qh->queue) && urb->bandwidth) | ||
1287 | usb_release_bandwidth(urb->dev, urb, 0); | ||
1288 | else | ||
1289 | /* bandwidth was passed on to queued URB, */ | ||
1290 | /* so don't let usb_unlink_urb() release it */ | ||
1291 | urb->bandwidth = 0; | ||
1292 | break; | ||
1293 | } | ||
1294 | |||
1295 | spin_unlock(&uhci->lock); | 1408 | spin_unlock(&uhci->lock); |
1296 | usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb); | 1409 | usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb); |
1297 | spin_lock(&uhci->lock); | 1410 | spin_lock(&uhci->lock); |
@@ -1300,9 +1413,8 @@ __acquires(uhci->lock) | |||
1300 | * reserved bandwidth. */ | 1413 | * reserved bandwidth. */ |
1301 | if (list_empty(&qh->queue)) { | 1414 | if (list_empty(&qh->queue)) { |
1302 | uhci_unlink_qh(uhci, qh); | 1415 | uhci_unlink_qh(uhci, qh); |
1303 | 1416 | if (qh->bandwidth_reserved) | |
1304 | /* Bandwidth stuff not yet implemented */ | 1417 | uhci_release_bandwidth(uhci, qh); |
1305 | qh->period = 0; | ||
1306 | } | 1418 | } |
1307 | } | 1419 | } |
1308 | 1420 | ||
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index 63a84bbc310d..d308afd06935 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c | |||
@@ -565,11 +565,15 @@ static void mdc800_usb_disconnect (struct usb_interface *intf) | |||
565 | 565 | ||
566 | usb_deregister_dev(intf, &mdc800_class); | 566 | usb_deregister_dev(intf, &mdc800_class); |
567 | 567 | ||
568 | /* must be under lock to make sure no URB | ||
569 | is submitted after usb_kill_urb() */ | ||
570 | mutex_lock(&mdc800->io_lock); | ||
568 | mdc800->state=NOT_CONNECTED; | 571 | mdc800->state=NOT_CONNECTED; |
569 | 572 | ||
570 | usb_kill_urb(mdc800->irq_urb); | 573 | usb_kill_urb(mdc800->irq_urb); |
571 | usb_kill_urb(mdc800->write_urb); | 574 | usb_kill_urb(mdc800->write_urb); |
572 | usb_kill_urb(mdc800->download_urb); | 575 | usb_kill_urb(mdc800->download_urb); |
576 | mutex_unlock(&mdc800->io_lock); | ||
573 | 577 | ||
574 | mdc800->dev = NULL; | 578 | mdc800->dev = NULL; |
575 | usb_set_intfdata(intf, NULL); | 579 | usb_set_intfdata(intf, NULL); |
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig index 661af7aa6236..2e71d3cca198 100644 --- a/drivers/usb/input/Kconfig +++ b/drivers/usb/input/Kconfig | |||
@@ -6,14 +6,14 @@ comment "USB Input Devices" | |||
6 | 6 | ||
7 | config USB_HID | 7 | config USB_HID |
8 | tristate "USB Human Interface Device (full HID) support" | 8 | tristate "USB Human Interface Device (full HID) support" |
9 | depends on USB | 9 | default y |
10 | depends on USB && INPUT | ||
11 | select HID | ||
10 | ---help--- | 12 | ---help--- |
11 | Say Y here if you want full HID support to connect keyboards, | 13 | Say Y here if you want full HID support to connect USB keyboards, |
12 | mice, joysticks, graphic tablets, or any other HID based devices | 14 | mice, joysticks, graphic tablets, or any other HID based devices |
13 | to your computer via USB. You also need to select HID Input layer | 15 | to your computer via USB, as well as Uninterruptible Power Supply |
14 | support (below) if you want to use keyboards, mice, joysticks and | 16 | (UPS) and monitor control devices. |
15 | the like ... as well as Uninterruptible Power Supply (UPS) and | ||
16 | monitor control devices. | ||
17 | 17 | ||
18 | You can't use this driver and the HIDBP (Boot Protocol) keyboard | 18 | You can't use this driver and the HIDBP (Boot Protocol) keyboard |
19 | and mouse drivers at the same time. More information is available: | 19 | and mouse drivers at the same time. More information is available: |
@@ -27,20 +27,10 @@ config USB_HID | |||
27 | comment "Input core support is needed for USB HID input layer or HIDBP support" | 27 | comment "Input core support is needed for USB HID input layer or HIDBP support" |
28 | depends on USB_HID && INPUT=n | 28 | depends on USB_HID && INPUT=n |
29 | 29 | ||
30 | config USB_HIDINPUT | ||
31 | bool "HID input layer support" | ||
32 | default y | ||
33 | depends on INPUT && USB_HID | ||
34 | help | ||
35 | Say Y here if you want to use a USB keyboard, mouse or joystick, | ||
36 | or any other HID input device. | ||
37 | |||
38 | If unsure, say Y. | ||
39 | |||
40 | config USB_HIDINPUT_POWERBOOK | 30 | config USB_HIDINPUT_POWERBOOK |
41 | bool "Enable support for iBook/PowerBook special keys" | 31 | bool "Enable support for iBook/PowerBook special keys" |
42 | default n | 32 | default n |
43 | depends on USB_HIDINPUT | 33 | depends on USB_HID |
44 | help | 34 | help |
45 | Say Y here if you want support for the special keys (Fn, Numlock) on | 35 | Say Y here if you want support for the special keys (Fn, Numlock) on |
46 | Apple iBooks and PowerBooks. | 36 | Apple iBooks and PowerBooks. |
@@ -49,7 +39,7 @@ config USB_HIDINPUT_POWERBOOK | |||
49 | 39 | ||
50 | config HID_FF | 40 | config HID_FF |
51 | bool "Force feedback support (EXPERIMENTAL)" | 41 | bool "Force feedback support (EXPERIMENTAL)" |
52 | depends on USB_HIDINPUT && EXPERIMENTAL | 42 | depends on USB_HID && EXPERIMENTAL |
53 | help | 43 | help |
54 | Say Y here is you want force feedback support for a few HID devices. | 44 | Say Y here is you want force feedback support for a few HID devices. |
55 | See below for a list of supported devices. | 45 | See below for a list of supported devices. |
@@ -79,6 +69,14 @@ config LOGITECH_FF | |||
79 | Note: if you say N here, this device will still be supported, but without | 69 | Note: if you say N here, this device will still be supported, but without |
80 | force feedback. | 70 | force feedback. |
81 | 71 | ||
72 | config PANTHERLORD_FF | ||
73 | bool "PantherLord USB/PS2 2in1 Adapter support" | ||
74 | depends on HID_FF | ||
75 | select INPUT_FF_MEMLESS if USB_HID | ||
76 | help | ||
77 | Say Y here if you have a PantherLord USB/PS2 2in1 Adapter and want | ||
78 | to enable force feedback support for it. | ||
79 | |||
82 | config THRUSTMASTER_FF | 80 | config THRUSTMASTER_FF |
83 | bool "ThrustMaster FireStorm Dual Power 2 support (EXPERIMENTAL)" | 81 | bool "ThrustMaster FireStorm Dual Power 2 support (EXPERIMENTAL)" |
84 | depends on HID_FF && EXPERIMENTAL | 82 | depends on HID_FF && EXPERIMENTAL |
@@ -354,3 +352,15 @@ config USB_APPLETOUCH | |||
354 | 352 | ||
355 | To compile this driver as a module, choose M here: the | 353 | To compile this driver as a module, choose M here: the |
356 | module will be called appletouch. | 354 | module will be called appletouch. |
355 | |||
356 | config USB_GTCO | ||
357 | tristate "GTCO CalComp/InterWrite USB Support" | ||
358 | depends on USB && INPUT | ||
359 | ---help--- | ||
360 | Say Y here if you want to use the USB version of the GTCO | ||
361 | CalComp/InterWrite Tablet. Make sure to say Y to "Mouse support" | ||
362 | (CONFIG_INPUT_MOUSEDEV) and/or "Event interface support" | ||
363 | (CONFIG_INPUT_EVDEV) as well. | ||
364 | |||
365 | To compile this driver as a module, choose M here: the | ||
366 | module will be called gtco. | ||
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile index d946d5213b30..a9d206c945e9 100644 --- a/drivers/usb/input/Makefile +++ b/drivers/usb/input/Makefile | |||
@@ -11,15 +11,15 @@ usbhid-objs := hid-core.o | |||
11 | ifeq ($(CONFIG_USB_HIDDEV),y) | 11 | ifeq ($(CONFIG_USB_HIDDEV),y) |
12 | usbhid-objs += hiddev.o | 12 | usbhid-objs += hiddev.o |
13 | endif | 13 | endif |
14 | ifeq ($(CONFIG_USB_HIDINPUT),y) | ||
15 | usbhid-objs += hid-input.o | ||
16 | endif | ||
17 | ifeq ($(CONFIG_HID_PID),y) | 14 | ifeq ($(CONFIG_HID_PID),y) |
18 | usbhid-objs += hid-pidff.o | 15 | usbhid-objs += hid-pidff.o |
19 | endif | 16 | endif |
20 | ifeq ($(CONFIG_LOGITECH_FF),y) | 17 | ifeq ($(CONFIG_LOGITECH_FF),y) |
21 | usbhid-objs += hid-lgff.o | 18 | usbhid-objs += hid-lgff.o |
22 | endif | 19 | endif |
20 | ifeq ($(CONFIG_PANTHERLORD_FF),y) | ||
21 | usbhid-objs += hid-plff.o | ||
22 | endif | ||
23 | ifeq ($(CONFIG_THRUSTMASTER_FF),y) | 23 | ifeq ($(CONFIG_THRUSTMASTER_FF),y) |
24 | usbhid-objs += hid-tmff.o | 24 | usbhid-objs += hid-tmff.o |
25 | endif | 25 | endif |
@@ -48,6 +48,7 @@ obj-$(CONFIG_USB_ACECAD) += acecad.o | |||
48 | obj-$(CONFIG_USB_YEALINK) += yealink.o | 48 | obj-$(CONFIG_USB_YEALINK) += yealink.o |
49 | obj-$(CONFIG_USB_XPAD) += xpad.o | 49 | obj-$(CONFIG_USB_XPAD) += xpad.o |
50 | obj-$(CONFIG_USB_APPLETOUCH) += appletouch.o | 50 | obj-$(CONFIG_USB_APPLETOUCH) += appletouch.o |
51 | obj-$(CONFIG_USB_GTCO) += gtco.o | ||
51 | 52 | ||
52 | ifeq ($(CONFIG_USB_DEBUG),y) | 53 | ifeq ($(CONFIG_USB_DEBUG),y) |
53 | EXTRA_CFLAGS += -DDEBUG | 54 | EXTRA_CFLAGS += -DDEBUG |
diff --git a/drivers/usb/input/gtco.c b/drivers/usb/input/gtco.c new file mode 100644 index 000000000000..203cdc1bbba4 --- /dev/null +++ b/drivers/usb/input/gtco.c | |||
@@ -0,0 +1,1104 @@ | |||
1 | /* -*- linux-c -*- | ||
2 | |||
3 | GTCO digitizer USB driver | ||
4 | |||
5 | Use the err(), dbg() and info() macros from usb.h for system logging | ||
6 | |||
7 | TO CHECK: Is pressure done right on report 5? | ||
8 | |||
9 | Copyright (C) 2006 GTCO CalComp | ||
10 | |||
11 | This program is free software; you can redistribute it and/or | ||
12 | modify it under the terms of the GNU General Public License | ||
13 | as published by the Free Software Foundation; version 2 | ||
14 | of the License. | ||
15 | |||
16 | This program is distributed in the hope that it will be useful, | ||
17 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | GNU General Public License for more details. | ||
20 | |||
21 | You should have received a copy of the GNU General Public License | ||
22 | along with this program; if not, write to the Free Software | ||
23 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
24 | |||
25 | Permission to use, copy, modify, distribute, and sell this software and its | ||
26 | documentation for any purpose is hereby granted without fee, provided that | ||
27 | the above copyright notice appear in all copies and that both that | ||
28 | copyright notice and this permission notice appear in supporting | ||
29 | documentation, and that the name of GTCO-CalComp not be used in advertising | ||
30 | or publicity pertaining to distribution of the software without specific, | ||
31 | written prior permission. GTCO-CalComp makes no representations about the | ||
32 | suitability of this software for any purpose. It is provided "as is" | ||
33 | without express or implied warranty. | ||
34 | |||
35 | GTCO-CALCOMP DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, | ||
36 | INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO | ||
37 | EVENT SHALL GTCO-CALCOMP BE LIABLE FOR ANY SPECIAL, INDIRECT OR | ||
38 | CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | ||
39 | DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER | ||
40 | TORTIOUS ACTIONS, ARISING OUT OF OR IN CONNECTION WITH THE USE OR | ||
41 | PERFORMANCE OF THIS SOFTWARE. | ||
42 | |||
43 | GTCO CalComp, Inc. | ||
44 | 7125 Riverwood Drive | ||
45 | Columbia, MD 21046 | ||
46 | |||
47 | Jeremy Roberson jroberson@gtcocalcomp.com | ||
48 | Scott Hill shill@gtcocalcomp.com | ||
49 | */ | ||
50 | |||
51 | |||
52 | |||
53 | /*#define DEBUG*/ | ||
54 | |||
55 | #include <linux/kernel.h> | ||
56 | #include <linux/module.h> | ||
57 | #include <linux/errno.h> | ||
58 | #include <linux/init.h> | ||
59 | #include <linux/slab.h> | ||
60 | #include <linux/input.h> | ||
61 | #include <linux/usb.h> | ||
62 | #include <asm/uaccess.h> | ||
63 | #include <asm/unaligned.h> | ||
64 | #include <asm/byteorder.h> | ||
65 | |||
66 | |||
67 | #include <linux/version.h> | ||
68 | #include <linux/usb/input.h> | ||
69 | |||
70 | /* Version with a Major number of 2 is for kernel inclusion only. */ | ||
71 | #define GTCO_VERSION "2.00.0006" | ||
72 | |||
73 | |||
74 | /* MACROS */ | ||
75 | |||
76 | #define VENDOR_ID_GTCO 0x078C | ||
77 | #define PID_400 0x400 | ||
78 | #define PID_401 0x401 | ||
79 | #define PID_1000 0x1000 | ||
80 | #define PID_1001 0x1001 | ||
81 | #define PID_1002 0x1002 | ||
82 | |||
83 | /* Max size of a single report */ | ||
84 | #define REPORT_MAX_SIZE 10 | ||
85 | |||
86 | |||
87 | /* Bitmask whether pen is in range */ | ||
88 | #define MASK_INRANGE 0x20 | ||
89 | #define MASK_BUTTON 0x01F | ||
90 | |||
91 | #define PATHLENGTH 64 | ||
92 | |||
93 | /* DATA STRUCTURES */ | ||
94 | |||
95 | /* Device table */ | ||
96 | static struct usb_device_id gtco_usbid_table [] = { | ||
97 | { USB_DEVICE(VENDOR_ID_GTCO, PID_400) }, | ||
98 | { USB_DEVICE(VENDOR_ID_GTCO, PID_401) }, | ||
99 | { USB_DEVICE(VENDOR_ID_GTCO, PID_1000) }, | ||
100 | { USB_DEVICE(VENDOR_ID_GTCO, PID_1001) }, | ||
101 | { USB_DEVICE(VENDOR_ID_GTCO, PID_1002) }, | ||
102 | { } | ||
103 | }; | ||
104 | MODULE_DEVICE_TABLE (usb, gtco_usbid_table); | ||
105 | |||
106 | |||
107 | /* Structure to hold all of our device specific stuff */ | ||
108 | struct gtco { | ||
109 | |||
110 | struct input_dev *inputdevice; /* input device struct pointer */ | ||
111 | struct usb_device *usbdev; /* the usb device for this device */ | ||
112 | struct urb *urbinfo; /* urb for incoming reports */ | ||
113 | dma_addr_t buf_dma; /* dma addr of the data buffer*/ | ||
114 | unsigned char * buffer; /* databuffer for reports */ | ||
115 | |||
116 | char usbpath[PATHLENGTH]; | ||
117 | int openCount; | ||
118 | |||
119 | /* Information pulled from Report Descriptor */ | ||
120 | u32 usage; | ||
121 | u32 min_X; | ||
122 | u32 max_X; | ||
123 | u32 min_Y; | ||
124 | u32 max_Y; | ||
125 | s8 mintilt_X; | ||
126 | s8 maxtilt_X; | ||
127 | s8 mintilt_Y; | ||
128 | s8 maxtilt_Y; | ||
129 | u32 maxpressure; | ||
130 | u32 minpressure; | ||
131 | }; | ||
132 | |||
133 | |||
134 | |||
135 | /* Code for parsing the HID REPORT DESCRIPTOR */ | ||
136 | |||
137 | /* From HID1.11 spec */ | ||
138 | struct hid_descriptor | ||
139 | { | ||
140 | struct usb_descriptor_header header; | ||
141 | __le16 bcdHID; | ||
142 | u8 bCountryCode; | ||
143 | u8 bNumDescriptors; | ||
144 | u8 bDescriptorType; | ||
145 | __le16 wDescriptorLength; | ||
146 | } __attribute__ ((packed)); | ||
147 | |||
148 | |||
149 | #define HID_DESCRIPTOR_SIZE 9 | ||
150 | #define HID_DEVICE_TYPE 33 | ||
151 | #define REPORT_DEVICE_TYPE 34 | ||
152 | |||
153 | |||
154 | #define PREF_TAG(x) ((x)>>4) | ||
155 | #define PREF_TYPE(x) ((x>>2)&0x03) | ||
156 | #define PREF_SIZE(x) ((x)&0x03) | ||
157 | |||
158 | #define TYPE_MAIN 0 | ||
159 | #define TYPE_GLOBAL 1 | ||
160 | #define TYPE_LOCAL 2 | ||
161 | #define TYPE_RESERVED 3 | ||
162 | |||
163 | #define TAG_MAIN_INPUT 0x8 | ||
164 | #define TAG_MAIN_OUTPUT 0x9 | ||
165 | #define TAG_MAIN_FEATURE 0xB | ||
166 | #define TAG_MAIN_COL_START 0xA | ||
167 | #define TAG_MAIN_COL_END 0xC | ||
168 | |||
169 | #define TAG_GLOB_USAGE 0 | ||
170 | #define TAG_GLOB_LOG_MIN 1 | ||
171 | #define TAG_GLOB_LOG_MAX 2 | ||
172 | #define TAG_GLOB_PHYS_MIN 3 | ||
173 | #define TAG_GLOB_PHYS_MAX 4 | ||
174 | #define TAG_GLOB_UNIT_EXP 5 | ||
175 | #define TAG_GLOB_UNIT 6 | ||
176 | #define TAG_GLOB_REPORT_SZ 7 | ||
177 | #define TAG_GLOB_REPORT_ID 8 | ||
178 | #define TAG_GLOB_REPORT_CNT 9 | ||
179 | #define TAG_GLOB_PUSH 10 | ||
180 | #define TAG_GLOB_POP 11 | ||
181 | |||
182 | #define TAG_GLOB_MAX 12 | ||
183 | |||
184 | #define DIGITIZER_USAGE_TIP_PRESSURE 0x30 | ||
185 | #define DIGITIZER_USAGE_TILT_X 0x3D | ||
186 | #define DIGITIZER_USAGE_TILT_Y 0x3E | ||
187 | |||
188 | |||
189 | /* | ||
190 | * | ||
191 | * This is an abbreviated parser for the HID Report Descriptor. We | ||
192 | * know what devices we are talking to, so this is by no means meant | ||
193 | * to be generic. We can make some safe assumptions: | ||
194 | * | ||
195 | * - We know there are no LONG tags, all short | ||
196 | * - We know that we have no MAIN Feature and MAIN Output items | ||
197 | * - We know what the IRQ reports are supposed to look like. | ||
198 | * | ||
199 | * The main purpose of this is to use the HID report desc to figure | ||
200 | * out the mins and maxs of the fields in the IRQ reports. The IRQ | ||
201 | * reports for 400/401 change slightly if the max X is bigger than 64K. | ||
202 | * | ||
203 | */ | ||
204 | static void parse_hid_report_descriptor(struct gtco *device, char * report, | ||
205 | int length) | ||
206 | { | ||
207 | int x,i=0; | ||
208 | |||
209 | /* Tag primitive vars */ | ||
210 | __u8 prefix; | ||
211 | __u8 size; | ||
212 | __u8 tag; | ||
213 | __u8 type; | ||
214 | __u8 data = 0; | ||
215 | __u16 data16 = 0; | ||
216 | __u32 data32 = 0; | ||
217 | |||
218 | |||
219 | /* For parsing logic */ | ||
220 | int inputnum = 0; | ||
221 | __u32 usage = 0; | ||
222 | |||
223 | /* Global Values, indexed by TAG */ | ||
224 | __u32 globalval[TAG_GLOB_MAX]; | ||
225 | __u32 oldval[TAG_GLOB_MAX]; | ||
226 | |||
227 | /* Debug stuff */ | ||
228 | char maintype='x'; | ||
229 | char globtype[12]; | ||
230 | int indent=0; | ||
231 | char indentstr[10]=""; | ||
232 | |||
233 | |||
234 | |||
235 | dbg("======>>>>>>PARSE<<<<<<======"); | ||
236 | |||
237 | /* Walk this report and pull out the info we need */ | ||
238 | while (i<length){ | ||
239 | prefix=report[i]; | ||
240 | |||
241 | /* Skip over prefix */ | ||
242 | i++; | ||
243 | |||
244 | /* Determine data size and save the data in the proper variable */ | ||
245 | size = PREF_SIZE(prefix); | ||
246 | switch(size){ | ||
247 | case 1: | ||
248 | data = report[i]; | ||
249 | break; | ||
250 | case 2: | ||
251 | data16 = le16_to_cpu(get_unaligned((__le16*)(&(report[i])))); | ||
252 | break; | ||
253 | case 3: | ||
254 | size = 4; | ||
255 | data32 = le32_to_cpu(get_unaligned((__le32*)(&(report[i])))); | ||
256 | } | ||
257 | |||
258 | /* Skip size of data */ | ||
259 | i+=size; | ||
260 | |||
261 | /* What we do depends on the tag type */ | ||
262 | tag = PREF_TAG(prefix); | ||
263 | type = PREF_TYPE(prefix); | ||
264 | switch(type){ | ||
265 | case TYPE_MAIN: | ||
266 | strcpy(globtype,""); | ||
267 | switch(tag){ | ||
268 | |||
269 | case TAG_MAIN_INPUT: | ||
270 | /* | ||
271 | * The INPUT MAIN tag signifies this is | ||
272 | * information from a report. We need to | ||
273 | * figure out what it is and store the | ||
274 | * min/max values | ||
275 | */ | ||
276 | |||
277 | maintype='I'; | ||
278 | if (data==2){ | ||
279 | strcpy(globtype,"Variable"); | ||
280 | } | ||
281 | if (data==3){ | ||
282 | strcpy(globtype,"Var|Const"); | ||
283 | } | ||
284 | |||
285 | dbg("::::: Saving Report: %d input #%d Max: 0x%X(%d) Min:0x%X(%d) of %d bits", | ||
286 | globalval[TAG_GLOB_REPORT_ID],inputnum, | ||
287 | globalval[TAG_GLOB_LOG_MAX],globalval[TAG_GLOB_LOG_MAX], | ||
288 | globalval[TAG_GLOB_LOG_MIN],globalval[TAG_GLOB_LOG_MIN], | ||
289 | (globalval[TAG_GLOB_REPORT_SZ] * globalval[TAG_GLOB_REPORT_CNT])); | ||
290 | |||
291 | |||
292 | /* | ||
293 | We can assume that the first two input items | ||
294 | are always the X and Y coordinates. After | ||
295 | that, we look for everything else by | ||
296 | local usage value | ||
297 | */ | ||
298 | switch (inputnum){ | ||
299 | case 0: /* X coord */ | ||
300 | dbg("GER: X Usage: 0x%x",usage); | ||
301 | if (device->max_X == 0){ | ||
302 | device->max_X = globalval[TAG_GLOB_LOG_MAX]; | ||
303 | device->min_X = globalval[TAG_GLOB_LOG_MIN]; | ||
304 | } | ||
305 | |||
306 | break; | ||
307 | case 1: /* Y coord */ | ||
308 | dbg("GER: Y Usage: 0x%x",usage); | ||
309 | if (device->max_Y == 0){ | ||
310 | device->max_Y = globalval[TAG_GLOB_LOG_MAX]; | ||
311 | device->min_Y = globalval[TAG_GLOB_LOG_MIN]; | ||
312 | } | ||
313 | break; | ||
314 | default: | ||
315 | /* Tilt X */ | ||
316 | if (usage == DIGITIZER_USAGE_TILT_X){ | ||
317 | if (device->maxtilt_X == 0){ | ||
318 | device->maxtilt_X = globalval[TAG_GLOB_LOG_MAX]; | ||
319 | device->mintilt_X = globalval[TAG_GLOB_LOG_MIN]; | ||
320 | } | ||
321 | } | ||
322 | |||
323 | /* Tilt Y */ | ||
324 | if (usage == DIGITIZER_USAGE_TILT_Y){ | ||
325 | if (device->maxtilt_Y == 0){ | ||
326 | device->maxtilt_Y = globalval[TAG_GLOB_LOG_MAX]; | ||
327 | device->mintilt_Y = globalval[TAG_GLOB_LOG_MIN]; | ||
328 | } | ||
329 | } | ||
330 | |||
331 | |||
332 | /* Pressure */ | ||
333 | if (usage == DIGITIZER_USAGE_TIP_PRESSURE){ | ||
334 | if (device->maxpressure == 0){ | ||
335 | device->maxpressure = globalval[TAG_GLOB_LOG_MAX]; | ||
336 | device->minpressure = globalval[TAG_GLOB_LOG_MIN]; | ||
337 | } | ||
338 | } | ||
339 | |||
340 | break; | ||
341 | } | ||
342 | |||
343 | inputnum++; | ||
344 | |||
345 | |||
346 | break; | ||
347 | case TAG_MAIN_OUTPUT: | ||
348 | maintype='O'; | ||
349 | break; | ||
350 | case TAG_MAIN_FEATURE: | ||
351 | maintype='F'; | ||
352 | break; | ||
353 | case TAG_MAIN_COL_START: | ||
354 | maintype='S'; | ||
355 | |||
356 | if (data==0){ | ||
357 | dbg("======>>>>>> Physical"); | ||
358 | strcpy(globtype,"Physical"); | ||
359 | }else{ | ||
360 | dbg("======>>>>>>"); | ||
361 | } | ||
362 | |||
363 | /* Indent the debug output */ | ||
364 | indent++; | ||
365 | for (x=0;x<indent;x++){ | ||
366 | indentstr[x]='-'; | ||
367 | } | ||
368 | indentstr[x]=0; | ||
369 | |||
370 | /* Save global tags */ | ||
371 | for (x=0;x<TAG_GLOB_MAX;x++){ | ||
372 | oldval[x] = globalval[x]; | ||
373 | } | ||
374 | |||
375 | break; | ||
376 | case TAG_MAIN_COL_END: | ||
377 | dbg("<<<<<<======"); | ||
378 | maintype='E'; | ||
379 | indent--; | ||
380 | for (x=0;x<indent;x++){ | ||
381 | indentstr[x]='-'; | ||
382 | } | ||
383 | indentstr[x]=0; | ||
384 | |||
385 | /* Copy global tags back */ | ||
386 | for (x=0;x<TAG_GLOB_MAX;x++){ | ||
387 | globalval[x] = oldval[x]; | ||
388 | } | ||
389 | |||
390 | break; | ||
391 | } | ||
392 | |||
393 | switch (size){ | ||
394 | case 1: | ||
395 | dbg("%sMAINTAG:(%d) %c SIZE: %d Data: %s 0x%x", | ||
396 | indentstr,tag,maintype,size,globtype,data); | ||
397 | break; | ||
398 | case 2: | ||
399 | dbg("%sMAINTAG:(%d) %c SIZE: %d Data: %s 0x%x", | ||
400 | indentstr,tag,maintype,size,globtype, data16); | ||
401 | break; | ||
402 | case 4: | ||
403 | dbg("%sMAINTAG:(%d) %c SIZE: %d Data: %s 0x%x", | ||
404 | indentstr,tag,maintype,size,globtype,data32); | ||
405 | break; | ||
406 | } | ||
407 | break; | ||
408 | case TYPE_GLOBAL: | ||
409 | switch(tag){ | ||
410 | case TAG_GLOB_USAGE: | ||
411 | /* | ||
412 | * First time we hit the global usage tag, | ||
413 | * it should tell us the type of device | ||
414 | */ | ||
415 | if (device->usage == 0){ | ||
416 | device->usage = data; | ||
417 | } | ||
418 | strcpy(globtype,"USAGE"); | ||
419 | break; | ||
420 | case TAG_GLOB_LOG_MIN : | ||
421 | strcpy(globtype,"LOG_MIN"); | ||
422 | break; | ||
423 | case TAG_GLOB_LOG_MAX : | ||
424 | strcpy(globtype,"LOG_MAX"); | ||
425 | break; | ||
426 | case TAG_GLOB_PHYS_MIN : | ||
427 | strcpy(globtype,"PHYS_MIN"); | ||
428 | break; | ||
429 | case TAG_GLOB_PHYS_MAX : | ||
430 | strcpy(globtype,"PHYS_MAX"); | ||
431 | break; | ||
432 | case TAG_GLOB_UNIT_EXP : | ||
433 | strcpy(globtype,"EXP"); | ||
434 | break; | ||
435 | case TAG_GLOB_UNIT : | ||
436 | strcpy(globtype,"UNIT"); | ||
437 | break; | ||
438 | case TAG_GLOB_REPORT_SZ : | ||
439 | strcpy(globtype,"REPORT_SZ"); | ||
440 | break; | ||
441 | case TAG_GLOB_REPORT_ID : | ||
442 | strcpy(globtype,"REPORT_ID"); | ||
443 | /* New report, restart numbering */ | ||
444 | inputnum=0; | ||
445 | break; | ||
446 | case TAG_GLOB_REPORT_CNT: | ||
447 | strcpy(globtype,"REPORT_CNT"); | ||
448 | break; | ||
449 | case TAG_GLOB_PUSH : | ||
450 | strcpy(globtype,"PUSH"); | ||
451 | break; | ||
452 | case TAG_GLOB_POP: | ||
453 | strcpy(globtype,"POP"); | ||
454 | break; | ||
455 | } | ||
456 | |||
457 | |||
458 | /* Check to make sure we have a good tag number | ||
459 | so we don't overflow array */ | ||
460 | if (tag < TAG_GLOB_MAX){ | ||
461 | switch (size){ | ||
462 | case 1: | ||
463 | dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",indentstr,globtype,tag,size,data); | ||
464 | globalval[tag]=data; | ||
465 | break; | ||
466 | case 2: | ||
467 | dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",indentstr,globtype,tag,size,data16); | ||
468 | globalval[tag]=data16; | ||
469 | break; | ||
470 | case 4: | ||
471 | dbg("%sGLOBALTAG:%s(%d) SIZE: %d Data: 0x%x",indentstr,globtype,tag,size,data32); | ||
472 | globalval[tag]=data32; | ||
473 | break; | ||
474 | } | ||
475 | }else{ | ||
476 | dbg("%sGLOBALTAG: ILLEGAL TAG:%d SIZE: %d ", | ||
477 | indentstr,tag,size); | ||
478 | } | ||
479 | |||
480 | |||
481 | break; | ||
482 | |||
483 | case TYPE_LOCAL: | ||
484 | switch(tag){ | ||
485 | case TAG_GLOB_USAGE: | ||
486 | strcpy(globtype,"USAGE"); | ||
487 | /* Always 1 byte */ | ||
488 | usage = data; | ||
489 | break; | ||
490 | case TAG_GLOB_LOG_MIN : | ||
491 | strcpy(globtype,"MIN"); | ||
492 | break; | ||
493 | case TAG_GLOB_LOG_MAX : | ||
494 | strcpy(globtype,"MAX"); | ||
495 | break; | ||
496 | default: | ||
497 | strcpy(globtype,"UNKNOWN"); | ||
498 | } | ||
499 | |||
500 | switch (size){ | ||
501 | case 1: | ||
502 | dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x", | ||
503 | indentstr,tag,globtype,size,data); | ||
504 | break; | ||
505 | case 2: | ||
506 | dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x", | ||
507 | indentstr,tag,globtype,size,data16); | ||
508 | break; | ||
509 | case 4: | ||
510 | dbg("%sLOCALTAG:(%d) %s SIZE: %d Data: 0x%x", | ||
511 | indentstr,tag,globtype,size,data32); | ||
512 | break; | ||
513 | } | ||
514 | |||
515 | break; | ||
516 | } | ||
517 | |||
518 | } | ||
519 | |||
520 | } | ||
521 | |||
522 | |||
523 | |||
524 | /* INPUT DRIVER Routines */ | ||
525 | |||
526 | |||
527 | /* | ||
528 | * Called when opening the input device. This will submit the URB to | ||
529 | * the usb system so we start getting reports | ||
530 | */ | ||
531 | static int gtco_input_open(struct input_dev *inputdev) | ||
532 | { | ||
533 | struct gtco *device; | ||
534 | device = inputdev->private; | ||
535 | |||
536 | device->urbinfo->dev = device->usbdev; | ||
537 | if (usb_submit_urb(device->urbinfo, GFP_KERNEL)) { | ||
538 | return -EIO; | ||
539 | } | ||
540 | return 0; | ||
541 | } | ||
542 | |||
543 | /** | ||
544 | Called when closing the input device. This will unlink the URB | ||
545 | */ | ||
546 | static void gtco_input_close(struct input_dev *inputdev) | ||
547 | { | ||
548 | struct gtco *device = inputdev->private; | ||
549 | |||
550 | usb_kill_urb(device->urbinfo); | ||
551 | |||
552 | } | ||
553 | |||
554 | |||
555 | /* | ||
556 | * Setup input device capabilities. Tell the input system what this | ||
557 | * device is capable of generating. | ||
558 | * | ||
559 | * This information is based on what is read from the HID report and | ||
560 | * placed in the struct gtco structure | ||
561 | * | ||
562 | */ | ||
563 | static void gtco_setup_caps(struct input_dev *inputdev) | ||
564 | { | ||
565 | struct gtco *device = inputdev->private; | ||
566 | |||
567 | |||
568 | /* Which events */ | ||
569 | inputdev->evbit[0] = BIT(EV_KEY) | BIT(EV_ABS) | BIT(EV_MSC); | ||
570 | |||
571 | |||
572 | /* Misc event menu block */ | ||
573 | inputdev->mscbit[0] = BIT(MSC_SCAN)|BIT(MSC_SERIAL)|BIT(MSC_RAW) ; | ||
574 | |||
575 | |||
576 | /* Absolute values based on HID report info */ | ||
577 | input_set_abs_params(inputdev, ABS_X, device->min_X, device->max_X, | ||
578 | 0, 0); | ||
579 | input_set_abs_params(inputdev, ABS_Y, device->min_Y, device->max_Y, | ||
580 | 0, 0); | ||
581 | |||
582 | /* Proximity */ | ||
583 | input_set_abs_params(inputdev, ABS_DISTANCE, 0, 1, 0, 0); | ||
584 | |||
585 | /* Tilt & pressure */ | ||
586 | input_set_abs_params(inputdev, ABS_TILT_X, device->mintilt_X, | ||
587 | device->maxtilt_X, 0, 0); | ||
588 | input_set_abs_params(inputdev, ABS_TILT_Y, device->mintilt_Y, | ||
589 | device->maxtilt_Y, 0, 0); | ||
590 | input_set_abs_params(inputdev, ABS_PRESSURE, device->minpressure, | ||
591 | device->maxpressure, 0, 0); | ||
592 | |||
593 | |||
594 | /* Transducer */ | ||
595 | input_set_abs_params(inputdev, ABS_MISC, 0,0xFF, 0, 0); | ||
596 | |||
597 | } | ||
598 | |||
599 | |||
600 | |||
601 | /* USB Routines */ | ||
602 | |||
603 | |||
604 | /* | ||
605 | * URB callback routine. Called when we get IRQ reports from the | ||
606 | * digitizer. | ||
607 | * | ||
608 | * This bridges the USB and input device worlds. It generates events | ||
609 | * on the input device based on the USB reports. | ||
610 | */ | ||
611 | static void gtco_urb_callback(struct urb *urbinfo) | ||
612 | { | ||
613 | |||
614 | |||
615 | struct gtco *device = urbinfo->context; | ||
616 | struct input_dev *inputdev; | ||
617 | int rc; | ||
618 | u32 val = 0; | ||
619 | s8 valsigned = 0; | ||
620 | char le_buffer[2]; | ||
621 | |||
622 | inputdev = device->inputdevice; | ||
623 | |||
624 | |||
625 | /* Was callback OK? */ | ||
626 | if ((urbinfo->status == -ECONNRESET ) || | ||
627 | (urbinfo->status == -ENOENT ) || | ||
628 | (urbinfo->status == -ESHUTDOWN )){ | ||
629 | |||
630 | /* Shutdown is occurring. Return and don't queue up any more */ | ||
631 | return; | ||
632 | } | ||
633 | |||
634 | if (urbinfo->status != 0 ) { | ||
635 | /* Some unknown error. Hopefully temporary. Just go and */ | ||
636 | /* requeue an URB */ | ||
637 | goto resubmit; | ||
638 | } | ||
639 | |||
640 | /* | ||
641 | * Good URB, now process | ||
642 | */ | ||
643 | |||
644 | /* PID dependent when we interpret the report */ | ||
645 | if ((inputdev->id.product == PID_1000 )|| | ||
646 | (inputdev->id.product == PID_1001 )|| | ||
647 | (inputdev->id.product == PID_1002 )) | ||
648 | { | ||
649 | |||
650 | /* | ||
651 | * Switch on the report ID | ||
652 | * Conveniently, the reports have more information, the higher | ||
653 | * the report number. We can just fall through the case | ||
654 | * statements if we start with the highest number report | ||
655 | */ | ||
656 | switch(device->buffer[0]){ | ||
657 | case 5: | ||
658 | /* Pressure is 9 bits */ | ||
659 | val = ((u16)(device->buffer[8]) << 1); | ||
660 | val |= (u16)(device->buffer[7] >> 7); | ||
661 | input_report_abs(inputdev, ABS_PRESSURE, | ||
662 | device->buffer[8]); | ||
663 | |||
664 | /* Mask out the Y tilt value used for pressure */ | ||
665 | device->buffer[7] = (u8)((device->buffer[7]) & 0x7F); | ||
666 | |||
667 | |||
668 | /* Fall thru */ | ||
669 | case 4: | ||
670 | /* Tilt */ | ||
671 | |||
672 | /* Sign extend these 7 bit numbers. */ | ||
673 | if (device->buffer[6] & 0x40) | ||
674 | device->buffer[6] |= 0x80; | ||
675 | |||
676 | if (device->buffer[7] & 0x40) | ||
677 | device->buffer[7] |= 0x80; | ||
678 | |||
679 | |||
680 | valsigned = (device->buffer[6]); | ||
681 | input_report_abs(inputdev, ABS_TILT_X, (s32)valsigned); | ||
682 | |||
683 | valsigned = (device->buffer[7]); | ||
684 | input_report_abs(inputdev, ABS_TILT_Y, (s32)valsigned); | ||
685 | |||
686 | /* Fall thru */ | ||
687 | |||
688 | case 2: | ||
689 | case 3: | ||
690 | /* Convert buttons, only 5 bits possible */ | ||
691 | val = (device->buffer[5])&MASK_BUTTON; | ||
692 | |||
693 | /* We don't apply any meaning to the bitmask, | ||
694 | just report */ | ||
695 | input_event(inputdev, EV_MSC, MSC_SERIAL, val); | ||
696 | |||
697 | /* Fall thru */ | ||
698 | case 1: | ||
699 | |||
700 | /* All reports have X and Y coords in the same place */ | ||
701 | val = le16_to_cpu(get_unaligned((__le16 *) &(device->buffer[1]))); | ||
702 | input_report_abs(inputdev, ABS_X, val); | ||
703 | |||
704 | val = le16_to_cpu(get_unaligned((__le16 *) &(device->buffer[3]))); | ||
705 | input_report_abs(inputdev, ABS_Y, val); | ||
706 | |||
707 | |||
708 | /* Ditto for proximity bit */ | ||
709 | if (device->buffer[5]& MASK_INRANGE){ | ||
710 | val = 1; | ||
711 | }else{ | ||
712 | val=0; | ||
713 | } | ||
714 | input_report_abs(inputdev, ABS_DISTANCE, val); | ||
715 | |||
716 | |||
717 | /* Report 1 is an exception to how we handle buttons */ | ||
718 | /* Buttons are an index, not a bitmask */ | ||
719 | if (device->buffer[0] == 1){ | ||
720 | |||
721 | /* Convert buttons, 5 bit index */ | ||
722 | /* Report value of index set as one, | ||
723 | the rest as 0 */ | ||
724 | val = device->buffer[5]& MASK_BUTTON; | ||
725 | dbg("======>>>>>>REPORT 1: val 0x%X(%d)", | ||
726 | val,val); | ||
727 | |||
728 | /* | ||
729 | * We don't apply any meaning to the button | ||
730 | * index, just report it | ||
731 | */ | ||
732 | input_event(inputdev, EV_MSC, MSC_SERIAL, val); | ||
733 | |||
734 | |||
735 | } | ||
736 | |||
737 | break; | ||
738 | case 7: | ||
739 | /* Menu blocks */ | ||
740 | input_event(inputdev, EV_MSC, MSC_SCAN, | ||
741 | device->buffer[1]); | ||
742 | |||
743 | |||
744 | break; | ||
745 | |||
746 | } | ||
747 | |||
748 | |||
749 | } | ||
750 | /* Other pid class */ | ||
751 | if ((inputdev->id.product == PID_400 )|| | ||
752 | (inputdev->id.product == PID_401 )) | ||
753 | { | ||
754 | |||
755 | /* Report 2 */ | ||
756 | if (device->buffer[0] == 2){ | ||
757 | /* Menu blocks */ | ||
758 | input_event(inputdev, EV_MSC, MSC_SCAN, | ||
759 | device->buffer[1]); | ||
760 | } | ||
761 | |||
762 | /* Report 1 */ | ||
763 | if (device->buffer[0] == 1){ | ||
764 | char buttonbyte; | ||
765 | |||
766 | |||
767 | /* IF X max > 64K, we still a bit from the y report */ | ||
768 | if (device->max_X > 0x10000){ | ||
769 | |||
770 | val = (u16)(((u16)(device->buffer[2]<<8))|((u8)(device->buffer[1]))); | ||
771 | val |= (u32)(((u8)device->buffer[3]&0x1)<< 16); | ||
772 | |||
773 | input_report_abs(inputdev, ABS_X, val); | ||
774 | |||
775 | le_buffer[0] = (u8)((u8)(device->buffer[3])>>1); | ||
776 | le_buffer[0] |= (u8)((device->buffer[3]&0x1)<<7); | ||
777 | |||
778 | le_buffer[1] = (u8)(device->buffer[4]>>1); | ||
779 | le_buffer[1] |= (u8)((device->buffer[5]&0x1)<<7); | ||
780 | |||
781 | val = le16_to_cpu(get_unaligned((__le16 *)(le_buffer))); | ||
782 | |||
783 | input_report_abs(inputdev, ABS_Y, val); | ||
784 | |||
785 | |||
786 | /* | ||
787 | * Shift the button byte right by one to | ||
788 | * make it look like the standard report | ||
789 | */ | ||
790 | buttonbyte = (device->buffer[5])>>1; | ||
791 | }else{ | ||
792 | |||
793 | val = le16_to_cpu(get_unaligned((__le16 *) (&(device->buffer[1])))); | ||
794 | input_report_abs(inputdev, ABS_X, val); | ||
795 | |||
796 | val = le16_to_cpu(get_unaligned((__le16 *) (&(device->buffer[3])))); | ||
797 | input_report_abs(inputdev, ABS_Y, val); | ||
798 | |||
799 | buttonbyte = device->buffer[5]; | ||
800 | |||
801 | } | ||
802 | |||
803 | |||
804 | /* BUTTONS and PROXIMITY */ | ||
805 | if (buttonbyte& MASK_INRANGE){ | ||
806 | val = 1; | ||
807 | }else{ | ||
808 | val=0; | ||
809 | } | ||
810 | input_report_abs(inputdev, ABS_DISTANCE, val); | ||
811 | |||
812 | /* Convert buttons, only 4 bits possible */ | ||
813 | val = buttonbyte&0x0F; | ||
814 | #ifdef USE_BUTTONS | ||
815 | for ( i=0;i<5;i++){ | ||
816 | input_report_key(inputdev, BTN_DIGI+i,val&(1<<i)); | ||
817 | } | ||
818 | #else | ||
819 | /* We don't apply any meaning to the bitmask, just report */ | ||
820 | input_event(inputdev, EV_MSC, MSC_SERIAL, val); | ||
821 | #endif | ||
822 | /* TRANSDUCER */ | ||
823 | input_report_abs(inputdev, ABS_MISC, device->buffer[6]); | ||
824 | |||
825 | } | ||
826 | } | ||
827 | |||
828 | /* Everybody gets report ID's */ | ||
829 | input_event(inputdev, EV_MSC, MSC_RAW, device->buffer[0]); | ||
830 | |||
831 | /* Sync it up */ | ||
832 | input_sync(inputdev); | ||
833 | |||
834 | resubmit: | ||
835 | rc = usb_submit_urb(urbinfo, GFP_ATOMIC); | ||
836 | if (rc != 0) { | ||
837 | err("usb_submit_urb failed rc=0x%x",rc); | ||
838 | } | ||
839 | |||
840 | } | ||
841 | |||
842 | /* | ||
843 | * The probe routine. This is called when the kernel find the matching USB | ||
844 | * vendor/product. We do the following: | ||
845 | * | ||
846 | * - Allocate mem for a local structure to manage the device | ||
847 | * - Request a HID Report Descriptor from the device and parse it to | ||
848 | * find out the device parameters | ||
849 | * - Create an input device and assign it attributes | ||
850 | * - Allocate an URB so the device can talk to us when the input | ||
851 | * queue is open | ||
852 | */ | ||
853 | static int gtco_probe(struct usb_interface *usbinterface, | ||
854 | const struct usb_device_id *id) | ||
855 | { | ||
856 | |||
857 | struct gtco *device = NULL; | ||
858 | char path[PATHLENGTH]; | ||
859 | struct input_dev *inputdev; | ||
860 | struct hid_descriptor *hid_desc; | ||
861 | char *report; | ||
862 | int result=0, retry; | ||
863 | struct usb_endpoint_descriptor *endpoint; | ||
864 | |||
865 | /* Allocate memory for device structure */ | ||
866 | device = kzalloc(sizeof(struct gtco), GFP_KERNEL); | ||
867 | if (device == NULL) { | ||
868 | err("No more memory"); | ||
869 | return -ENOMEM; | ||
870 | } | ||
871 | |||
872 | |||
873 | device->inputdevice = input_allocate_device(); | ||
874 | if (!device->inputdevice){ | ||
875 | kfree(device); | ||
876 | err("No more memory"); | ||
877 | return -ENOMEM; | ||
878 | } | ||
879 | |||
880 | /* Get pointer to the input device */ | ||
881 | inputdev = device->inputdevice; | ||
882 | |||
883 | /* Save interface information */ | ||
884 | device->usbdev = usb_get_dev(interface_to_usbdev(usbinterface)); | ||
885 | |||
886 | |||
887 | /* Allocate some data for incoming reports */ | ||
888 | device->buffer = usb_buffer_alloc(device->usbdev, REPORT_MAX_SIZE, | ||
889 | GFP_KERNEL, &(device->buf_dma)); | ||
890 | if (!device->buffer){ | ||
891 | input_free_device(device->inputdevice); | ||
892 | kfree(device); | ||
893 | err("No more memory"); | ||
894 | return -ENOMEM; | ||
895 | } | ||
896 | |||
897 | /* Allocate URB for reports */ | ||
898 | device->urbinfo = usb_alloc_urb(0, GFP_KERNEL); | ||
899 | if (!device->urbinfo) { | ||
900 | usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, | ||
901 | device->buffer, device->buf_dma); | ||
902 | input_free_device(device->inputdevice); | ||
903 | kfree(device); | ||
904 | err("No more memory"); | ||
905 | return -ENOMEM; | ||
906 | } | ||
907 | |||
908 | |||
909 | /* | ||
910 | * The endpoint is always altsetting 0, we know this since we know | ||
911 | * this device only has one interrupt endpoint | ||
912 | */ | ||
913 | endpoint = &usbinterface->altsetting[0].endpoint[0].desc; | ||
914 | |||
915 | /* Some debug */ | ||
916 | dbg("gtco # interfaces: %d",usbinterface->num_altsetting); | ||
917 | dbg("num endpoints: %d",usbinterface->cur_altsetting->desc.bNumEndpoints); | ||
918 | dbg("interface class: %d",usbinterface->cur_altsetting->desc.bInterfaceClass); | ||
919 | dbg("endpoint: attribute:0x%x type:0x%x",endpoint->bmAttributes,endpoint->bDescriptorType); | ||
920 | if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) | ||
921 | dbg("endpoint: we have interrupt endpoint\n"); | ||
922 | |||
923 | dbg("endpoint extra len:%d ",usbinterface->altsetting[0].extralen); | ||
924 | |||
925 | |||
926 | |||
927 | /* | ||
928 | * Find the HID descriptor so we can find out the size of the | ||
929 | * HID report descriptor | ||
930 | */ | ||
931 | if (usb_get_extra_descriptor(usbinterface->cur_altsetting, | ||
932 | HID_DEVICE_TYPE,&hid_desc) != 0){ | ||
933 | err("Can't retrieve exta USB descriptor to get hid report descriptor length"); | ||
934 | usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, | ||
935 | device->buffer, device->buf_dma); | ||
936 | input_free_device(device->inputdevice); | ||
937 | kfree(device); | ||
938 | return -EIO; | ||
939 | } | ||
940 | |||
941 | dbg("Extra descriptor success: type:%d len:%d", | ||
942 | hid_desc->bDescriptorType, hid_desc->wDescriptorLength); | ||
943 | |||
944 | if (!(report = kzalloc(hid_desc->wDescriptorLength, GFP_KERNEL))) { | ||
945 | usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, | ||
946 | device->buffer, device->buf_dma); | ||
947 | |||
948 | input_free_device(device->inputdevice); | ||
949 | kfree(device); | ||
950 | err("No more memory"); | ||
951 | return -ENOMEM; | ||
952 | } | ||
953 | |||
954 | /* Couple of tries to get reply */ | ||
955 | for (retry=0;retry<3;retry++) { | ||
956 | result = usb_control_msg(device->usbdev, | ||
957 | usb_rcvctrlpipe(device->usbdev, 0), | ||
958 | USB_REQ_GET_DESCRIPTOR, | ||
959 | USB_RECIP_INTERFACE | USB_DIR_IN, | ||
960 | (REPORT_DEVICE_TYPE << 8), | ||
961 | 0, /* interface */ | ||
962 | report, | ||
963 | hid_desc->wDescriptorLength, | ||
964 | 5000); /* 5 secs */ | ||
965 | |||
966 | if (result == hid_desc->wDescriptorLength) | ||
967 | break; | ||
968 | } | ||
969 | |||
970 | /* If we didn't get the report, fail */ | ||
971 | dbg("usb_control_msg result: :%d", result); | ||
972 | if (result != hid_desc->wDescriptorLength){ | ||
973 | kfree(report); | ||
974 | usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, | ||
975 | device->buffer, device->buf_dma); | ||
976 | input_free_device(device->inputdevice); | ||
977 | kfree(device); | ||
978 | err("Failed to get HID Report Descriptor of size: %d", | ||
979 | hid_desc->wDescriptorLength); | ||
980 | return -EIO; | ||
981 | } | ||
982 | |||
983 | |||
984 | /* Now we parse the report */ | ||
985 | parse_hid_report_descriptor(device,report,result); | ||
986 | |||
987 | /* Now we delete it */ | ||
988 | kfree(report); | ||
989 | |||
990 | /* Create a device file node */ | ||
991 | usb_make_path(device->usbdev, path, PATHLENGTH); | ||
992 | sprintf(device->usbpath, "%s/input0", path); | ||
993 | |||
994 | |||
995 | /* Set Input device functions */ | ||
996 | inputdev->open = gtco_input_open; | ||
997 | inputdev->close = gtco_input_close; | ||
998 | |||
999 | /* Set input device information */ | ||
1000 | inputdev->name = "GTCO_CalComp"; | ||
1001 | inputdev->phys = device->usbpath; | ||
1002 | inputdev->private = device; | ||
1003 | |||
1004 | |||
1005 | /* Now set up all the input device capabilities */ | ||
1006 | gtco_setup_caps(inputdev); | ||
1007 | |||
1008 | /* Set input device required ID information */ | ||
1009 | usb_to_input_id(device->usbdev, &device->inputdevice->id); | ||
1010 | inputdev->cdev.dev = &usbinterface->dev; | ||
1011 | |||
1012 | /* Setup the URB, it will be posted later on open of input device */ | ||
1013 | endpoint = &usbinterface->altsetting[0].endpoint[0].desc; | ||
1014 | |||
1015 | usb_fill_int_urb(device->urbinfo, | ||
1016 | device->usbdev, | ||
1017 | usb_rcvintpipe(device->usbdev, | ||
1018 | endpoint->bEndpointAddress), | ||
1019 | device->buffer, | ||
1020 | REPORT_MAX_SIZE, | ||
1021 | gtco_urb_callback, | ||
1022 | device, | ||
1023 | endpoint->bInterval); | ||
1024 | |||
1025 | device->urbinfo->transfer_dma = device->buf_dma; | ||
1026 | device->urbinfo->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
1027 | |||
1028 | |||
1029 | /* Save device pointer in USB interface device */ | ||
1030 | usb_set_intfdata(usbinterface, device); | ||
1031 | |||
1032 | /* All done, now register the input device */ | ||
1033 | input_register_device(inputdev); | ||
1034 | |||
1035 | info( "gtco driver created usb: %s\n", path); | ||
1036 | return 0; | ||
1037 | |||
1038 | } | ||
1039 | |||
1040 | /* | ||
1041 | * This function is a standard USB function called when the USB device | ||
1042 | * is disconnected. We will get rid of the URV, de-register the input | ||
1043 | * device, and free up allocated memory | ||
1044 | */ | ||
1045 | static void gtco_disconnect(struct usb_interface *interface) | ||
1046 | { | ||
1047 | |||
1048 | /* Grab private device ptr */ | ||
1049 | struct gtco *device = usb_get_intfdata (interface); | ||
1050 | struct input_dev *inputdev; | ||
1051 | |||
1052 | inputdev = device->inputdevice; | ||
1053 | |||
1054 | /* Now reverse all the registration stuff */ | ||
1055 | if (device) { | ||
1056 | input_unregister_device(inputdev); | ||
1057 | usb_kill_urb(device->urbinfo); | ||
1058 | usb_free_urb(device->urbinfo); | ||
1059 | usb_buffer_free(device->usbdev, REPORT_MAX_SIZE, | ||
1060 | device->buffer, device->buf_dma); | ||
1061 | kfree(device); | ||
1062 | } | ||
1063 | |||
1064 | info("gtco driver disconnected"); | ||
1065 | } | ||
1066 | |||
1067 | |||
1068 | /* STANDARD MODULE LOAD ROUTINES */ | ||
1069 | |||
1070 | static struct usb_driver gtco_driverinfo_table = { | ||
1071 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)) | ||
1072 | .owner = THIS_MODULE, | ||
1073 | #endif | ||
1074 | .name = "gtco", | ||
1075 | .id_table = gtco_usbid_table, | ||
1076 | .probe = gtco_probe, | ||
1077 | .disconnect = gtco_disconnect, | ||
1078 | }; | ||
1079 | /* | ||
1080 | * Register this module with the USB subsystem | ||
1081 | */ | ||
1082 | static int __init gtco_init(void) | ||
1083 | { | ||
1084 | int rc; | ||
1085 | rc = usb_register(>co_driverinfo_table); | ||
1086 | if (rc) { | ||
1087 | err("usb_register() failed rc=0x%x", rc); | ||
1088 | } | ||
1089 | printk("GTCO usb driver version: %s",GTCO_VERSION); | ||
1090 | return rc; | ||
1091 | } | ||
1092 | |||
1093 | /* | ||
1094 | * Deregister this module with the USB subsystem | ||
1095 | */ | ||
1096 | static void __exit gtco_exit(void) | ||
1097 | { | ||
1098 | usb_deregister(>co_driverinfo_table); | ||
1099 | } | ||
1100 | |||
1101 | module_init (gtco_init); | ||
1102 | module_exit (gtco_exit); | ||
1103 | |||
1104 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 0811c39bd14f..84983d1b7164 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c | |||
@@ -4,6 +4,7 @@ | |||
4 | * Copyright (c) 1999 Andreas Gal | 4 | * Copyright (c) 1999 Andreas Gal |
5 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> | 5 | * Copyright (c) 2000-2005 Vojtech Pavlik <vojtech@suse.cz> |
6 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc | 6 | * Copyright (c) 2005 Michael Haboustak <mike-@cinci.rr.com> for Concept2, Inc |
7 | * Copyright (c) 2006 Jiri Kosina | ||
7 | */ | 8 | */ |
8 | 9 | ||
9 | /* | 10 | /* |
@@ -32,8 +33,10 @@ | |||
32 | 33 | ||
33 | #include <linux/usb.h> | 34 | #include <linux/usb.h> |
34 | 35 | ||
35 | #include "hid.h" | 36 | #include <linux/hid.h> |
36 | #include <linux/hiddev.h> | 37 | #include <linux/hiddev.h> |
38 | #include <linux/hid-debug.h> | ||
39 | #include "usbhid.h" | ||
37 | 40 | ||
38 | /* | 41 | /* |
39 | * Version Information | 42 | * Version Information |
@@ -55,887 +58,6 @@ module_param_named(mousepoll, hid_mousepoll_interval, uint, 0644); | |||
55 | MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); | 58 | MODULE_PARM_DESC(mousepoll, "Polling interval of mice"); |
56 | 59 | ||
57 | /* | 60 | /* |
58 | * Register a new report for a device. | ||
59 | */ | ||
60 | |||
61 | static struct hid_report *hid_register_report(struct hid_device *device, unsigned type, unsigned id) | ||
62 | { | ||
63 | struct hid_report_enum *report_enum = device->report_enum + type; | ||
64 | struct hid_report *report; | ||
65 | |||
66 | if (report_enum->report_id_hash[id]) | ||
67 | return report_enum->report_id_hash[id]; | ||
68 | |||
69 | if (!(report = kzalloc(sizeof(struct hid_report), GFP_KERNEL))) | ||
70 | return NULL; | ||
71 | |||
72 | if (id != 0) | ||
73 | report_enum->numbered = 1; | ||
74 | |||
75 | report->id = id; | ||
76 | report->type = type; | ||
77 | report->size = 0; | ||
78 | report->device = device; | ||
79 | report_enum->report_id_hash[id] = report; | ||
80 | |||
81 | list_add_tail(&report->list, &report_enum->report_list); | ||
82 | |||
83 | return report; | ||
84 | } | ||
85 | |||
86 | /* | ||
87 | * Register a new field for this report. | ||
88 | */ | ||
89 | |||
90 | static struct hid_field *hid_register_field(struct hid_report *report, unsigned usages, unsigned values) | ||
91 | { | ||
92 | struct hid_field *field; | ||
93 | |||
94 | if (report->maxfield == HID_MAX_FIELDS) { | ||
95 | dbg("too many fields in report"); | ||
96 | return NULL; | ||
97 | } | ||
98 | |||
99 | if (!(field = kzalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage) | ||
100 | + values * sizeof(unsigned), GFP_KERNEL))) return NULL; | ||
101 | |||
102 | field->index = report->maxfield++; | ||
103 | report->field[field->index] = field; | ||
104 | field->usage = (struct hid_usage *)(field + 1); | ||
105 | field->value = (unsigned *)(field->usage + usages); | ||
106 | field->report = report; | ||
107 | |||
108 | return field; | ||
109 | } | ||
110 | |||
111 | /* | ||
112 | * Open a collection. The type/usage is pushed on the stack. | ||
113 | */ | ||
114 | |||
115 | static int open_collection(struct hid_parser *parser, unsigned type) | ||
116 | { | ||
117 | struct hid_collection *collection; | ||
118 | unsigned usage; | ||
119 | |||
120 | usage = parser->local.usage[0]; | ||
121 | |||
122 | if (parser->collection_stack_ptr == HID_COLLECTION_STACK_SIZE) { | ||
123 | dbg("collection stack overflow"); | ||
124 | return -1; | ||
125 | } | ||
126 | |||
127 | if (parser->device->maxcollection == parser->device->collection_size) { | ||
128 | collection = kmalloc(sizeof(struct hid_collection) * | ||
129 | parser->device->collection_size * 2, GFP_KERNEL); | ||
130 | if (collection == NULL) { | ||
131 | dbg("failed to reallocate collection array"); | ||
132 | return -1; | ||
133 | } | ||
134 | memcpy(collection, parser->device->collection, | ||
135 | sizeof(struct hid_collection) * | ||
136 | parser->device->collection_size); | ||
137 | memset(collection + parser->device->collection_size, 0, | ||
138 | sizeof(struct hid_collection) * | ||
139 | parser->device->collection_size); | ||
140 | kfree(parser->device->collection); | ||
141 | parser->device->collection = collection; | ||
142 | parser->device->collection_size *= 2; | ||
143 | } | ||
144 | |||
145 | parser->collection_stack[parser->collection_stack_ptr++] = | ||
146 | parser->device->maxcollection; | ||
147 | |||
148 | collection = parser->device->collection + | ||
149 | parser->device->maxcollection++; | ||
150 | collection->type = type; | ||
151 | collection->usage = usage; | ||
152 | collection->level = parser->collection_stack_ptr - 1; | ||
153 | |||
154 | if (type == HID_COLLECTION_APPLICATION) | ||
155 | parser->device->maxapplication++; | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | /* | ||
161 | * Close a collection. | ||
162 | */ | ||
163 | |||
164 | static int close_collection(struct hid_parser *parser) | ||
165 | { | ||
166 | if (!parser->collection_stack_ptr) { | ||
167 | dbg("collection stack underflow"); | ||
168 | return -1; | ||
169 | } | ||
170 | parser->collection_stack_ptr--; | ||
171 | return 0; | ||
172 | } | ||
173 | |||
174 | /* | ||
175 | * Climb up the stack, search for the specified collection type | ||
176 | * and return the usage. | ||
177 | */ | ||
178 | |||
179 | static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type) | ||
180 | { | ||
181 | int n; | ||
182 | for (n = parser->collection_stack_ptr - 1; n >= 0; n--) | ||
183 | if (parser->device->collection[parser->collection_stack[n]].type == type) | ||
184 | return parser->device->collection[parser->collection_stack[n]].usage; | ||
185 | return 0; /* we know nothing about this usage type */ | ||
186 | } | ||
187 | |||
188 | /* | ||
189 | * Add a usage to the temporary parser table. | ||
190 | */ | ||
191 | |||
192 | static int hid_add_usage(struct hid_parser *parser, unsigned usage) | ||
193 | { | ||
194 | if (parser->local.usage_index >= HID_MAX_USAGES) { | ||
195 | dbg("usage index exceeded"); | ||
196 | return -1; | ||
197 | } | ||
198 | parser->local.usage[parser->local.usage_index] = usage; | ||
199 | parser->local.collection_index[parser->local.usage_index] = | ||
200 | parser->collection_stack_ptr ? | ||
201 | parser->collection_stack[parser->collection_stack_ptr - 1] : 0; | ||
202 | parser->local.usage_index++; | ||
203 | return 0; | ||
204 | } | ||
205 | |||
206 | /* | ||
207 | * Register a new field for this report. | ||
208 | */ | ||
209 | |||
210 | static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsigned flags) | ||
211 | { | ||
212 | struct hid_report *report; | ||
213 | struct hid_field *field; | ||
214 | int usages; | ||
215 | unsigned offset; | ||
216 | int i; | ||
217 | |||
218 | if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) { | ||
219 | dbg("hid_register_report failed"); | ||
220 | return -1; | ||
221 | } | ||
222 | |||
223 | if (parser->global.logical_maximum < parser->global.logical_minimum) { | ||
224 | dbg("logical range invalid %d %d", parser->global.logical_minimum, parser->global.logical_maximum); | ||
225 | return -1; | ||
226 | } | ||
227 | |||
228 | offset = report->size; | ||
229 | report->size += parser->global.report_size * parser->global.report_count; | ||
230 | |||
231 | if (!parser->local.usage_index) /* Ignore padding fields */ | ||
232 | return 0; | ||
233 | |||
234 | usages = max_t(int, parser->local.usage_index, parser->global.report_count); | ||
235 | |||
236 | if ((field = hid_register_field(report, usages, parser->global.report_count)) == NULL) | ||
237 | return 0; | ||
238 | |||
239 | field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL); | ||
240 | field->logical = hid_lookup_collection(parser, HID_COLLECTION_LOGICAL); | ||
241 | field->application = hid_lookup_collection(parser, HID_COLLECTION_APPLICATION); | ||
242 | |||
243 | for (i = 0; i < usages; i++) { | ||
244 | int j = i; | ||
245 | /* Duplicate the last usage we parsed if we have excess values */ | ||
246 | if (i >= parser->local.usage_index) | ||
247 | j = parser->local.usage_index - 1; | ||
248 | field->usage[i].hid = parser->local.usage[j]; | ||
249 | field->usage[i].collection_index = | ||
250 | parser->local.collection_index[j]; | ||
251 | } | ||
252 | |||
253 | field->maxusage = usages; | ||
254 | field->flags = flags; | ||
255 | field->report_offset = offset; | ||
256 | field->report_type = report_type; | ||
257 | field->report_size = parser->global.report_size; | ||
258 | field->report_count = parser->global.report_count; | ||
259 | field->logical_minimum = parser->global.logical_minimum; | ||
260 | field->logical_maximum = parser->global.logical_maximum; | ||
261 | field->physical_minimum = parser->global.physical_minimum; | ||
262 | field->physical_maximum = parser->global.physical_maximum; | ||
263 | field->unit_exponent = parser->global.unit_exponent; | ||
264 | field->unit = parser->global.unit; | ||
265 | |||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | /* | ||
270 | * Read data value from item. | ||
271 | */ | ||
272 | |||
273 | static u32 item_udata(struct hid_item *item) | ||
274 | { | ||
275 | switch (item->size) { | ||
276 | case 1: return item->data.u8; | ||
277 | case 2: return item->data.u16; | ||
278 | case 4: return item->data.u32; | ||
279 | } | ||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | static s32 item_sdata(struct hid_item *item) | ||
284 | { | ||
285 | switch (item->size) { | ||
286 | case 1: return item->data.s8; | ||
287 | case 2: return item->data.s16; | ||
288 | case 4: return item->data.s32; | ||
289 | } | ||
290 | return 0; | ||
291 | } | ||
292 | |||
293 | /* | ||
294 | * Process a global item. | ||
295 | */ | ||
296 | |||
297 | static int hid_parser_global(struct hid_parser *parser, struct hid_item *item) | ||
298 | { | ||
299 | switch (item->tag) { | ||
300 | |||
301 | case HID_GLOBAL_ITEM_TAG_PUSH: | ||
302 | |||
303 | if (parser->global_stack_ptr == HID_GLOBAL_STACK_SIZE) { | ||
304 | dbg("global enviroment stack overflow"); | ||
305 | return -1; | ||
306 | } | ||
307 | |||
308 | memcpy(parser->global_stack + parser->global_stack_ptr++, | ||
309 | &parser->global, sizeof(struct hid_global)); | ||
310 | return 0; | ||
311 | |||
312 | case HID_GLOBAL_ITEM_TAG_POP: | ||
313 | |||
314 | if (!parser->global_stack_ptr) { | ||
315 | dbg("global enviroment stack underflow"); | ||
316 | return -1; | ||
317 | } | ||
318 | |||
319 | memcpy(&parser->global, parser->global_stack + --parser->global_stack_ptr, | ||
320 | sizeof(struct hid_global)); | ||
321 | return 0; | ||
322 | |||
323 | case HID_GLOBAL_ITEM_TAG_USAGE_PAGE: | ||
324 | parser->global.usage_page = item_udata(item); | ||
325 | return 0; | ||
326 | |||
327 | case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM: | ||
328 | parser->global.logical_minimum = item_sdata(item); | ||
329 | return 0; | ||
330 | |||
331 | case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM: | ||
332 | if (parser->global.logical_minimum < 0) | ||
333 | parser->global.logical_maximum = item_sdata(item); | ||
334 | else | ||
335 | parser->global.logical_maximum = item_udata(item); | ||
336 | return 0; | ||
337 | |||
338 | case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM: | ||
339 | parser->global.physical_minimum = item_sdata(item); | ||
340 | return 0; | ||
341 | |||
342 | case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM: | ||
343 | if (parser->global.physical_minimum < 0) | ||
344 | parser->global.physical_maximum = item_sdata(item); | ||
345 | else | ||
346 | parser->global.physical_maximum = item_udata(item); | ||
347 | return 0; | ||
348 | |||
349 | case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT: | ||
350 | parser->global.unit_exponent = item_sdata(item); | ||
351 | return 0; | ||
352 | |||
353 | case HID_GLOBAL_ITEM_TAG_UNIT: | ||
354 | parser->global.unit = item_udata(item); | ||
355 | return 0; | ||
356 | |||
357 | case HID_GLOBAL_ITEM_TAG_REPORT_SIZE: | ||
358 | if ((parser->global.report_size = item_udata(item)) > 32) { | ||
359 | dbg("invalid report_size %d", parser->global.report_size); | ||
360 | return -1; | ||
361 | } | ||
362 | return 0; | ||
363 | |||
364 | case HID_GLOBAL_ITEM_TAG_REPORT_COUNT: | ||
365 | if ((parser->global.report_count = item_udata(item)) > HID_MAX_USAGES) { | ||
366 | dbg("invalid report_count %d", parser->global.report_count); | ||
367 | return -1; | ||
368 | } | ||
369 | return 0; | ||
370 | |||
371 | case HID_GLOBAL_ITEM_TAG_REPORT_ID: | ||
372 | if ((parser->global.report_id = item_udata(item)) == 0) { | ||
373 | dbg("report_id 0 is invalid"); | ||
374 | return -1; | ||
375 | } | ||
376 | return 0; | ||
377 | |||
378 | default: | ||
379 | dbg("unknown global tag 0x%x", item->tag); | ||
380 | return -1; | ||
381 | } | ||
382 | } | ||
383 | |||
384 | /* | ||
385 | * Process a local item. | ||
386 | */ | ||
387 | |||
388 | static int hid_parser_local(struct hid_parser *parser, struct hid_item *item) | ||
389 | { | ||
390 | __u32 data; | ||
391 | unsigned n; | ||
392 | |||
393 | if (item->size == 0) { | ||
394 | dbg("item data expected for local item"); | ||
395 | return -1; | ||
396 | } | ||
397 | |||
398 | data = item_udata(item); | ||
399 | |||
400 | switch (item->tag) { | ||
401 | |||
402 | case HID_LOCAL_ITEM_TAG_DELIMITER: | ||
403 | |||
404 | if (data) { | ||
405 | /* | ||
406 | * We treat items before the first delimiter | ||
407 | * as global to all usage sets (branch 0). | ||
408 | * In the moment we process only these global | ||
409 | * items and the first delimiter set. | ||
410 | */ | ||
411 | if (parser->local.delimiter_depth != 0) { | ||
412 | dbg("nested delimiters"); | ||
413 | return -1; | ||
414 | } | ||
415 | parser->local.delimiter_depth++; | ||
416 | parser->local.delimiter_branch++; | ||
417 | } else { | ||
418 | if (parser->local.delimiter_depth < 1) { | ||
419 | dbg("bogus close delimiter"); | ||
420 | return -1; | ||
421 | } | ||
422 | parser->local.delimiter_depth--; | ||
423 | } | ||
424 | return 1; | ||
425 | |||
426 | case HID_LOCAL_ITEM_TAG_USAGE: | ||
427 | |||
428 | if (parser->local.delimiter_branch > 1) { | ||
429 | dbg("alternative usage ignored"); | ||
430 | return 0; | ||
431 | } | ||
432 | |||
433 | if (item->size <= 2) | ||
434 | data = (parser->global.usage_page << 16) + data; | ||
435 | |||
436 | return hid_add_usage(parser, data); | ||
437 | |||
438 | case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM: | ||
439 | |||
440 | if (parser->local.delimiter_branch > 1) { | ||
441 | dbg("alternative usage ignored"); | ||
442 | return 0; | ||
443 | } | ||
444 | |||
445 | if (item->size <= 2) | ||
446 | data = (parser->global.usage_page << 16) + data; | ||
447 | |||
448 | parser->local.usage_minimum = data; | ||
449 | return 0; | ||
450 | |||
451 | case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM: | ||
452 | |||
453 | if (parser->local.delimiter_branch > 1) { | ||
454 | dbg("alternative usage ignored"); | ||
455 | return 0; | ||
456 | } | ||
457 | |||
458 | if (item->size <= 2) | ||
459 | data = (parser->global.usage_page << 16) + data; | ||
460 | |||
461 | for (n = parser->local.usage_minimum; n <= data; n++) | ||
462 | if (hid_add_usage(parser, n)) { | ||
463 | dbg("hid_add_usage failed\n"); | ||
464 | return -1; | ||
465 | } | ||
466 | return 0; | ||
467 | |||
468 | default: | ||
469 | |||
470 | dbg("unknown local item tag 0x%x", item->tag); | ||
471 | return 0; | ||
472 | } | ||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | /* | ||
477 | * Process a main item. | ||
478 | */ | ||
479 | |||
480 | static int hid_parser_main(struct hid_parser *parser, struct hid_item *item) | ||
481 | { | ||
482 | __u32 data; | ||
483 | int ret; | ||
484 | |||
485 | data = item_udata(item); | ||
486 | |||
487 | switch (item->tag) { | ||
488 | case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION: | ||
489 | ret = open_collection(parser, data & 0xff); | ||
490 | break; | ||
491 | case HID_MAIN_ITEM_TAG_END_COLLECTION: | ||
492 | ret = close_collection(parser); | ||
493 | break; | ||
494 | case HID_MAIN_ITEM_TAG_INPUT: | ||
495 | ret = hid_add_field(parser, HID_INPUT_REPORT, data); | ||
496 | break; | ||
497 | case HID_MAIN_ITEM_TAG_OUTPUT: | ||
498 | ret = hid_add_field(parser, HID_OUTPUT_REPORT, data); | ||
499 | break; | ||
500 | case HID_MAIN_ITEM_TAG_FEATURE: | ||
501 | ret = hid_add_field(parser, HID_FEATURE_REPORT, data); | ||
502 | break; | ||
503 | default: | ||
504 | dbg("unknown main item tag 0x%x", item->tag); | ||
505 | ret = 0; | ||
506 | } | ||
507 | |||
508 | memset(&parser->local, 0, sizeof(parser->local)); /* Reset the local parser environment */ | ||
509 | |||
510 | return ret; | ||
511 | } | ||
512 | |||
513 | /* | ||
514 | * Process a reserved item. | ||
515 | */ | ||
516 | |||
517 | static int hid_parser_reserved(struct hid_parser *parser, struct hid_item *item) | ||
518 | { | ||
519 | dbg("reserved item type, tag 0x%x", item->tag); | ||
520 | return 0; | ||
521 | } | ||
522 | |||
523 | /* | ||
524 | * Free a report and all registered fields. The field->usage and | ||
525 | * field->value table's are allocated behind the field, so we need | ||
526 | * only to free(field) itself. | ||
527 | */ | ||
528 | |||
529 | static void hid_free_report(struct hid_report *report) | ||
530 | { | ||
531 | unsigned n; | ||
532 | |||
533 | for (n = 0; n < report->maxfield; n++) | ||
534 | kfree(report->field[n]); | ||
535 | kfree(report); | ||
536 | } | ||
537 | |||
538 | /* | ||
539 | * Free a device structure, all reports, and all fields. | ||
540 | */ | ||
541 | |||
542 | static void hid_free_device(struct hid_device *device) | ||
543 | { | ||
544 | unsigned i,j; | ||
545 | |||
546 | for (i = 0; i < HID_REPORT_TYPES; i++) { | ||
547 | struct hid_report_enum *report_enum = device->report_enum + i; | ||
548 | |||
549 | for (j = 0; j < 256; j++) { | ||
550 | struct hid_report *report = report_enum->report_id_hash[j]; | ||
551 | if (report) | ||
552 | hid_free_report(report); | ||
553 | } | ||
554 | } | ||
555 | |||
556 | kfree(device->rdesc); | ||
557 | kfree(device); | ||
558 | } | ||
559 | |||
560 | /* | ||
561 | * Fetch a report description item from the data stream. We support long | ||
562 | * items, though they are not used yet. | ||
563 | */ | ||
564 | |||
565 | static u8 *fetch_item(__u8 *start, __u8 *end, struct hid_item *item) | ||
566 | { | ||
567 | u8 b; | ||
568 | |||
569 | if ((end - start) <= 0) | ||
570 | return NULL; | ||
571 | |||
572 | b = *start++; | ||
573 | |||
574 | item->type = (b >> 2) & 3; | ||
575 | item->tag = (b >> 4) & 15; | ||
576 | |||
577 | if (item->tag == HID_ITEM_TAG_LONG) { | ||
578 | |||
579 | item->format = HID_ITEM_FORMAT_LONG; | ||
580 | |||
581 | if ((end - start) < 2) | ||
582 | return NULL; | ||
583 | |||
584 | item->size = *start++; | ||
585 | item->tag = *start++; | ||
586 | |||
587 | if ((end - start) < item->size) | ||
588 | return NULL; | ||
589 | |||
590 | item->data.longdata = start; | ||
591 | start += item->size; | ||
592 | return start; | ||
593 | } | ||
594 | |||
595 | item->format = HID_ITEM_FORMAT_SHORT; | ||
596 | item->size = b & 3; | ||
597 | |||
598 | switch (item->size) { | ||
599 | |||
600 | case 0: | ||
601 | return start; | ||
602 | |||
603 | case 1: | ||
604 | if ((end - start) < 1) | ||
605 | return NULL; | ||
606 | item->data.u8 = *start++; | ||
607 | return start; | ||
608 | |||
609 | case 2: | ||
610 | if ((end - start) < 2) | ||
611 | return NULL; | ||
612 | item->data.u16 = le16_to_cpu(get_unaligned((__le16*)start)); | ||
613 | start = (__u8 *)((__le16 *)start + 1); | ||
614 | return start; | ||
615 | |||
616 | case 3: | ||
617 | item->size++; | ||
618 | if ((end - start) < 4) | ||
619 | return NULL; | ||
620 | item->data.u32 = le32_to_cpu(get_unaligned((__le32*)start)); | ||
621 | start = (__u8 *)((__le32 *)start + 1); | ||
622 | return start; | ||
623 | } | ||
624 | |||
625 | return NULL; | ||
626 | } | ||
627 | |||
628 | /* | ||
629 | * Parse a report description into a hid_device structure. Reports are | ||
630 | * enumerated, fields are attached to these reports. | ||
631 | */ | ||
632 | |||
633 | static struct hid_device *hid_parse_report(__u8 *start, unsigned size) | ||
634 | { | ||
635 | struct hid_device *device; | ||
636 | struct hid_parser *parser; | ||
637 | struct hid_item item; | ||
638 | __u8 *end; | ||
639 | unsigned i; | ||
640 | static int (*dispatch_type[])(struct hid_parser *parser, | ||
641 | struct hid_item *item) = { | ||
642 | hid_parser_main, | ||
643 | hid_parser_global, | ||
644 | hid_parser_local, | ||
645 | hid_parser_reserved | ||
646 | }; | ||
647 | |||
648 | if (!(device = kzalloc(sizeof(struct hid_device), GFP_KERNEL))) | ||
649 | return NULL; | ||
650 | |||
651 | if (!(device->collection = kzalloc(sizeof(struct hid_collection) * | ||
652 | HID_DEFAULT_NUM_COLLECTIONS, GFP_KERNEL))) { | ||
653 | kfree(device); | ||
654 | return NULL; | ||
655 | } | ||
656 | device->collection_size = HID_DEFAULT_NUM_COLLECTIONS; | ||
657 | |||
658 | for (i = 0; i < HID_REPORT_TYPES; i++) | ||
659 | INIT_LIST_HEAD(&device->report_enum[i].report_list); | ||
660 | |||
661 | if (!(device->rdesc = (__u8 *)kmalloc(size, GFP_KERNEL))) { | ||
662 | kfree(device->collection); | ||
663 | kfree(device); | ||
664 | return NULL; | ||
665 | } | ||
666 | memcpy(device->rdesc, start, size); | ||
667 | device->rsize = size; | ||
668 | |||
669 | if (!(parser = kzalloc(sizeof(struct hid_parser), GFP_KERNEL))) { | ||
670 | kfree(device->rdesc); | ||
671 | kfree(device->collection); | ||
672 | kfree(device); | ||
673 | return NULL; | ||
674 | } | ||
675 | parser->device = device; | ||
676 | |||
677 | end = start + size; | ||
678 | while ((start = fetch_item(start, end, &item)) != NULL) { | ||
679 | |||
680 | if (item.format != HID_ITEM_FORMAT_SHORT) { | ||
681 | dbg("unexpected long global item"); | ||
682 | kfree(device->collection); | ||
683 | hid_free_device(device); | ||
684 | kfree(parser); | ||
685 | return NULL; | ||
686 | } | ||
687 | |||
688 | if (dispatch_type[item.type](parser, &item)) { | ||
689 | dbg("item %u %u %u %u parsing failed\n", | ||
690 | item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); | ||
691 | kfree(device->collection); | ||
692 | hid_free_device(device); | ||
693 | kfree(parser); | ||
694 | return NULL; | ||
695 | } | ||
696 | |||
697 | if (start == end) { | ||
698 | if (parser->collection_stack_ptr) { | ||
699 | dbg("unbalanced collection at end of report description"); | ||
700 | kfree(device->collection); | ||
701 | hid_free_device(device); | ||
702 | kfree(parser); | ||
703 | return NULL; | ||
704 | } | ||
705 | if (parser->local.delimiter_depth) { | ||
706 | dbg("unbalanced delimiter at end of report description"); | ||
707 | kfree(device->collection); | ||
708 | hid_free_device(device); | ||
709 | kfree(parser); | ||
710 | return NULL; | ||
711 | } | ||
712 | kfree(parser); | ||
713 | return device; | ||
714 | } | ||
715 | } | ||
716 | |||
717 | dbg("item fetching failed at offset %d\n", (int)(end - start)); | ||
718 | kfree(device->collection); | ||
719 | hid_free_device(device); | ||
720 | kfree(parser); | ||
721 | return NULL; | ||
722 | } | ||
723 | |||
724 | /* | ||
725 | * Convert a signed n-bit integer to signed 32-bit integer. Common | ||
726 | * cases are done through the compiler, the screwed things has to be | ||
727 | * done by hand. | ||
728 | */ | ||
729 | |||
730 | static s32 snto32(__u32 value, unsigned n) | ||
731 | { | ||
732 | switch (n) { | ||
733 | case 8: return ((__s8)value); | ||
734 | case 16: return ((__s16)value); | ||
735 | case 32: return ((__s32)value); | ||
736 | } | ||
737 | return value & (1 << (n - 1)) ? value | (-1 << n) : value; | ||
738 | } | ||
739 | |||
740 | /* | ||
741 | * Convert a signed 32-bit integer to a signed n-bit integer. | ||
742 | */ | ||
743 | |||
744 | static u32 s32ton(__s32 value, unsigned n) | ||
745 | { | ||
746 | s32 a = value >> (n - 1); | ||
747 | if (a && a != -1) | ||
748 | return value < 0 ? 1 << (n - 1) : (1 << (n - 1)) - 1; | ||
749 | return value & ((1 << n) - 1); | ||
750 | } | ||
751 | |||
752 | /* | ||
753 | * Extract/implement a data field from/to a little endian report (bit array). | ||
754 | * | ||
755 | * Code sort-of follows HID spec: | ||
756 | * http://www.usb.org/developers/devclass_docs/HID1_11.pdf | ||
757 | * | ||
758 | * While the USB HID spec allows unlimited length bit fields in "report | ||
759 | * descriptors", most devices never use more than 16 bits. | ||
760 | * One model of UPS is claimed to report "LINEV" as a 32-bit field. | ||
761 | * Search linux-kernel and linux-usb-devel archives for "hid-core extract". | ||
762 | */ | ||
763 | |||
764 | static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) | ||
765 | { | ||
766 | u64 x; | ||
767 | |||
768 | WARN_ON(n > 32); | ||
769 | |||
770 | report += offset >> 3; /* adjust byte index */ | ||
771 | offset &= 7; /* now only need bit offset into one byte */ | ||
772 | x = get_unaligned((u64 *) report); | ||
773 | x = le64_to_cpu(x); | ||
774 | x = (x >> offset) & ((1ULL << n) - 1); /* extract bit field */ | ||
775 | return (u32) x; | ||
776 | } | ||
777 | |||
778 | /* | ||
779 | * "implement" : set bits in a little endian bit stream. | ||
780 | * Same concepts as "extract" (see comments above). | ||
781 | * The data mangled in the bit stream remains in little endian | ||
782 | * order the whole time. It make more sense to talk about | ||
783 | * endianness of register values by considering a register | ||
784 | * a "cached" copy of the little endiad bit stream. | ||
785 | */ | ||
786 | static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) | ||
787 | { | ||
788 | u64 x; | ||
789 | u64 m = (1ULL << n) - 1; | ||
790 | |||
791 | WARN_ON(n > 32); | ||
792 | |||
793 | WARN_ON(value > m); | ||
794 | value &= m; | ||
795 | |||
796 | report += offset >> 3; | ||
797 | offset &= 7; | ||
798 | |||
799 | x = get_unaligned((u64 *)report); | ||
800 | x &= cpu_to_le64(~(m << offset)); | ||
801 | x |= cpu_to_le64(((u64) value) << offset); | ||
802 | put_unaligned(x, (u64 *) report); | ||
803 | } | ||
804 | |||
805 | /* | ||
806 | * Search an array for a value. | ||
807 | */ | ||
808 | |||
809 | static __inline__ int search(__s32 *array, __s32 value, unsigned n) | ||
810 | { | ||
811 | while (n--) { | ||
812 | if (*array++ == value) | ||
813 | return 0; | ||
814 | } | ||
815 | return -1; | ||
816 | } | ||
817 | |||
818 | static void hid_process_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value, int interrupt) | ||
819 | { | ||
820 | hid_dump_input(usage, value); | ||
821 | if (hid->claimed & HID_CLAIMED_INPUT) | ||
822 | hidinput_hid_event(hid, field, usage, value); | ||
823 | if (hid->claimed & HID_CLAIMED_HIDDEV && interrupt) | ||
824 | hiddev_hid_event(hid, field, usage, value); | ||
825 | } | ||
826 | |||
827 | /* | ||
828 | * Analyse a received field, and fetch the data from it. The field | ||
829 | * content is stored for next report processing (we do differential | ||
830 | * reporting to the layer). | ||
831 | */ | ||
832 | |||
833 | static void hid_input_field(struct hid_device *hid, struct hid_field *field, __u8 *data, int interrupt) | ||
834 | { | ||
835 | unsigned n; | ||
836 | unsigned count = field->report_count; | ||
837 | unsigned offset = field->report_offset; | ||
838 | unsigned size = field->report_size; | ||
839 | __s32 min = field->logical_minimum; | ||
840 | __s32 max = field->logical_maximum; | ||
841 | __s32 *value; | ||
842 | |||
843 | if (!(value = kmalloc(sizeof(__s32) * count, GFP_ATOMIC))) | ||
844 | return; | ||
845 | |||
846 | for (n = 0; n < count; n++) { | ||
847 | |||
848 | value[n] = min < 0 ? snto32(extract(data, offset + n * size, size), size) : | ||
849 | extract(data, offset + n * size, size); | ||
850 | |||
851 | if (!(field->flags & HID_MAIN_ITEM_VARIABLE) /* Ignore report if ErrorRollOver */ | ||
852 | && value[n] >= min && value[n] <= max | ||
853 | && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) | ||
854 | goto exit; | ||
855 | } | ||
856 | |||
857 | for (n = 0; n < count; n++) { | ||
858 | |||
859 | if (HID_MAIN_ITEM_VARIABLE & field->flags) { | ||
860 | hid_process_event(hid, field, &field->usage[n], value[n], interrupt); | ||
861 | continue; | ||
862 | } | ||
863 | |||
864 | if (field->value[n] >= min && field->value[n] <= max | ||
865 | && field->usage[field->value[n] - min].hid | ||
866 | && search(value, field->value[n], count)) | ||
867 | hid_process_event(hid, field, &field->usage[field->value[n] - min], 0, interrupt); | ||
868 | |||
869 | if (value[n] >= min && value[n] <= max | ||
870 | && field->usage[value[n] - min].hid | ||
871 | && search(field->value, value[n], count)) | ||
872 | hid_process_event(hid, field, &field->usage[value[n] - min], 1, interrupt); | ||
873 | } | ||
874 | |||
875 | memcpy(field->value, value, count * sizeof(__s32)); | ||
876 | exit: | ||
877 | kfree(value); | ||
878 | } | ||
879 | |||
880 | static int hid_input_report(int type, struct urb *urb, int interrupt) | ||
881 | { | ||
882 | struct hid_device *hid = urb->context; | ||
883 | struct hid_report_enum *report_enum = hid->report_enum + type; | ||
884 | u8 *data = urb->transfer_buffer; | ||
885 | int len = urb->actual_length; | ||
886 | struct hid_report *report; | ||
887 | int n, size; | ||
888 | |||
889 | if (!len) { | ||
890 | dbg("empty report"); | ||
891 | return -1; | ||
892 | } | ||
893 | |||
894 | #ifdef DEBUG_DATA | ||
895 | printk(KERN_DEBUG __FILE__ ": report (size %u) (%snumbered)\n", len, report_enum->numbered ? "" : "un"); | ||
896 | #endif | ||
897 | |||
898 | n = 0; /* Normally report number is 0 */ | ||
899 | if (report_enum->numbered) { /* Device uses numbered reports, data[0] is report number */ | ||
900 | n = *data++; | ||
901 | len--; | ||
902 | } | ||
903 | |||
904 | #ifdef DEBUG_DATA | ||
905 | { | ||
906 | int i; | ||
907 | printk(KERN_DEBUG __FILE__ ": report %d (size %u) = ", n, len); | ||
908 | for (i = 0; i < len; i++) | ||
909 | printk(" %02x", data[i]); | ||
910 | printk("\n"); | ||
911 | } | ||
912 | #endif | ||
913 | |||
914 | if (!(report = report_enum->report_id_hash[n])) { | ||
915 | dbg("undefined report_id %d received", n); | ||
916 | return -1; | ||
917 | } | ||
918 | |||
919 | size = ((report->size - 1) >> 3) + 1; | ||
920 | |||
921 | if (len < size) { | ||
922 | dbg("report %d is too short, (%d < %d)", report->id, len, size); | ||
923 | memset(data + len, 0, size - len); | ||
924 | } | ||
925 | |||
926 | if (hid->claimed & HID_CLAIMED_HIDDEV) | ||
927 | hiddev_report_event(hid, report); | ||
928 | |||
929 | for (n = 0; n < report->maxfield; n++) | ||
930 | hid_input_field(hid, report->field[n], data, interrupt); | ||
931 | |||
932 | if (hid->claimed & HID_CLAIMED_INPUT) | ||
933 | hidinput_report_event(hid, report); | ||
934 | |||
935 | return 0; | ||
936 | } | ||
937 | |||
938 | /* | ||
939 | * Input submission and I/O error handler. | 61 | * Input submission and I/O error handler. |
940 | */ | 62 | */ |
941 | 63 | ||
@@ -946,15 +68,16 @@ static int hid_start_in(struct hid_device *hid) | |||
946 | { | 68 | { |
947 | unsigned long flags; | 69 | unsigned long flags; |
948 | int rc = 0; | 70 | int rc = 0; |
71 | struct usbhid_device *usbhid = hid->driver_data; | ||
949 | 72 | ||
950 | spin_lock_irqsave(&hid->inlock, flags); | 73 | spin_lock_irqsave(&usbhid->inlock, flags); |
951 | if (hid->open > 0 && !test_bit(HID_SUSPENDED, &hid->iofl) && | 74 | if (hid->open > 0 && !test_bit(HID_SUSPENDED, &usbhid->iofl) && |
952 | !test_and_set_bit(HID_IN_RUNNING, &hid->iofl)) { | 75 | !test_and_set_bit(HID_IN_RUNNING, &usbhid->iofl)) { |
953 | rc = usb_submit_urb(hid->urbin, GFP_ATOMIC); | 76 | rc = usb_submit_urb(usbhid->urbin, GFP_ATOMIC); |
954 | if (rc != 0) | 77 | if (rc != 0) |
955 | clear_bit(HID_IN_RUNNING, &hid->iofl); | 78 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); |
956 | } | 79 | } |
957 | spin_unlock_irqrestore(&hid->inlock, flags); | 80 | spin_unlock_irqrestore(&usbhid->inlock, flags); |
958 | return rc; | 81 | return rc; |
959 | } | 82 | } |
960 | 83 | ||
@@ -962,8 +85,9 @@ static int hid_start_in(struct hid_device *hid) | |||
962 | static void hid_retry_timeout(unsigned long _hid) | 85 | static void hid_retry_timeout(unsigned long _hid) |
963 | { | 86 | { |
964 | struct hid_device *hid = (struct hid_device *) _hid; | 87 | struct hid_device *hid = (struct hid_device *) _hid; |
88 | struct usbhid_device *usbhid = hid->driver_data; | ||
965 | 89 | ||
966 | dev_dbg(&hid->intf->dev, "retrying intr urb\n"); | 90 | dev_dbg(&usbhid->intf->dev, "retrying intr urb\n"); |
967 | if (hid_start_in(hid)) | 91 | if (hid_start_in(hid)) |
968 | hid_io_error(hid); | 92 | hid_io_error(hid); |
969 | } | 93 | } |
@@ -971,38 +95,39 @@ static void hid_retry_timeout(unsigned long _hid) | |||
971 | /* Workqueue routine to reset the device or clear a halt */ | 95 | /* Workqueue routine to reset the device or clear a halt */ |
972 | static void hid_reset(struct work_struct *work) | 96 | static void hid_reset(struct work_struct *work) |
973 | { | 97 | { |
974 | struct hid_device *hid = | 98 | struct usbhid_device *usbhid = |
975 | container_of(work, struct hid_device, reset_work); | 99 | container_of(work, struct usbhid_device, reset_work); |
100 | struct hid_device *hid = usbhid->hid; | ||
976 | int rc_lock, rc = 0; | 101 | int rc_lock, rc = 0; |
977 | 102 | ||
978 | if (test_bit(HID_CLEAR_HALT, &hid->iofl)) { | 103 | if (test_bit(HID_CLEAR_HALT, &usbhid->iofl)) { |
979 | dev_dbg(&hid->intf->dev, "clear halt\n"); | 104 | dev_dbg(&usbhid->intf->dev, "clear halt\n"); |
980 | rc = usb_clear_halt(hid->dev, hid->urbin->pipe); | 105 | rc = usb_clear_halt(hid_to_usb_dev(hid), usbhid->urbin->pipe); |
981 | clear_bit(HID_CLEAR_HALT, &hid->iofl); | 106 | clear_bit(HID_CLEAR_HALT, &usbhid->iofl); |
982 | hid_start_in(hid); | 107 | hid_start_in(hid); |
983 | } | 108 | } |
984 | 109 | ||
985 | else if (test_bit(HID_RESET_PENDING, &hid->iofl)) { | 110 | else if (test_bit(HID_RESET_PENDING, &usbhid->iofl)) { |
986 | dev_dbg(&hid->intf->dev, "resetting device\n"); | 111 | dev_dbg(&usbhid->intf->dev, "resetting device\n"); |
987 | rc = rc_lock = usb_lock_device_for_reset(hid->dev, hid->intf); | 112 | rc = rc_lock = usb_lock_device_for_reset(hid_to_usb_dev(hid), usbhid->intf); |
988 | if (rc_lock >= 0) { | 113 | if (rc_lock >= 0) { |
989 | rc = usb_reset_composite_device(hid->dev, hid->intf); | 114 | rc = usb_reset_composite_device(hid_to_usb_dev(hid), usbhid->intf); |
990 | if (rc_lock) | 115 | if (rc_lock) |
991 | usb_unlock_device(hid->dev); | 116 | usb_unlock_device(hid_to_usb_dev(hid)); |
992 | } | 117 | } |
993 | clear_bit(HID_RESET_PENDING, &hid->iofl); | 118 | clear_bit(HID_RESET_PENDING, &usbhid->iofl); |
994 | } | 119 | } |
995 | 120 | ||
996 | switch (rc) { | 121 | switch (rc) { |
997 | case 0: | 122 | case 0: |
998 | if (!test_bit(HID_IN_RUNNING, &hid->iofl)) | 123 | if (!test_bit(HID_IN_RUNNING, &usbhid->iofl)) |
999 | hid_io_error(hid); | 124 | hid_io_error(hid); |
1000 | break; | 125 | break; |
1001 | default: | 126 | default: |
1002 | err("can't reset device, %s-%s/input%d, status %d", | 127 | err("can't reset device, %s-%s/input%d, status %d", |
1003 | hid->dev->bus->bus_name, | 128 | hid_to_usb_dev(hid)->bus->bus_name, |
1004 | hid->dev->devpath, | 129 | hid_to_usb_dev(hid)->devpath, |
1005 | hid->ifnum, rc); | 130 | usbhid->ifnum, rc); |
1006 | /* FALLTHROUGH */ | 131 | /* FALLTHROUGH */ |
1007 | case -EHOSTUNREACH: | 132 | case -EHOSTUNREACH: |
1008 | case -ENODEV: | 133 | case -ENODEV: |
@@ -1015,33 +140,34 @@ static void hid_reset(struct work_struct *work) | |||
1015 | static void hid_io_error(struct hid_device *hid) | 140 | static void hid_io_error(struct hid_device *hid) |
1016 | { | 141 | { |
1017 | unsigned long flags; | 142 | unsigned long flags; |
143 | struct usbhid_device *usbhid = hid->driver_data; | ||
1018 | 144 | ||
1019 | spin_lock_irqsave(&hid->inlock, flags); | 145 | spin_lock_irqsave(&usbhid->inlock, flags); |
1020 | 146 | ||
1021 | /* Stop when disconnected */ | 147 | /* Stop when disconnected */ |
1022 | if (usb_get_intfdata(hid->intf) == NULL) | 148 | if (usb_get_intfdata(usbhid->intf) == NULL) |
1023 | goto done; | 149 | goto done; |
1024 | 150 | ||
1025 | /* When an error occurs, retry at increasing intervals */ | 151 | /* When an error occurs, retry at increasing intervals */ |
1026 | if (hid->retry_delay == 0) { | 152 | if (usbhid->retry_delay == 0) { |
1027 | hid->retry_delay = 13; /* Then 26, 52, 104, 104, ... */ | 153 | usbhid->retry_delay = 13; /* Then 26, 52, 104, 104, ... */ |
1028 | hid->stop_retry = jiffies + msecs_to_jiffies(1000); | 154 | usbhid->stop_retry = jiffies + msecs_to_jiffies(1000); |
1029 | } else if (hid->retry_delay < 100) | 155 | } else if (usbhid->retry_delay < 100) |
1030 | hid->retry_delay *= 2; | 156 | usbhid->retry_delay *= 2; |
1031 | 157 | ||
1032 | if (time_after(jiffies, hid->stop_retry)) { | 158 | if (time_after(jiffies, usbhid->stop_retry)) { |
1033 | 159 | ||
1034 | /* Retries failed, so do a port reset */ | 160 | /* Retries failed, so do a port reset */ |
1035 | if (!test_and_set_bit(HID_RESET_PENDING, &hid->iofl)) { | 161 | if (!test_and_set_bit(HID_RESET_PENDING, &usbhid->iofl)) { |
1036 | schedule_work(&hid->reset_work); | 162 | schedule_work(&usbhid->reset_work); |
1037 | goto done; | 163 | goto done; |
1038 | } | 164 | } |
1039 | } | 165 | } |
1040 | 166 | ||
1041 | mod_timer(&hid->io_retry, | 167 | mod_timer(&usbhid->io_retry, |
1042 | jiffies + msecs_to_jiffies(hid->retry_delay)); | 168 | jiffies + msecs_to_jiffies(usbhid->retry_delay)); |
1043 | done: | 169 | done: |
1044 | spin_unlock_irqrestore(&hid->inlock, flags); | 170 | spin_unlock_irqrestore(&usbhid->inlock, flags); |
1045 | } | 171 | } |
1046 | 172 | ||
1047 | /* | 173 | /* |
@@ -1051,28 +177,31 @@ done: | |||
1051 | static void hid_irq_in(struct urb *urb) | 177 | static void hid_irq_in(struct urb *urb) |
1052 | { | 178 | { |
1053 | struct hid_device *hid = urb->context; | 179 | struct hid_device *hid = urb->context; |
180 | struct usbhid_device *usbhid = hid->driver_data; | ||
1054 | int status; | 181 | int status; |
1055 | 182 | ||
1056 | switch (urb->status) { | 183 | switch (urb->status) { |
1057 | case 0: /* success */ | 184 | case 0: /* success */ |
1058 | hid->retry_delay = 0; | 185 | usbhid->retry_delay = 0; |
1059 | hid_input_report(HID_INPUT_REPORT, urb, 1); | 186 | hid_input_report(urb->context, HID_INPUT_REPORT, |
187 | urb->transfer_buffer, | ||
188 | urb->actual_length, 1); | ||
1060 | break; | 189 | break; |
1061 | case -EPIPE: /* stall */ | 190 | case -EPIPE: /* stall */ |
1062 | clear_bit(HID_IN_RUNNING, &hid->iofl); | 191 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); |
1063 | set_bit(HID_CLEAR_HALT, &hid->iofl); | 192 | set_bit(HID_CLEAR_HALT, &usbhid->iofl); |
1064 | schedule_work(&hid->reset_work); | 193 | schedule_work(&usbhid->reset_work); |
1065 | return; | 194 | return; |
1066 | case -ECONNRESET: /* unlink */ | 195 | case -ECONNRESET: /* unlink */ |
1067 | case -ENOENT: | 196 | case -ENOENT: |
1068 | case -ESHUTDOWN: /* unplug */ | 197 | case -ESHUTDOWN: /* unplug */ |
1069 | clear_bit(HID_IN_RUNNING, &hid->iofl); | 198 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); |
1070 | return; | 199 | return; |
1071 | case -EILSEQ: /* protocol error or unplug */ | 200 | case -EILSEQ: /* protocol error or unplug */ |
1072 | case -EPROTO: /* protocol error or unplug */ | 201 | case -EPROTO: /* protocol error or unplug */ |
1073 | case -ETIME: /* protocol error or unplug */ | 202 | case -ETIME: /* protocol error or unplug */ |
1074 | case -ETIMEDOUT: /* Should never happen, but... */ | 203 | case -ETIMEDOUT: /* Should never happen, but... */ |
1075 | clear_bit(HID_IN_RUNNING, &hid->iofl); | 204 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); |
1076 | hid_io_error(hid); | 205 | hid_io_error(hid); |
1077 | return; | 206 | return; |
1078 | default: /* error */ | 207 | default: /* error */ |
@@ -1081,108 +210,31 @@ static void hid_irq_in(struct urb *urb) | |||
1081 | 210 | ||
1082 | status = usb_submit_urb(urb, GFP_ATOMIC); | 211 | status = usb_submit_urb(urb, GFP_ATOMIC); |
1083 | if (status) { | 212 | if (status) { |
1084 | clear_bit(HID_IN_RUNNING, &hid->iofl); | 213 | clear_bit(HID_IN_RUNNING, &usbhid->iofl); |
1085 | if (status != -EPERM) { | 214 | if (status != -EPERM) { |
1086 | err("can't resubmit intr, %s-%s/input%d, status %d", | 215 | err("can't resubmit intr, %s-%s/input%d, status %d", |
1087 | hid->dev->bus->bus_name, | 216 | hid_to_usb_dev(hid)->bus->bus_name, |
1088 | hid->dev->devpath, | 217 | hid_to_usb_dev(hid)->devpath, |
1089 | hid->ifnum, status); | 218 | usbhid->ifnum, status); |
1090 | hid_io_error(hid); | 219 | hid_io_error(hid); |
1091 | } | 220 | } |
1092 | } | 221 | } |
1093 | } | 222 | } |
1094 | 223 | ||
1095 | /* | ||
1096 | * Output the field into the report. | ||
1097 | */ | ||
1098 | |||
1099 | static void hid_output_field(struct hid_field *field, __u8 *data) | ||
1100 | { | ||
1101 | unsigned count = field->report_count; | ||
1102 | unsigned offset = field->report_offset; | ||
1103 | unsigned size = field->report_size; | ||
1104 | unsigned n; | ||
1105 | |||
1106 | for (n = 0; n < count; n++) { | ||
1107 | if (field->logical_minimum < 0) /* signed values */ | ||
1108 | implement(data, offset + n * size, size, s32ton(field->value[n], size)); | ||
1109 | else /* unsigned values */ | ||
1110 | implement(data, offset + n * size, size, field->value[n]); | ||
1111 | } | ||
1112 | } | ||
1113 | |||
1114 | /* | ||
1115 | * Create a report. | ||
1116 | */ | ||
1117 | |||
1118 | static void hid_output_report(struct hid_report *report, __u8 *data) | ||
1119 | { | ||
1120 | unsigned n; | ||
1121 | |||
1122 | if (report->id > 0) | ||
1123 | *data++ = report->id; | ||
1124 | |||
1125 | for (n = 0; n < report->maxfield; n++) | ||
1126 | hid_output_field(report->field[n], data); | ||
1127 | } | ||
1128 | |||
1129 | /* | ||
1130 | * Set a field value. The report this field belongs to has to be | ||
1131 | * created and transferred to the device, to set this value in the | ||
1132 | * device. | ||
1133 | */ | ||
1134 | |||
1135 | int hid_set_field(struct hid_field *field, unsigned offset, __s32 value) | ||
1136 | { | ||
1137 | unsigned size = field->report_size; | ||
1138 | |||
1139 | hid_dump_input(field->usage + offset, value); | ||
1140 | |||
1141 | if (offset >= field->report_count) { | ||
1142 | dbg("offset (%d) exceeds report_count (%d)", offset, field->report_count); | ||
1143 | hid_dump_field(field, 8); | ||
1144 | return -1; | ||
1145 | } | ||
1146 | if (field->logical_minimum < 0) { | ||
1147 | if (value != snto32(s32ton(value, size), size)) { | ||
1148 | dbg("value %d is out of range", value); | ||
1149 | return -1; | ||
1150 | } | ||
1151 | } | ||
1152 | field->value[offset] = value; | ||
1153 | return 0; | ||
1154 | } | ||
1155 | |||
1156 | /* | ||
1157 | * Find a report field with a specified HID usage. | ||
1158 | */ | ||
1159 | #if 0 | ||
1160 | struct hid_field *hid_find_field_by_usage(struct hid_device *hid, __u32 wanted_usage, int type) | ||
1161 | { | ||
1162 | struct hid_report *report; | ||
1163 | int i; | ||
1164 | |||
1165 | list_for_each_entry(report, &hid->report_enum[type].report_list, list) | ||
1166 | for (i = 0; i < report->maxfield; i++) | ||
1167 | if (report->field[i]->logical == wanted_usage) | ||
1168 | return report->field[i]; | ||
1169 | return NULL; | ||
1170 | } | ||
1171 | #endif /* 0 */ | ||
1172 | |||
1173 | static int hid_submit_out(struct hid_device *hid) | 224 | static int hid_submit_out(struct hid_device *hid) |
1174 | { | 225 | { |
1175 | struct hid_report *report; | 226 | struct hid_report *report; |
227 | struct usbhid_device *usbhid = hid->driver_data; | ||
1176 | 228 | ||
1177 | report = hid->out[hid->outtail]; | 229 | report = usbhid->out[usbhid->outtail]; |
1178 | 230 | ||
1179 | hid_output_report(report, hid->outbuf); | 231 | hid_output_report(report, usbhid->outbuf); |
1180 | hid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); | 232 | usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); |
1181 | hid->urbout->dev = hid->dev; | 233 | usbhid->urbout->dev = hid_to_usb_dev(hid); |
1182 | 234 | ||
1183 | dbg("submitting out urb"); | 235 | dbg("submitting out urb"); |
1184 | 236 | ||
1185 | if (usb_submit_urb(hid->urbout, GFP_ATOMIC)) { | 237 | if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) { |
1186 | err("usb_submit_urb(out) failed"); | 238 | err("usb_submit_urb(out) failed"); |
1187 | return -1; | 239 | return -1; |
1188 | } | 240 | } |
@@ -1195,42 +247,43 @@ static int hid_submit_ctrl(struct hid_device *hid) | |||
1195 | struct hid_report *report; | 247 | struct hid_report *report; |
1196 | unsigned char dir; | 248 | unsigned char dir; |
1197 | int len; | 249 | int len; |
250 | struct usbhid_device *usbhid = hid->driver_data; | ||
1198 | 251 | ||
1199 | report = hid->ctrl[hid->ctrltail].report; | 252 | report = usbhid->ctrl[usbhid->ctrltail].report; |
1200 | dir = hid->ctrl[hid->ctrltail].dir; | 253 | dir = usbhid->ctrl[usbhid->ctrltail].dir; |
1201 | 254 | ||
1202 | len = ((report->size - 1) >> 3) + 1 + (report->id > 0); | 255 | len = ((report->size - 1) >> 3) + 1 + (report->id > 0); |
1203 | if (dir == USB_DIR_OUT) { | 256 | if (dir == USB_DIR_OUT) { |
1204 | hid_output_report(report, hid->ctrlbuf); | 257 | hid_output_report(report, usbhid->ctrlbuf); |
1205 | hid->urbctrl->pipe = usb_sndctrlpipe(hid->dev, 0); | 258 | usbhid->urbctrl->pipe = usb_sndctrlpipe(hid_to_usb_dev(hid), 0); |
1206 | hid->urbctrl->transfer_buffer_length = len; | 259 | usbhid->urbctrl->transfer_buffer_length = len; |
1207 | } else { | 260 | } else { |
1208 | int maxpacket, padlen; | 261 | int maxpacket, padlen; |
1209 | 262 | ||
1210 | hid->urbctrl->pipe = usb_rcvctrlpipe(hid->dev, 0); | 263 | usbhid->urbctrl->pipe = usb_rcvctrlpipe(hid_to_usb_dev(hid), 0); |
1211 | maxpacket = usb_maxpacket(hid->dev, hid->urbctrl->pipe, 0); | 264 | maxpacket = usb_maxpacket(hid_to_usb_dev(hid), usbhid->urbctrl->pipe, 0); |
1212 | if (maxpacket > 0) { | 265 | if (maxpacket > 0) { |
1213 | padlen = (len + maxpacket - 1) / maxpacket; | 266 | padlen = (len + maxpacket - 1) / maxpacket; |
1214 | padlen *= maxpacket; | 267 | padlen *= maxpacket; |
1215 | if (padlen > hid->bufsize) | 268 | if (padlen > usbhid->bufsize) |
1216 | padlen = hid->bufsize; | 269 | padlen = usbhid->bufsize; |
1217 | } else | 270 | } else |
1218 | padlen = 0; | 271 | padlen = 0; |
1219 | hid->urbctrl->transfer_buffer_length = padlen; | 272 | usbhid->urbctrl->transfer_buffer_length = padlen; |
1220 | } | 273 | } |
1221 | hid->urbctrl->dev = hid->dev; | 274 | usbhid->urbctrl->dev = hid_to_usb_dev(hid); |
1222 | 275 | ||
1223 | hid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir; | 276 | usbhid->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE | dir; |
1224 | hid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT; | 277 | usbhid->cr->bRequest = (dir == USB_DIR_OUT) ? HID_REQ_SET_REPORT : HID_REQ_GET_REPORT; |
1225 | hid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id); | 278 | usbhid->cr->wValue = cpu_to_le16(((report->type + 1) << 8) | report->id); |
1226 | hid->cr->wIndex = cpu_to_le16(hid->ifnum); | 279 | usbhid->cr->wIndex = cpu_to_le16(usbhid->ifnum); |
1227 | hid->cr->wLength = cpu_to_le16(len); | 280 | usbhid->cr->wLength = cpu_to_le16(len); |
1228 | 281 | ||
1229 | dbg("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u", | 282 | dbg("submitting ctrl urb: %s wValue=0x%04x wIndex=0x%04x wLength=%u", |
1230 | hid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report", | 283 | usbhid->cr->bRequest == HID_REQ_SET_REPORT ? "Set_Report" : "Get_Report", |
1231 | hid->cr->wValue, hid->cr->wIndex, hid->cr->wLength); | 284 | usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength); |
1232 | 285 | ||
1233 | if (usb_submit_urb(hid->urbctrl, GFP_ATOMIC)) { | 286 | if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) { |
1234 | err("usb_submit_urb(ctrl) failed"); | 287 | err("usb_submit_urb(ctrl) failed"); |
1235 | return -1; | 288 | return -1; |
1236 | } | 289 | } |
@@ -1245,6 +298,7 @@ static int hid_submit_ctrl(struct hid_device *hid) | |||
1245 | static void hid_irq_out(struct urb *urb) | 298 | static void hid_irq_out(struct urb *urb) |
1246 | { | 299 | { |
1247 | struct hid_device *hid = urb->context; | 300 | struct hid_device *hid = urb->context; |
301 | struct usbhid_device *usbhid = hid->driver_data; | ||
1248 | unsigned long flags; | 302 | unsigned long flags; |
1249 | int unplug = 0; | 303 | int unplug = 0; |
1250 | 304 | ||
@@ -1262,24 +316,24 @@ static void hid_irq_out(struct urb *urb) | |||
1262 | warn("output irq status %d received", urb->status); | 316 | warn("output irq status %d received", urb->status); |
1263 | } | 317 | } |
1264 | 318 | ||
1265 | spin_lock_irqsave(&hid->outlock, flags); | 319 | spin_lock_irqsave(&usbhid->outlock, flags); |
1266 | 320 | ||
1267 | if (unplug) | 321 | if (unplug) |
1268 | hid->outtail = hid->outhead; | 322 | usbhid->outtail = usbhid->outhead; |
1269 | else | 323 | else |
1270 | hid->outtail = (hid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1); | 324 | usbhid->outtail = (usbhid->outtail + 1) & (HID_OUTPUT_FIFO_SIZE - 1); |
1271 | 325 | ||
1272 | if (hid->outhead != hid->outtail) { | 326 | if (usbhid->outhead != usbhid->outtail) { |
1273 | if (hid_submit_out(hid)) { | 327 | if (hid_submit_out(hid)) { |
1274 | clear_bit(HID_OUT_RUNNING, &hid->iofl); | 328 | clear_bit(HID_OUT_RUNNING, &usbhid->iofl); |
1275 | wake_up(&hid->wait); | 329 | wake_up(&hid->wait); |
1276 | } | 330 | } |
1277 | spin_unlock_irqrestore(&hid->outlock, flags); | 331 | spin_unlock_irqrestore(&usbhid->outlock, flags); |
1278 | return; | 332 | return; |
1279 | } | 333 | } |
1280 | 334 | ||
1281 | clear_bit(HID_OUT_RUNNING, &hid->iofl); | 335 | clear_bit(HID_OUT_RUNNING, &usbhid->iofl); |
1282 | spin_unlock_irqrestore(&hid->outlock, flags); | 336 | spin_unlock_irqrestore(&usbhid->outlock, flags); |
1283 | wake_up(&hid->wait); | 337 | wake_up(&hid->wait); |
1284 | } | 338 | } |
1285 | 339 | ||
@@ -1290,15 +344,17 @@ static void hid_irq_out(struct urb *urb) | |||
1290 | static void hid_ctrl(struct urb *urb) | 344 | static void hid_ctrl(struct urb *urb) |
1291 | { | 345 | { |
1292 | struct hid_device *hid = urb->context; | 346 | struct hid_device *hid = urb->context; |
347 | struct usbhid_device *usbhid = hid->driver_data; | ||
1293 | unsigned long flags; | 348 | unsigned long flags; |
1294 | int unplug = 0; | 349 | int unplug = 0; |
1295 | 350 | ||
1296 | spin_lock_irqsave(&hid->ctrllock, flags); | 351 | spin_lock_irqsave(&usbhid->ctrllock, flags); |
1297 | 352 | ||
1298 | switch (urb->status) { | 353 | switch (urb->status) { |
1299 | case 0: /* success */ | 354 | case 0: /* success */ |
1300 | if (hid->ctrl[hid->ctrltail].dir == USB_DIR_IN) | 355 | if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_IN) |
1301 | hid_input_report(hid->ctrl[hid->ctrltail].report->type, urb, 0); | 356 | hid_input_report(urb->context, usbhid->ctrl[usbhid->ctrltail].report->type, |
357 | urb->transfer_buffer, urb->actual_length, 0); | ||
1302 | break; | 358 | break; |
1303 | case -ESHUTDOWN: /* unplug */ | 359 | case -ESHUTDOWN: /* unplug */ |
1304 | unplug = 1; | 360 | unplug = 1; |
@@ -1313,76 +369,102 @@ static void hid_ctrl(struct urb *urb) | |||
1313 | } | 369 | } |
1314 | 370 | ||
1315 | if (unplug) | 371 | if (unplug) |
1316 | hid->ctrltail = hid->ctrlhead; | 372 | usbhid->ctrltail = usbhid->ctrlhead; |
1317 | else | 373 | else |
1318 | hid->ctrltail = (hid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1); | 374 | usbhid->ctrltail = (usbhid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1); |
1319 | 375 | ||
1320 | if (hid->ctrlhead != hid->ctrltail) { | 376 | if (usbhid->ctrlhead != usbhid->ctrltail) { |
1321 | if (hid_submit_ctrl(hid)) { | 377 | if (hid_submit_ctrl(hid)) { |
1322 | clear_bit(HID_CTRL_RUNNING, &hid->iofl); | 378 | clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); |
1323 | wake_up(&hid->wait); | 379 | wake_up(&hid->wait); |
1324 | } | 380 | } |
1325 | spin_unlock_irqrestore(&hid->ctrllock, flags); | 381 | spin_unlock_irqrestore(&usbhid->ctrllock, flags); |
1326 | return; | 382 | return; |
1327 | } | 383 | } |
1328 | 384 | ||
1329 | clear_bit(HID_CTRL_RUNNING, &hid->iofl); | 385 | clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); |
1330 | spin_unlock_irqrestore(&hid->ctrllock, flags); | 386 | spin_unlock_irqrestore(&usbhid->ctrllock, flags); |
1331 | wake_up(&hid->wait); | 387 | wake_up(&hid->wait); |
1332 | } | 388 | } |
1333 | 389 | ||
1334 | void hid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) | 390 | void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir) |
1335 | { | 391 | { |
1336 | int head; | 392 | int head; |
1337 | unsigned long flags; | 393 | unsigned long flags; |
394 | struct usbhid_device *usbhid = hid->driver_data; | ||
1338 | 395 | ||
1339 | if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN) | 396 | if ((hid->quirks & HID_QUIRK_NOGET) && dir == USB_DIR_IN) |
1340 | return; | 397 | return; |
1341 | 398 | ||
1342 | if (hid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) { | 399 | if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) { |
1343 | 400 | ||
1344 | spin_lock_irqsave(&hid->outlock, flags); | 401 | spin_lock_irqsave(&usbhid->outlock, flags); |
1345 | 402 | ||
1346 | if ((head = (hid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == hid->outtail) { | 403 | if ((head = (usbhid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == usbhid->outtail) { |
1347 | spin_unlock_irqrestore(&hid->outlock, flags); | 404 | spin_unlock_irqrestore(&usbhid->outlock, flags); |
1348 | warn("output queue full"); | 405 | warn("output queue full"); |
1349 | return; | 406 | return; |
1350 | } | 407 | } |
1351 | 408 | ||
1352 | hid->out[hid->outhead] = report; | 409 | usbhid->out[usbhid->outhead] = report; |
1353 | hid->outhead = head; | 410 | usbhid->outhead = head; |
1354 | 411 | ||
1355 | if (!test_and_set_bit(HID_OUT_RUNNING, &hid->iofl)) | 412 | if (!test_and_set_bit(HID_OUT_RUNNING, &usbhid->iofl)) |
1356 | if (hid_submit_out(hid)) | 413 | if (hid_submit_out(hid)) |
1357 | clear_bit(HID_OUT_RUNNING, &hid->iofl); | 414 | clear_bit(HID_OUT_RUNNING, &usbhid->iofl); |
1358 | 415 | ||
1359 | spin_unlock_irqrestore(&hid->outlock, flags); | 416 | spin_unlock_irqrestore(&usbhid->outlock, flags); |
1360 | return; | 417 | return; |
1361 | } | 418 | } |
1362 | 419 | ||
1363 | spin_lock_irqsave(&hid->ctrllock, flags); | 420 | spin_lock_irqsave(&usbhid->ctrllock, flags); |
1364 | 421 | ||
1365 | if ((head = (hid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == hid->ctrltail) { | 422 | if ((head = (usbhid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == usbhid->ctrltail) { |
1366 | spin_unlock_irqrestore(&hid->ctrllock, flags); | 423 | spin_unlock_irqrestore(&usbhid->ctrllock, flags); |
1367 | warn("control queue full"); | 424 | warn("control queue full"); |
1368 | return; | 425 | return; |
1369 | } | 426 | } |
1370 | 427 | ||
1371 | hid->ctrl[hid->ctrlhead].report = report; | 428 | usbhid->ctrl[usbhid->ctrlhead].report = report; |
1372 | hid->ctrl[hid->ctrlhead].dir = dir; | 429 | usbhid->ctrl[usbhid->ctrlhead].dir = dir; |
1373 | hid->ctrlhead = head; | 430 | usbhid->ctrlhead = head; |
1374 | 431 | ||
1375 | if (!test_and_set_bit(HID_CTRL_RUNNING, &hid->iofl)) | 432 | if (!test_and_set_bit(HID_CTRL_RUNNING, &usbhid->iofl)) |
1376 | if (hid_submit_ctrl(hid)) | 433 | if (hid_submit_ctrl(hid)) |
1377 | clear_bit(HID_CTRL_RUNNING, &hid->iofl); | 434 | clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); |
435 | |||
436 | spin_unlock_irqrestore(&usbhid->ctrllock, flags); | ||
437 | } | ||
438 | |||
439 | static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | ||
440 | { | ||
441 | struct hid_device *hid = dev->private; | ||
442 | struct hid_field *field; | ||
443 | int offset; | ||
1378 | 444 | ||
1379 | spin_unlock_irqrestore(&hid->ctrllock, flags); | 445 | if (type == EV_FF) |
446 | return input_ff_event(dev, type, code, value); | ||
447 | |||
448 | if (type != EV_LED) | ||
449 | return -1; | ||
450 | |||
451 | if ((offset = hidinput_find_field(hid, type, code, &field)) == -1) { | ||
452 | warn("event field not found"); | ||
453 | return -1; | ||
454 | } | ||
455 | |||
456 | hid_set_field(field, offset, value); | ||
457 | usbhid_submit_report(hid, field->report, USB_DIR_OUT); | ||
458 | |||
459 | return 0; | ||
1380 | } | 460 | } |
1381 | 461 | ||
1382 | int hid_wait_io(struct hid_device *hid) | 462 | int usbhid_wait_io(struct hid_device *hid) |
1383 | { | 463 | { |
1384 | if (!wait_event_timeout(hid->wait, (!test_bit(HID_CTRL_RUNNING, &hid->iofl) && | 464 | struct usbhid_device *usbhid = hid->driver_data; |
1385 | !test_bit(HID_OUT_RUNNING, &hid->iofl)), | 465 | |
466 | if (!wait_event_timeout(hid->wait, (!test_bit(HID_CTRL_RUNNING, &usbhid->iofl) && | ||
467 | !test_bit(HID_OUT_RUNNING, &usbhid->iofl)), | ||
1386 | 10*HZ)) { | 468 | 10*HZ)) { |
1387 | dbg("timeout waiting for ctrl or out queue to clear"); | 469 | dbg("timeout waiting for ctrl or out queue to clear"); |
1388 | return -1; | 470 | return -1; |
@@ -1403,7 +485,7 @@ static int hid_get_class_descriptor(struct usb_device *dev, int ifnum, | |||
1403 | { | 485 | { |
1404 | int result, retries = 4; | 486 | int result, retries = 4; |
1405 | 487 | ||
1406 | memset(buf,0,size); // Make sure we parse really received data | 488 | memset(buf, 0, size); |
1407 | 489 | ||
1408 | do { | 490 | do { |
1409 | result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | 491 | result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), |
@@ -1414,7 +496,7 @@ static int hid_get_class_descriptor(struct usb_device *dev, int ifnum, | |||
1414 | return result; | 496 | return result; |
1415 | } | 497 | } |
1416 | 498 | ||
1417 | int hid_open(struct hid_device *hid) | 499 | int usbhid_open(struct hid_device *hid) |
1418 | { | 500 | { |
1419 | ++hid->open; | 501 | ++hid->open; |
1420 | if (hid_start_in(hid)) | 502 | if (hid_start_in(hid)) |
@@ -1422,10 +504,12 @@ int hid_open(struct hid_device *hid) | |||
1422 | return 0; | 504 | return 0; |
1423 | } | 505 | } |
1424 | 506 | ||
1425 | void hid_close(struct hid_device *hid) | 507 | void usbhid_close(struct hid_device *hid) |
1426 | { | 508 | { |
509 | struct usbhid_device *usbhid = hid->driver_data; | ||
510 | |||
1427 | if (!--hid->open) | 511 | if (!--hid->open) |
1428 | usb_kill_urb(hid->urbin); | 512 | usb_kill_urb(usbhid->urbin); |
1429 | } | 513 | } |
1430 | 514 | ||
1431 | #define USB_VENDOR_ID_PANJIT 0x134c | 515 | #define USB_VENDOR_ID_PANJIT 0x134c |
@@ -1437,26 +521,27 @@ void hid_close(struct hid_device *hid) | |||
1437 | * Initialize all reports | 521 | * Initialize all reports |
1438 | */ | 522 | */ |
1439 | 523 | ||
1440 | void hid_init_reports(struct hid_device *hid) | 524 | void usbhid_init_reports(struct hid_device *hid) |
1441 | { | 525 | { |
1442 | struct hid_report *report; | 526 | struct hid_report *report; |
527 | struct usbhid_device *usbhid = hid->driver_data; | ||
1443 | int err, ret; | 528 | int err, ret; |
1444 | 529 | ||
1445 | list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list) | 530 | list_for_each_entry(report, &hid->report_enum[HID_INPUT_REPORT].report_list, list) |
1446 | hid_submit_report(hid, report, USB_DIR_IN); | 531 | usbhid_submit_report(hid, report, USB_DIR_IN); |
1447 | 532 | ||
1448 | list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list) | 533 | list_for_each_entry(report, &hid->report_enum[HID_FEATURE_REPORT].report_list, list) |
1449 | hid_submit_report(hid, report, USB_DIR_IN); | 534 | usbhid_submit_report(hid, report, USB_DIR_IN); |
1450 | 535 | ||
1451 | err = 0; | 536 | err = 0; |
1452 | ret = hid_wait_io(hid); | 537 | ret = usbhid_wait_io(hid); |
1453 | while (ret) { | 538 | while (ret) { |
1454 | err |= ret; | 539 | err |= ret; |
1455 | if (test_bit(HID_CTRL_RUNNING, &hid->iofl)) | 540 | if (test_bit(HID_CTRL_RUNNING, &usbhid->iofl)) |
1456 | usb_kill_urb(hid->urbctrl); | 541 | usb_kill_urb(usbhid->urbctrl); |
1457 | if (test_bit(HID_OUT_RUNNING, &hid->iofl)) | 542 | if (test_bit(HID_OUT_RUNNING, &usbhid->iofl)) |
1458 | usb_kill_urb(hid->urbout); | 543 | usb_kill_urb(usbhid->urbout); |
1459 | ret = hid_wait_io(hid); | 544 | ret = usbhid_wait_io(hid); |
1460 | } | 545 | } |
1461 | 546 | ||
1462 | if (err) | 547 | if (err) |
@@ -1464,6 +549,7 @@ void hid_init_reports(struct hid_device *hid) | |||
1464 | } | 549 | } |
1465 | 550 | ||
1466 | #define USB_VENDOR_ID_GTCO 0x078c | 551 | #define USB_VENDOR_ID_GTCO 0x078c |
552 | #define USB_VENDOR_ID_GTCO_IPANEL_2 0x5543 | ||
1467 | #define USB_DEVICE_ID_GTCO_90 0x0090 | 553 | #define USB_DEVICE_ID_GTCO_90 0x0090 |
1468 | #define USB_DEVICE_ID_GTCO_100 0x0100 | 554 | #define USB_DEVICE_ID_GTCO_100 0x0100 |
1469 | #define USB_DEVICE_ID_GTCO_101 0x0101 | 555 | #define USB_DEVICE_ID_GTCO_101 0x0101 |
@@ -1509,6 +595,8 @@ void hid_init_reports(struct hid_device *hid) | |||
1509 | #define USB_DEVICE_ID_GTCO_1004 0x1004 | 595 | #define USB_DEVICE_ID_GTCO_1004 0x1004 |
1510 | #define USB_DEVICE_ID_GTCO_1005 0x1005 | 596 | #define USB_DEVICE_ID_GTCO_1005 0x1005 |
1511 | #define USB_DEVICE_ID_GTCO_1006 0x1006 | 597 | #define USB_DEVICE_ID_GTCO_1006 0x1006 |
598 | #define USB_DEVICE_ID_GTCO_8 0x0008 | ||
599 | #define USB_DEVICE_ID_GTCO_d 0x000d | ||
1512 | 600 | ||
1513 | #define USB_VENDOR_ID_WACOM 0x056a | 601 | #define USB_VENDOR_ID_WACOM 0x056a |
1514 | 602 | ||
@@ -1654,6 +742,7 @@ void hid_init_reports(struct hid_device *hid) | |||
1654 | #define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c | 742 | #define USB_DEVICE_ID_APPLE_GEYSER4_JIS 0x021c |
1655 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a | 743 | #define USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY 0x030a |
1656 | #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b | 744 | #define USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY 0x030b |
745 | #define USB_DEVICE_ID_APPLE_IR 0x8240 | ||
1657 | 746 | ||
1658 | #define USB_VENDOR_ID_CHERRY 0x046a | 747 | #define USB_VENDOR_ID_CHERRY 0x046a |
1659 | #define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 | 748 | #define USB_DEVICE_ID_CHERRY_CYMOTION 0x0023 |
@@ -1673,6 +762,15 @@ void hid_init_reports(struct hid_device *hid) | |||
1673 | #define USB_VENDOR_ID_LOGITECH 0x046d | 762 | #define USB_VENDOR_ID_LOGITECH 0x046d |
1674 | #define USB_DEVICE_ID_LOGITECH_USB_RECEIVER 0xc101 | 763 | #define USB_DEVICE_ID_LOGITECH_USB_RECEIVER 0xc101 |
1675 | 764 | ||
765 | #define USB_VENDOR_ID_IMATION 0x0718 | ||
766 | #define USB_DEVICE_ID_DISC_STAKKA 0xd000 | ||
767 | |||
768 | #define USB_VENDOR_ID_PANTHERLORD 0x0810 | ||
769 | #define USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK 0x0001 | ||
770 | |||
771 | #define USB_VENDOR_ID_SONY 0x054c | ||
772 | #define USB_DEVICE_ID_SONY_PS3_CONTROLLER 0x0268 | ||
773 | |||
1676 | /* | 774 | /* |
1677 | * Alphabetically sorted blacklist by quirk type. | 775 | * Alphabetically sorted blacklist by quirk type. |
1678 | */ | 776 | */ |
@@ -1757,6 +855,9 @@ static const struct hid_blacklist { | |||
1757 | { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1004, HID_QUIRK_IGNORE }, | 855 | { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1004, HID_QUIRK_IGNORE }, |
1758 | { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005, HID_QUIRK_IGNORE }, | 856 | { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005, HID_QUIRK_IGNORE }, |
1759 | { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006, HID_QUIRK_IGNORE }, | 857 | { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006, HID_QUIRK_IGNORE }, |
858 | { USB_VENDOR_ID_GTCO_IPANEL_2, USB_DEVICE_ID_GTCO_8, HID_QUIRK_IGNORE }, | ||
859 | { USB_VENDOR_ID_GTCO_IPANEL_2, USB_DEVICE_ID_GTCO_d, HID_QUIRK_IGNORE }, | ||
860 | { USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA, HID_QUIRK_IGNORE }, | ||
1760 | { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE }, | 861 | { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE }, |
1761 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY, HID_QUIRK_IGNORE }, | 862 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY, HID_QUIRK_IGNORE }, |
1762 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY, HID_QUIRK_IGNORE }, | 863 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_POCKETCASSY, HID_QUIRK_IGNORE }, |
@@ -1824,19 +925,21 @@ static const struct hid_blacklist { | |||
1824 | 925 | ||
1825 | { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_CYMOTION }, | 926 | { USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION, HID_QUIRK_CYMOTION }, |
1826 | 927 | ||
1827 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_POWERBOOK_HAS_FN }, | 928 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
1828 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_POWERBOOK_HAS_FN }, | 929 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
1829 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_POWERBOOK_HAS_FN }, | 930 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
1830 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, | 931 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, |
1831 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_POWERBOOK_HAS_FN }, | 932 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER_JIS, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
1832 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_POWERBOOK_HAS_FN }, | 933 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
1833 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, | 934 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, |
1834 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_POWERBOOK_HAS_FN }, | 935 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER3_JIS, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
1835 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_POWERBOOK_HAS_FN }, | 936 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ANSI, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
1836 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_POWERBOOK_HAS_FN }, | 937 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_ISO, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE | HID_QUIRK_POWERBOOK_ISO_KEYBOARD}, |
1837 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_POWERBOOK_HAS_FN }, | 938 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER4_JIS, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
1838 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN }, | 939 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
1839 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN }, | 940 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY, HID_QUIRK_POWERBOOK_HAS_FN | HID_QUIRK_IGNORE_MOUSE }, |
941 | |||
942 | { USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_IR, HID_QUIRK_IGNORE }, | ||
1840 | 943 | ||
1841 | { USB_VENDOR_ID_PANJIT, 0x0001, HID_QUIRK_IGNORE }, | 944 | { USB_VENDOR_ID_PANJIT, 0x0001, HID_QUIRK_IGNORE }, |
1842 | { USB_VENDOR_ID_PANJIT, 0x0002, HID_QUIRK_IGNORE }, | 945 | { USB_VENDOR_ID_PANJIT, 0x0002, HID_QUIRK_IGNORE }, |
@@ -1847,6 +950,10 @@ static const struct hid_blacklist { | |||
1847 | 950 | ||
1848 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_USB_RECEIVER, HID_QUIRK_BAD_RELATIVE_KEYS }, | 951 | { USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_USB_RECEIVER, HID_QUIRK_BAD_RELATIVE_KEYS }, |
1849 | 952 | ||
953 | { USB_VENDOR_ID_PANTHERLORD, USB_DEVICE_ID_PANTHERLORD_TWIN_USB_JOYSTICK, HID_QUIRK_MULTI_INPUT | HID_QUIRK_SKIP_OUTPUT_REPORTS }, | ||
954 | |||
955 | { USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER, HID_QUIRK_SONY_PS3_CONTROLLER }, | ||
956 | |||
1850 | { 0, 0 } | 957 | { 0, 0 } |
1851 | }; | 958 | }; |
1852 | 959 | ||
@@ -1869,13 +976,15 @@ static void hid_find_max_report(struct hid_device *hid, unsigned int type, int * | |||
1869 | 976 | ||
1870 | static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid) | 977 | static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid) |
1871 | { | 978 | { |
1872 | if (!(hid->inbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->inbuf_dma))) | 979 | struct usbhid_device *usbhid = hid->driver_data; |
980 | |||
981 | if (!(usbhid->inbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_ATOMIC, &usbhid->inbuf_dma))) | ||
1873 | return -1; | 982 | return -1; |
1874 | if (!(hid->outbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->outbuf_dma))) | 983 | if (!(usbhid->outbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_ATOMIC, &usbhid->outbuf_dma))) |
1875 | return -1; | 984 | return -1; |
1876 | if (!(hid->cr = usb_buffer_alloc(dev, sizeof(*(hid->cr)), GFP_ATOMIC, &hid->cr_dma))) | 985 | if (!(usbhid->cr = usb_buffer_alloc(dev, sizeof(*(usbhid->cr)), GFP_ATOMIC, &usbhid->cr_dma))) |
1877 | return -1; | 986 | return -1; |
1878 | if (!(hid->ctrlbuf = usb_buffer_alloc(dev, hid->bufsize, GFP_ATOMIC, &hid->ctrlbuf_dma))) | 987 | if (!(usbhid->ctrlbuf = usb_buffer_alloc(dev, usbhid->bufsize, GFP_ATOMIC, &usbhid->ctrlbuf_dma))) |
1879 | return -1; | 988 | return -1; |
1880 | 989 | ||
1881 | return 0; | 990 | return 0; |
@@ -1883,14 +992,16 @@ static int hid_alloc_buffers(struct usb_device *dev, struct hid_device *hid) | |||
1883 | 992 | ||
1884 | static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) | 993 | static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) |
1885 | { | 994 | { |
1886 | if (hid->inbuf) | 995 | struct usbhid_device *usbhid = hid->driver_data; |
1887 | usb_buffer_free(dev, hid->bufsize, hid->inbuf, hid->inbuf_dma); | 996 | |
1888 | if (hid->outbuf) | 997 | if (usbhid->inbuf) |
1889 | usb_buffer_free(dev, hid->bufsize, hid->outbuf, hid->outbuf_dma); | 998 | usb_buffer_free(dev, usbhid->bufsize, usbhid->inbuf, usbhid->inbuf_dma); |
1890 | if (hid->cr) | 999 | if (usbhid->outbuf) |
1891 | usb_buffer_free(dev, sizeof(*(hid->cr)), hid->cr, hid->cr_dma); | 1000 | usb_buffer_free(dev, usbhid->bufsize, usbhid->outbuf, usbhid->outbuf_dma); |
1892 | if (hid->ctrlbuf) | 1001 | if (usbhid->cr) |
1893 | usb_buffer_free(dev, hid->bufsize, hid->ctrlbuf, hid->ctrlbuf_dma); | 1002 | usb_buffer_free(dev, sizeof(*(usbhid->cr)), usbhid->cr, usbhid->cr_dma); |
1003 | if (usbhid->ctrlbuf) | ||
1004 | usb_buffer_free(dev, usbhid->bufsize, usbhid->ctrlbuf, usbhid->ctrlbuf_dma); | ||
1894 | } | 1005 | } |
1895 | 1006 | ||
1896 | /* | 1007 | /* |
@@ -1907,6 +1018,32 @@ static void hid_fixup_cymotion_descriptor(char *rdesc, int rsize) | |||
1907 | } | 1018 | } |
1908 | } | 1019 | } |
1909 | 1020 | ||
1021 | /* | ||
1022 | * Sending HID_REQ_GET_REPORT changes the operation mode of the ps3 controller | ||
1023 | * to "operational". Without this, the ps3 controller will not report any | ||
1024 | * events. | ||
1025 | */ | ||
1026 | static void hid_fixup_sony_ps3_controller(struct usb_device *dev, int ifnum) | ||
1027 | { | ||
1028 | int result; | ||
1029 | char *buf = kmalloc(18, GFP_KERNEL); | ||
1030 | |||
1031 | if (!buf) | ||
1032 | return; | ||
1033 | |||
1034 | result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | ||
1035 | HID_REQ_GET_REPORT, | ||
1036 | USB_DIR_IN | USB_TYPE_CLASS | | ||
1037 | USB_RECIP_INTERFACE, | ||
1038 | (3 << 8) | 0xf2, ifnum, buf, 17, | ||
1039 | USB_CTRL_GET_TIMEOUT); | ||
1040 | |||
1041 | if (result < 0) | ||
1042 | err("%s failed: %d\n", __func__, result); | ||
1043 | |||
1044 | kfree(buf); | ||
1045 | } | ||
1046 | |||
1910 | static struct hid_device *usb_hid_configure(struct usb_interface *intf) | 1047 | static struct hid_device *usb_hid_configure(struct usb_interface *intf) |
1911 | { | 1048 | { |
1912 | struct usb_host_interface *interface = intf->cur_altsetting; | 1049 | struct usb_host_interface *interface = intf->cur_altsetting; |
@@ -1916,6 +1053,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
1916 | unsigned quirks = 0, rsize = 0; | 1053 | unsigned quirks = 0, rsize = 0; |
1917 | char *rdesc; | 1054 | char *rdesc; |
1918 | int n, len, insize = 0; | 1055 | int n, len, insize = 0; |
1056 | struct usbhid_device *usbhid; | ||
1919 | 1057 | ||
1920 | /* Ignore all Wacom devices */ | 1058 | /* Ignore all Wacom devices */ |
1921 | if (le16_to_cpu(dev->descriptor.idVendor) == USB_VENDOR_ID_WACOM) | 1059 | if (le16_to_cpu(dev->descriptor.idVendor) == USB_VENDOR_ID_WACOM) |
@@ -1937,6 +1075,11 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
1937 | if (quirks & HID_QUIRK_IGNORE) | 1075 | if (quirks & HID_QUIRK_IGNORE) |
1938 | return NULL; | 1076 | return NULL; |
1939 | 1077 | ||
1078 | if ((quirks & HID_QUIRK_IGNORE_MOUSE) && | ||
1079 | (interface->desc.bInterfaceProtocol == USB_INTERFACE_PROTOCOL_MOUSE)) | ||
1080 | return NULL; | ||
1081 | |||
1082 | |||
1940 | if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && | 1083 | if (usb_get_extra_descriptor(interface, HID_DT_HID, &hdesc) && |
1941 | (!interface->desc.bNumEndpoints || | 1084 | (!interface->desc.bNumEndpoints || |
1942 | usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { | 1085 | usb_get_extra_descriptor(&interface->endpoint[0], HID_DT_HID, &hdesc))) { |
@@ -1985,13 +1128,19 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
1985 | kfree(rdesc); | 1128 | kfree(rdesc); |
1986 | hid->quirks = quirks; | 1129 | hid->quirks = quirks; |
1987 | 1130 | ||
1988 | hid->bufsize = HID_MIN_BUFFER_SIZE; | 1131 | if (!(usbhid = kzalloc(sizeof(struct usbhid_device), GFP_KERNEL))) |
1989 | hid_find_max_report(hid, HID_INPUT_REPORT, &hid->bufsize); | 1132 | goto fail; |
1990 | hid_find_max_report(hid, HID_OUTPUT_REPORT, &hid->bufsize); | 1133 | |
1991 | hid_find_max_report(hid, HID_FEATURE_REPORT, &hid->bufsize); | 1134 | hid->driver_data = usbhid; |
1135 | usbhid->hid = hid; | ||
1136 | |||
1137 | usbhid->bufsize = HID_MIN_BUFFER_SIZE; | ||
1138 | hid_find_max_report(hid, HID_INPUT_REPORT, &usbhid->bufsize); | ||
1139 | hid_find_max_report(hid, HID_OUTPUT_REPORT, &usbhid->bufsize); | ||
1140 | hid_find_max_report(hid, HID_FEATURE_REPORT, &usbhid->bufsize); | ||
1992 | 1141 | ||
1993 | if (hid->bufsize > HID_MAX_BUFFER_SIZE) | 1142 | if (usbhid->bufsize > HID_MAX_BUFFER_SIZE) |
1994 | hid->bufsize = HID_MAX_BUFFER_SIZE; | 1143 | usbhid->bufsize = HID_MAX_BUFFER_SIZE; |
1995 | 1144 | ||
1996 | hid_find_max_report(hid, HID_INPUT_REPORT, &insize); | 1145 | hid_find_max_report(hid, HID_INPUT_REPORT, &insize); |
1997 | 1146 | ||
@@ -2020,47 +1169,47 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
2020 | interval = hid_mousepoll_interval; | 1169 | interval = hid_mousepoll_interval; |
2021 | 1170 | ||
2022 | if (usb_endpoint_dir_in(endpoint)) { | 1171 | if (usb_endpoint_dir_in(endpoint)) { |
2023 | if (hid->urbin) | 1172 | if (usbhid->urbin) |
2024 | continue; | 1173 | continue; |
2025 | if (!(hid->urbin = usb_alloc_urb(0, GFP_KERNEL))) | 1174 | if (!(usbhid->urbin = usb_alloc_urb(0, GFP_KERNEL))) |
2026 | goto fail; | 1175 | goto fail; |
2027 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); | 1176 | pipe = usb_rcvintpipe(dev, endpoint->bEndpointAddress); |
2028 | usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, insize, | 1177 | usb_fill_int_urb(usbhid->urbin, dev, pipe, usbhid->inbuf, insize, |
2029 | hid_irq_in, hid, interval); | 1178 | hid_irq_in, hid, interval); |
2030 | hid->urbin->transfer_dma = hid->inbuf_dma; | 1179 | usbhid->urbin->transfer_dma = usbhid->inbuf_dma; |
2031 | hid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 1180 | usbhid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
2032 | } else { | 1181 | } else { |
2033 | if (hid->urbout) | 1182 | if (usbhid->urbout) |
2034 | continue; | 1183 | continue; |
2035 | if (!(hid->urbout = usb_alloc_urb(0, GFP_KERNEL))) | 1184 | if (!(usbhid->urbout = usb_alloc_urb(0, GFP_KERNEL))) |
2036 | goto fail; | 1185 | goto fail; |
2037 | pipe = usb_sndintpipe(dev, endpoint->bEndpointAddress); | 1186 | pipe = usb_sndintpipe(dev, endpoint->bEndpointAddress); |
2038 | usb_fill_int_urb(hid->urbout, dev, pipe, hid->outbuf, 0, | 1187 | usb_fill_int_urb(usbhid->urbout, dev, pipe, usbhid->outbuf, 0, |
2039 | hid_irq_out, hid, interval); | 1188 | hid_irq_out, hid, interval); |
2040 | hid->urbout->transfer_dma = hid->outbuf_dma; | 1189 | usbhid->urbout->transfer_dma = usbhid->outbuf_dma; |
2041 | hid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | 1190 | usbhid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; |
2042 | } | 1191 | } |
2043 | } | 1192 | } |
2044 | 1193 | ||
2045 | if (!hid->urbin) { | 1194 | if (!usbhid->urbin) { |
2046 | err("couldn't find an input interrupt endpoint"); | 1195 | err("couldn't find an input interrupt endpoint"); |
2047 | goto fail; | 1196 | goto fail; |
2048 | } | 1197 | } |
2049 | 1198 | ||
2050 | init_waitqueue_head(&hid->wait); | 1199 | init_waitqueue_head(&hid->wait); |
2051 | 1200 | ||
2052 | INIT_WORK(&hid->reset_work, hid_reset); | 1201 | INIT_WORK(&usbhid->reset_work, hid_reset); |
2053 | setup_timer(&hid->io_retry, hid_retry_timeout, (unsigned long) hid); | 1202 | setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); |
2054 | 1203 | ||
2055 | spin_lock_init(&hid->inlock); | 1204 | spin_lock_init(&usbhid->inlock); |
2056 | spin_lock_init(&hid->outlock); | 1205 | spin_lock_init(&usbhid->outlock); |
2057 | spin_lock_init(&hid->ctrllock); | 1206 | spin_lock_init(&usbhid->ctrllock); |
2058 | 1207 | ||
2059 | hid->version = le16_to_cpu(hdesc->bcdHID); | 1208 | hid->version = le16_to_cpu(hdesc->bcdHID); |
2060 | hid->country = hdesc->bCountryCode; | 1209 | hid->country = hdesc->bCountryCode; |
2061 | hid->dev = dev; | 1210 | hid->dev = &intf->dev; |
2062 | hid->intf = intf; | 1211 | usbhid->intf = intf; |
2063 | hid->ifnum = interface->desc.bInterfaceNumber; | 1212 | usbhid->ifnum = interface->desc.bInterfaceNumber; |
2064 | 1213 | ||
2065 | hid->name[0] = 0; | 1214 | hid->name[0] = 0; |
2066 | 1215 | ||
@@ -2078,6 +1227,10 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
2078 | le16_to_cpu(dev->descriptor.idVendor), | 1227 | le16_to_cpu(dev->descriptor.idVendor), |
2079 | le16_to_cpu(dev->descriptor.idProduct)); | 1228 | le16_to_cpu(dev->descriptor.idProduct)); |
2080 | 1229 | ||
1230 | hid->bus = BUS_USB; | ||
1231 | hid->vendor = dev->descriptor.idVendor; | ||
1232 | hid->product = dev->descriptor.idProduct; | ||
1233 | |||
2081 | usb_make_path(dev, hid->phys, sizeof(hid->phys)); | 1234 | usb_make_path(dev, hid->phys, sizeof(hid->phys)); |
2082 | strlcat(hid->phys, "/input", sizeof(hid->phys)); | 1235 | strlcat(hid->phys, "/input", sizeof(hid->phys)); |
2083 | len = strlen(hid->phys); | 1236 | len = strlen(hid->phys); |
@@ -2088,22 +1241,28 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) | |||
2088 | if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) | 1241 | if (usb_string(dev, dev->descriptor.iSerialNumber, hid->uniq, 64) <= 0) |
2089 | hid->uniq[0] = 0; | 1242 | hid->uniq[0] = 0; |
2090 | 1243 | ||
2091 | hid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); | 1244 | usbhid->urbctrl = usb_alloc_urb(0, GFP_KERNEL); |
2092 | if (!hid->urbctrl) | 1245 | if (!usbhid->urbctrl) |
2093 | goto fail; | 1246 | goto fail; |
2094 | 1247 | ||
2095 | usb_fill_control_urb(hid->urbctrl, dev, 0, (void *) hid->cr, | 1248 | usb_fill_control_urb(usbhid->urbctrl, dev, 0, (void *) usbhid->cr, |
2096 | hid->ctrlbuf, 1, hid_ctrl, hid); | 1249 | usbhid->ctrlbuf, 1, hid_ctrl, hid); |
2097 | hid->urbctrl->setup_dma = hid->cr_dma; | 1250 | usbhid->urbctrl->setup_dma = usbhid->cr_dma; |
2098 | hid->urbctrl->transfer_dma = hid->ctrlbuf_dma; | 1251 | usbhid->urbctrl->transfer_dma = usbhid->ctrlbuf_dma; |
2099 | hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); | 1252 | usbhid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP); |
2100 | 1253 | hid->hidinput_input_event = usb_hidinput_input_event; | |
1254 | hid->hid_open = usbhid_open; | ||
1255 | hid->hid_close = usbhid_close; | ||
1256 | #ifdef CONFIG_USB_HIDDEV | ||
1257 | hid->hiddev_hid_event = hiddev_hid_event; | ||
1258 | hid->hiddev_report_event = hiddev_report_event; | ||
1259 | #endif | ||
2101 | return hid; | 1260 | return hid; |
2102 | 1261 | ||
2103 | fail: | 1262 | fail: |
2104 | usb_free_urb(hid->urbin); | 1263 | usb_free_urb(usbhid->urbin); |
2105 | usb_free_urb(hid->urbout); | 1264 | usb_free_urb(usbhid->urbout); |
2106 | usb_free_urb(hid->urbctrl); | 1265 | usb_free_urb(usbhid->urbctrl); |
2107 | hid_free_buffers(dev, hid); | 1266 | hid_free_buffers(dev, hid); |
2108 | hid_free_device(hid); | 1267 | hid_free_device(hid); |
2109 | 1268 | ||
@@ -2113,18 +1272,21 @@ fail: | |||
2113 | static void hid_disconnect(struct usb_interface *intf) | 1272 | static void hid_disconnect(struct usb_interface *intf) |
2114 | { | 1273 | { |
2115 | struct hid_device *hid = usb_get_intfdata (intf); | 1274 | struct hid_device *hid = usb_get_intfdata (intf); |
1275 | struct usbhid_device *usbhid; | ||
2116 | 1276 | ||
2117 | if (!hid) | 1277 | if (!hid) |
2118 | return; | 1278 | return; |
2119 | 1279 | ||
2120 | spin_lock_irq(&hid->inlock); /* Sync with error handler */ | 1280 | usbhid = hid->driver_data; |
1281 | |||
1282 | spin_lock_irq(&usbhid->inlock); /* Sync with error handler */ | ||
2121 | usb_set_intfdata(intf, NULL); | 1283 | usb_set_intfdata(intf, NULL); |
2122 | spin_unlock_irq(&hid->inlock); | 1284 | spin_unlock_irq(&usbhid->inlock); |
2123 | usb_kill_urb(hid->urbin); | 1285 | usb_kill_urb(usbhid->urbin); |
2124 | usb_kill_urb(hid->urbout); | 1286 | usb_kill_urb(usbhid->urbout); |
2125 | usb_kill_urb(hid->urbctrl); | 1287 | usb_kill_urb(usbhid->urbctrl); |
2126 | 1288 | ||
2127 | del_timer_sync(&hid->io_retry); | 1289 | del_timer_sync(&usbhid->io_retry); |
2128 | flush_scheduled_work(); | 1290 | flush_scheduled_work(); |
2129 | 1291 | ||
2130 | if (hid->claimed & HID_CLAIMED_INPUT) | 1292 | if (hid->claimed & HID_CLAIMED_INPUT) |
@@ -2132,11 +1294,11 @@ static void hid_disconnect(struct usb_interface *intf) | |||
2132 | if (hid->claimed & HID_CLAIMED_HIDDEV) | 1294 | if (hid->claimed & HID_CLAIMED_HIDDEV) |
2133 | hiddev_disconnect(hid); | 1295 | hiddev_disconnect(hid); |
2134 | 1296 | ||
2135 | usb_free_urb(hid->urbin); | 1297 | usb_free_urb(usbhid->urbin); |
2136 | usb_free_urb(hid->urbctrl); | 1298 | usb_free_urb(usbhid->urbctrl); |
2137 | usb_free_urb(hid->urbout); | 1299 | usb_free_urb(usbhid->urbout); |
2138 | 1300 | ||
2139 | hid_free_buffers(hid->dev, hid); | 1301 | hid_free_buffers(hid_to_usb_dev(hid), hid); |
2140 | hid_free_device(hid); | 1302 | hid_free_device(hid); |
2141 | } | 1303 | } |
2142 | 1304 | ||
@@ -2153,7 +1315,7 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
2153 | if (!(hid = usb_hid_configure(intf))) | 1315 | if (!(hid = usb_hid_configure(intf))) |
2154 | return -ENODEV; | 1316 | return -ENODEV; |
2155 | 1317 | ||
2156 | hid_init_reports(hid); | 1318 | usbhid_init_reports(hid); |
2157 | hid_dump_device(hid); | 1319 | hid_dump_device(hid); |
2158 | 1320 | ||
2159 | if (!hidinput_connect(hid)) | 1321 | if (!hidinput_connect(hid)) |
@@ -2169,6 +1331,13 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
2169 | return -ENODEV; | 1331 | return -ENODEV; |
2170 | } | 1332 | } |
2171 | 1333 | ||
1334 | if ((hid->claimed & HID_CLAIMED_INPUT)) | ||
1335 | hid_ff_init(hid); | ||
1336 | |||
1337 | if (hid->quirks & HID_QUIRK_SONY_PS3_CONTROLLER) | ||
1338 | hid_fixup_sony_ps3_controller(interface_to_usbdev(intf), | ||
1339 | intf->cur_altsetting->desc.bInterfaceNumber); | ||
1340 | |||
2172 | printk(KERN_INFO); | 1341 | printk(KERN_INFO); |
2173 | 1342 | ||
2174 | if (hid->claimed & HID_CLAIMED_INPUT) | 1343 | if (hid->claimed & HID_CLAIMED_INPUT) |
@@ -2199,12 +1368,13 @@ static int hid_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
2199 | static int hid_suspend(struct usb_interface *intf, pm_message_t message) | 1368 | static int hid_suspend(struct usb_interface *intf, pm_message_t message) |
2200 | { | 1369 | { |
2201 | struct hid_device *hid = usb_get_intfdata (intf); | 1370 | struct hid_device *hid = usb_get_intfdata (intf); |
1371 | struct usbhid_device *usbhid = hid->driver_data; | ||
2202 | 1372 | ||
2203 | spin_lock_irq(&hid->inlock); /* Sync with error handler */ | 1373 | spin_lock_irq(&usbhid->inlock); /* Sync with error handler */ |
2204 | set_bit(HID_SUSPENDED, &hid->iofl); | 1374 | set_bit(HID_SUSPENDED, &usbhid->iofl); |
2205 | spin_unlock_irq(&hid->inlock); | 1375 | spin_unlock_irq(&usbhid->inlock); |
2206 | del_timer(&hid->io_retry); | 1376 | del_timer(&usbhid->io_retry); |
2207 | usb_kill_urb(hid->urbin); | 1377 | usb_kill_urb(usbhid->urbin); |
2208 | dev_dbg(&intf->dev, "suspend\n"); | 1378 | dev_dbg(&intf->dev, "suspend\n"); |
2209 | return 0; | 1379 | return 0; |
2210 | } | 1380 | } |
@@ -2212,10 +1382,11 @@ static int hid_suspend(struct usb_interface *intf, pm_message_t message) | |||
2212 | static int hid_resume(struct usb_interface *intf) | 1382 | static int hid_resume(struct usb_interface *intf) |
2213 | { | 1383 | { |
2214 | struct hid_device *hid = usb_get_intfdata (intf); | 1384 | struct hid_device *hid = usb_get_intfdata (intf); |
1385 | struct usbhid_device *usbhid = hid->driver_data; | ||
2215 | int status; | 1386 | int status; |
2216 | 1387 | ||
2217 | clear_bit(HID_SUSPENDED, &hid->iofl); | 1388 | clear_bit(HID_SUSPENDED, &usbhid->iofl); |
2218 | hid->retry_delay = 0; | 1389 | usbhid->retry_delay = 0; |
2219 | status = hid_start_in(hid); | 1390 | status = hid_start_in(hid); |
2220 | dev_dbg(&intf->dev, "resume status %d\n", status); | 1391 | dev_dbg(&intf->dev, "resume status %d\n", status); |
2221 | return status; | 1392 | return status; |
diff --git a/drivers/usb/input/hid-debug.h b/drivers/usb/input/hid-debug.h deleted file mode 100644 index f04d6d75c098..000000000000 --- a/drivers/usb/input/hid-debug.h +++ /dev/null | |||
@@ -1,757 +0,0 @@ | |||
1 | /* | ||
2 | * $Id: hid-debug.h,v 1.8 2001/09/25 09:37:57 vojtech Exp $ | ||
3 | * | ||
4 | * (c) 1999 Andreas Gal <gal@cs.uni-magdeburg.de> | ||
5 | * (c) 2000-2001 Vojtech Pavlik <vojtech@ucw.cz> | ||
6 | * | ||
7 | * Some debug stuff for the HID parser. | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
24 | * | ||
25 | * Should you need to contact me, the author, you can do so either by | ||
26 | * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: | ||
27 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic | ||
28 | */ | ||
29 | |||
30 | #include <linux/input.h> | ||
31 | |||
32 | struct hid_usage_entry { | ||
33 | unsigned page; | ||
34 | unsigned usage; | ||
35 | char *description; | ||
36 | }; | ||
37 | |||
38 | static const struct hid_usage_entry hid_usage_table[] = { | ||
39 | { 0, 0, "Undefined" }, | ||
40 | { 1, 0, "GenericDesktop" }, | ||
41 | {0, 0x01, "Pointer"}, | ||
42 | {0, 0x02, "Mouse"}, | ||
43 | {0, 0x04, "Joystick"}, | ||
44 | {0, 0x05, "GamePad"}, | ||
45 | {0, 0x06, "Keyboard"}, | ||
46 | {0, 0x07, "Keypad"}, | ||
47 | {0, 0x08, "MultiAxis"}, | ||
48 | {0, 0x30, "X"}, | ||
49 | {0, 0x31, "Y"}, | ||
50 | {0, 0x32, "Z"}, | ||
51 | {0, 0x33, "Rx"}, | ||
52 | {0, 0x34, "Ry"}, | ||
53 | {0, 0x35, "Rz"}, | ||
54 | {0, 0x36, "Slider"}, | ||
55 | {0, 0x37, "Dial"}, | ||
56 | {0, 0x38, "Wheel"}, | ||
57 | {0, 0x39, "HatSwitch"}, | ||
58 | {0, 0x3a, "CountedBuffer"}, | ||
59 | {0, 0x3b, "ByteCount"}, | ||
60 | {0, 0x3c, "MotionWakeup"}, | ||
61 | {0, 0x3d, "Start"}, | ||
62 | {0, 0x3e, "Select"}, | ||
63 | {0, 0x40, "Vx"}, | ||
64 | {0, 0x41, "Vy"}, | ||
65 | {0, 0x42, "Vz"}, | ||
66 | {0, 0x43, "Vbrx"}, | ||
67 | {0, 0x44, "Vbry"}, | ||
68 | {0, 0x45, "Vbrz"}, | ||
69 | {0, 0x46, "Vno"}, | ||
70 | {0, 0x80, "SystemControl"}, | ||
71 | {0, 0x81, "SystemPowerDown"}, | ||
72 | {0, 0x82, "SystemSleep"}, | ||
73 | {0, 0x83, "SystemWakeUp"}, | ||
74 | {0, 0x84, "SystemContextMenu"}, | ||
75 | {0, 0x85, "SystemMainMenu"}, | ||
76 | {0, 0x86, "SystemAppMenu"}, | ||
77 | {0, 0x87, "SystemMenuHelp"}, | ||
78 | {0, 0x88, "SystemMenuExit"}, | ||
79 | {0, 0x89, "SystemMenuSelect"}, | ||
80 | {0, 0x8a, "SystemMenuRight"}, | ||
81 | {0, 0x8b, "SystemMenuLeft"}, | ||
82 | {0, 0x8c, "SystemMenuUp"}, | ||
83 | {0, 0x8d, "SystemMenuDown"}, | ||
84 | {0, 0x90, "D-PadUp"}, | ||
85 | {0, 0x91, "D-PadDown"}, | ||
86 | {0, 0x92, "D-PadRight"}, | ||
87 | {0, 0x93, "D-PadLeft"}, | ||
88 | { 2, 0, "Simulation" }, | ||
89 | {0, 0xb0, "Aileron"}, | ||
90 | {0, 0xb1, "AileronTrim"}, | ||
91 | {0, 0xb2, "Anti-Torque"}, | ||
92 | {0, 0xb3, "Autopilot"}, | ||
93 | {0, 0xb4, "Chaff"}, | ||
94 | {0, 0xb5, "Collective"}, | ||
95 | {0, 0xb6, "DiveBrake"}, | ||
96 | {0, 0xb7, "ElectronicCountermeasures"}, | ||
97 | {0, 0xb8, "Elevator"}, | ||
98 | {0, 0xb9, "ElevatorTrim"}, | ||
99 | {0, 0xba, "Rudder"}, | ||
100 | {0, 0xbb, "Throttle"}, | ||
101 | {0, 0xbc, "FlightCommunications"}, | ||
102 | {0, 0xbd, "FlareRelease"}, | ||
103 | {0, 0xbe, "LandingGear"}, | ||
104 | {0, 0xbf, "ToeBrake"}, | ||
105 | { 7, 0, "Keyboard" }, | ||
106 | { 8, 0, "LED" }, | ||
107 | {0, 0x01, "NumLock"}, | ||
108 | {0, 0x02, "CapsLock"}, | ||
109 | {0, 0x03, "ScrollLock"}, | ||
110 | {0, 0x04, "Compose"}, | ||
111 | {0, 0x05, "Kana"}, | ||
112 | {0, 0x4b, "GenericIndicator"}, | ||
113 | { 9, 0, "Button" }, | ||
114 | { 10, 0, "Ordinal" }, | ||
115 | { 12, 0, "Consumer" }, | ||
116 | {0, 0x238, "HorizontalWheel"}, | ||
117 | { 13, 0, "Digitizers" }, | ||
118 | {0, 0x01, "Digitizer"}, | ||
119 | {0, 0x02, "Pen"}, | ||
120 | {0, 0x03, "LightPen"}, | ||
121 | {0, 0x04, "TouchScreen"}, | ||
122 | {0, 0x05, "TouchPad"}, | ||
123 | {0, 0x20, "Stylus"}, | ||
124 | {0, 0x21, "Puck"}, | ||
125 | {0, 0x22, "Finger"}, | ||
126 | {0, 0x30, "TipPressure"}, | ||
127 | {0, 0x31, "BarrelPressure"}, | ||
128 | {0, 0x32, "InRange"}, | ||
129 | {0, 0x33, "Touch"}, | ||
130 | {0, 0x34, "UnTouch"}, | ||
131 | {0, 0x35, "Tap"}, | ||
132 | {0, 0x39, "TabletFunctionKey"}, | ||
133 | {0, 0x3a, "ProgramChangeKey"}, | ||
134 | {0, 0x3c, "Invert"}, | ||
135 | {0, 0x42, "TipSwitch"}, | ||
136 | {0, 0x43, "SecondaryTipSwitch"}, | ||
137 | {0, 0x44, "BarrelSwitch"}, | ||
138 | {0, 0x45, "Eraser"}, | ||
139 | {0, 0x46, "TabletPick"}, | ||
140 | { 15, 0, "PhysicalInterfaceDevice" }, | ||
141 | {0, 0x00, "Undefined"}, | ||
142 | {0, 0x01, "Physical_Interface_Device"}, | ||
143 | {0, 0x20, "Normal"}, | ||
144 | {0, 0x21, "Set_Effect_Report"}, | ||
145 | {0, 0x22, "Effect_Block_Index"}, | ||
146 | {0, 0x23, "Parameter_Block_Offset"}, | ||
147 | {0, 0x24, "ROM_Flag"}, | ||
148 | {0, 0x25, "Effect_Type"}, | ||
149 | {0, 0x26, "ET_Constant_Force"}, | ||
150 | {0, 0x27, "ET_Ramp"}, | ||
151 | {0, 0x28, "ET_Custom_Force_Data"}, | ||
152 | {0, 0x30, "ET_Square"}, | ||
153 | {0, 0x31, "ET_Sine"}, | ||
154 | {0, 0x32, "ET_Triangle"}, | ||
155 | {0, 0x33, "ET_Sawtooth_Up"}, | ||
156 | {0, 0x34, "ET_Sawtooth_Down"}, | ||
157 | {0, 0x40, "ET_Spring"}, | ||
158 | {0, 0x41, "ET_Damper"}, | ||
159 | {0, 0x42, "ET_Inertia"}, | ||
160 | {0, 0x43, "ET_Friction"}, | ||
161 | {0, 0x50, "Duration"}, | ||
162 | {0, 0x51, "Sample_Period"}, | ||
163 | {0, 0x52, "Gain"}, | ||
164 | {0, 0x53, "Trigger_Button"}, | ||
165 | {0, 0x54, "Trigger_Repeat_Interval"}, | ||
166 | {0, 0x55, "Axes_Enable"}, | ||
167 | {0, 0x56, "Direction_Enable"}, | ||
168 | {0, 0x57, "Direction"}, | ||
169 | {0, 0x58, "Type_Specific_Block_Offset"}, | ||
170 | {0, 0x59, "Block_Type"}, | ||
171 | {0, 0x5A, "Set_Envelope_Report"}, | ||
172 | {0, 0x5B, "Attack_Level"}, | ||
173 | {0, 0x5C, "Attack_Time"}, | ||
174 | {0, 0x5D, "Fade_Level"}, | ||
175 | {0, 0x5E, "Fade_Time"}, | ||
176 | {0, 0x5F, "Set_Condition_Report"}, | ||
177 | {0, 0x60, "CP_Offset"}, | ||
178 | {0, 0x61, "Positive_Coefficient"}, | ||
179 | {0, 0x62, "Negative_Coefficient"}, | ||
180 | {0, 0x63, "Positive_Saturation"}, | ||
181 | {0, 0x64, "Negative_Saturation"}, | ||
182 | {0, 0x65, "Dead_Band"}, | ||
183 | {0, 0x66, "Download_Force_Sample"}, | ||
184 | {0, 0x67, "Isoch_Custom_Force_Enable"}, | ||
185 | {0, 0x68, "Custom_Force_Data_Report"}, | ||
186 | {0, 0x69, "Custom_Force_Data"}, | ||
187 | {0, 0x6A, "Custom_Force_Vendor_Defined_Data"}, | ||
188 | {0, 0x6B, "Set_Custom_Force_Report"}, | ||
189 | {0, 0x6C, "Custom_Force_Data_Offset"}, | ||
190 | {0, 0x6D, "Sample_Count"}, | ||
191 | {0, 0x6E, "Set_Periodic_Report"}, | ||
192 | {0, 0x6F, "Offset"}, | ||
193 | {0, 0x70, "Magnitude"}, | ||
194 | {0, 0x71, "Phase"}, | ||
195 | {0, 0x72, "Period"}, | ||
196 | {0, 0x73, "Set_Constant_Force_Report"}, | ||
197 | {0, 0x74, "Set_Ramp_Force_Report"}, | ||
198 | {0, 0x75, "Ramp_Start"}, | ||
199 | {0, 0x76, "Ramp_End"}, | ||
200 | {0, 0x77, "Effect_Operation_Report"}, | ||
201 | {0, 0x78, "Effect_Operation"}, | ||
202 | {0, 0x79, "Op_Effect_Start"}, | ||
203 | {0, 0x7A, "Op_Effect_Start_Solo"}, | ||
204 | {0, 0x7B, "Op_Effect_Stop"}, | ||
205 | {0, 0x7C, "Loop_Count"}, | ||
206 | {0, 0x7D, "Device_Gain_Report"}, | ||
207 | {0, 0x7E, "Device_Gain"}, | ||
208 | {0, 0x7F, "PID_Pool_Report"}, | ||
209 | {0, 0x80, "RAM_Pool_Size"}, | ||
210 | {0, 0x81, "ROM_Pool_Size"}, | ||
211 | {0, 0x82, "ROM_Effect_Block_Count"}, | ||
212 | {0, 0x83, "Simultaneous_Effects_Max"}, | ||
213 | {0, 0x84, "Pool_Alignment"}, | ||
214 | {0, 0x85, "PID_Pool_Move_Report"}, | ||
215 | {0, 0x86, "Move_Source"}, | ||
216 | {0, 0x87, "Move_Destination"}, | ||
217 | {0, 0x88, "Move_Length"}, | ||
218 | {0, 0x89, "PID_Block_Load_Report"}, | ||
219 | {0, 0x8B, "Block_Load_Status"}, | ||
220 | {0, 0x8C, "Block_Load_Success"}, | ||
221 | {0, 0x8D, "Block_Load_Full"}, | ||
222 | {0, 0x8E, "Block_Load_Error"}, | ||
223 | {0, 0x8F, "Block_Handle"}, | ||
224 | {0, 0x90, "PID_Block_Free_Report"}, | ||
225 | {0, 0x91, "Type_Specific_Block_Handle"}, | ||
226 | {0, 0x92, "PID_State_Report"}, | ||
227 | {0, 0x94, "Effect_Playing"}, | ||
228 | {0, 0x95, "PID_Device_Control_Report"}, | ||
229 | {0, 0x96, "PID_Device_Control"}, | ||
230 | {0, 0x97, "DC_Enable_Actuators"}, | ||
231 | {0, 0x98, "DC_Disable_Actuators"}, | ||
232 | {0, 0x99, "DC_Stop_All_Effects"}, | ||
233 | {0, 0x9A, "DC_Device_Reset"}, | ||
234 | {0, 0x9B, "DC_Device_Pause"}, | ||
235 | {0, 0x9C, "DC_Device_Continue"}, | ||
236 | {0, 0x9F, "Device_Paused"}, | ||
237 | {0, 0xA0, "Actuators_Enabled"}, | ||
238 | {0, 0xA4, "Safety_Switch"}, | ||
239 | {0, 0xA5, "Actuator_Override_Switch"}, | ||
240 | {0, 0xA6, "Actuator_Power"}, | ||
241 | {0, 0xA7, "Start_Delay"}, | ||
242 | {0, 0xA8, "Parameter_Block_Size"}, | ||
243 | {0, 0xA9, "Device_Managed_Pool"}, | ||
244 | {0, 0xAA, "Shared_Parameter_Blocks"}, | ||
245 | {0, 0xAB, "Create_New_Effect_Report"}, | ||
246 | {0, 0xAC, "RAM_Pool_Available"}, | ||
247 | { 0x84, 0, "Power Device" }, | ||
248 | { 0x84, 0x02, "PresentStatus" }, | ||
249 | { 0x84, 0x03, "ChangeStatus" }, | ||
250 | { 0x84, 0x04, "UPS" }, | ||
251 | { 0x84, 0x05, "PowerSupply" }, | ||
252 | { 0x84, 0x10, "BatterySystem" }, | ||
253 | { 0x84, 0x11, "BatterySystemID" }, | ||
254 | { 0x84, 0x12, "Battery" }, | ||
255 | { 0x84, 0x13, "BatteryID" }, | ||
256 | { 0x84, 0x14, "Charger" }, | ||
257 | { 0x84, 0x15, "ChargerID" }, | ||
258 | { 0x84, 0x16, "PowerConverter" }, | ||
259 | { 0x84, 0x17, "PowerConverterID" }, | ||
260 | { 0x84, 0x18, "OutletSystem" }, | ||
261 | { 0x84, 0x19, "OutletSystemID" }, | ||
262 | { 0x84, 0x1a, "Input" }, | ||
263 | { 0x84, 0x1b, "InputID" }, | ||
264 | { 0x84, 0x1c, "Output" }, | ||
265 | { 0x84, 0x1d, "OutputID" }, | ||
266 | { 0x84, 0x1e, "Flow" }, | ||
267 | { 0x84, 0x1f, "FlowID" }, | ||
268 | { 0x84, 0x20, "Outlet" }, | ||
269 | { 0x84, 0x21, "OutletID" }, | ||
270 | { 0x84, 0x22, "Gang" }, | ||
271 | { 0x84, 0x24, "PowerSummary" }, | ||
272 | { 0x84, 0x25, "PowerSummaryID" }, | ||
273 | { 0x84, 0x30, "Voltage" }, | ||
274 | { 0x84, 0x31, "Current" }, | ||
275 | { 0x84, 0x32, "Frequency" }, | ||
276 | { 0x84, 0x33, "ApparentPower" }, | ||
277 | { 0x84, 0x35, "PercentLoad" }, | ||
278 | { 0x84, 0x40, "ConfigVoltage" }, | ||
279 | { 0x84, 0x41, "ConfigCurrent" }, | ||
280 | { 0x84, 0x43, "ConfigApparentPower" }, | ||
281 | { 0x84, 0x53, "LowVoltageTransfer" }, | ||
282 | { 0x84, 0x54, "HighVoltageTransfer" }, | ||
283 | { 0x84, 0x56, "DelayBeforeStartup" }, | ||
284 | { 0x84, 0x57, "DelayBeforeShutdown" }, | ||
285 | { 0x84, 0x58, "Test" }, | ||
286 | { 0x84, 0x5a, "AudibleAlarmControl" }, | ||
287 | { 0x84, 0x60, "Present" }, | ||
288 | { 0x84, 0x61, "Good" }, | ||
289 | { 0x84, 0x62, "InternalFailure" }, | ||
290 | { 0x84, 0x65, "Overload" }, | ||
291 | { 0x84, 0x66, "OverCharged" }, | ||
292 | { 0x84, 0x67, "OverTemperature" }, | ||
293 | { 0x84, 0x68, "ShutdownRequested" }, | ||
294 | { 0x84, 0x69, "ShutdownImminent" }, | ||
295 | { 0x84, 0x6b, "SwitchOn/Off" }, | ||
296 | { 0x84, 0x6c, "Switchable" }, | ||
297 | { 0x84, 0x6d, "Used" }, | ||
298 | { 0x84, 0x6e, "Boost" }, | ||
299 | { 0x84, 0x73, "CommunicationLost" }, | ||
300 | { 0x84, 0xfd, "iManufacturer" }, | ||
301 | { 0x84, 0xfe, "iProduct" }, | ||
302 | { 0x84, 0xff, "iSerialNumber" }, | ||
303 | { 0x85, 0, "Battery System" }, | ||
304 | { 0x85, 0x01, "SMBBatteryMode" }, | ||
305 | { 0x85, 0x02, "SMBBatteryStatus" }, | ||
306 | { 0x85, 0x03, "SMBAlarmWarning" }, | ||
307 | { 0x85, 0x04, "SMBChargerMode" }, | ||
308 | { 0x85, 0x05, "SMBChargerStatus" }, | ||
309 | { 0x85, 0x06, "SMBChargerSpecInfo" }, | ||
310 | { 0x85, 0x07, "SMBSelectorState" }, | ||
311 | { 0x85, 0x08, "SMBSelectorPresets" }, | ||
312 | { 0x85, 0x09, "SMBSelectorInfo" }, | ||
313 | { 0x85, 0x29, "RemainingCapacityLimit" }, | ||
314 | { 0x85, 0x2c, "CapacityMode" }, | ||
315 | { 0x85, 0x42, "BelowRemainingCapacityLimit" }, | ||
316 | { 0x85, 0x44, "Charging" }, | ||
317 | { 0x85, 0x45, "Discharging" }, | ||
318 | { 0x85, 0x4b, "NeedReplacement" }, | ||
319 | { 0x85, 0x66, "RemainingCapacity" }, | ||
320 | { 0x85, 0x68, "RunTimeToEmpty" }, | ||
321 | { 0x85, 0x6a, "AverageTimeToFull" }, | ||
322 | { 0x85, 0x83, "DesignCapacity" }, | ||
323 | { 0x85, 0x85, "ManufacturerDate" }, | ||
324 | { 0x85, 0x89, "iDeviceChemistry" }, | ||
325 | { 0x85, 0x8b, "Rechargable" }, | ||
326 | { 0x85, 0x8f, "iOEMInformation" }, | ||
327 | { 0x85, 0x8d, "CapacityGranularity1" }, | ||
328 | { 0x85, 0xd0, "ACPresent" }, | ||
329 | /* pages 0xff00 to 0xffff are vendor-specific */ | ||
330 | { 0xffff, 0, "Vendor-specific-FF" }, | ||
331 | { 0, 0, NULL } | ||
332 | }; | ||
333 | |||
334 | static void resolv_usage_page(unsigned page) { | ||
335 | const struct hid_usage_entry *p; | ||
336 | |||
337 | for (p = hid_usage_table; p->description; p++) | ||
338 | if (p->page == page) { | ||
339 | printk("%s", p->description); | ||
340 | return; | ||
341 | } | ||
342 | printk("%04x", page); | ||
343 | } | ||
344 | |||
345 | static void resolv_usage(unsigned usage) { | ||
346 | const struct hid_usage_entry *p; | ||
347 | |||
348 | resolv_usage_page(usage >> 16); | ||
349 | printk("."); | ||
350 | for (p = hid_usage_table; p->description; p++) | ||
351 | if (p->page == (usage >> 16)) { | ||
352 | for(++p; p->description && p->usage != 0; p++) | ||
353 | if (p->usage == (usage & 0xffff)) { | ||
354 | printk("%s", p->description); | ||
355 | return; | ||
356 | } | ||
357 | break; | ||
358 | } | ||
359 | printk("%04x", usage & 0xffff); | ||
360 | } | ||
361 | |||
362 | __inline__ static void tab(int n) { | ||
363 | while (n--) printk(" "); | ||
364 | } | ||
365 | |||
366 | static void hid_dump_field(struct hid_field *field, int n) { | ||
367 | int j; | ||
368 | |||
369 | if (field->physical) { | ||
370 | tab(n); | ||
371 | printk("Physical("); | ||
372 | resolv_usage(field->physical); printk(")\n"); | ||
373 | } | ||
374 | if (field->logical) { | ||
375 | tab(n); | ||
376 | printk("Logical("); | ||
377 | resolv_usage(field->logical); printk(")\n"); | ||
378 | } | ||
379 | tab(n); printk("Usage(%d)\n", field->maxusage); | ||
380 | for (j = 0; j < field->maxusage; j++) { | ||
381 | tab(n+2);resolv_usage(field->usage[j].hid); printk("\n"); | ||
382 | } | ||
383 | if (field->logical_minimum != field->logical_maximum) { | ||
384 | tab(n); printk("Logical Minimum(%d)\n", field->logical_minimum); | ||
385 | tab(n); printk("Logical Maximum(%d)\n", field->logical_maximum); | ||
386 | } | ||
387 | if (field->physical_minimum != field->physical_maximum) { | ||
388 | tab(n); printk("Physical Minimum(%d)\n", field->physical_minimum); | ||
389 | tab(n); printk("Physical Maximum(%d)\n", field->physical_maximum); | ||
390 | } | ||
391 | if (field->unit_exponent) { | ||
392 | tab(n); printk("Unit Exponent(%d)\n", field->unit_exponent); | ||
393 | } | ||
394 | if (field->unit) { | ||
395 | char *systems[5] = { "None", "SI Linear", "SI Rotation", "English Linear", "English Rotation" }; | ||
396 | char *units[5][8] = { | ||
397 | { "None", "None", "None", "None", "None", "None", "None", "None" }, | ||
398 | { "None", "Centimeter", "Gram", "Seconds", "Kelvin", "Ampere", "Candela", "None" }, | ||
399 | { "None", "Radians", "Gram", "Seconds", "Kelvin", "Ampere", "Candela", "None" }, | ||
400 | { "None", "Inch", "Slug", "Seconds", "Fahrenheit", "Ampere", "Candela", "None" }, | ||
401 | { "None", "Degrees", "Slug", "Seconds", "Fahrenheit", "Ampere", "Candela", "None" } | ||
402 | }; | ||
403 | |||
404 | int i; | ||
405 | int sys; | ||
406 | __u32 data = field->unit; | ||
407 | |||
408 | /* First nibble tells us which system we're in. */ | ||
409 | sys = data & 0xf; | ||
410 | data >>= 4; | ||
411 | |||
412 | if(sys > 4) { | ||
413 | tab(n); printk("Unit(Invalid)\n"); | ||
414 | } | ||
415 | else { | ||
416 | int earlier_unit = 0; | ||
417 | |||
418 | tab(n); printk("Unit(%s : ", systems[sys]); | ||
419 | |||
420 | for (i=1 ; i<sizeof(__u32)*2 ; i++) { | ||
421 | char nibble = data & 0xf; | ||
422 | data >>= 4; | ||
423 | if (nibble != 0) { | ||
424 | if(earlier_unit++ > 0) | ||
425 | printk("*"); | ||
426 | printk("%s", units[sys][i]); | ||
427 | if(nibble != 1) { | ||
428 | /* This is a _signed_ nibble(!) */ | ||
429 | |||
430 | int val = nibble & 0x7; | ||
431 | if(nibble & 0x08) | ||
432 | val = -((0x7 & ~val) +1); | ||
433 | printk("^%d", val); | ||
434 | } | ||
435 | } | ||
436 | } | ||
437 | printk(")\n"); | ||
438 | } | ||
439 | } | ||
440 | tab(n); printk("Report Size(%u)\n", field->report_size); | ||
441 | tab(n); printk("Report Count(%u)\n", field->report_count); | ||
442 | tab(n); printk("Report Offset(%u)\n", field->report_offset); | ||
443 | |||
444 | tab(n); printk("Flags( "); | ||
445 | j = field->flags; | ||
446 | printk("%s", HID_MAIN_ITEM_CONSTANT & j ? "Constant " : ""); | ||
447 | printk("%s", HID_MAIN_ITEM_VARIABLE & j ? "Variable " : "Array "); | ||
448 | printk("%s", HID_MAIN_ITEM_RELATIVE & j ? "Relative " : "Absolute "); | ||
449 | printk("%s", HID_MAIN_ITEM_WRAP & j ? "Wrap " : ""); | ||
450 | printk("%s", HID_MAIN_ITEM_NONLINEAR & j ? "NonLinear " : ""); | ||
451 | printk("%s", HID_MAIN_ITEM_NO_PREFERRED & j ? "NoPrefferedState " : ""); | ||
452 | printk("%s", HID_MAIN_ITEM_NULL_STATE & j ? "NullState " : ""); | ||
453 | printk("%s", HID_MAIN_ITEM_VOLATILE & j ? "Volatile " : ""); | ||
454 | printk("%s", HID_MAIN_ITEM_BUFFERED_BYTE & j ? "BufferedByte " : ""); | ||
455 | printk(")\n"); | ||
456 | } | ||
457 | |||
458 | static void __attribute__((unused)) hid_dump_device(struct hid_device *device) { | ||
459 | struct hid_report_enum *report_enum; | ||
460 | struct hid_report *report; | ||
461 | struct list_head *list; | ||
462 | unsigned i,k; | ||
463 | static char *table[] = {"INPUT", "OUTPUT", "FEATURE"}; | ||
464 | |||
465 | for (i = 0; i < HID_REPORT_TYPES; i++) { | ||
466 | report_enum = device->report_enum + i; | ||
467 | list = report_enum->report_list.next; | ||
468 | while (list != &report_enum->report_list) { | ||
469 | report = (struct hid_report *) list; | ||
470 | tab(2); | ||
471 | printk("%s", table[i]); | ||
472 | if (report->id) | ||
473 | printk("(%d)", report->id); | ||
474 | printk("[%s]", table[report->type]); | ||
475 | printk("\n"); | ||
476 | for (k = 0; k < report->maxfield; k++) { | ||
477 | tab(4); | ||
478 | printk("Field(%d)\n", k); | ||
479 | hid_dump_field(report->field[k], 6); | ||
480 | } | ||
481 | list = list->next; | ||
482 | } | ||
483 | } | ||
484 | } | ||
485 | |||
486 | static void __attribute__((unused)) hid_dump_input(struct hid_usage *usage, __s32 value) { | ||
487 | printk("hid-debug: input "); | ||
488 | resolv_usage(usage->hid); | ||
489 | printk(" = %d\n", value); | ||
490 | } | ||
491 | |||
492 | |||
493 | static char *events[EV_MAX + 1] = { | ||
494 | [EV_SYN] = "Sync", [EV_KEY] = "Key", | ||
495 | [EV_REL] = "Relative", [EV_ABS] = "Absolute", | ||
496 | [EV_MSC] = "Misc", [EV_LED] = "LED", | ||
497 | [EV_SND] = "Sound", [EV_REP] = "Repeat", | ||
498 | [EV_FF] = "ForceFeedback", [EV_PWR] = "Power", | ||
499 | [EV_FF_STATUS] = "ForceFeedbackStatus", | ||
500 | }; | ||
501 | |||
502 | static char *syncs[2] = { | ||
503 | [SYN_REPORT] = "Report", [SYN_CONFIG] = "Config", | ||
504 | }; | ||
505 | static char *keys[KEY_MAX + 1] = { | ||
506 | [KEY_RESERVED] = "Reserved", [KEY_ESC] = "Esc", | ||
507 | [KEY_1] = "1", [KEY_2] = "2", | ||
508 | [KEY_3] = "3", [KEY_4] = "4", | ||
509 | [KEY_5] = "5", [KEY_6] = "6", | ||
510 | [KEY_7] = "7", [KEY_8] = "8", | ||
511 | [KEY_9] = "9", [KEY_0] = "0", | ||
512 | [KEY_MINUS] = "Minus", [KEY_EQUAL] = "Equal", | ||
513 | [KEY_BACKSPACE] = "Backspace", [KEY_TAB] = "Tab", | ||
514 | [KEY_Q] = "Q", [KEY_W] = "W", | ||
515 | [KEY_E] = "E", [KEY_R] = "R", | ||
516 | [KEY_T] = "T", [KEY_Y] = "Y", | ||
517 | [KEY_U] = "U", [KEY_I] = "I", | ||
518 | [KEY_O] = "O", [KEY_P] = "P", | ||
519 | [KEY_LEFTBRACE] = "LeftBrace", [KEY_RIGHTBRACE] = "RightBrace", | ||
520 | [KEY_ENTER] = "Enter", [KEY_LEFTCTRL] = "LeftControl", | ||
521 | [KEY_A] = "A", [KEY_S] = "S", | ||
522 | [KEY_D] = "D", [KEY_F] = "F", | ||
523 | [KEY_G] = "G", [KEY_H] = "H", | ||
524 | [KEY_J] = "J", [KEY_K] = "K", | ||
525 | [KEY_L] = "L", [KEY_SEMICOLON] = "Semicolon", | ||
526 | [KEY_APOSTROPHE] = "Apostrophe", [KEY_GRAVE] = "Grave", | ||
527 | [KEY_LEFTSHIFT] = "LeftShift", [KEY_BACKSLASH] = "BackSlash", | ||
528 | [KEY_Z] = "Z", [KEY_X] = "X", | ||
529 | [KEY_C] = "C", [KEY_V] = "V", | ||
530 | [KEY_B] = "B", [KEY_N] = "N", | ||
531 | [KEY_M] = "M", [KEY_COMMA] = "Comma", | ||
532 | [KEY_DOT] = "Dot", [KEY_SLASH] = "Slash", | ||
533 | [KEY_RIGHTSHIFT] = "RightShift", [KEY_KPASTERISK] = "KPAsterisk", | ||
534 | [KEY_LEFTALT] = "LeftAlt", [KEY_SPACE] = "Space", | ||
535 | [KEY_CAPSLOCK] = "CapsLock", [KEY_F1] = "F1", | ||
536 | [KEY_F2] = "F2", [KEY_F3] = "F3", | ||
537 | [KEY_F4] = "F4", [KEY_F5] = "F5", | ||
538 | [KEY_F6] = "F6", [KEY_F7] = "F7", | ||
539 | [KEY_F8] = "F8", [KEY_F9] = "F9", | ||
540 | [KEY_F10] = "F10", [KEY_NUMLOCK] = "NumLock", | ||
541 | [KEY_SCROLLLOCK] = "ScrollLock", [KEY_KP7] = "KP7", | ||
542 | [KEY_KP8] = "KP8", [KEY_KP9] = "KP9", | ||
543 | [KEY_KPMINUS] = "KPMinus", [KEY_KP4] = "KP4", | ||
544 | [KEY_KP5] = "KP5", [KEY_KP6] = "KP6", | ||
545 | [KEY_KPPLUS] = "KPPlus", [KEY_KP1] = "KP1", | ||
546 | [KEY_KP2] = "KP2", [KEY_KP3] = "KP3", | ||
547 | [KEY_KP0] = "KP0", [KEY_KPDOT] = "KPDot", | ||
548 | [KEY_ZENKAKUHANKAKU] = "Zenkaku/Hankaku", [KEY_102ND] = "102nd", | ||
549 | [KEY_F11] = "F11", [KEY_F12] = "F12", | ||
550 | [KEY_RO] = "RO", [KEY_KATAKANA] = "Katakana", | ||
551 | [KEY_HIRAGANA] = "HIRAGANA", [KEY_HENKAN] = "Henkan", | ||
552 | [KEY_KATAKANAHIRAGANA] = "Katakana/Hiragana", [KEY_MUHENKAN] = "Muhenkan", | ||
553 | [KEY_KPJPCOMMA] = "KPJpComma", [KEY_KPENTER] = "KPEnter", | ||
554 | [KEY_RIGHTCTRL] = "RightCtrl", [KEY_KPSLASH] = "KPSlash", | ||
555 | [KEY_SYSRQ] = "SysRq", [KEY_RIGHTALT] = "RightAlt", | ||
556 | [KEY_LINEFEED] = "LineFeed", [KEY_HOME] = "Home", | ||
557 | [KEY_UP] = "Up", [KEY_PAGEUP] = "PageUp", | ||
558 | [KEY_LEFT] = "Left", [KEY_RIGHT] = "Right", | ||
559 | [KEY_END] = "End", [KEY_DOWN] = "Down", | ||
560 | [KEY_PAGEDOWN] = "PageDown", [KEY_INSERT] = "Insert", | ||
561 | [KEY_DELETE] = "Delete", [KEY_MACRO] = "Macro", | ||
562 | [KEY_MUTE] = "Mute", [KEY_VOLUMEDOWN] = "VolumeDown", | ||
563 | [KEY_VOLUMEUP] = "VolumeUp", [KEY_POWER] = "Power", | ||
564 | [KEY_KPEQUAL] = "KPEqual", [KEY_KPPLUSMINUS] = "KPPlusMinus", | ||
565 | [KEY_PAUSE] = "Pause", [KEY_KPCOMMA] = "KPComma", | ||
566 | [KEY_HANGUEL] = "Hangeul", [KEY_HANJA] = "Hanja", | ||
567 | [KEY_YEN] = "Yen", [KEY_LEFTMETA] = "LeftMeta", | ||
568 | [KEY_RIGHTMETA] = "RightMeta", [KEY_COMPOSE] = "Compose", | ||
569 | [KEY_STOP] = "Stop", [KEY_AGAIN] = "Again", | ||
570 | [KEY_PROPS] = "Props", [KEY_UNDO] = "Undo", | ||
571 | [KEY_FRONT] = "Front", [KEY_COPY] = "Copy", | ||
572 | [KEY_OPEN] = "Open", [KEY_PASTE] = "Paste", | ||
573 | [KEY_FIND] = "Find", [KEY_CUT] = "Cut", | ||
574 | [KEY_HELP] = "Help", [KEY_MENU] = "Menu", | ||
575 | [KEY_CALC] = "Calc", [KEY_SETUP] = "Setup", | ||
576 | [KEY_SLEEP] = "Sleep", [KEY_WAKEUP] = "WakeUp", | ||
577 | [KEY_FILE] = "File", [KEY_SENDFILE] = "SendFile", | ||
578 | [KEY_DELETEFILE] = "DeleteFile", [KEY_XFER] = "X-fer", | ||
579 | [KEY_PROG1] = "Prog1", [KEY_PROG2] = "Prog2", | ||
580 | [KEY_WWW] = "WWW", [KEY_MSDOS] = "MSDOS", | ||
581 | [KEY_COFFEE] = "Coffee", [KEY_DIRECTION] = "Direction", | ||
582 | [KEY_CYCLEWINDOWS] = "CycleWindows", [KEY_MAIL] = "Mail", | ||
583 | [KEY_BOOKMARKS] = "Bookmarks", [KEY_COMPUTER] = "Computer", | ||
584 | [KEY_BACK] = "Back", [KEY_FORWARD] = "Forward", | ||
585 | [KEY_CLOSECD] = "CloseCD", [KEY_EJECTCD] = "EjectCD", | ||
586 | [KEY_EJECTCLOSECD] = "EjectCloseCD", [KEY_NEXTSONG] = "NextSong", | ||
587 | [KEY_PLAYPAUSE] = "PlayPause", [KEY_PREVIOUSSONG] = "PreviousSong", | ||
588 | [KEY_STOPCD] = "StopCD", [KEY_RECORD] = "Record", | ||
589 | [KEY_REWIND] = "Rewind", [KEY_PHONE] = "Phone", | ||
590 | [KEY_ISO] = "ISOKey", [KEY_CONFIG] = "Config", | ||
591 | [KEY_HOMEPAGE] = "HomePage", [KEY_REFRESH] = "Refresh", | ||
592 | [KEY_EXIT] = "Exit", [KEY_MOVE] = "Move", | ||
593 | [KEY_EDIT] = "Edit", [KEY_SCROLLUP] = "ScrollUp", | ||
594 | [KEY_SCROLLDOWN] = "ScrollDown", [KEY_KPLEFTPAREN] = "KPLeftParenthesis", | ||
595 | [KEY_KPRIGHTPAREN] = "KPRightParenthesis", [KEY_NEW] = "New", | ||
596 | [KEY_REDO] = "Redo", [KEY_F13] = "F13", | ||
597 | [KEY_F14] = "F14", [KEY_F15] = "F15", | ||
598 | [KEY_F16] = "F16", [KEY_F17] = "F17", | ||
599 | [KEY_F18] = "F18", [KEY_F19] = "F19", | ||
600 | [KEY_F20] = "F20", [KEY_F21] = "F21", | ||
601 | [KEY_F22] = "F22", [KEY_F23] = "F23", | ||
602 | [KEY_F24] = "F24", [KEY_PLAYCD] = "PlayCD", | ||
603 | [KEY_PAUSECD] = "PauseCD", [KEY_PROG3] = "Prog3", | ||
604 | [KEY_PROG4] = "Prog4", [KEY_SUSPEND] = "Suspend", | ||
605 | [KEY_CLOSE] = "Close", [KEY_PLAY] = "Play", | ||
606 | [KEY_FASTFORWARD] = "FastForward", [KEY_BASSBOOST] = "BassBoost", | ||
607 | [KEY_PRINT] = "Print", [KEY_HP] = "HP", | ||
608 | [KEY_CAMERA] = "Camera", [KEY_SOUND] = "Sound", | ||
609 | [KEY_QUESTION] = "Question", [KEY_EMAIL] = "Email", | ||
610 | [KEY_CHAT] = "Chat", [KEY_SEARCH] = "Search", | ||
611 | [KEY_CONNECT] = "Connect", [KEY_FINANCE] = "Finance", | ||
612 | [KEY_SPORT] = "Sport", [KEY_SHOP] = "Shop", | ||
613 | [KEY_ALTERASE] = "AlternateErase", [KEY_CANCEL] = "Cancel", | ||
614 | [KEY_BRIGHTNESSDOWN] = "BrightnessDown", [KEY_BRIGHTNESSUP] = "BrightnessUp", | ||
615 | [KEY_MEDIA] = "Media", [KEY_UNKNOWN] = "Unknown", | ||
616 | [BTN_0] = "Btn0", [BTN_1] = "Btn1", | ||
617 | [BTN_2] = "Btn2", [BTN_3] = "Btn3", | ||
618 | [BTN_4] = "Btn4", [BTN_5] = "Btn5", | ||
619 | [BTN_6] = "Btn6", [BTN_7] = "Btn7", | ||
620 | [BTN_8] = "Btn8", [BTN_9] = "Btn9", | ||
621 | [BTN_LEFT] = "LeftBtn", [BTN_RIGHT] = "RightBtn", | ||
622 | [BTN_MIDDLE] = "MiddleBtn", [BTN_SIDE] = "SideBtn", | ||
623 | [BTN_EXTRA] = "ExtraBtn", [BTN_FORWARD] = "ForwardBtn", | ||
624 | [BTN_BACK] = "BackBtn", [BTN_TASK] = "TaskBtn", | ||
625 | [BTN_TRIGGER] = "Trigger", [BTN_THUMB] = "ThumbBtn", | ||
626 | [BTN_THUMB2] = "ThumbBtn2", [BTN_TOP] = "TopBtn", | ||
627 | [BTN_TOP2] = "TopBtn2", [BTN_PINKIE] = "PinkieBtn", | ||
628 | [BTN_BASE] = "BaseBtn", [BTN_BASE2] = "BaseBtn2", | ||
629 | [BTN_BASE3] = "BaseBtn3", [BTN_BASE4] = "BaseBtn4", | ||
630 | [BTN_BASE5] = "BaseBtn5", [BTN_BASE6] = "BaseBtn6", | ||
631 | [BTN_DEAD] = "BtnDead", [BTN_A] = "BtnA", | ||
632 | [BTN_B] = "BtnB", [BTN_C] = "BtnC", | ||
633 | [BTN_X] = "BtnX", [BTN_Y] = "BtnY", | ||
634 | [BTN_Z] = "BtnZ", [BTN_TL] = "BtnTL", | ||
635 | [BTN_TR] = "BtnTR", [BTN_TL2] = "BtnTL2", | ||
636 | [BTN_TR2] = "BtnTR2", [BTN_SELECT] = "BtnSelect", | ||
637 | [BTN_START] = "BtnStart", [BTN_MODE] = "BtnMode", | ||
638 | [BTN_THUMBL] = "BtnThumbL", [BTN_THUMBR] = "BtnThumbR", | ||
639 | [BTN_TOOL_PEN] = "ToolPen", [BTN_TOOL_RUBBER] = "ToolRubber", | ||
640 | [BTN_TOOL_BRUSH] = "ToolBrush", [BTN_TOOL_PENCIL] = "ToolPencil", | ||
641 | [BTN_TOOL_AIRBRUSH] = "ToolAirbrush", [BTN_TOOL_FINGER] = "ToolFinger", | ||
642 | [BTN_TOOL_MOUSE] = "ToolMouse", [BTN_TOOL_LENS] = "ToolLens", | ||
643 | [BTN_TOUCH] = "Touch", [BTN_STYLUS] = "Stylus", | ||
644 | [BTN_STYLUS2] = "Stylus2", [BTN_TOOL_DOUBLETAP] = "ToolDoubleTap", | ||
645 | [BTN_TOOL_TRIPLETAP] = "ToolTripleTap", [BTN_GEAR_DOWN] = "WheelBtn", | ||
646 | [BTN_GEAR_UP] = "Gear up", [KEY_OK] = "Ok", | ||
647 | [KEY_SELECT] = "Select", [KEY_GOTO] = "Goto", | ||
648 | [KEY_CLEAR] = "Clear", [KEY_POWER2] = "Power2", | ||
649 | [KEY_OPTION] = "Option", [KEY_INFO] = "Info", | ||
650 | [KEY_TIME] = "Time", [KEY_VENDOR] = "Vendor", | ||
651 | [KEY_ARCHIVE] = "Archive", [KEY_PROGRAM] = "Program", | ||
652 | [KEY_CHANNEL] = "Channel", [KEY_FAVORITES] = "Favorites", | ||
653 | [KEY_EPG] = "EPG", [KEY_PVR] = "PVR", | ||
654 | [KEY_MHP] = "MHP", [KEY_LANGUAGE] = "Language", | ||
655 | [KEY_TITLE] = "Title", [KEY_SUBTITLE] = "Subtitle", | ||
656 | [KEY_ANGLE] = "Angle", [KEY_ZOOM] = "Zoom", | ||
657 | [KEY_MODE] = "Mode", [KEY_KEYBOARD] = "Keyboard", | ||
658 | [KEY_SCREEN] = "Screen", [KEY_PC] = "PC", | ||
659 | [KEY_TV] = "TV", [KEY_TV2] = "TV2", | ||
660 | [KEY_VCR] = "VCR", [KEY_VCR2] = "VCR2", | ||
661 | [KEY_SAT] = "Sat", [KEY_SAT2] = "Sat2", | ||
662 | [KEY_CD] = "CD", [KEY_TAPE] = "Tape", | ||
663 | [KEY_RADIO] = "Radio", [KEY_TUNER] = "Tuner", | ||
664 | [KEY_PLAYER] = "Player", [KEY_TEXT] = "Text", | ||
665 | [KEY_DVD] = "DVD", [KEY_AUX] = "Aux", | ||
666 | [KEY_MP3] = "MP3", [KEY_AUDIO] = "Audio", | ||
667 | [KEY_VIDEO] = "Video", [KEY_DIRECTORY] = "Directory", | ||
668 | [KEY_LIST] = "List", [KEY_MEMO] = "Memo", | ||
669 | [KEY_CALENDAR] = "Calendar", [KEY_RED] = "Red", | ||
670 | [KEY_GREEN] = "Green", [KEY_YELLOW] = "Yellow", | ||
671 | [KEY_BLUE] = "Blue", [KEY_CHANNELUP] = "ChannelUp", | ||
672 | [KEY_CHANNELDOWN] = "ChannelDown", [KEY_FIRST] = "First", | ||
673 | [KEY_LAST] = "Last", [KEY_AB] = "AB", | ||
674 | [KEY_NEXT] = "Next", [KEY_RESTART] = "Restart", | ||
675 | [KEY_SLOW] = "Slow", [KEY_SHUFFLE] = "Shuffle", | ||
676 | [KEY_BREAK] = "Break", [KEY_PREVIOUS] = "Previous", | ||
677 | [KEY_DIGITS] = "Digits", [KEY_TEEN] = "TEEN", | ||
678 | [KEY_TWEN] = "TWEN", [KEY_DEL_EOL] = "DeleteEOL", | ||
679 | [KEY_DEL_EOS] = "DeleteEOS", [KEY_INS_LINE] = "InsertLine", | ||
680 | [KEY_DEL_LINE] = "DeleteLine", | ||
681 | [KEY_SEND] = "Send", [KEY_REPLY] = "Reply", | ||
682 | [KEY_FORWARDMAIL] = "ForwardMail", [KEY_SAVE] = "Save", | ||
683 | [KEY_DOCUMENTS] = "Documents", | ||
684 | [KEY_FN] = "Fn", [KEY_FN_ESC] = "Fn+ESC", | ||
685 | [KEY_FN_1] = "Fn+1", [KEY_FN_2] = "Fn+2", | ||
686 | [KEY_FN_B] = "Fn+B", [KEY_FN_D] = "Fn+D", | ||
687 | [KEY_FN_E] = "Fn+E", [KEY_FN_F] = "Fn+F", | ||
688 | [KEY_FN_S] = "Fn+S", | ||
689 | [KEY_FN_F1] = "Fn+F1", [KEY_FN_F2] = "Fn+F2", | ||
690 | [KEY_FN_F3] = "Fn+F3", [KEY_FN_F4] = "Fn+F4", | ||
691 | [KEY_FN_F5] = "Fn+F5", [KEY_FN_F6] = "Fn+F6", | ||
692 | [KEY_FN_F7] = "Fn+F7", [KEY_FN_F8] = "Fn+F8", | ||
693 | [KEY_FN_F9] = "Fn+F9", [KEY_FN_F10] = "Fn+F10", | ||
694 | [KEY_FN_F11] = "Fn+F11", [KEY_FN_F12] = "Fn+F12", | ||
695 | [KEY_KBDILLUMTOGGLE] = "KbdIlluminationToggle", | ||
696 | [KEY_KBDILLUMDOWN] = "KbdIlluminationDown", | ||
697 | [KEY_KBDILLUMUP] = "KbdIlluminationUp", | ||
698 | [KEY_SWITCHVIDEOMODE] = "SwitchVideoMode", | ||
699 | }; | ||
700 | |||
701 | static char *relatives[REL_MAX + 1] = { | ||
702 | [REL_X] = "X", [REL_Y] = "Y", | ||
703 | [REL_Z] = "Z", [REL_HWHEEL] = "HWheel", | ||
704 | [REL_DIAL] = "Dial", [REL_WHEEL] = "Wheel", | ||
705 | [REL_MISC] = "Misc", | ||
706 | }; | ||
707 | |||
708 | static char *absolutes[ABS_MAX + 1] = { | ||
709 | [ABS_X] = "X", [ABS_Y] = "Y", | ||
710 | [ABS_Z] = "Z", [ABS_RX] = "Rx", | ||
711 | [ABS_RY] = "Ry", [ABS_RZ] = "Rz", | ||
712 | [ABS_THROTTLE] = "Throttle", [ABS_RUDDER] = "Rudder", | ||
713 | [ABS_WHEEL] = "Wheel", [ABS_GAS] = "Gas", | ||
714 | [ABS_BRAKE] = "Brake", [ABS_HAT0X] = "Hat0X", | ||
715 | [ABS_HAT0Y] = "Hat0Y", [ABS_HAT1X] = "Hat1X", | ||
716 | [ABS_HAT1Y] = "Hat1Y", [ABS_HAT2X] = "Hat2X", | ||
717 | [ABS_HAT2Y] = "Hat2Y", [ABS_HAT3X] = "Hat3X", | ||
718 | [ABS_HAT3Y] = "Hat 3Y", [ABS_PRESSURE] = "Pressure", | ||
719 | [ABS_DISTANCE] = "Distance", [ABS_TILT_X] = "XTilt", | ||
720 | [ABS_TILT_Y] = "YTilt", [ABS_TOOL_WIDTH] = "Tool Width", | ||
721 | [ABS_VOLUME] = "Volume", [ABS_MISC] = "Misc", | ||
722 | }; | ||
723 | |||
724 | static char *misc[MSC_MAX + 1] = { | ||
725 | [MSC_SERIAL] = "Serial", [MSC_PULSELED] = "Pulseled", | ||
726 | [MSC_GESTURE] = "Gesture", [MSC_RAW] = "RawData" | ||
727 | }; | ||
728 | |||
729 | static char *leds[LED_MAX + 1] = { | ||
730 | [LED_NUML] = "NumLock", [LED_CAPSL] = "CapsLock", | ||
731 | [LED_SCROLLL] = "ScrollLock", [LED_COMPOSE] = "Compose", | ||
732 | [LED_KANA] = "Kana", [LED_SLEEP] = "Sleep", | ||
733 | [LED_SUSPEND] = "Suspend", [LED_MUTE] = "Mute", | ||
734 | [LED_MISC] = "Misc", | ||
735 | }; | ||
736 | |||
737 | static char *repeats[REP_MAX + 1] = { | ||
738 | [REP_DELAY] = "Delay", [REP_PERIOD] = "Period" | ||
739 | }; | ||
740 | |||
741 | static char *sounds[SND_MAX + 1] = { | ||
742 | [SND_CLICK] = "Click", [SND_BELL] = "Bell", | ||
743 | [SND_TONE] = "Tone" | ||
744 | }; | ||
745 | |||
746 | static char **names[EV_MAX + 1] = { | ||
747 | [EV_SYN] = syncs, [EV_KEY] = keys, | ||
748 | [EV_REL] = relatives, [EV_ABS] = absolutes, | ||
749 | [EV_MSC] = misc, [EV_LED] = leds, | ||
750 | [EV_SND] = sounds, [EV_REP] = repeats, | ||
751 | }; | ||
752 | |||
753 | static void __attribute__((unused)) resolv_event(__u8 type, __u16 code) { | ||
754 | |||
755 | printk("%s.%s", events[type] ? events[type] : "?", | ||
756 | names[type] ? (names[type][code] ? names[type][code] : "?") : "?"); | ||
757 | } | ||
diff --git a/drivers/usb/input/hid-ff.c b/drivers/usb/input/hid-ff.c index 0d644fa37c68..bc7f8e6f8c97 100644 --- a/drivers/usb/input/hid-ff.c +++ b/drivers/usb/input/hid-ff.c | |||
@@ -32,7 +32,8 @@ | |||
32 | #undef DEBUG | 32 | #undef DEBUG |
33 | #include <linux/usb.h> | 33 | #include <linux/usb.h> |
34 | 34 | ||
35 | #include "hid.h" | 35 | #include <linux/hid.h> |
36 | #include "usbhid.h" | ||
36 | 37 | ||
37 | /* | 38 | /* |
38 | * This table contains pointers to initializers. To add support for new | 39 | * This table contains pointers to initializers. To add support for new |
@@ -58,6 +59,9 @@ static struct hid_ff_initializer inits[] = { | |||
58 | { 0x46d, 0xc219, hid_lgff_init }, /* Logitech Cordless rumble pad 2 */ | 59 | { 0x46d, 0xc219, hid_lgff_init }, /* Logitech Cordless rumble pad 2 */ |
59 | { 0x46d, 0xca03, hid_lgff_init }, /* Logitech MOMO force wheel */ | 60 | { 0x46d, 0xca03, hid_lgff_init }, /* Logitech MOMO force wheel */ |
60 | #endif | 61 | #endif |
62 | #ifdef CONFIG_PANTHERLORD_FF | ||
63 | { 0x810, 0x0001, hid_plff_init }, | ||
64 | #endif | ||
61 | #ifdef CONFIG_THRUSTMASTER_FF | 65 | #ifdef CONFIG_THRUSTMASTER_FF |
62 | { 0x44f, 0xb304, hid_tmff_init }, | 66 | { 0x44f, 0xb304, hid_tmff_init }, |
63 | #endif | 67 | #endif |
@@ -71,8 +75,8 @@ static struct hid_ff_initializer inits[] = { | |||
71 | int hid_ff_init(struct hid_device* hid) | 75 | int hid_ff_init(struct hid_device* hid) |
72 | { | 76 | { |
73 | struct hid_ff_initializer *init; | 77 | struct hid_ff_initializer *init; |
74 | int vendor = le16_to_cpu(hid->dev->descriptor.idVendor); | 78 | int vendor = le16_to_cpu(hid_to_usb_dev(hid)->descriptor.idVendor); |
75 | int product = le16_to_cpu(hid->dev->descriptor.idProduct); | 79 | int product = le16_to_cpu(hid_to_usb_dev(hid)->descriptor.idProduct); |
76 | 80 | ||
77 | for (init = inits; init->idVendor; init++) | 81 | for (init = inits; init->idVendor; init++) |
78 | if (init->idVendor == vendor && init->idProduct == product) | 82 | if (init->idVendor == vendor && init->idProduct == product) |
@@ -80,3 +84,5 @@ int hid_ff_init(struct hid_device* hid) | |||
80 | 84 | ||
81 | return init->init(hid); | 85 | return init->init(hid); |
82 | } | 86 | } |
87 | EXPORT_SYMBOL_GPL(hid_ff_init); | ||
88 | |||
diff --git a/drivers/usb/input/hid-input.c b/drivers/usb/input/hid-input.c deleted file mode 100644 index 3a7e5fbff025..000000000000 --- a/drivers/usb/input/hid-input.c +++ /dev/null | |||
@@ -1,872 +0,0 @@ | |||
1 | /* | ||
2 | * $Id: hid-input.c,v 1.2 2002/04/23 00:59:25 rdamazio Exp $ | ||
3 | * | ||
4 | * Copyright (c) 2000-2001 Vojtech Pavlik | ||
5 | * | ||
6 | * USB HID to Linux Input mapping | ||
7 | */ | ||
8 | |||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
23 | * | ||
24 | * Should you need to contact me, the author, you can do so either by | ||
25 | * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: | ||
26 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic | ||
27 | */ | ||
28 | |||
29 | #include <linux/module.h> | ||
30 | #include <linux/slab.h> | ||
31 | #include <linux/kernel.h> | ||
32 | #include <linux/usb/input.h> | ||
33 | |||
34 | #undef DEBUG | ||
35 | |||
36 | #include "hid.h" | ||
37 | |||
38 | #define unk KEY_UNKNOWN | ||
39 | |||
40 | static const unsigned char hid_keyboard[256] = { | ||
41 | 0, 0, 0, 0, 30, 48, 46, 32, 18, 33, 34, 35, 23, 36, 37, 38, | ||
42 | 50, 49, 24, 25, 16, 19, 31, 20, 22, 47, 17, 45, 21, 44, 2, 3, | ||
43 | 4, 5, 6, 7, 8, 9, 10, 11, 28, 1, 14, 15, 57, 12, 13, 26, | ||
44 | 27, 43, 43, 39, 40, 41, 51, 52, 53, 58, 59, 60, 61, 62, 63, 64, | ||
45 | 65, 66, 67, 68, 87, 88, 99, 70,119,110,102,104,111,107,109,106, | ||
46 | 105,108,103, 69, 98, 55, 74, 78, 96, 79, 80, 81, 75, 76, 77, 71, | ||
47 | 72, 73, 82, 83, 86,127,116,117,183,184,185,186,187,188,189,190, | ||
48 | 191,192,193,194,134,138,130,132,128,129,131,137,133,135,136,113, | ||
49 | 115,114,unk,unk,unk,121,unk, 89, 93,124, 92, 94, 95,unk,unk,unk, | ||
50 | 122,123, 90, 91, 85,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, | ||
51 | unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, | ||
52 | unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, | ||
53 | unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, | ||
54 | unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk,unk, | ||
55 | 29, 42, 56,125, 97, 54,100,126,164,166,165,163,161,115,114,113, | ||
56 | 150,158,159,128,136,177,178,176,142,152,173,140,unk,unk,unk,unk | ||
57 | }; | ||
58 | |||
59 | static const struct { | ||
60 | __s32 x; | ||
61 | __s32 y; | ||
62 | } hid_hat_to_axis[] = {{ 0, 0}, { 0,-1}, { 1,-1}, { 1, 0}, { 1, 1}, { 0, 1}, {-1, 1}, {-1, 0}, {-1,-1}}; | ||
63 | |||
64 | #define map_abs(c) do { usage->code = c; usage->type = EV_ABS; bit = input->absbit; max = ABS_MAX; } while (0) | ||
65 | #define map_rel(c) do { usage->code = c; usage->type = EV_REL; bit = input->relbit; max = REL_MAX; } while (0) | ||
66 | #define map_key(c) do { usage->code = c; usage->type = EV_KEY; bit = input->keybit; max = KEY_MAX; } while (0) | ||
67 | #define map_led(c) do { usage->code = c; usage->type = EV_LED; bit = input->ledbit; max = LED_MAX; } while (0) | ||
68 | |||
69 | #define map_abs_clear(c) do { map_abs(c); clear_bit(c, bit); } while (0) | ||
70 | #define map_key_clear(c) do { map_key(c); clear_bit(c, bit); } while (0) | ||
71 | |||
72 | #ifdef CONFIG_USB_HIDINPUT_POWERBOOK | ||
73 | |||
74 | struct hidinput_key_translation { | ||
75 | u16 from; | ||
76 | u16 to; | ||
77 | u8 flags; | ||
78 | }; | ||
79 | |||
80 | #define POWERBOOK_FLAG_FKEY 0x01 | ||
81 | |||
82 | static struct hidinput_key_translation powerbook_fn_keys[] = { | ||
83 | { KEY_BACKSPACE, KEY_DELETE }, | ||
84 | { KEY_F1, KEY_BRIGHTNESSDOWN, POWERBOOK_FLAG_FKEY }, | ||
85 | { KEY_F2, KEY_BRIGHTNESSUP, POWERBOOK_FLAG_FKEY }, | ||
86 | { KEY_F3, KEY_MUTE, POWERBOOK_FLAG_FKEY }, | ||
87 | { KEY_F4, KEY_VOLUMEDOWN, POWERBOOK_FLAG_FKEY }, | ||
88 | { KEY_F5, KEY_VOLUMEUP, POWERBOOK_FLAG_FKEY }, | ||
89 | { KEY_F6, KEY_NUMLOCK, POWERBOOK_FLAG_FKEY }, | ||
90 | { KEY_F7, KEY_SWITCHVIDEOMODE, POWERBOOK_FLAG_FKEY }, | ||
91 | { KEY_F8, KEY_KBDILLUMTOGGLE, POWERBOOK_FLAG_FKEY }, | ||
92 | { KEY_F9, KEY_KBDILLUMDOWN, POWERBOOK_FLAG_FKEY }, | ||
93 | { KEY_F10, KEY_KBDILLUMUP, POWERBOOK_FLAG_FKEY }, | ||
94 | { KEY_UP, KEY_PAGEUP }, | ||
95 | { KEY_DOWN, KEY_PAGEDOWN }, | ||
96 | { KEY_LEFT, KEY_HOME }, | ||
97 | { KEY_RIGHT, KEY_END }, | ||
98 | { } | ||
99 | }; | ||
100 | |||
101 | static struct hidinput_key_translation powerbook_numlock_keys[] = { | ||
102 | { KEY_J, KEY_KP1 }, | ||
103 | { KEY_K, KEY_KP2 }, | ||
104 | { KEY_L, KEY_KP3 }, | ||
105 | { KEY_U, KEY_KP4 }, | ||
106 | { KEY_I, KEY_KP5 }, | ||
107 | { KEY_O, KEY_KP6 }, | ||
108 | { KEY_7, KEY_KP7 }, | ||
109 | { KEY_8, KEY_KP8 }, | ||
110 | { KEY_9, KEY_KP9 }, | ||
111 | { KEY_M, KEY_KP0 }, | ||
112 | { KEY_DOT, KEY_KPDOT }, | ||
113 | { KEY_SLASH, KEY_KPPLUS }, | ||
114 | { KEY_SEMICOLON, KEY_KPMINUS }, | ||
115 | { KEY_P, KEY_KPASTERISK }, | ||
116 | { KEY_MINUS, KEY_KPEQUAL }, | ||
117 | { KEY_0, KEY_KPSLASH }, | ||
118 | { KEY_F6, KEY_NUMLOCK }, | ||
119 | { KEY_KPENTER, KEY_KPENTER }, | ||
120 | { KEY_BACKSPACE, KEY_BACKSPACE }, | ||
121 | { } | ||
122 | }; | ||
123 | |||
124 | static struct hidinput_key_translation powerbook_iso_keyboard[] = { | ||
125 | { KEY_GRAVE, KEY_102ND }, | ||
126 | { KEY_102ND, KEY_GRAVE }, | ||
127 | { } | ||
128 | }; | ||
129 | |||
130 | static int usbhid_pb_fnmode = 1; | ||
131 | module_param_named(pb_fnmode, usbhid_pb_fnmode, int, 0644); | ||
132 | MODULE_PARM_DESC(pb_fnmode, | ||
133 | "Mode of fn key on PowerBooks (0 = disabled, 1 = fkeyslast, 2 = fkeysfirst)"); | ||
134 | |||
135 | static struct hidinput_key_translation *find_translation(struct hidinput_key_translation *table, u16 from) | ||
136 | { | ||
137 | struct hidinput_key_translation *trans; | ||
138 | |||
139 | /* Look for the translation */ | ||
140 | for (trans = table; trans->from; trans++) | ||
141 | if (trans->from == from) | ||
142 | return trans; | ||
143 | |||
144 | return NULL; | ||
145 | } | ||
146 | |||
147 | static int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, | ||
148 | struct hid_usage *usage, __s32 value) | ||
149 | { | ||
150 | struct hidinput_key_translation *trans; | ||
151 | |||
152 | if (usage->code == KEY_FN) { | ||
153 | if (value) hid->quirks |= HID_QUIRK_POWERBOOK_FN_ON; | ||
154 | else hid->quirks &= ~HID_QUIRK_POWERBOOK_FN_ON; | ||
155 | |||
156 | input_event(input, usage->type, usage->code, value); | ||
157 | |||
158 | return 1; | ||
159 | } | ||
160 | |||
161 | if (usbhid_pb_fnmode) { | ||
162 | int do_translate; | ||
163 | |||
164 | trans = find_translation(powerbook_fn_keys, usage->code); | ||
165 | if (trans) { | ||
166 | if (test_bit(usage->code, hid->pb_pressed_fn)) | ||
167 | do_translate = 1; | ||
168 | else if (trans->flags & POWERBOOK_FLAG_FKEY) | ||
169 | do_translate = | ||
170 | (usbhid_pb_fnmode == 2 && (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)) || | ||
171 | (usbhid_pb_fnmode == 1 && !(hid->quirks & HID_QUIRK_POWERBOOK_FN_ON)); | ||
172 | else | ||
173 | do_translate = (hid->quirks & HID_QUIRK_POWERBOOK_FN_ON); | ||
174 | |||
175 | if (do_translate) { | ||
176 | if (value) | ||
177 | set_bit(usage->code, hid->pb_pressed_fn); | ||
178 | else | ||
179 | clear_bit(usage->code, hid->pb_pressed_fn); | ||
180 | |||
181 | input_event(input, usage->type, trans->to, value); | ||
182 | |||
183 | return 1; | ||
184 | } | ||
185 | } | ||
186 | |||
187 | if (test_bit(usage->code, hid->pb_pressed_numlock) || | ||
188 | test_bit(LED_NUML, input->led)) { | ||
189 | trans = find_translation(powerbook_numlock_keys, usage->code); | ||
190 | |||
191 | if (trans) { | ||
192 | if (value) | ||
193 | set_bit(usage->code, hid->pb_pressed_numlock); | ||
194 | else | ||
195 | clear_bit(usage->code, hid->pb_pressed_numlock); | ||
196 | |||
197 | input_event(input, usage->type, trans->to, value); | ||
198 | } | ||
199 | |||
200 | return 1; | ||
201 | } | ||
202 | } | ||
203 | |||
204 | if (hid->quirks & HID_QUIRK_POWERBOOK_ISO_KEYBOARD) { | ||
205 | trans = find_translation(powerbook_iso_keyboard, usage->code); | ||
206 | if (trans) { | ||
207 | input_event(input, usage->type, trans->to, value); | ||
208 | return 1; | ||
209 | } | ||
210 | } | ||
211 | |||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | static void hidinput_pb_setup(struct input_dev *input) | ||
216 | { | ||
217 | struct hidinput_key_translation *trans; | ||
218 | |||
219 | set_bit(KEY_NUMLOCK, input->keybit); | ||
220 | |||
221 | /* Enable all needed keys */ | ||
222 | for (trans = powerbook_fn_keys; trans->from; trans++) | ||
223 | set_bit(trans->to, input->keybit); | ||
224 | |||
225 | for (trans = powerbook_numlock_keys; trans->from; trans++) | ||
226 | set_bit(trans->to, input->keybit); | ||
227 | |||
228 | for (trans = powerbook_iso_keyboard; trans->from; trans++) | ||
229 | set_bit(trans->to, input->keybit); | ||
230 | } | ||
231 | #else | ||
232 | static inline int hidinput_pb_event(struct hid_device *hid, struct input_dev *input, | ||
233 | struct hid_usage *usage, __s32 value) | ||
234 | { | ||
235 | return 0; | ||
236 | } | ||
237 | |||
238 | static inline void hidinput_pb_setup(struct input_dev *input) | ||
239 | { | ||
240 | } | ||
241 | #endif | ||
242 | |||
243 | static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_field *field, | ||
244 | struct hid_usage *usage) | ||
245 | { | ||
246 | struct input_dev *input = hidinput->input; | ||
247 | struct hid_device *device = input->private; | ||
248 | int max = 0, code; | ||
249 | unsigned long *bit = NULL; | ||
250 | |||
251 | field->hidinput = hidinput; | ||
252 | |||
253 | #ifdef DEBUG | ||
254 | printk(KERN_DEBUG "Mapping: "); | ||
255 | resolv_usage(usage->hid); | ||
256 | printk(" ---> "); | ||
257 | #endif | ||
258 | |||
259 | if (field->flags & HID_MAIN_ITEM_CONSTANT) | ||
260 | goto ignore; | ||
261 | |||
262 | switch (usage->hid & HID_USAGE_PAGE) { | ||
263 | |||
264 | case HID_UP_UNDEFINED: | ||
265 | goto ignore; | ||
266 | |||
267 | case HID_UP_KEYBOARD: | ||
268 | |||
269 | set_bit(EV_REP, input->evbit); | ||
270 | |||
271 | if ((usage->hid & HID_USAGE) < 256) { | ||
272 | if (!hid_keyboard[usage->hid & HID_USAGE]) goto ignore; | ||
273 | map_key_clear(hid_keyboard[usage->hid & HID_USAGE]); | ||
274 | } else | ||
275 | map_key(KEY_UNKNOWN); | ||
276 | |||
277 | break; | ||
278 | |||
279 | case HID_UP_BUTTON: | ||
280 | |||
281 | code = ((usage->hid - 1) & 0xf); | ||
282 | |||
283 | switch (field->application) { | ||
284 | case HID_GD_MOUSE: | ||
285 | case HID_GD_POINTER: code += 0x110; break; | ||
286 | case HID_GD_JOYSTICK: code += 0x120; break; | ||
287 | case HID_GD_GAMEPAD: code += 0x130; break; | ||
288 | default: | ||
289 | switch (field->physical) { | ||
290 | case HID_GD_MOUSE: | ||
291 | case HID_GD_POINTER: code += 0x110; break; | ||
292 | case HID_GD_JOYSTICK: code += 0x120; break; | ||
293 | case HID_GD_GAMEPAD: code += 0x130; break; | ||
294 | default: code += 0x100; | ||
295 | } | ||
296 | } | ||
297 | |||
298 | map_key(code); | ||
299 | break; | ||
300 | |||
301 | |||
302 | case HID_UP_SIMULATION: | ||
303 | |||
304 | switch (usage->hid & 0xffff) { | ||
305 | case 0xba: map_abs(ABS_RUDDER); break; | ||
306 | case 0xbb: map_abs(ABS_THROTTLE); break; | ||
307 | case 0xc4: map_abs(ABS_GAS); break; | ||
308 | case 0xc5: map_abs(ABS_BRAKE); break; | ||
309 | case 0xc8: map_abs(ABS_WHEEL); break; | ||
310 | default: goto ignore; | ||
311 | } | ||
312 | break; | ||
313 | |||
314 | case HID_UP_GENDESK: | ||
315 | |||
316 | if ((usage->hid & 0xf0) == 0x80) { /* SystemControl */ | ||
317 | switch (usage->hid & 0xf) { | ||
318 | case 0x1: map_key_clear(KEY_POWER); break; | ||
319 | case 0x2: map_key_clear(KEY_SLEEP); break; | ||
320 | case 0x3: map_key_clear(KEY_WAKEUP); break; | ||
321 | default: goto unknown; | ||
322 | } | ||
323 | break; | ||
324 | } | ||
325 | |||
326 | if ((usage->hid & 0xf0) == 0x90) { /* D-pad */ | ||
327 | switch (usage->hid) { | ||
328 | case HID_GD_UP: usage->hat_dir = 1; break; | ||
329 | case HID_GD_DOWN: usage->hat_dir = 5; break; | ||
330 | case HID_GD_RIGHT: usage->hat_dir = 3; break; | ||
331 | case HID_GD_LEFT: usage->hat_dir = 7; break; | ||
332 | default: goto unknown; | ||
333 | } | ||
334 | if (field->dpad) { | ||
335 | map_abs(field->dpad); | ||
336 | goto ignore; | ||
337 | } | ||
338 | map_abs(ABS_HAT0X); | ||
339 | break; | ||
340 | } | ||
341 | |||
342 | switch (usage->hid) { | ||
343 | |||
344 | /* These usage IDs map directly to the usage codes. */ | ||
345 | case HID_GD_X: case HID_GD_Y: case HID_GD_Z: | ||
346 | case HID_GD_RX: case HID_GD_RY: case HID_GD_RZ: | ||
347 | case HID_GD_SLIDER: case HID_GD_DIAL: case HID_GD_WHEEL: | ||
348 | if (field->flags & HID_MAIN_ITEM_RELATIVE) | ||
349 | map_rel(usage->hid & 0xf); | ||
350 | else | ||
351 | map_abs(usage->hid & 0xf); | ||
352 | break; | ||
353 | |||
354 | case HID_GD_HATSWITCH: | ||
355 | usage->hat_min = field->logical_minimum; | ||
356 | usage->hat_max = field->logical_maximum; | ||
357 | map_abs(ABS_HAT0X); | ||
358 | break; | ||
359 | |||
360 | case HID_GD_START: map_key_clear(BTN_START); break; | ||
361 | case HID_GD_SELECT: map_key_clear(BTN_SELECT); break; | ||
362 | |||
363 | default: goto unknown; | ||
364 | } | ||
365 | |||
366 | break; | ||
367 | |||
368 | case HID_UP_LED: | ||
369 | if (((usage->hid - 1) & 0xffff) >= LED_MAX) | ||
370 | goto ignore; | ||
371 | map_led((usage->hid - 1) & 0xffff); | ||
372 | break; | ||
373 | |||
374 | case HID_UP_DIGITIZER: | ||
375 | |||
376 | switch (usage->hid & 0xff) { | ||
377 | |||
378 | case 0x30: /* TipPressure */ | ||
379 | if (!test_bit(BTN_TOUCH, input->keybit)) { | ||
380 | device->quirks |= HID_QUIRK_NOTOUCH; | ||
381 | set_bit(EV_KEY, input->evbit); | ||
382 | set_bit(BTN_TOUCH, input->keybit); | ||
383 | } | ||
384 | |||
385 | map_abs_clear(ABS_PRESSURE); | ||
386 | break; | ||
387 | |||
388 | case 0x32: /* InRange */ | ||
389 | switch (field->physical & 0xff) { | ||
390 | case 0x21: map_key(BTN_TOOL_MOUSE); break; | ||
391 | case 0x22: map_key(BTN_TOOL_FINGER); break; | ||
392 | default: map_key(BTN_TOOL_PEN); break; | ||
393 | } | ||
394 | break; | ||
395 | |||
396 | case 0x3c: /* Invert */ | ||
397 | map_key_clear(BTN_TOOL_RUBBER); | ||
398 | break; | ||
399 | |||
400 | case 0x33: /* Touch */ | ||
401 | case 0x42: /* TipSwitch */ | ||
402 | case 0x43: /* TipSwitch2 */ | ||
403 | device->quirks &= ~HID_QUIRK_NOTOUCH; | ||
404 | map_key_clear(BTN_TOUCH); | ||
405 | break; | ||
406 | |||
407 | case 0x44: /* BarrelSwitch */ | ||
408 | map_key_clear(BTN_STYLUS); | ||
409 | break; | ||
410 | |||
411 | default: goto unknown; | ||
412 | } | ||
413 | break; | ||
414 | |||
415 | case HID_UP_CONSUMER: /* USB HUT v1.1, pages 56-62 */ | ||
416 | |||
417 | switch (usage->hid & HID_USAGE) { | ||
418 | case 0x000: goto ignore; | ||
419 | case 0x034: map_key_clear(KEY_SLEEP); break; | ||
420 | case 0x036: map_key_clear(BTN_MISC); break; | ||
421 | case 0x045: map_key_clear(KEY_RADIO); break; | ||
422 | case 0x08a: map_key_clear(KEY_WWW); break; | ||
423 | case 0x08d: map_key_clear(KEY_PROGRAM); break; | ||
424 | case 0x095: map_key_clear(KEY_HELP); break; | ||
425 | case 0x09c: map_key_clear(KEY_CHANNELUP); break; | ||
426 | case 0x09d: map_key_clear(KEY_CHANNELDOWN); break; | ||
427 | case 0x0b0: map_key_clear(KEY_PLAY); break; | ||
428 | case 0x0b1: map_key_clear(KEY_PAUSE); break; | ||
429 | case 0x0b2: map_key_clear(KEY_RECORD); break; | ||
430 | case 0x0b3: map_key_clear(KEY_FASTFORWARD); break; | ||
431 | case 0x0b4: map_key_clear(KEY_REWIND); break; | ||
432 | case 0x0b5: map_key_clear(KEY_NEXTSONG); break; | ||
433 | case 0x0b6: map_key_clear(KEY_PREVIOUSSONG); break; | ||
434 | case 0x0b7: map_key_clear(KEY_STOPCD); break; | ||
435 | case 0x0b8: map_key_clear(KEY_EJECTCD); break; | ||
436 | case 0x0cd: map_key_clear(KEY_PLAYPAUSE); break; | ||
437 | case 0x0e0: map_abs_clear(ABS_VOLUME); break; | ||
438 | case 0x0e2: map_key_clear(KEY_MUTE); break; | ||
439 | case 0x0e5: map_key_clear(KEY_BASSBOOST); break; | ||
440 | case 0x0e9: map_key_clear(KEY_VOLUMEUP); break; | ||
441 | case 0x0ea: map_key_clear(KEY_VOLUMEDOWN); break; | ||
442 | case 0x183: map_key_clear(KEY_CONFIG); break; | ||
443 | case 0x18a: map_key_clear(KEY_MAIL); break; | ||
444 | case 0x192: map_key_clear(KEY_CALC); break; | ||
445 | case 0x194: map_key_clear(KEY_FILE); break; | ||
446 | case 0x1a7: map_key_clear(KEY_DOCUMENTS); break; | ||
447 | case 0x201: map_key_clear(KEY_NEW); break; | ||
448 | case 0x207: map_key_clear(KEY_SAVE); break; | ||
449 | case 0x208: map_key_clear(KEY_PRINT); break; | ||
450 | case 0x209: map_key_clear(KEY_PROPS); break; | ||
451 | case 0x21a: map_key_clear(KEY_UNDO); break; | ||
452 | case 0x21b: map_key_clear(KEY_COPY); break; | ||
453 | case 0x21c: map_key_clear(KEY_CUT); break; | ||
454 | case 0x21d: map_key_clear(KEY_PASTE); break; | ||
455 | case 0x221: map_key_clear(KEY_FIND); break; | ||
456 | case 0x223: map_key_clear(KEY_HOMEPAGE); break; | ||
457 | case 0x224: map_key_clear(KEY_BACK); break; | ||
458 | case 0x225: map_key_clear(KEY_FORWARD); break; | ||
459 | case 0x226: map_key_clear(KEY_STOP); break; | ||
460 | case 0x227: map_key_clear(KEY_REFRESH); break; | ||
461 | case 0x22a: map_key_clear(KEY_BOOKMARKS); break; | ||
462 | case 0x233: map_key_clear(KEY_SCROLLUP); break; | ||
463 | case 0x234: map_key_clear(KEY_SCROLLDOWN); break; | ||
464 | case 0x238: map_rel(REL_HWHEEL); break; | ||
465 | case 0x279: map_key_clear(KEY_REDO); break; | ||
466 | case 0x289: map_key_clear(KEY_REPLY); break; | ||
467 | case 0x28b: map_key_clear(KEY_FORWARDMAIL); break; | ||
468 | case 0x28c: map_key_clear(KEY_SEND); break; | ||
469 | |||
470 | /* Reported on a Cherry Cymotion keyboard */ | ||
471 | case 0x301: map_key_clear(KEY_PROG1); break; | ||
472 | case 0x302: map_key_clear(KEY_PROG2); break; | ||
473 | case 0x303: map_key_clear(KEY_PROG3); break; | ||
474 | |||
475 | default: goto ignore; | ||
476 | } | ||
477 | break; | ||
478 | |||
479 | case HID_UP_HPVENDOR: /* Reported on a Dutch layout HP5308 */ | ||
480 | |||
481 | set_bit(EV_REP, input->evbit); | ||
482 | switch (usage->hid & HID_USAGE) { | ||
483 | case 0x021: map_key_clear(KEY_PRINT); break; | ||
484 | case 0x070: map_key_clear(KEY_HP); break; | ||
485 | case 0x071: map_key_clear(KEY_CAMERA); break; | ||
486 | case 0x072: map_key_clear(KEY_SOUND); break; | ||
487 | case 0x073: map_key_clear(KEY_QUESTION); break; | ||
488 | case 0x080: map_key_clear(KEY_EMAIL); break; | ||
489 | case 0x081: map_key_clear(KEY_CHAT); break; | ||
490 | case 0x082: map_key_clear(KEY_SEARCH); break; | ||
491 | case 0x083: map_key_clear(KEY_CONNECT); break; | ||
492 | case 0x084: map_key_clear(KEY_FINANCE); break; | ||
493 | case 0x085: map_key_clear(KEY_SPORT); break; | ||
494 | case 0x086: map_key_clear(KEY_SHOP); break; | ||
495 | default: goto ignore; | ||
496 | } | ||
497 | break; | ||
498 | |||
499 | case HID_UP_MSVENDOR: | ||
500 | goto ignore; | ||
501 | |||
502 | case HID_UP_CUSTOM: /* Reported on Logitech and Powerbook USB keyboards */ | ||
503 | |||
504 | set_bit(EV_REP, input->evbit); | ||
505 | switch(usage->hid & HID_USAGE) { | ||
506 | case 0x003: | ||
507 | /* The fn key on Apple PowerBooks */ | ||
508 | map_key_clear(KEY_FN); | ||
509 | hidinput_pb_setup(input); | ||
510 | break; | ||
511 | |||
512 | default: goto ignore; | ||
513 | } | ||
514 | break; | ||
515 | |||
516 | case HID_UP_LOGIVENDOR: /* Reported on Logitech Ultra X Media Remote */ | ||
517 | |||
518 | set_bit(EV_REP, input->evbit); | ||
519 | switch(usage->hid & HID_USAGE) { | ||
520 | case 0x004: map_key_clear(KEY_AGAIN); break; | ||
521 | case 0x00d: map_key_clear(KEY_HOME); break; | ||
522 | case 0x024: map_key_clear(KEY_SHUFFLE); break; | ||
523 | case 0x025: map_key_clear(KEY_TV); break; | ||
524 | case 0x026: map_key_clear(KEY_MENU); break; | ||
525 | case 0x031: map_key_clear(KEY_AUDIO); break; | ||
526 | case 0x032: map_key_clear(KEY_TEXT); break; | ||
527 | case 0x033: map_key_clear(KEY_LAST); break; | ||
528 | case 0x047: map_key_clear(KEY_MP3); break; | ||
529 | case 0x048: map_key_clear(KEY_DVD); break; | ||
530 | case 0x049: map_key_clear(KEY_MEDIA); break; | ||
531 | case 0x04a: map_key_clear(KEY_VIDEO); break; | ||
532 | case 0x04b: map_key_clear(KEY_ANGLE); break; | ||
533 | case 0x04c: map_key_clear(KEY_LANGUAGE); break; | ||
534 | case 0x04d: map_key_clear(KEY_SUBTITLE); break; | ||
535 | case 0x051: map_key_clear(KEY_RED); break; | ||
536 | case 0x052: map_key_clear(KEY_CLOSE); break; | ||
537 | default: goto ignore; | ||
538 | } | ||
539 | break; | ||
540 | |||
541 | case HID_UP_PID: | ||
542 | |||
543 | switch(usage->hid & HID_USAGE) { | ||
544 | case 0xa4: map_key_clear(BTN_DEAD); break; | ||
545 | default: goto ignore; | ||
546 | } | ||
547 | break; | ||
548 | |||
549 | default: | ||
550 | unknown: | ||
551 | if (field->report_size == 1) { | ||
552 | if (field->report->type == HID_OUTPUT_REPORT) { | ||
553 | map_led(LED_MISC); | ||
554 | break; | ||
555 | } | ||
556 | map_key(BTN_MISC); | ||
557 | break; | ||
558 | } | ||
559 | if (field->flags & HID_MAIN_ITEM_RELATIVE) { | ||
560 | map_rel(REL_MISC); | ||
561 | break; | ||
562 | } | ||
563 | map_abs(ABS_MISC); | ||
564 | break; | ||
565 | } | ||
566 | |||
567 | if (device->quirks & HID_QUIRK_MIGHTYMOUSE) { | ||
568 | if (usage->hid == HID_GD_Z) | ||
569 | map_rel(REL_HWHEEL); | ||
570 | else if (usage->code == BTN_1) | ||
571 | map_key(BTN_2); | ||
572 | else if (usage->code == BTN_2) | ||
573 | map_key(BTN_1); | ||
574 | } | ||
575 | |||
576 | if ((device->quirks & (HID_QUIRK_2WHEEL_MOUSE_HACK_7 | HID_QUIRK_2WHEEL_MOUSE_HACK_5)) && | ||
577 | (usage->type == EV_REL) && (usage->code == REL_WHEEL)) | ||
578 | set_bit(REL_HWHEEL, bit); | ||
579 | |||
580 | if (((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) | ||
581 | || ((device->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) | ||
582 | goto ignore; | ||
583 | |||
584 | if ((device->quirks & HID_QUIRK_BAD_RELATIVE_KEYS) && | ||
585 | usage->type == EV_KEY && (field->flags & HID_MAIN_ITEM_RELATIVE)) | ||
586 | field->flags &= ~HID_MAIN_ITEM_RELATIVE; | ||
587 | |||
588 | set_bit(usage->type, input->evbit); | ||
589 | |||
590 | while (usage->code <= max && test_and_set_bit(usage->code, bit)) | ||
591 | usage->code = find_next_zero_bit(bit, max + 1, usage->code); | ||
592 | |||
593 | if (usage->code > max) | ||
594 | goto ignore; | ||
595 | |||
596 | |||
597 | if (usage->type == EV_ABS) { | ||
598 | |||
599 | int a = field->logical_minimum; | ||
600 | int b = field->logical_maximum; | ||
601 | |||
602 | if ((device->quirks & HID_QUIRK_BADPAD) && (usage->code == ABS_X || usage->code == ABS_Y)) { | ||
603 | a = field->logical_minimum = 0; | ||
604 | b = field->logical_maximum = 255; | ||
605 | } | ||
606 | |||
607 | if (field->application == HID_GD_GAMEPAD || field->application == HID_GD_JOYSTICK) | ||
608 | input_set_abs_params(input, usage->code, a, b, (b - a) >> 8, (b - a) >> 4); | ||
609 | else input_set_abs_params(input, usage->code, a, b, 0, 0); | ||
610 | |||
611 | } | ||
612 | |||
613 | if (usage->type == EV_ABS && | ||
614 | (usage->hat_min < usage->hat_max || usage->hat_dir)) { | ||
615 | int i; | ||
616 | for (i = usage->code; i < usage->code + 2 && i <= max; i++) { | ||
617 | input_set_abs_params(input, i, -1, 1, 0, 0); | ||
618 | set_bit(i, input->absbit); | ||
619 | } | ||
620 | if (usage->hat_dir && !field->dpad) | ||
621 | field->dpad = usage->code; | ||
622 | } | ||
623 | |||
624 | #ifdef DEBUG | ||
625 | resolv_event(usage->type, usage->code); | ||
626 | printk("\n"); | ||
627 | #endif | ||
628 | return; | ||
629 | |||
630 | ignore: | ||
631 | #ifdef DEBUG | ||
632 | printk("IGNORED\n"); | ||
633 | #endif | ||
634 | return; | ||
635 | } | ||
636 | |||
637 | void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) | ||
638 | { | ||
639 | struct input_dev *input; | ||
640 | int *quirks = &hid->quirks; | ||
641 | |||
642 | if (!field->hidinput) | ||
643 | return; | ||
644 | |||
645 | input = field->hidinput->input; | ||
646 | |||
647 | if (!usage->type) | ||
648 | return; | ||
649 | |||
650 | if (((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_5) && (usage->hid == 0x00090005)) | ||
651 | || ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_7) && (usage->hid == 0x00090007))) { | ||
652 | if (value) hid->quirks |= HID_QUIRK_2WHEEL_MOUSE_HACK_ON; | ||
653 | else hid->quirks &= ~HID_QUIRK_2WHEEL_MOUSE_HACK_ON; | ||
654 | return; | ||
655 | } | ||
656 | |||
657 | if ((hid->quirks & HID_QUIRK_INVERT_HWHEEL) && (usage->code == REL_HWHEEL)) { | ||
658 | input_event(input, usage->type, usage->code, -value); | ||
659 | return; | ||
660 | } | ||
661 | |||
662 | if ((hid->quirks & HID_QUIRK_2WHEEL_MOUSE_HACK_ON) && (usage->code == REL_WHEEL)) { | ||
663 | input_event(input, usage->type, REL_HWHEEL, value); | ||
664 | return; | ||
665 | } | ||
666 | |||
667 | if ((hid->quirks & HID_QUIRK_POWERBOOK_HAS_FN) && hidinput_pb_event(hid, input, usage, value)) | ||
668 | return; | ||
669 | |||
670 | if (usage->hat_min < usage->hat_max || usage->hat_dir) { | ||
671 | int hat_dir = usage->hat_dir; | ||
672 | if (!hat_dir) | ||
673 | hat_dir = (value - usage->hat_min) * 8 / (usage->hat_max - usage->hat_min + 1) + 1; | ||
674 | if (hat_dir < 0 || hat_dir > 8) hat_dir = 0; | ||
675 | input_event(input, usage->type, usage->code , hid_hat_to_axis[hat_dir].x); | ||
676 | input_event(input, usage->type, usage->code + 1, hid_hat_to_axis[hat_dir].y); | ||
677 | return; | ||
678 | } | ||
679 | |||
680 | if (usage->hid == (HID_UP_DIGITIZER | 0x003c)) { /* Invert */ | ||
681 | *quirks = value ? (*quirks | HID_QUIRK_INVERT) : (*quirks & ~HID_QUIRK_INVERT); | ||
682 | return; | ||
683 | } | ||
684 | |||
685 | if (usage->hid == (HID_UP_DIGITIZER | 0x0032)) { /* InRange */ | ||
686 | if (value) { | ||
687 | input_event(input, usage->type, (*quirks & HID_QUIRK_INVERT) ? BTN_TOOL_RUBBER : usage->code, 1); | ||
688 | return; | ||
689 | } | ||
690 | input_event(input, usage->type, usage->code, 0); | ||
691 | input_event(input, usage->type, BTN_TOOL_RUBBER, 0); | ||
692 | return; | ||
693 | } | ||
694 | |||
695 | if (usage->hid == (HID_UP_DIGITIZER | 0x0030) && (*quirks & HID_QUIRK_NOTOUCH)) { /* Pressure */ | ||
696 | int a = field->logical_minimum; | ||
697 | int b = field->logical_maximum; | ||
698 | input_event(input, EV_KEY, BTN_TOUCH, value > a + ((b - a) >> 3)); | ||
699 | } | ||
700 | |||
701 | if (usage->hid == (HID_UP_PID | 0x83UL)) { /* Simultaneous Effects Max */ | ||
702 | dbg("Maximum Effects - %d",value); | ||
703 | return; | ||
704 | } | ||
705 | |||
706 | if (usage->hid == (HID_UP_PID | 0x7fUL)) { | ||
707 | dbg("PID Pool Report\n"); | ||
708 | return; | ||
709 | } | ||
710 | |||
711 | if ((usage->type == EV_KEY) && (usage->code == 0)) /* Key 0 is "unassigned", not KEY_UNKNOWN */ | ||
712 | return; | ||
713 | |||
714 | input_event(input, usage->type, usage->code, value); | ||
715 | |||
716 | if ((field->flags & HID_MAIN_ITEM_RELATIVE) && (usage->type == EV_KEY)) | ||
717 | input_event(input, usage->type, usage->code, 0); | ||
718 | } | ||
719 | |||
720 | void hidinput_report_event(struct hid_device *hid, struct hid_report *report) | ||
721 | { | ||
722 | struct hid_input *hidinput; | ||
723 | |||
724 | list_for_each_entry(hidinput, &hid->inputs, list) | ||
725 | input_sync(hidinput->input); | ||
726 | } | ||
727 | |||
728 | static int hidinput_find_field(struct hid_device *hid, unsigned int type, unsigned int code, struct hid_field **field) | ||
729 | { | ||
730 | struct hid_report *report; | ||
731 | int i, j; | ||
732 | |||
733 | list_for_each_entry(report, &hid->report_enum[HID_OUTPUT_REPORT].report_list, list) { | ||
734 | for (i = 0; i < report->maxfield; i++) { | ||
735 | *field = report->field[i]; | ||
736 | for (j = 0; j < (*field)->maxusage; j++) | ||
737 | if ((*field)->usage[j].type == type && (*field)->usage[j].code == code) | ||
738 | return j; | ||
739 | } | ||
740 | } | ||
741 | return -1; | ||
742 | } | ||
743 | |||
744 | static int hidinput_input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | ||
745 | { | ||
746 | struct hid_device *hid = dev->private; | ||
747 | struct hid_field *field; | ||
748 | int offset; | ||
749 | |||
750 | if (type == EV_FF) | ||
751 | return input_ff_event(dev, type, code, value); | ||
752 | |||
753 | if (type != EV_LED) | ||
754 | return -1; | ||
755 | |||
756 | if ((offset = hidinput_find_field(hid, type, code, &field)) == -1) { | ||
757 | warn("event field not found"); | ||
758 | return -1; | ||
759 | } | ||
760 | |||
761 | hid_set_field(field, offset, value); | ||
762 | hid_submit_report(hid, field->report, USB_DIR_OUT); | ||
763 | |||
764 | return 0; | ||
765 | } | ||
766 | |||
767 | static int hidinput_open(struct input_dev *dev) | ||
768 | { | ||
769 | struct hid_device *hid = dev->private; | ||
770 | return hid_open(hid); | ||
771 | } | ||
772 | |||
773 | static void hidinput_close(struct input_dev *dev) | ||
774 | { | ||
775 | struct hid_device *hid = dev->private; | ||
776 | hid_close(hid); | ||
777 | } | ||
778 | |||
779 | /* | ||
780 | * Register the input device; print a message. | ||
781 | * Configure the input layer interface | ||
782 | * Read all reports and initialize the absolute field values. | ||
783 | */ | ||
784 | |||
785 | int hidinput_connect(struct hid_device *hid) | ||
786 | { | ||
787 | struct usb_device *dev = hid->dev; | ||
788 | struct hid_report *report; | ||
789 | struct hid_input *hidinput = NULL; | ||
790 | struct input_dev *input_dev; | ||
791 | int i, j, k; | ||
792 | |||
793 | INIT_LIST_HEAD(&hid->inputs); | ||
794 | |||
795 | for (i = 0; i < hid->maxcollection; i++) | ||
796 | if (hid->collection[i].type == HID_COLLECTION_APPLICATION || | ||
797 | hid->collection[i].type == HID_COLLECTION_PHYSICAL) | ||
798 | if (IS_INPUT_APPLICATION(hid->collection[i].usage)) | ||
799 | break; | ||
800 | |||
801 | if (i == hid->maxcollection) | ||
802 | return -1; | ||
803 | |||
804 | for (k = HID_INPUT_REPORT; k <= HID_OUTPUT_REPORT; k++) | ||
805 | list_for_each_entry(report, &hid->report_enum[k].report_list, list) { | ||
806 | |||
807 | if (!report->maxfield) | ||
808 | continue; | ||
809 | |||
810 | if (!hidinput) { | ||
811 | hidinput = kzalloc(sizeof(*hidinput), GFP_KERNEL); | ||
812 | input_dev = input_allocate_device(); | ||
813 | if (!hidinput || !input_dev) { | ||
814 | kfree(hidinput); | ||
815 | input_free_device(input_dev); | ||
816 | err("Out of memory during hid input probe"); | ||
817 | return -1; | ||
818 | } | ||
819 | |||
820 | input_dev->private = hid; | ||
821 | input_dev->event = hidinput_input_event; | ||
822 | input_dev->open = hidinput_open; | ||
823 | input_dev->close = hidinput_close; | ||
824 | |||
825 | input_dev->name = hid->name; | ||
826 | input_dev->phys = hid->phys; | ||
827 | input_dev->uniq = hid->uniq; | ||
828 | usb_to_input_id(dev, &input_dev->id); | ||
829 | input_dev->cdev.dev = &hid->intf->dev; | ||
830 | |||
831 | hidinput->input = input_dev; | ||
832 | list_add_tail(&hidinput->list, &hid->inputs); | ||
833 | } | ||
834 | |||
835 | for (i = 0; i < report->maxfield; i++) | ||
836 | for (j = 0; j < report->field[i]->maxusage; j++) | ||
837 | hidinput_configure_usage(hidinput, report->field[i], | ||
838 | report->field[i]->usage + j); | ||
839 | |||
840 | if (hid->quirks & HID_QUIRK_MULTI_INPUT) { | ||
841 | /* This will leave hidinput NULL, so that it | ||
842 | * allocates another one if we have more inputs on | ||
843 | * the same interface. Some devices (e.g. Happ's | ||
844 | * UGCI) cram a lot of unrelated inputs into the | ||
845 | * same interface. */ | ||
846 | hidinput->report = report; | ||
847 | input_register_device(hidinput->input); | ||
848 | hidinput = NULL; | ||
849 | } | ||
850 | } | ||
851 | |||
852 | /* This only gets called when we are a single-input (most of the | ||
853 | * time). IOW, not a HID_QUIRK_MULTI_INPUT. The hid_ff_init() is | ||
854 | * only useful in this case, and not for multi-input quirks. */ | ||
855 | if (hidinput) { | ||
856 | hid_ff_init(hid); | ||
857 | input_register_device(hidinput->input); | ||
858 | } | ||
859 | |||
860 | return 0; | ||
861 | } | ||
862 | |||
863 | void hidinput_disconnect(struct hid_device *hid) | ||
864 | { | ||
865 | struct hid_input *hidinput, *next; | ||
866 | |||
867 | list_for_each_entry_safe(hidinput, next, &hid->inputs, list) { | ||
868 | list_del(&hidinput->list); | ||
869 | input_unregister_device(hidinput->input); | ||
870 | kfree(hidinput); | ||
871 | } | ||
872 | } | ||
diff --git a/drivers/usb/input/hid-lgff.c b/drivers/usb/input/hid-lgff.c index 52be7a8f55aa..4df0968f852e 100644 --- a/drivers/usb/input/hid-lgff.c +++ b/drivers/usb/input/hid-lgff.c | |||
@@ -29,9 +29,10 @@ | |||
29 | 29 | ||
30 | #include <linux/input.h> | 30 | #include <linux/input.h> |
31 | #include <linux/usb.h> | 31 | #include <linux/usb.h> |
32 | #include "hid.h" | 32 | #include <linux/hid.h> |
33 | #include "usbhid.h" | ||
33 | 34 | ||
34 | struct device_type { | 35 | struct dev_type { |
35 | u16 idVendor; | 36 | u16 idVendor; |
36 | u16 idProduct; | 37 | u16 idProduct; |
37 | const signed short *ff; | 38 | const signed short *ff; |
@@ -47,7 +48,7 @@ static const signed short ff_joystick[] = { | |||
47 | -1 | 48 | -1 |
48 | }; | 49 | }; |
49 | 50 | ||
50 | static const struct device_type devices[] = { | 51 | static const struct dev_type devices[] = { |
51 | { 0x046d, 0xc211, ff_rumble }, | 52 | { 0x046d, 0xc211, ff_rumble }, |
52 | { 0x046d, 0xc219, ff_rumble }, | 53 | { 0x046d, 0xc219, ff_rumble }, |
53 | { 0x046d, 0xc283, ff_joystick }, | 54 | { 0x046d, 0xc283, ff_joystick }, |
@@ -76,7 +77,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef | |||
76 | report->field[0]->value[2] = x; | 77 | report->field[0]->value[2] = x; |
77 | report->field[0]->value[3] = y; | 78 | report->field[0]->value[3] = y; |
78 | dbg("(x, y)=(%04x, %04x)", x, y); | 79 | dbg("(x, y)=(%04x, %04x)", x, y); |
79 | hid_submit_report(hid, report, USB_DIR_OUT); | 80 | usbhid_submit_report(hid, report, USB_DIR_OUT); |
80 | break; | 81 | break; |
81 | 82 | ||
82 | case FF_RUMBLE: | 83 | case FF_RUMBLE: |
@@ -91,7 +92,7 @@ static int hid_lgff_play(struct input_dev *dev, void *data, struct ff_effect *ef | |||
91 | report->field[0]->value[2] = left; | 92 | report->field[0]->value[2] = left; |
92 | report->field[0]->value[3] = right; | 93 | report->field[0]->value[3] = right; |
93 | dbg("(left, right)=(%04x, %04x)", left, right); | 94 | dbg("(left, right)=(%04x, %04x)", left, right); |
94 | hid_submit_report(hid, report, USB_DIR_OUT); | 95 | usbhid_submit_report(hid, report, USB_DIR_OUT); |
95 | break; | 96 | break; |
96 | } | 97 | } |
97 | return 0; | 98 | return 0; |
diff --git a/drivers/usb/input/hid-pidff.c b/drivers/usb/input/hid-pidff.c index 5420c13eb8eb..cbd2d53fefff 100644 --- a/drivers/usb/input/hid-pidff.c +++ b/drivers/usb/input/hid-pidff.c | |||
@@ -28,7 +28,9 @@ | |||
28 | #include <linux/input.h> | 28 | #include <linux/input.h> |
29 | #include <linux/usb.h> | 29 | #include <linux/usb.h> |
30 | 30 | ||
31 | #include "hid.h" | 31 | #include <linux/hid.h> |
32 | |||
33 | #include "usbhid.h" | ||
32 | 34 | ||
33 | #define PID_EFFECTS_MAX 64 | 35 | #define PID_EFFECTS_MAX 64 |
34 | 36 | ||
@@ -260,7 +262,7 @@ static void pidff_set_envelope_report(struct pidff_device *pidff, | |||
260 | debug("attack %u => %d", envelope->attack_level, | 262 | debug("attack %u => %d", envelope->attack_level, |
261 | pidff->set_envelope[PID_ATTACK_LEVEL].value[0]); | 263 | pidff->set_envelope[PID_ATTACK_LEVEL].value[0]); |
262 | 264 | ||
263 | hid_submit_report(pidff->hid, pidff->reports[PID_SET_ENVELOPE], | 265 | usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_ENVELOPE], |
264 | USB_DIR_OUT); | 266 | USB_DIR_OUT); |
265 | } | 267 | } |
266 | 268 | ||
@@ -287,7 +289,7 @@ static void pidff_set_constant_force_report(struct pidff_device *pidff, | |||
287 | pidff_set_signed(&pidff->set_constant[PID_MAGNITUDE], | 289 | pidff_set_signed(&pidff->set_constant[PID_MAGNITUDE], |
288 | effect->u.constant.level); | 290 | effect->u.constant.level); |
289 | 291 | ||
290 | hid_submit_report(pidff->hid, pidff->reports[PID_SET_CONSTANT], | 292 | usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_CONSTANT], |
291 | USB_DIR_OUT); | 293 | USB_DIR_OUT); |
292 | } | 294 | } |
293 | 295 | ||
@@ -322,7 +324,7 @@ static void pidff_set_effect_report(struct pidff_device *pidff, | |||
322 | pidff->effect_direction); | 324 | pidff->effect_direction); |
323 | pidff->set_effect[PID_START_DELAY].value[0] = effect->replay.delay; | 325 | pidff->set_effect[PID_START_DELAY].value[0] = effect->replay.delay; |
324 | 326 | ||
325 | hid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT], | 327 | usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT], |
326 | USB_DIR_OUT); | 328 | USB_DIR_OUT); |
327 | } | 329 | } |
328 | 330 | ||
@@ -354,7 +356,7 @@ static void pidff_set_periodic_report(struct pidff_device *pidff, | |||
354 | pidff_set(&pidff->set_periodic[PID_PHASE], effect->u.periodic.phase); | 356 | pidff_set(&pidff->set_periodic[PID_PHASE], effect->u.periodic.phase); |
355 | pidff->set_periodic[PID_PERIOD].value[0] = effect->u.periodic.period; | 357 | pidff->set_periodic[PID_PERIOD].value[0] = effect->u.periodic.period; |
356 | 358 | ||
357 | hid_submit_report(pidff->hid, pidff->reports[PID_SET_PERIODIC], | 359 | usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_PERIODIC], |
358 | USB_DIR_OUT); | 360 | USB_DIR_OUT); |
359 | 361 | ||
360 | } | 362 | } |
@@ -396,8 +398,8 @@ static void pidff_set_condition_report(struct pidff_device *pidff, | |||
396 | effect->u.condition[i].left_saturation); | 398 | effect->u.condition[i].left_saturation); |
397 | pidff_set(&pidff->set_condition[PID_DEAD_BAND], | 399 | pidff_set(&pidff->set_condition[PID_DEAD_BAND], |
398 | effect->u.condition[i].deadband); | 400 | effect->u.condition[i].deadband); |
399 | hid_wait_io(pidff->hid); | 401 | usbhid_wait_io(pidff->hid); |
400 | hid_submit_report(pidff->hid, pidff->reports[PID_SET_CONDITION], | 402 | usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_CONDITION], |
401 | USB_DIR_OUT); | 403 | USB_DIR_OUT); |
402 | } | 404 | } |
403 | } | 405 | } |
@@ -438,7 +440,7 @@ static void pidff_set_ramp_force_report(struct pidff_device *pidff, | |||
438 | effect->u.ramp.start_level); | 440 | effect->u.ramp.start_level); |
439 | pidff_set_signed(&pidff->set_ramp[PID_RAMP_END], | 441 | pidff_set_signed(&pidff->set_ramp[PID_RAMP_END], |
440 | effect->u.ramp.end_level); | 442 | effect->u.ramp.end_level); |
441 | hid_submit_report(pidff->hid, pidff->reports[PID_SET_RAMP], | 443 | usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_RAMP], |
442 | USB_DIR_OUT); | 444 | USB_DIR_OUT); |
443 | } | 445 | } |
444 | 446 | ||
@@ -463,19 +465,19 @@ static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum) | |||
463 | int j; | 465 | int j; |
464 | 466 | ||
465 | pidff->create_new_effect_type->value[0] = efnum; | 467 | pidff->create_new_effect_type->value[0] = efnum; |
466 | hid_submit_report(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT], | 468 | usbhid_submit_report(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT], |
467 | USB_DIR_OUT); | 469 | USB_DIR_OUT); |
468 | debug("create_new_effect sent, type: %d", efnum); | 470 | debug("create_new_effect sent, type: %d", efnum); |
469 | 471 | ||
470 | pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0; | 472 | pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0; |
471 | pidff->block_load_status->value[0] = 0; | 473 | pidff->block_load_status->value[0] = 0; |
472 | hid_wait_io(pidff->hid); | 474 | usbhid_wait_io(pidff->hid); |
473 | 475 | ||
474 | for (j = 0; j < 60; j++) { | 476 | for (j = 0; j < 60; j++) { |
475 | debug("pid_block_load requested"); | 477 | debug("pid_block_load requested"); |
476 | hid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_LOAD], | 478 | usbhid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_LOAD], |
477 | USB_DIR_IN); | 479 | USB_DIR_IN); |
478 | hid_wait_io(pidff->hid); | 480 | usbhid_wait_io(pidff->hid); |
479 | if (pidff->block_load_status->value[0] == | 481 | if (pidff->block_load_status->value[0] == |
480 | pidff->status_id[PID_BLOCK_LOAD_SUCCESS]) { | 482 | pidff->status_id[PID_BLOCK_LOAD_SUCCESS]) { |
481 | debug("device reported free memory: %d bytes", | 483 | debug("device reported free memory: %d bytes", |
@@ -511,8 +513,8 @@ static void pidff_playback_pid(struct pidff_device *pidff, int pid_id, int n) | |||
511 | pidff->effect_operation[PID_LOOP_COUNT].value[0] = n; | 513 | pidff->effect_operation[PID_LOOP_COUNT].value[0] = n; |
512 | } | 514 | } |
513 | 515 | ||
514 | hid_wait_io(pidff->hid); | 516 | usbhid_wait_io(pidff->hid); |
515 | hid_submit_report(pidff->hid, pidff->reports[PID_EFFECT_OPERATION], | 517 | usbhid_submit_report(pidff->hid, pidff->reports[PID_EFFECT_OPERATION], |
516 | USB_DIR_OUT); | 518 | USB_DIR_OUT); |
517 | } | 519 | } |
518 | 520 | ||
@@ -534,7 +536,7 @@ static int pidff_playback(struct input_dev *dev, int effect_id, int value) | |||
534 | static void pidff_erase_pid(struct pidff_device *pidff, int pid_id) | 536 | static void pidff_erase_pid(struct pidff_device *pidff, int pid_id) |
535 | { | 537 | { |
536 | pidff->block_free[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id; | 538 | pidff->block_free[PID_EFFECT_BLOCK_INDEX].value[0] = pid_id; |
537 | hid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_FREE], | 539 | usbhid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_FREE], |
538 | USB_DIR_OUT); | 540 | USB_DIR_OUT); |
539 | } | 541 | } |
540 | 542 | ||
@@ -714,7 +716,7 @@ static void pidff_set_gain(struct input_dev *dev, u16 gain) | |||
714 | struct pidff_device *pidff = dev->ff->private; | 716 | struct pidff_device *pidff = dev->ff->private; |
715 | 717 | ||
716 | pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], gain); | 718 | pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], gain); |
717 | hid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN], | 719 | usbhid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN], |
718 | USB_DIR_OUT); | 720 | USB_DIR_OUT); |
719 | } | 721 | } |
720 | 722 | ||
@@ -739,7 +741,7 @@ static void pidff_autocenter(struct pidff_device *pidff, u16 magnitude) | |||
739 | pidff_set(&pidff->set_effect[PID_GAIN], magnitude); | 741 | pidff_set(&pidff->set_effect[PID_GAIN], magnitude); |
740 | pidff->set_effect[PID_START_DELAY].value[0] = 0; | 742 | pidff->set_effect[PID_START_DELAY].value[0] = 0; |
741 | 743 | ||
742 | hid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT], | 744 | usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_EFFECT], |
743 | USB_DIR_OUT); | 745 | USB_DIR_OUT); |
744 | } | 746 | } |
745 | 747 | ||
@@ -1163,19 +1165,19 @@ static void pidff_reset(struct pidff_device *pidff) | |||
1163 | 1165 | ||
1164 | pidff->device_control->value[0] = pidff->control_id[PID_RESET]; | 1166 | pidff->device_control->value[0] = pidff->control_id[PID_RESET]; |
1165 | /* We reset twice as sometimes hid_wait_io isn't waiting long enough */ | 1167 | /* We reset twice as sometimes hid_wait_io isn't waiting long enough */ |
1166 | hid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT); | 1168 | usbhid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT); |
1167 | hid_wait_io(hid); | 1169 | usbhid_wait_io(hid); |
1168 | hid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT); | 1170 | usbhid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT); |
1169 | hid_wait_io(hid); | 1171 | usbhid_wait_io(hid); |
1170 | 1172 | ||
1171 | pidff->device_control->value[0] = | 1173 | pidff->device_control->value[0] = |
1172 | pidff->control_id[PID_ENABLE_ACTUATORS]; | 1174 | pidff->control_id[PID_ENABLE_ACTUATORS]; |
1173 | hid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT); | 1175 | usbhid_submit_report(hid, pidff->reports[PID_DEVICE_CONTROL], USB_DIR_OUT); |
1174 | hid_wait_io(hid); | 1176 | usbhid_wait_io(hid); |
1175 | 1177 | ||
1176 | /* pool report is sometimes messed up, refetch it */ | 1178 | /* pool report is sometimes messed up, refetch it */ |
1177 | hid_submit_report(hid, pidff->reports[PID_POOL], USB_DIR_IN); | 1179 | usbhid_submit_report(hid, pidff->reports[PID_POOL], USB_DIR_IN); |
1178 | hid_wait_io(hid); | 1180 | usbhid_wait_io(hid); |
1179 | 1181 | ||
1180 | if (pidff->pool[PID_SIMULTANEOUS_MAX].value) { | 1182 | if (pidff->pool[PID_SIMULTANEOUS_MAX].value) { |
1181 | int sim_effects = pidff->pool[PID_SIMULTANEOUS_MAX].value[0]; | 1183 | int sim_effects = pidff->pool[PID_SIMULTANEOUS_MAX].value[0]; |
@@ -1187,9 +1189,9 @@ static void pidff_reset(struct pidff_device *pidff) | |||
1187 | break; | 1189 | break; |
1188 | } | 1190 | } |
1189 | debug("pid_pool requested again"); | 1191 | debug("pid_pool requested again"); |
1190 | hid_submit_report(hid, pidff->reports[PID_POOL], | 1192 | usbhid_submit_report(hid, pidff->reports[PID_POOL], |
1191 | USB_DIR_IN); | 1193 | USB_DIR_IN); |
1192 | hid_wait_io(hid); | 1194 | usbhid_wait_io(hid); |
1193 | } | 1195 | } |
1194 | } | 1196 | } |
1195 | } | 1197 | } |
@@ -1275,7 +1277,7 @@ int hid_pidff_init(struct hid_device *hid) | |||
1275 | 1277 | ||
1276 | if (test_bit(FF_GAIN, dev->ffbit)) { | 1278 | if (test_bit(FF_GAIN, dev->ffbit)) { |
1277 | pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], 0xffff); | 1279 | pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], 0xffff); |
1278 | hid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN], | 1280 | usbhid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN], |
1279 | USB_DIR_OUT); | 1281 | USB_DIR_OUT); |
1280 | } | 1282 | } |
1281 | 1283 | ||
diff --git a/drivers/usb/input/hid-plff.c b/drivers/usb/input/hid-plff.c new file mode 100644 index 000000000000..76d2e6e14db4 --- /dev/null +++ b/drivers/usb/input/hid-plff.c | |||
@@ -0,0 +1,129 @@ | |||
1 | /* | ||
2 | * Force feedback support for PantherLord USB/PS2 2in1 Adapter devices | ||
3 | * | ||
4 | * Copyright (c) 2007 Anssi Hannula <anssi.hannula@gmail.com> | ||
5 | */ | ||
6 | |||
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 program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | |||
24 | /* #define DEBUG */ | ||
25 | |||
26 | #define debug(format, arg...) pr_debug("hid-plff: " format "\n" , ## arg) | ||
27 | |||
28 | #include <linux/input.h> | ||
29 | #include <linux/usb.h> | ||
30 | #include <linux/hid.h> | ||
31 | #include "usbhid.h" | ||
32 | |||
33 | struct plff_device { | ||
34 | struct hid_report *report; | ||
35 | }; | ||
36 | |||
37 | static int hid_plff_play(struct input_dev *dev, void *data, | ||
38 | struct ff_effect *effect) | ||
39 | { | ||
40 | struct hid_device *hid = dev->private; | ||
41 | struct plff_device *plff = data; | ||
42 | int left, right; | ||
43 | |||
44 | left = effect->u.rumble.strong_magnitude; | ||
45 | right = effect->u.rumble.weak_magnitude; | ||
46 | debug("called with 0x%04x 0x%04x", left, right); | ||
47 | |||
48 | left = left * 0x7f / 0xffff; | ||
49 | right = right * 0x7f / 0xffff; | ||
50 | |||
51 | plff->report->field[0]->value[2] = left; | ||
52 | plff->report->field[0]->value[3] = right; | ||
53 | debug("running with 0x%02x 0x%02x", left, right); | ||
54 | usbhid_submit_report(hid, plff->report, USB_DIR_OUT); | ||
55 | |||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | int hid_plff_init(struct hid_device *hid) | ||
60 | { | ||
61 | struct plff_device *plff; | ||
62 | struct hid_report *report; | ||
63 | struct hid_input *hidinput; | ||
64 | struct list_head *report_list = | ||
65 | &hid->report_enum[HID_OUTPUT_REPORT].report_list; | ||
66 | struct list_head *report_ptr = report_list; | ||
67 | struct input_dev *dev; | ||
68 | int error; | ||
69 | |||
70 | /* The device contains 2 output reports (one for each | ||
71 | HID_QUIRK_MULTI_INPUT device), both containing 1 field, which | ||
72 | contains 4 ff00.0002 usages and 4 16bit absolute values. | ||
73 | |||
74 | The 2 input reports also contain a field which contains | ||
75 | 8 ff00.0001 usages and 8 boolean values. Their meaning is | ||
76 | currently unknown. */ | ||
77 | |||
78 | if (list_empty(report_list)) { | ||
79 | printk(KERN_ERR "hid-plff: no output reports found\n"); | ||
80 | return -ENODEV; | ||
81 | } | ||
82 | |||
83 | list_for_each_entry(hidinput, &hid->inputs, list) { | ||
84 | |||
85 | report_ptr = report_ptr->next; | ||
86 | |||
87 | if (report_ptr == report_list) { | ||
88 | printk(KERN_ERR "hid-plff: required output report is missing\n"); | ||
89 | return -ENODEV; | ||
90 | } | ||
91 | |||
92 | report = list_entry(report_ptr, struct hid_report, list); | ||
93 | if (report->maxfield < 1) { | ||
94 | printk(KERN_ERR "hid-plff: no fields in the report\n"); | ||
95 | return -ENODEV; | ||
96 | } | ||
97 | |||
98 | if (report->field[0]->report_count < 4) { | ||
99 | printk(KERN_ERR "hid-plff: not enough values in the field\n"); | ||
100 | return -ENODEV; | ||
101 | } | ||
102 | |||
103 | plff = kzalloc(sizeof(struct plff_device), GFP_KERNEL); | ||
104 | if (!plff) | ||
105 | return -ENOMEM; | ||
106 | |||
107 | dev = hidinput->input; | ||
108 | |||
109 | set_bit(FF_RUMBLE, dev->ffbit); | ||
110 | |||
111 | error = input_ff_create_memless(dev, plff, hid_plff_play); | ||
112 | if (error) { | ||
113 | kfree(plff); | ||
114 | return error; | ||
115 | } | ||
116 | |||
117 | plff->report = report; | ||
118 | plff->report->field[0]->value[0] = 0x00; | ||
119 | plff->report->field[0]->value[1] = 0x00; | ||
120 | plff->report->field[0]->value[2] = 0x00; | ||
121 | plff->report->field[0]->value[3] = 0x00; | ||
122 | usbhid_submit_report(hid, plff->report, USB_DIR_OUT); | ||
123 | } | ||
124 | |||
125 | printk(KERN_INFO "hid-plff: Force feedback for PantherLord USB/PS2 " | ||
126 | "2in1 Adapters by Anssi Hannula <anssi.hannula@gmail.com>\n"); | ||
127 | |||
128 | return 0; | ||
129 | } | ||
diff --git a/drivers/usb/input/hid-tmff.c b/drivers/usb/input/hid-tmff.c index 2d5be4c318ac..ab67331620d0 100644 --- a/drivers/usb/input/hid-tmff.c +++ b/drivers/usb/input/hid-tmff.c | |||
@@ -32,7 +32,8 @@ | |||
32 | #undef DEBUG | 32 | #undef DEBUG |
33 | #include <linux/usb.h> | 33 | #include <linux/usb.h> |
34 | 34 | ||
35 | #include "hid.h" | 35 | #include <linux/hid.h> |
36 | #include "usbhid.h" | ||
36 | 37 | ||
37 | /* Usages for thrustmaster devices I know about */ | 38 | /* Usages for thrustmaster devices I know about */ |
38 | #define THRUSTMASTER_USAGE_RUMBLE_LR (HID_UP_GENDESK | 0xbb) | 39 | #define THRUSTMASTER_USAGE_RUMBLE_LR (HID_UP_GENDESK | 0xbb) |
@@ -70,7 +71,7 @@ static int hid_tmff_play(struct input_dev *dev, void *data, struct ff_effect *ef | |||
70 | tmff->rumble->value[0] = left; | 71 | tmff->rumble->value[0] = left; |
71 | tmff->rumble->value[1] = right; | 72 | tmff->rumble->value[1] = right; |
72 | dbg("(left,right)=(%08x, %08x)", left, right); | 73 | dbg("(left,right)=(%08x, %08x)", left, right); |
73 | hid_submit_report(hid, tmff->report, USB_DIR_OUT); | 74 | usbhid_submit_report(hid, tmff->report, USB_DIR_OUT); |
74 | 75 | ||
75 | return 0; | 76 | return 0; |
76 | } | 77 | } |
diff --git a/drivers/usb/input/hid-zpff.c b/drivers/usb/input/hid-zpff.c index d2ce3214572c..7bd8238ca212 100644 --- a/drivers/usb/input/hid-zpff.c +++ b/drivers/usb/input/hid-zpff.c | |||
@@ -27,7 +27,8 @@ | |||
27 | 27 | ||
28 | #include <linux/input.h> | 28 | #include <linux/input.h> |
29 | #include <linux/usb.h> | 29 | #include <linux/usb.h> |
30 | #include "hid.h" | 30 | #include <linux/hid.h> |
31 | #include "usbhid.h" | ||
31 | 32 | ||
32 | struct zpff_device { | 33 | struct zpff_device { |
33 | struct hid_report *report; | 34 | struct hid_report *report; |
@@ -56,7 +57,7 @@ static int hid_zpff_play(struct input_dev *dev, void *data, | |||
56 | zpff->report->field[2]->value[0] = left; | 57 | zpff->report->field[2]->value[0] = left; |
57 | zpff->report->field[3]->value[0] = right; | 58 | zpff->report->field[3]->value[0] = right; |
58 | debug("running with 0x%02x 0x%02x", left, right); | 59 | debug("running with 0x%02x 0x%02x", left, right); |
59 | hid_submit_report(hid, zpff->report, USB_DIR_OUT); | 60 | usbhid_submit_report(hid, zpff->report, USB_DIR_OUT); |
60 | 61 | ||
61 | return 0; | 62 | return 0; |
62 | } | 63 | } |
@@ -101,7 +102,7 @@ int hid_zpff_init(struct hid_device *hid) | |||
101 | zpff->report->field[1]->value[0] = 0x02; | 102 | zpff->report->field[1]->value[0] = 0x02; |
102 | zpff->report->field[2]->value[0] = 0x00; | 103 | zpff->report->field[2]->value[0] = 0x00; |
103 | zpff->report->field[3]->value[0] = 0x00; | 104 | zpff->report->field[3]->value[0] = 0x00; |
104 | hid_submit_report(hid, zpff->report, USB_DIR_OUT); | 105 | usbhid_submit_report(hid, zpff->report, USB_DIR_OUT); |
105 | 106 | ||
106 | printk(KERN_INFO "Force feedback for Zeroplus based devices by " | 107 | printk(KERN_INFO "Force feedback for Zeroplus based devices by " |
107 | "Anssi Hannula <anssi.hannula@gmail.com>\n"); | 108 | "Anssi Hannula <anssi.hannula@gmail.com>\n"); |
diff --git a/drivers/usb/input/hid.h b/drivers/usb/input/hid.h deleted file mode 100644 index 76ad68d9edfd..000000000000 --- a/drivers/usb/input/hid.h +++ /dev/null | |||
@@ -1,540 +0,0 @@ | |||
1 | #ifndef __HID_H | ||
2 | #define __HID_H | ||
3 | |||
4 | /* | ||
5 | * $Id: hid.h,v 1.24 2001/12/27 10:37:41 vojtech Exp $ | ||
6 | * | ||
7 | * Copyright (c) 1999 Andreas Gal | ||
8 | * Copyright (c) 2000-2001 Vojtech Pavlik | ||
9 | */ | ||
10 | |||
11 | /* | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
25 | * | ||
26 | * Should you need to contact me, the author, you can do so either by | ||
27 | * e-mail - mail your message to <vojtech@ucw.cz>, or by paper mail: | ||
28 | * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic | ||
29 | */ | ||
30 | |||
31 | #include <linux/types.h> | ||
32 | #include <linux/slab.h> | ||
33 | #include <linux/list.h> | ||
34 | #include <linux/timer.h> | ||
35 | #include <linux/workqueue.h> | ||
36 | |||
37 | /* | ||
38 | * USB HID (Human Interface Device) interface class code | ||
39 | */ | ||
40 | |||
41 | #define USB_INTERFACE_CLASS_HID 3 | ||
42 | |||
43 | /* | ||
44 | * USB HID interface subclass and protocol codes | ||
45 | */ | ||
46 | |||
47 | #define USB_INTERFACE_SUBCLASS_BOOT 1 | ||
48 | #define USB_INTERFACE_PROTOCOL_KEYBOARD 1 | ||
49 | #define USB_INTERFACE_PROTOCOL_MOUSE 2 | ||
50 | |||
51 | /* | ||
52 | * HID class requests | ||
53 | */ | ||
54 | |||
55 | #define HID_REQ_GET_REPORT 0x01 | ||
56 | #define HID_REQ_GET_IDLE 0x02 | ||
57 | #define HID_REQ_GET_PROTOCOL 0x03 | ||
58 | #define HID_REQ_SET_REPORT 0x09 | ||
59 | #define HID_REQ_SET_IDLE 0x0A | ||
60 | #define HID_REQ_SET_PROTOCOL 0x0B | ||
61 | |||
62 | /* | ||
63 | * HID class descriptor types | ||
64 | */ | ||
65 | |||
66 | #define HID_DT_HID (USB_TYPE_CLASS | 0x01) | ||
67 | #define HID_DT_REPORT (USB_TYPE_CLASS | 0x02) | ||
68 | #define HID_DT_PHYSICAL (USB_TYPE_CLASS | 0x03) | ||
69 | |||
70 | /* | ||
71 | * We parse each description item into this structure. Short items data | ||
72 | * values are expanded to 32-bit signed int, long items contain a pointer | ||
73 | * into the data area. | ||
74 | */ | ||
75 | |||
76 | struct hid_item { | ||
77 | unsigned format; | ||
78 | __u8 size; | ||
79 | __u8 type; | ||
80 | __u8 tag; | ||
81 | union { | ||
82 | __u8 u8; | ||
83 | __s8 s8; | ||
84 | __u16 u16; | ||
85 | __s16 s16; | ||
86 | __u32 u32; | ||
87 | __s32 s32; | ||
88 | __u8 *longdata; | ||
89 | } data; | ||
90 | }; | ||
91 | |||
92 | /* | ||
93 | * HID report item format | ||
94 | */ | ||
95 | |||
96 | #define HID_ITEM_FORMAT_SHORT 0 | ||
97 | #define HID_ITEM_FORMAT_LONG 1 | ||
98 | |||
99 | /* | ||
100 | * Special tag indicating long items | ||
101 | */ | ||
102 | |||
103 | #define HID_ITEM_TAG_LONG 15 | ||
104 | |||
105 | /* | ||
106 | * HID report descriptor item type (prefix bit 2,3) | ||
107 | */ | ||
108 | |||
109 | #define HID_ITEM_TYPE_MAIN 0 | ||
110 | #define HID_ITEM_TYPE_GLOBAL 1 | ||
111 | #define HID_ITEM_TYPE_LOCAL 2 | ||
112 | #define HID_ITEM_TYPE_RESERVED 3 | ||
113 | |||
114 | /* | ||
115 | * HID report descriptor main item tags | ||
116 | */ | ||
117 | |||
118 | #define HID_MAIN_ITEM_TAG_INPUT 8 | ||
119 | #define HID_MAIN_ITEM_TAG_OUTPUT 9 | ||
120 | #define HID_MAIN_ITEM_TAG_FEATURE 11 | ||
121 | #define HID_MAIN_ITEM_TAG_BEGIN_COLLECTION 10 | ||
122 | #define HID_MAIN_ITEM_TAG_END_COLLECTION 12 | ||
123 | |||
124 | /* | ||
125 | * HID report descriptor main item contents | ||
126 | */ | ||
127 | |||
128 | #define HID_MAIN_ITEM_CONSTANT 0x001 | ||
129 | #define HID_MAIN_ITEM_VARIABLE 0x002 | ||
130 | #define HID_MAIN_ITEM_RELATIVE 0x004 | ||
131 | #define HID_MAIN_ITEM_WRAP 0x008 | ||
132 | #define HID_MAIN_ITEM_NONLINEAR 0x010 | ||
133 | #define HID_MAIN_ITEM_NO_PREFERRED 0x020 | ||
134 | #define HID_MAIN_ITEM_NULL_STATE 0x040 | ||
135 | #define HID_MAIN_ITEM_VOLATILE 0x080 | ||
136 | #define HID_MAIN_ITEM_BUFFERED_BYTE 0x100 | ||
137 | |||
138 | /* | ||
139 | * HID report descriptor collection item types | ||
140 | */ | ||
141 | |||
142 | #define HID_COLLECTION_PHYSICAL 0 | ||
143 | #define HID_COLLECTION_APPLICATION 1 | ||
144 | #define HID_COLLECTION_LOGICAL 2 | ||
145 | |||
146 | /* | ||
147 | * HID report descriptor global item tags | ||
148 | */ | ||
149 | |||
150 | #define HID_GLOBAL_ITEM_TAG_USAGE_PAGE 0 | ||
151 | #define HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM 1 | ||
152 | #define HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM 2 | ||
153 | #define HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM 3 | ||
154 | #define HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM 4 | ||
155 | #define HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT 5 | ||
156 | #define HID_GLOBAL_ITEM_TAG_UNIT 6 | ||
157 | #define HID_GLOBAL_ITEM_TAG_REPORT_SIZE 7 | ||
158 | #define HID_GLOBAL_ITEM_TAG_REPORT_ID 8 | ||
159 | #define HID_GLOBAL_ITEM_TAG_REPORT_COUNT 9 | ||
160 | #define HID_GLOBAL_ITEM_TAG_PUSH 10 | ||
161 | #define HID_GLOBAL_ITEM_TAG_POP 11 | ||
162 | |||
163 | /* | ||
164 | * HID report descriptor local item tags | ||
165 | */ | ||
166 | |||
167 | #define HID_LOCAL_ITEM_TAG_USAGE 0 | ||
168 | #define HID_LOCAL_ITEM_TAG_USAGE_MINIMUM 1 | ||
169 | #define HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM 2 | ||
170 | #define HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX 3 | ||
171 | #define HID_LOCAL_ITEM_TAG_DESIGNATOR_MINIMUM 4 | ||
172 | #define HID_LOCAL_ITEM_TAG_DESIGNATOR_MAXIMUM 5 | ||
173 | #define HID_LOCAL_ITEM_TAG_STRING_INDEX 7 | ||
174 | #define HID_LOCAL_ITEM_TAG_STRING_MINIMUM 8 | ||
175 | #define HID_LOCAL_ITEM_TAG_STRING_MAXIMUM 9 | ||
176 | #define HID_LOCAL_ITEM_TAG_DELIMITER 10 | ||
177 | |||
178 | /* | ||
179 | * HID usage tables | ||
180 | */ | ||
181 | |||
182 | #define HID_USAGE_PAGE 0xffff0000 | ||
183 | |||
184 | #define HID_UP_UNDEFINED 0x00000000 | ||
185 | #define HID_UP_GENDESK 0x00010000 | ||
186 | #define HID_UP_SIMULATION 0x00020000 | ||
187 | #define HID_UP_KEYBOARD 0x00070000 | ||
188 | #define HID_UP_LED 0x00080000 | ||
189 | #define HID_UP_BUTTON 0x00090000 | ||
190 | #define HID_UP_ORDINAL 0x000a0000 | ||
191 | #define HID_UP_CONSUMER 0x000c0000 | ||
192 | #define HID_UP_DIGITIZER 0x000d0000 | ||
193 | #define HID_UP_PID 0x000f0000 | ||
194 | #define HID_UP_HPVENDOR 0xff7f0000 | ||
195 | #define HID_UP_MSVENDOR 0xff000000 | ||
196 | #define HID_UP_CUSTOM 0x00ff0000 | ||
197 | #define HID_UP_LOGIVENDOR 0xffbc0000 | ||
198 | |||
199 | #define HID_USAGE 0x0000ffff | ||
200 | |||
201 | #define HID_GD_POINTER 0x00010001 | ||
202 | #define HID_GD_MOUSE 0x00010002 | ||
203 | #define HID_GD_JOYSTICK 0x00010004 | ||
204 | #define HID_GD_GAMEPAD 0x00010005 | ||
205 | #define HID_GD_KEYBOARD 0x00010006 | ||
206 | #define HID_GD_KEYPAD 0x00010007 | ||
207 | #define HID_GD_MULTIAXIS 0x00010008 | ||
208 | #define HID_GD_X 0x00010030 | ||
209 | #define HID_GD_Y 0x00010031 | ||
210 | #define HID_GD_Z 0x00010032 | ||
211 | #define HID_GD_RX 0x00010033 | ||
212 | #define HID_GD_RY 0x00010034 | ||
213 | #define HID_GD_RZ 0x00010035 | ||
214 | #define HID_GD_SLIDER 0x00010036 | ||
215 | #define HID_GD_DIAL 0x00010037 | ||
216 | #define HID_GD_WHEEL 0x00010038 | ||
217 | #define HID_GD_HATSWITCH 0x00010039 | ||
218 | #define HID_GD_BUFFER 0x0001003a | ||
219 | #define HID_GD_BYTECOUNT 0x0001003b | ||
220 | #define HID_GD_MOTION 0x0001003c | ||
221 | #define HID_GD_START 0x0001003d | ||
222 | #define HID_GD_SELECT 0x0001003e | ||
223 | #define HID_GD_VX 0x00010040 | ||
224 | #define HID_GD_VY 0x00010041 | ||
225 | #define HID_GD_VZ 0x00010042 | ||
226 | #define HID_GD_VBRX 0x00010043 | ||
227 | #define HID_GD_VBRY 0x00010044 | ||
228 | #define HID_GD_VBRZ 0x00010045 | ||
229 | #define HID_GD_VNO 0x00010046 | ||
230 | #define HID_GD_FEATURE 0x00010047 | ||
231 | #define HID_GD_UP 0x00010090 | ||
232 | #define HID_GD_DOWN 0x00010091 | ||
233 | #define HID_GD_RIGHT 0x00010092 | ||
234 | #define HID_GD_LEFT 0x00010093 | ||
235 | |||
236 | /* | ||
237 | * HID report types --- Ouch! HID spec says 1 2 3! | ||
238 | */ | ||
239 | |||
240 | #define HID_INPUT_REPORT 0 | ||
241 | #define HID_OUTPUT_REPORT 1 | ||
242 | #define HID_FEATURE_REPORT 2 | ||
243 | |||
244 | /* | ||
245 | * HID device quirks. | ||
246 | */ | ||
247 | |||
248 | #define HID_QUIRK_INVERT 0x00000001 | ||
249 | #define HID_QUIRK_NOTOUCH 0x00000002 | ||
250 | #define HID_QUIRK_IGNORE 0x00000004 | ||
251 | #define HID_QUIRK_NOGET 0x00000008 | ||
252 | #define HID_QUIRK_HIDDEV 0x00000010 | ||
253 | #define HID_QUIRK_BADPAD 0x00000020 | ||
254 | #define HID_QUIRK_MULTI_INPUT 0x00000040 | ||
255 | #define HID_QUIRK_2WHEEL_MOUSE_HACK_7 0x00000080 | ||
256 | #define HID_QUIRK_2WHEEL_MOUSE_HACK_5 0x00000100 | ||
257 | #define HID_QUIRK_2WHEEL_MOUSE_HACK_ON 0x00000200 | ||
258 | #define HID_QUIRK_MIGHTYMOUSE 0x00000400 | ||
259 | #define HID_QUIRK_CYMOTION 0x00000800 | ||
260 | #define HID_QUIRK_POWERBOOK_HAS_FN 0x00001000 | ||
261 | #define HID_QUIRK_POWERBOOK_FN_ON 0x00002000 | ||
262 | #define HID_QUIRK_INVERT_HWHEEL 0x00004000 | ||
263 | #define HID_QUIRK_POWERBOOK_ISO_KEYBOARD 0x00008000 | ||
264 | #define HID_QUIRK_BAD_RELATIVE_KEYS 0x00010000 | ||
265 | |||
266 | /* | ||
267 | * This is the global environment of the parser. This information is | ||
268 | * persistent for main-items. The global environment can be saved and | ||
269 | * restored with PUSH/POP statements. | ||
270 | */ | ||
271 | |||
272 | struct hid_global { | ||
273 | unsigned usage_page; | ||
274 | __s32 logical_minimum; | ||
275 | __s32 logical_maximum; | ||
276 | __s32 physical_minimum; | ||
277 | __s32 physical_maximum; | ||
278 | __s32 unit_exponent; | ||
279 | unsigned unit; | ||
280 | unsigned report_id; | ||
281 | unsigned report_size; | ||
282 | unsigned report_count; | ||
283 | }; | ||
284 | |||
285 | /* | ||
286 | * This is the local environment. It is persistent up the next main-item. | ||
287 | */ | ||
288 | |||
289 | #define HID_MAX_DESCRIPTOR_SIZE 4096 | ||
290 | #define HID_MAX_USAGES 1024 | ||
291 | #define HID_DEFAULT_NUM_COLLECTIONS 16 | ||
292 | |||
293 | struct hid_local { | ||
294 | unsigned usage[HID_MAX_USAGES]; /* usage array */ | ||
295 | unsigned collection_index[HID_MAX_USAGES]; /* collection index array */ | ||
296 | unsigned usage_index; | ||
297 | unsigned usage_minimum; | ||
298 | unsigned delimiter_depth; | ||
299 | unsigned delimiter_branch; | ||
300 | }; | ||
301 | |||
302 | /* | ||
303 | * This is the collection stack. We climb up the stack to determine | ||
304 | * application and function of each field. | ||
305 | */ | ||
306 | |||
307 | struct hid_collection { | ||
308 | unsigned type; | ||
309 | unsigned usage; | ||
310 | unsigned level; | ||
311 | }; | ||
312 | |||
313 | struct hid_usage { | ||
314 | unsigned hid; /* hid usage code */ | ||
315 | unsigned collection_index; /* index into collection array */ | ||
316 | /* hidinput data */ | ||
317 | __u16 code; /* input driver code */ | ||
318 | __u8 type; /* input driver type */ | ||
319 | __s8 hat_min; /* hat switch fun */ | ||
320 | __s8 hat_max; /* ditto */ | ||
321 | __s8 hat_dir; /* ditto */ | ||
322 | }; | ||
323 | |||
324 | struct hid_input; | ||
325 | |||
326 | struct hid_field { | ||
327 | unsigned physical; /* physical usage for this field */ | ||
328 | unsigned logical; /* logical usage for this field */ | ||
329 | unsigned application; /* application usage for this field */ | ||
330 | struct hid_usage *usage; /* usage table for this function */ | ||
331 | unsigned maxusage; /* maximum usage index */ | ||
332 | unsigned flags; /* main-item flags (i.e. volatile,array,constant) */ | ||
333 | unsigned report_offset; /* bit offset in the report */ | ||
334 | unsigned report_size; /* size of this field in the report */ | ||
335 | unsigned report_count; /* number of this field in the report */ | ||
336 | unsigned report_type; /* (input,output,feature) */ | ||
337 | __s32 *value; /* last known value(s) */ | ||
338 | __s32 logical_minimum; | ||
339 | __s32 logical_maximum; | ||
340 | __s32 physical_minimum; | ||
341 | __s32 physical_maximum; | ||
342 | __s32 unit_exponent; | ||
343 | unsigned unit; | ||
344 | struct hid_report *report; /* associated report */ | ||
345 | unsigned index; /* index into report->field[] */ | ||
346 | /* hidinput data */ | ||
347 | struct hid_input *hidinput; /* associated input structure */ | ||
348 | __u16 dpad; /* dpad input code */ | ||
349 | }; | ||
350 | |||
351 | #define HID_MAX_FIELDS 64 | ||
352 | |||
353 | struct hid_report { | ||
354 | struct list_head list; | ||
355 | unsigned id; /* id of this report */ | ||
356 | unsigned type; /* report type */ | ||
357 | struct hid_field *field[HID_MAX_FIELDS]; /* fields of the report */ | ||
358 | unsigned maxfield; /* maximum valid field index */ | ||
359 | unsigned size; /* size of the report (bits) */ | ||
360 | struct hid_device *device; /* associated device */ | ||
361 | }; | ||
362 | |||
363 | struct hid_report_enum { | ||
364 | unsigned numbered; | ||
365 | struct list_head report_list; | ||
366 | struct hid_report *report_id_hash[256]; | ||
367 | }; | ||
368 | |||
369 | #define HID_REPORT_TYPES 3 | ||
370 | |||
371 | #define HID_MIN_BUFFER_SIZE 64 /* make sure there is at least a packet size of space */ | ||
372 | #define HID_MAX_BUFFER_SIZE 4096 /* 4kb */ | ||
373 | #define HID_CONTROL_FIFO_SIZE 256 /* to init devices with >100 reports */ | ||
374 | #define HID_OUTPUT_FIFO_SIZE 64 | ||
375 | |||
376 | struct hid_control_fifo { | ||
377 | unsigned char dir; | ||
378 | struct hid_report *report; | ||
379 | }; | ||
380 | |||
381 | #define HID_CLAIMED_INPUT 1 | ||
382 | #define HID_CLAIMED_HIDDEV 2 | ||
383 | |||
384 | #define HID_CTRL_RUNNING 1 | ||
385 | #define HID_OUT_RUNNING 2 | ||
386 | #define HID_IN_RUNNING 3 | ||
387 | #define HID_RESET_PENDING 4 | ||
388 | #define HID_SUSPENDED 5 | ||
389 | #define HID_CLEAR_HALT 6 | ||
390 | |||
391 | struct hid_input { | ||
392 | struct list_head list; | ||
393 | struct hid_report *report; | ||
394 | struct input_dev *input; | ||
395 | }; | ||
396 | |||
397 | struct hid_device { /* device report descriptor */ | ||
398 | __u8 *rdesc; | ||
399 | unsigned rsize; | ||
400 | struct hid_collection *collection; /* List of HID collections */ | ||
401 | unsigned collection_size; /* Number of allocated hid_collections */ | ||
402 | unsigned maxcollection; /* Number of parsed collections */ | ||
403 | unsigned maxapplication; /* Number of applications */ | ||
404 | unsigned version; /* HID version */ | ||
405 | unsigned country; /* HID country */ | ||
406 | struct hid_report_enum report_enum[HID_REPORT_TYPES]; | ||
407 | |||
408 | struct usb_device *dev; /* USB device */ | ||
409 | struct usb_interface *intf; /* USB interface */ | ||
410 | int ifnum; /* USB interface number */ | ||
411 | |||
412 | unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */ | ||
413 | struct timer_list io_retry; /* Retry timer */ | ||
414 | unsigned long stop_retry; /* Time to give up, in jiffies */ | ||
415 | unsigned int retry_delay; /* Delay length in ms */ | ||
416 | struct work_struct reset_work; /* Task context for resets */ | ||
417 | |||
418 | unsigned int bufsize; /* URB buffer size */ | ||
419 | |||
420 | struct urb *urbin; /* Input URB */ | ||
421 | char *inbuf; /* Input buffer */ | ||
422 | dma_addr_t inbuf_dma; /* Input buffer dma */ | ||
423 | spinlock_t inlock; /* Input fifo spinlock */ | ||
424 | |||
425 | struct urb *urbctrl; /* Control URB */ | ||
426 | struct usb_ctrlrequest *cr; /* Control request struct */ | ||
427 | dma_addr_t cr_dma; /* Control request struct dma */ | ||
428 | struct hid_control_fifo ctrl[HID_CONTROL_FIFO_SIZE]; /* Control fifo */ | ||
429 | unsigned char ctrlhead, ctrltail; /* Control fifo head & tail */ | ||
430 | char *ctrlbuf; /* Control buffer */ | ||
431 | dma_addr_t ctrlbuf_dma; /* Control buffer dma */ | ||
432 | spinlock_t ctrllock; /* Control fifo spinlock */ | ||
433 | |||
434 | struct urb *urbout; /* Output URB */ | ||
435 | struct hid_report *out[HID_CONTROL_FIFO_SIZE]; /* Output pipe fifo */ | ||
436 | unsigned char outhead, outtail; /* Output pipe fifo head & tail */ | ||
437 | char *outbuf; /* Output buffer */ | ||
438 | dma_addr_t outbuf_dma; /* Output buffer dma */ | ||
439 | spinlock_t outlock; /* Output fifo spinlock */ | ||
440 | |||
441 | unsigned claimed; /* Claimed by hidinput, hiddev? */ | ||
442 | unsigned quirks; /* Various quirks the device can pull on us */ | ||
443 | |||
444 | struct list_head inputs; /* The list of inputs */ | ||
445 | void *hiddev; /* The hiddev structure */ | ||
446 | int minor; /* Hiddev minor number */ | ||
447 | |||
448 | wait_queue_head_t wait; /* For sleeping */ | ||
449 | |||
450 | int open; /* is the device open by anyone? */ | ||
451 | char name[128]; /* Device name */ | ||
452 | char phys[64]; /* Device physical location */ | ||
453 | char uniq[64]; /* Device unique identifier (serial #) */ | ||
454 | |||
455 | #ifdef CONFIG_USB_HIDINPUT_POWERBOOK | ||
456 | unsigned long pb_pressed_fn[NBITS(KEY_MAX)]; | ||
457 | unsigned long pb_pressed_numlock[NBITS(KEY_MAX)]; | ||
458 | #endif | ||
459 | }; | ||
460 | |||
461 | #define HID_GLOBAL_STACK_SIZE 4 | ||
462 | #define HID_COLLECTION_STACK_SIZE 4 | ||
463 | |||
464 | struct hid_parser { | ||
465 | struct hid_global global; | ||
466 | struct hid_global global_stack[HID_GLOBAL_STACK_SIZE]; | ||
467 | unsigned global_stack_ptr; | ||
468 | struct hid_local local; | ||
469 | unsigned collection_stack[HID_COLLECTION_STACK_SIZE]; | ||
470 | unsigned collection_stack_ptr; | ||
471 | struct hid_device *device; | ||
472 | }; | ||
473 | |||
474 | struct hid_class_descriptor { | ||
475 | __u8 bDescriptorType; | ||
476 | __u16 wDescriptorLength; | ||
477 | } __attribute__ ((packed)); | ||
478 | |||
479 | struct hid_descriptor { | ||
480 | __u8 bLength; | ||
481 | __u8 bDescriptorType; | ||
482 | __u16 bcdHID; | ||
483 | __u8 bCountryCode; | ||
484 | __u8 bNumDescriptors; | ||
485 | |||
486 | struct hid_class_descriptor desc[1]; | ||
487 | } __attribute__ ((packed)); | ||
488 | |||
489 | #ifdef DEBUG | ||
490 | #include "hid-debug.h" | ||
491 | #else | ||
492 | #define hid_dump_input(a,b) do { } while (0) | ||
493 | #define hid_dump_device(c) do { } while (0) | ||
494 | #define hid_dump_field(a,b) do { } while (0) | ||
495 | #define resolv_usage(a) do { } while (0) | ||
496 | #define resolv_event(a,b) do { } while (0) | ||
497 | #endif | ||
498 | |||
499 | #endif | ||
500 | |||
501 | #ifdef CONFIG_USB_HIDINPUT | ||
502 | /* Applications from HID Usage Tables 4/8/99 Version 1.1 */ | ||
503 | /* We ignore a few input applications that are not widely used */ | ||
504 | #define IS_INPUT_APPLICATION(a) (((a >= 0x00010000) && (a <= 0x00010008)) || (a == 0x00010080) || (a == 0x000c0001)) | ||
505 | extern void hidinput_hid_event(struct hid_device *, struct hid_field *, struct hid_usage *, __s32); | ||
506 | extern void hidinput_report_event(struct hid_device *hid, struct hid_report *report); | ||
507 | extern int hidinput_connect(struct hid_device *); | ||
508 | extern void hidinput_disconnect(struct hid_device *); | ||
509 | #else | ||
510 | #define IS_INPUT_APPLICATION(a) (0) | ||
511 | static inline void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct hid_usage *usage, __s32 value) { } | ||
512 | static inline void hidinput_report_event(struct hid_device *hid, struct hid_report *report) { } | ||
513 | static inline int hidinput_connect(struct hid_device *hid) { return -ENODEV; } | ||
514 | static inline void hidinput_disconnect(struct hid_device *hid) { } | ||
515 | #endif | ||
516 | |||
517 | int hid_open(struct hid_device *); | ||
518 | void hid_close(struct hid_device *); | ||
519 | int hid_set_field(struct hid_field *, unsigned, __s32); | ||
520 | void hid_submit_report(struct hid_device *, struct hid_report *, unsigned char dir); | ||
521 | void hid_init_reports(struct hid_device *hid); | ||
522 | int hid_wait_io(struct hid_device* hid); | ||
523 | |||
524 | |||
525 | #ifdef CONFIG_HID_FF | ||
526 | int hid_ff_init(struct hid_device *hid); | ||
527 | |||
528 | int hid_lgff_init(struct hid_device *hid); | ||
529 | int hid_tmff_init(struct hid_device *hid); | ||
530 | int hid_zpff_init(struct hid_device *hid); | ||
531 | #ifdef CONFIG_HID_PID | ||
532 | int hid_pidff_init(struct hid_device *hid); | ||
533 | #else | ||
534 | static inline int hid_pidff_init(struct hid_device *hid) { return -ENODEV; } | ||
535 | #endif | ||
536 | |||
537 | #else | ||
538 | static inline int hid_ff_init(struct hid_device *hid) { return -1; } | ||
539 | #endif | ||
540 | |||
diff --git a/drivers/usb/input/hiddev.c b/drivers/usb/input/hiddev.c index 7dc14d0cacc1..a8b3d66cd498 100644 --- a/drivers/usb/input/hiddev.c +++ b/drivers/usb/input/hiddev.c | |||
@@ -32,8 +32,9 @@ | |||
32 | #include <linux/smp_lock.h> | 32 | #include <linux/smp_lock.h> |
33 | #include <linux/input.h> | 33 | #include <linux/input.h> |
34 | #include <linux/usb.h> | 34 | #include <linux/usb.h> |
35 | #include "hid.h" | 35 | #include <linux/hid.h> |
36 | #include <linux/hiddev.h> | 36 | #include <linux/hiddev.h> |
37 | #include "usbhid.h" | ||
37 | 38 | ||
38 | #ifdef CONFIG_USB_DYNAMIC_MINORS | 39 | #ifdef CONFIG_USB_DYNAMIC_MINORS |
39 | #define HIDDEV_MINOR_BASE 0 | 40 | #define HIDDEV_MINOR_BASE 0 |
@@ -196,7 +197,7 @@ void hiddev_hid_event(struct hid_device *hid, struct hid_field *field, | |||
196 | 197 | ||
197 | hiddev_send_event(hid, &uref); | 198 | hiddev_send_event(hid, &uref); |
198 | } | 199 | } |
199 | 200 | EXPORT_SYMBOL_GPL(hiddev_hid_event); | |
200 | 201 | ||
201 | void hiddev_report_event(struct hid_device *hid, struct hid_report *report) | 202 | void hiddev_report_event(struct hid_device *hid, struct hid_report *report) |
202 | { | 203 | { |
@@ -213,6 +214,7 @@ void hiddev_report_event(struct hid_device *hid, struct hid_report *report) | |||
213 | 214 | ||
214 | hiddev_send_event(hid, &uref); | 215 | hiddev_send_event(hid, &uref); |
215 | } | 216 | } |
217 | |||
216 | /* | 218 | /* |
217 | * fasync file op | 219 | * fasync file op |
218 | */ | 220 | */ |
@@ -239,7 +241,7 @@ static int hiddev_release(struct inode * inode, struct file * file) | |||
239 | 241 | ||
240 | if (!--list->hiddev->open) { | 242 | if (!--list->hiddev->open) { |
241 | if (list->hiddev->exist) | 243 | if (list->hiddev->exist) |
242 | hid_close(list->hiddev->hid); | 244 | usbhid_close(list->hiddev->hid); |
243 | else | 245 | else |
244 | kfree(list->hiddev); | 246 | kfree(list->hiddev); |
245 | } | 247 | } |
@@ -270,7 +272,7 @@ static int hiddev_open(struct inode *inode, struct file *file) | |||
270 | 272 | ||
271 | if (!list->hiddev->open++) | 273 | if (!list->hiddev->open++) |
272 | if (list->hiddev->exist) | 274 | if (list->hiddev->exist) |
273 | hid_open(hiddev_table[i]->hid); | 275 | usbhid_open(hiddev_table[i]->hid); |
274 | 276 | ||
275 | return 0; | 277 | return 0; |
276 | } | 278 | } |
@@ -382,7 +384,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
382 | struct hiddev_list *list = file->private_data; | 384 | struct hiddev_list *list = file->private_data; |
383 | struct hiddev *hiddev = list->hiddev; | 385 | struct hiddev *hiddev = list->hiddev; |
384 | struct hid_device *hid = hiddev->hid; | 386 | struct hid_device *hid = hiddev->hid; |
385 | struct usb_device *dev = hid->dev; | 387 | struct usb_device *dev = hid_to_usb_dev(hid); |
386 | struct hiddev_collection_info cinfo; | 388 | struct hiddev_collection_info cinfo; |
387 | struct hiddev_report_info rinfo; | 389 | struct hiddev_report_info rinfo; |
388 | struct hiddev_field_info finfo; | 390 | struct hiddev_field_info finfo; |
@@ -391,6 +393,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
391 | struct hiddev_devinfo dinfo; | 393 | struct hiddev_devinfo dinfo; |
392 | struct hid_report *report; | 394 | struct hid_report *report; |
393 | struct hid_field *field; | 395 | struct hid_field *field; |
396 | struct usbhid_device *usbhid = hid->driver_data; | ||
394 | void __user *user_arg = (void __user *)arg; | 397 | void __user *user_arg = (void __user *)arg; |
395 | int i; | 398 | int i; |
396 | 399 | ||
@@ -420,7 +423,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
420 | dinfo.bustype = BUS_USB; | 423 | dinfo.bustype = BUS_USB; |
421 | dinfo.busnum = dev->bus->busnum; | 424 | dinfo.busnum = dev->bus->busnum; |
422 | dinfo.devnum = dev->devnum; | 425 | dinfo.devnum = dev->devnum; |
423 | dinfo.ifnum = hid->ifnum; | 426 | dinfo.ifnum = usbhid->ifnum; |
424 | dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor); | 427 | dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor); |
425 | dinfo.product = le16_to_cpu(dev->descriptor.idProduct); | 428 | dinfo.product = le16_to_cpu(dev->descriptor.idProduct); |
426 | dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice); | 429 | dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice); |
@@ -479,7 +482,7 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
479 | } | 482 | } |
480 | 483 | ||
481 | case HIDIOCINITREPORT: | 484 | case HIDIOCINITREPORT: |
482 | hid_init_reports(hid); | 485 | usbhid_init_reports(hid); |
483 | 486 | ||
484 | return 0; | 487 | return 0; |
485 | 488 | ||
@@ -493,8 +496,8 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
493 | if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) | 496 | if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) |
494 | return -EINVAL; | 497 | return -EINVAL; |
495 | 498 | ||
496 | hid_submit_report(hid, report, USB_DIR_IN); | 499 | usbhid_submit_report(hid, report, USB_DIR_IN); |
497 | hid_wait_io(hid); | 500 | usbhid_wait_io(hid); |
498 | 501 | ||
499 | return 0; | 502 | return 0; |
500 | 503 | ||
@@ -508,8 +511,8 @@ static int hiddev_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
508 | if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) | 511 | if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) |
509 | return -EINVAL; | 512 | return -EINVAL; |
510 | 513 | ||
511 | hid_submit_report(hid, report, USB_DIR_OUT); | 514 | usbhid_submit_report(hid, report, USB_DIR_OUT); |
512 | hid_wait_io(hid); | 515 | usbhid_wait_io(hid); |
513 | 516 | ||
514 | return 0; | 517 | return 0; |
515 | 518 | ||
@@ -745,6 +748,7 @@ static struct usb_class_driver hiddev_class = { | |||
745 | int hiddev_connect(struct hid_device *hid) | 748 | int hiddev_connect(struct hid_device *hid) |
746 | { | 749 | { |
747 | struct hiddev *hiddev; | 750 | struct hiddev *hiddev; |
751 | struct usbhid_device *usbhid = hid->driver_data; | ||
748 | int i; | 752 | int i; |
749 | int retval; | 753 | int retval; |
750 | 754 | ||
@@ -760,7 +764,7 @@ int hiddev_connect(struct hid_device *hid) | |||
760 | if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL))) | 764 | if (!(hiddev = kzalloc(sizeof(struct hiddev), GFP_KERNEL))) |
761 | return -1; | 765 | return -1; |
762 | 766 | ||
763 | retval = usb_register_dev(hid->intf, &hiddev_class); | 767 | retval = usb_register_dev(usbhid->intf, &hiddev_class); |
764 | if (retval) { | 768 | if (retval) { |
765 | err("Not able to get a minor for this device."); | 769 | err("Not able to get a minor for this device."); |
766 | kfree(hiddev); | 770 | kfree(hiddev); |
@@ -772,10 +776,10 @@ int hiddev_connect(struct hid_device *hid) | |||
772 | hiddev->hid = hid; | 776 | hiddev->hid = hid; |
773 | hiddev->exist = 1; | 777 | hiddev->exist = 1; |
774 | 778 | ||
775 | hid->minor = hid->intf->minor; | 779 | hid->minor = usbhid->intf->minor; |
776 | hid->hiddev = hiddev; | 780 | hid->hiddev = hiddev; |
777 | 781 | ||
778 | hiddev_table[hid->intf->minor - HIDDEV_MINOR_BASE] = hiddev; | 782 | hiddev_table[usbhid->intf->minor - HIDDEV_MINOR_BASE] = hiddev; |
779 | 783 | ||
780 | return 0; | 784 | return 0; |
781 | } | 785 | } |
@@ -788,14 +792,15 @@ static struct usb_class_driver hiddev_class; | |||
788 | void hiddev_disconnect(struct hid_device *hid) | 792 | void hiddev_disconnect(struct hid_device *hid) |
789 | { | 793 | { |
790 | struct hiddev *hiddev = hid->hiddev; | 794 | struct hiddev *hiddev = hid->hiddev; |
795 | struct usbhid_device *usbhid = hid->driver_data; | ||
791 | 796 | ||
792 | hiddev->exist = 0; | 797 | hiddev->exist = 0; |
793 | 798 | ||
794 | hiddev_table[hiddev->hid->minor - HIDDEV_MINOR_BASE] = NULL; | 799 | hiddev_table[hiddev->hid->minor - HIDDEV_MINOR_BASE] = NULL; |
795 | usb_deregister_dev(hiddev->hid->intf, &hiddev_class); | 800 | usb_deregister_dev(usbhid->intf, &hiddev_class); |
796 | 801 | ||
797 | if (hiddev->open) { | 802 | if (hiddev->open) { |
798 | hid_close(hiddev->hid); | 803 | usbhid_close(hiddev->hid); |
799 | wake_up_interruptible(&hiddev->wait); | 804 | wake_up_interruptible(&hiddev->wait); |
800 | } else { | 805 | } else { |
801 | kfree(hiddev); | 806 | kfree(hiddev); |
diff --git a/drivers/usb/input/usbhid.h b/drivers/usb/input/usbhid.h new file mode 100644 index 000000000000..0023f96d4294 --- /dev/null +++ b/drivers/usb/input/usbhid.h | |||
@@ -0,0 +1,87 @@ | |||
1 | #ifndef __USBHID_H | ||
2 | #define __USBHID_H | ||
3 | |||
4 | /* | ||
5 | * Copyright (c) 1999 Andreas Gal | ||
6 | * Copyright (c) 2000-2001 Vojtech Pavlik | ||
7 | * Copyright (c) 2006 Jiri Kosina | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License as published by | ||
13 | * the Free Software Foundation; either version 2 of the License, or | ||
14 | * (at your option) any later version. | ||
15 | * | ||
16 | * This program is distributed in the hope that it will be useful, | ||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
19 | * GNU General Public License for more details. | ||
20 | * | ||
21 | * You should have received a copy of the GNU General Public License | ||
22 | * along with this program; if not, write to the Free Software | ||
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | #include <linux/types.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/list.h> | ||
30 | #include <linux/timer.h> | ||
31 | #include <linux/workqueue.h> | ||
32 | #include <linux/input.h> | ||
33 | |||
34 | /* API provided by hid-core.c for USB HID drivers */ | ||
35 | int usbhid_wait_io(struct hid_device* hid); | ||
36 | void usbhid_close(struct hid_device *hid); | ||
37 | int usbhid_open(struct hid_device *hid); | ||
38 | void usbhid_init_reports(struct hid_device *hid); | ||
39 | void usbhid_submit_report(struct hid_device *hid, struct hid_report *report, unsigned char dir); | ||
40 | |||
41 | /* | ||
42 | * USB-specific HID struct, to be pointed to | ||
43 | * from struct hid_device->driver_data | ||
44 | */ | ||
45 | |||
46 | struct usbhid_device { | ||
47 | struct hid_device *hid; /* pointer to corresponding HID dev */ | ||
48 | |||
49 | struct usb_interface *intf; /* USB interface */ | ||
50 | int ifnum; /* USB interface number */ | ||
51 | |||
52 | unsigned int bufsize; /* URB buffer size */ | ||
53 | |||
54 | struct urb *urbin; /* Input URB */ | ||
55 | char *inbuf; /* Input buffer */ | ||
56 | dma_addr_t inbuf_dma; /* Input buffer dma */ | ||
57 | spinlock_t inlock; /* Input fifo spinlock */ | ||
58 | |||
59 | struct urb *urbctrl; /* Control URB */ | ||
60 | struct usb_ctrlrequest *cr; /* Control request struct */ | ||
61 | dma_addr_t cr_dma; /* Control request struct dma */ | ||
62 | struct hid_control_fifo ctrl[HID_CONTROL_FIFO_SIZE]; /* Control fifo */ | ||
63 | unsigned char ctrlhead, ctrltail; /* Control fifo head & tail */ | ||
64 | char *ctrlbuf; /* Control buffer */ | ||
65 | dma_addr_t ctrlbuf_dma; /* Control buffer dma */ | ||
66 | spinlock_t ctrllock; /* Control fifo spinlock */ | ||
67 | |||
68 | struct urb *urbout; /* Output URB */ | ||
69 | struct hid_report *out[HID_CONTROL_FIFO_SIZE]; /* Output pipe fifo */ | ||
70 | unsigned char outhead, outtail; /* Output pipe fifo head & tail */ | ||
71 | char *outbuf; /* Output buffer */ | ||
72 | dma_addr_t outbuf_dma; /* Output buffer dma */ | ||
73 | spinlock_t outlock; /* Output fifo spinlock */ | ||
74 | |||
75 | unsigned long iofl; /* I/O flags (CTRL_RUNNING, OUT_RUNNING) */ | ||
76 | struct timer_list io_retry; /* Retry timer */ | ||
77 | unsigned long stop_retry; /* Time to give up, in jiffies */ | ||
78 | unsigned int retry_delay; /* Delay length in ms */ | ||
79 | struct work_struct reset_work; /* Task context for resets */ | ||
80 | |||
81 | }; | ||
82 | |||
83 | #define hid_to_usb_dev(hid_dev) \ | ||
84 | container_of(hid_dev->dev->parent, struct usb_device, dev) | ||
85 | |||
86 | #endif | ||
87 | |||
diff --git a/drivers/usb/input/usbtouchscreen.c b/drivers/usb/input/usbtouchscreen.c index 7f3c57da9bc0..86e37a20f8e5 100644 --- a/drivers/usb/input/usbtouchscreen.c +++ b/drivers/usb/input/usbtouchscreen.c | |||
@@ -66,7 +66,7 @@ struct usbtouch_device_info { | |||
66 | 66 | ||
67 | void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt, int len); | 67 | void (*process_pkt) (struct usbtouch_usb *usbtouch, unsigned char *pkt, int len); |
68 | int (*get_pkt_len) (unsigned char *pkt, int len); | 68 | int (*get_pkt_len) (unsigned char *pkt, int len); |
69 | int (*read_data) (unsigned char *pkt, int *x, int *y, int *touch, int *press); | 69 | int (*read_data) (struct usbtouch_usb *usbtouch, unsigned char *pkt); |
70 | int (*init) (struct usbtouch_usb *usbtouch); | 70 | int (*init) (struct usbtouch_usb *usbtouch); |
71 | }; | 71 | }; |
72 | 72 | ||
@@ -85,6 +85,9 @@ struct usbtouch_usb { | |||
85 | struct usbtouch_device_info *type; | 85 | struct usbtouch_device_info *type; |
86 | char name[128]; | 86 | char name[128]; |
87 | char phys[64]; | 87 | char phys[64]; |
88 | |||
89 | int x, y; | ||
90 | int touch, press; | ||
88 | }; | 91 | }; |
89 | 92 | ||
90 | 93 | ||
@@ -161,14 +164,14 @@ static struct usb_device_id usbtouch_devices[] = { | |||
161 | #define EGALAX_PKT_TYPE_REPT 0x80 | 164 | #define EGALAX_PKT_TYPE_REPT 0x80 |
162 | #define EGALAX_PKT_TYPE_DIAG 0x0A | 165 | #define EGALAX_PKT_TYPE_DIAG 0x0A |
163 | 166 | ||
164 | static int egalax_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) | 167 | static int egalax_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
165 | { | 168 | { |
166 | if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT) | 169 | if ((pkt[0] & EGALAX_PKT_TYPE_MASK) != EGALAX_PKT_TYPE_REPT) |
167 | return 0; | 170 | return 0; |
168 | 171 | ||
169 | *x = ((pkt[3] & 0x0F) << 7) | (pkt[4] & 0x7F); | 172 | dev->x = ((pkt[3] & 0x0F) << 7) | (pkt[4] & 0x7F); |
170 | *y = ((pkt[1] & 0x0F) << 7) | (pkt[2] & 0x7F); | 173 | dev->y = ((pkt[1] & 0x0F) << 7) | (pkt[2] & 0x7F); |
171 | *touch = pkt[0] & 0x01; | 174 | dev->touch = pkt[0] & 0x01; |
172 | 175 | ||
173 | return 1; | 176 | return 1; |
174 | } | 177 | } |
@@ -195,11 +198,11 @@ static int egalax_get_pkt_len(unsigned char *buf, int len) | |||
195 | * PanJit Part | 198 | * PanJit Part |
196 | */ | 199 | */ |
197 | #ifdef CONFIG_USB_TOUCHSCREEN_PANJIT | 200 | #ifdef CONFIG_USB_TOUCHSCREEN_PANJIT |
198 | static int panjit_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) | 201 | static int panjit_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
199 | { | 202 | { |
200 | *x = ((pkt[2] & 0x0F) << 8) | pkt[1]; | 203 | dev->x = ((pkt[2] & 0x0F) << 8) | pkt[1]; |
201 | *y = ((pkt[4] & 0x0F) << 8) | pkt[3]; | 204 | dev->y = ((pkt[4] & 0x0F) << 8) | pkt[3]; |
202 | *touch = pkt[0] & 0x01; | 205 | dev->touch = pkt[0] & 0x01; |
203 | 206 | ||
204 | return 1; | 207 | return 1; |
205 | } | 208 | } |
@@ -215,11 +218,11 @@ static int panjit_read_data(unsigned char *pkt, int *x, int *y, int *touch, int | |||
215 | #define MTOUCHUSB_RESET 7 | 218 | #define MTOUCHUSB_RESET 7 |
216 | #define MTOUCHUSB_REQ_CTRLLR_ID 10 | 219 | #define MTOUCHUSB_REQ_CTRLLR_ID 10 |
217 | 220 | ||
218 | static int mtouch_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) | 221 | static int mtouch_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
219 | { | 222 | { |
220 | *x = (pkt[8] << 8) | pkt[7]; | 223 | dev->x = (pkt[8] << 8) | pkt[7]; |
221 | *y = (pkt[10] << 8) | pkt[9]; | 224 | dev->y = (pkt[10] << 8) | pkt[9]; |
222 | *touch = (pkt[2] & 0x40) ? 1 : 0; | 225 | dev->touch = (pkt[2] & 0x40) ? 1 : 0; |
223 | 226 | ||
224 | return 1; | 227 | return 1; |
225 | } | 228 | } |
@@ -260,14 +263,32 @@ static int mtouch_init(struct usbtouch_usb *usbtouch) | |||
260 | * ITM Part | 263 | * ITM Part |
261 | */ | 264 | */ |
262 | #ifdef CONFIG_USB_TOUCHSCREEN_ITM | 265 | #ifdef CONFIG_USB_TOUCHSCREEN_ITM |
263 | static int itm_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) | 266 | static int itm_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
264 | { | 267 | { |
265 | *x = ((pkt[0] & 0x1F) << 7) | (pkt[3] & 0x7F); | 268 | int touch; |
266 | *y = ((pkt[1] & 0x1F) << 7) | (pkt[4] & 0x7F); | 269 | /* |
267 | *press = ((pkt[2] & 0x01) << 7) | (pkt[5] & 0x7F); | 270 | * ITM devices report invalid x/y data if not touched. |
268 | *touch = ~pkt[7] & 0x20; | 271 | * if the screen was touched before but is not touched any more |
272 | * report touch as 0 with the last valid x/y data once. then stop | ||
273 | * reporting data until touched again. | ||
274 | */ | ||
275 | dev->press = ((pkt[2] & 0x01) << 7) | (pkt[5] & 0x7F); | ||
276 | |||
277 | touch = ~pkt[7] & 0x20; | ||
278 | if (!touch) { | ||
279 | if (dev->touch) { | ||
280 | dev->touch = 0; | ||
281 | return 1; | ||
282 | } | ||
269 | 283 | ||
270 | return *touch; | 284 | return 0; |
285 | } | ||
286 | |||
287 | dev->x = ((pkt[0] & 0x1F) << 7) | (pkt[3] & 0x7F); | ||
288 | dev->y = ((pkt[1] & 0x1F) << 7) | (pkt[4] & 0x7F); | ||
289 | dev->touch = touch; | ||
290 | |||
291 | return 1; | ||
271 | } | 292 | } |
272 | #endif | 293 | #endif |
273 | 294 | ||
@@ -276,7 +297,7 @@ static int itm_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *pr | |||
276 | * eTurboTouch part | 297 | * eTurboTouch part |
277 | */ | 298 | */ |
278 | #ifdef CONFIG_USB_TOUCHSCREEN_ETURBO | 299 | #ifdef CONFIG_USB_TOUCHSCREEN_ETURBO |
279 | static int eturbo_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) | 300 | static int eturbo_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
280 | { | 301 | { |
281 | unsigned int shift; | 302 | unsigned int shift; |
282 | 303 | ||
@@ -285,9 +306,9 @@ static int eturbo_read_data(unsigned char *pkt, int *x, int *y, int *touch, int | |||
285 | return 0; | 306 | return 0; |
286 | 307 | ||
287 | shift = (6 - (pkt[0] & 0x03)); | 308 | shift = (6 - (pkt[0] & 0x03)); |
288 | *x = ((pkt[3] << 7) | pkt[4]) >> shift; | 309 | dev->x = ((pkt[3] << 7) | pkt[4]) >> shift; |
289 | *y = ((pkt[1] << 7) | pkt[2]) >> shift; | 310 | dev->y = ((pkt[1] << 7) | pkt[2]) >> shift; |
290 | *touch = (pkt[0] & 0x10) ? 1 : 0; | 311 | dev->touch = (pkt[0] & 0x10) ? 1 : 0; |
291 | 312 | ||
292 | return 1; | 313 | return 1; |
293 | } | 314 | } |
@@ -307,14 +328,14 @@ static int eturbo_get_pkt_len(unsigned char *buf, int len) | |||
307 | * Gunze part | 328 | * Gunze part |
308 | */ | 329 | */ |
309 | #ifdef CONFIG_USB_TOUCHSCREEN_GUNZE | 330 | #ifdef CONFIG_USB_TOUCHSCREEN_GUNZE |
310 | static int gunze_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) | 331 | static int gunze_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
311 | { | 332 | { |
312 | if (!(pkt[0] & 0x80) || ((pkt[1] | pkt[2] | pkt[3]) & 0x80)) | 333 | if (!(pkt[0] & 0x80) || ((pkt[1] | pkt[2] | pkt[3]) & 0x80)) |
313 | return 0; | 334 | return 0; |
314 | 335 | ||
315 | *x = ((pkt[0] & 0x1F) << 7) | (pkt[2] & 0x7F); | 336 | dev->x = ((pkt[0] & 0x1F) << 7) | (pkt[2] & 0x7F); |
316 | *y = ((pkt[1] & 0x1F) << 7) | (pkt[3] & 0x7F); | 337 | dev->y = ((pkt[1] & 0x1F) << 7) | (pkt[3] & 0x7F); |
317 | *touch = pkt[0] & 0x20; | 338 | dev->touch = pkt[0] & 0x20; |
318 | 339 | ||
319 | return 1; | 340 | return 1; |
320 | } | 341 | } |
@@ -383,11 +404,11 @@ static int dmc_tsc10_init(struct usbtouch_usb *usbtouch) | |||
383 | } | 404 | } |
384 | 405 | ||
385 | 406 | ||
386 | static int dmc_tsc10_read_data(unsigned char *pkt, int *x, int *y, int *touch, int *press) | 407 | static int dmc_tsc10_read_data(struct usbtouch_usb *dev, unsigned char *pkt) |
387 | { | 408 | { |
388 | *x = ((pkt[2] & 0x03) << 8) | pkt[1]; | 409 | dev->x = ((pkt[2] & 0x03) << 8) | pkt[1]; |
389 | *y = ((pkt[4] & 0x03) << 8) | pkt[3]; | 410 | dev->y = ((pkt[4] & 0x03) << 8) | pkt[3]; |
390 | *touch = pkt[0] & 0x01; | 411 | dev->touch = pkt[0] & 0x01; |
391 | 412 | ||
392 | return 1; | 413 | return 1; |
393 | } | 414 | } |
@@ -492,23 +513,22 @@ static struct usbtouch_device_info usbtouch_dev_info[] = { | |||
492 | static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch, | 513 | static void usbtouch_process_pkt(struct usbtouch_usb *usbtouch, |
493 | unsigned char *pkt, int len) | 514 | unsigned char *pkt, int len) |
494 | { | 515 | { |
495 | int x, y, touch, press; | ||
496 | struct usbtouch_device_info *type = usbtouch->type; | 516 | struct usbtouch_device_info *type = usbtouch->type; |
497 | 517 | ||
498 | if (!type->read_data(pkt, &x, &y, &touch, &press)) | 518 | if (!type->read_data(usbtouch, pkt)) |
499 | return; | 519 | return; |
500 | 520 | ||
501 | input_report_key(usbtouch->input, BTN_TOUCH, touch); | 521 | input_report_key(usbtouch->input, BTN_TOUCH, usbtouch->touch); |
502 | 522 | ||
503 | if (swap_xy) { | 523 | if (swap_xy) { |
504 | input_report_abs(usbtouch->input, ABS_X, y); | 524 | input_report_abs(usbtouch->input, ABS_X, usbtouch->y); |
505 | input_report_abs(usbtouch->input, ABS_Y, x); | 525 | input_report_abs(usbtouch->input, ABS_Y, usbtouch->x); |
506 | } else { | 526 | } else { |
507 | input_report_abs(usbtouch->input, ABS_X, x); | 527 | input_report_abs(usbtouch->input, ABS_X, usbtouch->x); |
508 | input_report_abs(usbtouch->input, ABS_Y, y); | 528 | input_report_abs(usbtouch->input, ABS_Y, usbtouch->y); |
509 | } | 529 | } |
510 | if (type->max_press) | 530 | if (type->max_press) |
511 | input_report_abs(usbtouch->input, ABS_PRESSURE, press); | 531 | input_report_abs(usbtouch->input, ABS_PRESSURE, usbtouch->press); |
512 | input_sync(usbtouch->input); | 532 | input_sync(usbtouch->input); |
513 | } | 533 | } |
514 | 534 | ||
diff --git a/drivers/usb/input/wacom_sys.c b/drivers/usb/input/wacom_sys.c index e7cc20ab8155..12b42746ded8 100644 --- a/drivers/usb/input/wacom_sys.c +++ b/drivers/usb/input/wacom_sys.c | |||
@@ -159,13 +159,13 @@ void input_dev_i3s(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | |||
159 | { | 159 | { |
160 | input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); | 160 | input_dev->keybit[LONG(BTN_DIGI)] |= BIT(BTN_TOOL_FINGER); |
161 | input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); | 161 | input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_0) | BIT(BTN_1) | BIT(BTN_2) | BIT(BTN_3); |
162 | input_set_abs_params(input_dev, ABS_RX, 0, 4097, 0, 0); | 162 | input_set_abs_params(input_dev, ABS_RX, 0, 4096, 0, 0); |
163 | } | 163 | } |
164 | 164 | ||
165 | void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 165 | void input_dev_i3(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
166 | { | 166 | { |
167 | input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); | 167 | input_dev->keybit[LONG(BTN_LEFT)] |= BIT(BTN_4) | BIT(BTN_5) | BIT(BTN_6) | BIT(BTN_7); |
168 | input_set_abs_params(input_dev, ABS_RY, 0, 4097, 0, 0); | 168 | input_set_abs_params(input_dev, ABS_RY, 0, 4096, 0, 0); |
169 | } | 169 | } |
170 | 170 | ||
171 | void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) | 171 | void input_dev_i(struct input_dev *input_dev, struct wacom_wac *wacom_wac) |
diff --git a/drivers/usb/input/wacom_wac.c b/drivers/usb/input/wacom_wac.c index 92726fe89379..4142e36730fc 100644 --- a/drivers/usb/input/wacom_wac.c +++ b/drivers/usb/input/wacom_wac.c | |||
@@ -209,13 +209,15 @@ static int wacom_graphire_irq(struct wacom_wac *wacom, void *wcombo) | |||
209 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); | 209 | wacom_report_key(wcombo, BTN_STYLUS, data[1] & 0x02); |
210 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04); | 210 | wacom_report_key(wcombo, BTN_STYLUS2, data[1] & 0x04); |
211 | } | 211 | } |
212 | } | ||
213 | |||
214 | if (data[1] & 0x10) | ||
215 | wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */ | 212 | wacom_report_abs(wcombo, ABS_MISC, id); /* report tool id */ |
213 | } | ||
216 | else | 214 | else |
217 | wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ | 215 | wacom_report_abs(wcombo, ABS_MISC, 0); /* reset tool id */ |
218 | wacom_report_key(wcombo, wacom->tool[0], data[1] & 0x10); | 216 | |
217 | if (data[1] & 0x10) /* only report prox-in when in area */ | ||
218 | wacom_report_key(wcombo, wacom->tool[0], 1); | ||
219 | if (!(data[1] & 0x90)) /* report prox-out when physically out */ | ||
220 | wacom_report_key(wcombo, wacom->tool[0], 0); | ||
219 | wacom_input_sync(wcombo); | 221 | wacom_input_sync(wcombo); |
220 | 222 | ||
221 | /* send pad data */ | 223 | /* send pad data */ |
@@ -405,7 +407,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
405 | if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40)) | 407 | if ((wacom->features->type == CINTIQ) && !(data[1] & 0x40)) |
406 | return 0; | 408 | return 0; |
407 | 409 | ||
408 | if (wacom->features->type >= INTUOS3) { | 410 | if (wacom->features->type >= INTUOS3S) { |
409 | wacom_report_abs(wcombo, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); | 411 | wacom_report_abs(wcombo, ABS_X, (data[2] << 9) | (data[3] << 1) | ((data[9] >> 1) & 1)); |
410 | wacom_report_abs(wcombo, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); | 412 | wacom_report_abs(wcombo, ABS_Y, (data[4] << 9) | (data[5] << 1) | (data[9] & 1)); |
411 | wacom_report_abs(wcombo, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); | 413 | wacom_report_abs(wcombo, ABS_DISTANCE, ((data[9] >> 2) & 0x3f)); |
@@ -423,7 +425,7 @@ static int wacom_intuos_irq(struct wacom_wac *wacom, void *wcombo) | |||
423 | 425 | ||
424 | if (data[1] & 0x02) { | 426 | if (data[1] & 0x02) { |
425 | /* Rotation packet */ | 427 | /* Rotation packet */ |
426 | if (wacom->features->type >= INTUOS3) { | 428 | if (wacom->features->type >= INTUOS3S) { |
427 | /* I3 marker pen rotation reported as wheel | 429 | /* I3 marker pen rotation reported as wheel |
428 | * due to valuator limitation | 430 | * due to valuator limitation |
429 | */ | 431 | */ |
@@ -547,11 +549,11 @@ static struct wacom_features wacom_features[] = { | |||
547 | { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 63, GRAPHIRE }, | 549 | { "Wacom Graphire3 6x8", 8, 16704, 12064, 511, 63, GRAPHIRE }, |
548 | { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 63, WACOM_G4 }, | 550 | { "Wacom Graphire4 4x5", 8, 10208, 7424, 511, 63, WACOM_G4 }, |
549 | { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 63, WACOM_G4 }, | 551 | { "Wacom Graphire4 6x8", 8, 16704, 12064, 511, 63, WACOM_G4 }, |
550 | { "Wacom Volito", 8, 5104, 3712, 511, 0, GRAPHIRE }, | 552 | { "Wacom Volito", 8, 5104, 3712, 511, 63, GRAPHIRE }, |
551 | { "Wacom PenStation2", 8, 3250, 2320, 255, 0, GRAPHIRE }, | 553 | { "Wacom PenStation2", 8, 3250, 2320, 255, 63, GRAPHIRE }, |
552 | { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 0, GRAPHIRE }, | 554 | { "Wacom Volito2 4x5", 8, 5104, 3712, 511, 63, GRAPHIRE }, |
553 | { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 0, GRAPHIRE }, | 555 | { "Wacom Volito2 2x3", 8, 3248, 2320, 511, 63, GRAPHIRE }, |
554 | { "Wacom PenPartner2", 8, 3250, 2320, 255, 0, GRAPHIRE }, | 556 | { "Wacom PenPartner2", 8, 3250, 2320, 255, 63, GRAPHIRE }, |
555 | { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 63, INTUOS }, | 557 | { "Wacom Intuos 4x5", 10, 12700, 10600, 1023, 63, INTUOS }, |
556 | { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 63, INTUOS }, | 558 | { "Wacom Intuos 6x8", 10, 20320, 16240, 1023, 63, INTUOS }, |
557 | { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 63, INTUOS }, | 559 | { "Wacom Intuos 9x12", 10, 30480, 24060, 1023, 63, INTUOS }, |
@@ -580,7 +582,7 @@ static struct wacom_features wacom_features[] = { | |||
580 | { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 63, INTUOS3L }, | 582 | { "Wacom Intuos3 12x12", 10, 60960, 60960, 1023, 63, INTUOS3L }, |
581 | { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 63, INTUOS3L }, | 583 | { "Wacom Intuos3 12x19", 10, 97536, 60960, 1023, 63, INTUOS3L }, |
582 | { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3 }, | 584 | { "Wacom Intuos3 6x11", 10, 54204, 31750, 1023, 63, INTUOS3 }, |
583 | { "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 15, INTUOS3S }, | 585 | { "Wacom Intuos3 4x6", 10, 31496, 19685, 1023, 63, INTUOS3S }, |
584 | { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ }, | 586 | { "Wacom Cintiq 21UX", 10, 87200, 65600, 1023, 63, CINTIQ }, |
585 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 63, INTUOS }, | 587 | { "Wacom Intuos2 6x8", 10, 20320, 16240, 1023, 63, INTUOS }, |
586 | { } | 588 | { } |
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index 02cbb7fff24f..a7932a72d298 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c | |||
@@ -281,7 +281,7 @@ static int appledisplay_probe(struct usb_interface *iface, | |||
281 | /* Register backlight device */ | 281 | /* Register backlight device */ |
282 | snprintf(bl_name, sizeof(bl_name), "appledisplay%d", | 282 | snprintf(bl_name, sizeof(bl_name), "appledisplay%d", |
283 | atomic_inc_return(&count_displays) - 1); | 283 | atomic_inc_return(&count_displays) - 1); |
284 | pdata->bd = backlight_device_register(bl_name, pdata, | 284 | pdata->bd = backlight_device_register(bl_name, NULL, NULL, |
285 | &appledisplay_bl_data); | 285 | &appledisplay_bl_data); |
286 | if (IS_ERR(pdata->bd)) { | 286 | if (IS_ERR(pdata->bd)) { |
287 | err("appledisplay: Backlight registration failed"); | 287 | err("appledisplay: Backlight registration failed"); |
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index c703f73e1655..b5332e679c46 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c | |||
@@ -766,7 +766,7 @@ static int auerbuf_setup (pauerbufctl_t bcp, unsigned int numElements, unsigned | |||
766 | bep->bufp = kmalloc (bufsize, GFP_KERNEL); | 766 | bep->bufp = kmalloc (bufsize, GFP_KERNEL); |
767 | if (!bep->bufp) | 767 | if (!bep->bufp) |
768 | goto bl_fail; | 768 | goto bl_fail; |
769 | bep->dr = (struct usb_ctrlrequest *) kmalloc (sizeof (struct usb_ctrlrequest), GFP_KERNEL); | 769 | bep->dr = kmalloc(sizeof (struct usb_ctrlrequest), GFP_KERNEL); |
770 | if (!bep->dr) | 770 | if (!bep->dr) |
771 | goto bl_fail; | 771 | goto bl_fail; |
772 | bep->urbp = usb_alloc_urb (0, GFP_KERNEL); | 772 | bep->urbp = usb_alloc_urb (0, GFP_KERNEL); |
@@ -1376,7 +1376,7 @@ static int auerchar_open (struct inode *inode, struct file *file) | |||
1376 | } | 1376 | } |
1377 | 1377 | ||
1378 | /* we have access to the device. Now lets allocate memory */ | 1378 | /* we have access to the device. Now lets allocate memory */ |
1379 | ccp = (pauerchar_t) kmalloc(sizeof(auerchar_t), GFP_KERNEL); | 1379 | ccp = kzalloc(sizeof(auerchar_t), GFP_KERNEL); |
1380 | if (ccp == NULL) { | 1380 | if (ccp == NULL) { |
1381 | err ("out of memory"); | 1381 | err ("out of memory"); |
1382 | ret = -ENOMEM; | 1382 | ret = -ENOMEM; |
@@ -1384,7 +1384,6 @@ static int auerchar_open (struct inode *inode, struct file *file) | |||
1384 | } | 1384 | } |
1385 | 1385 | ||
1386 | /* Initialize device descriptor */ | 1386 | /* Initialize device descriptor */ |
1387 | memset( ccp, 0, sizeof(auerchar_t)); | ||
1388 | init_MUTEX( &ccp->mutex); | 1387 | init_MUTEX( &ccp->mutex); |
1389 | init_MUTEX( &ccp->readmutex); | 1388 | init_MUTEX( &ccp->readmutex); |
1390 | auerbuf_init (&ccp->bufctl); | 1389 | auerbuf_init (&ccp->bufctl); |
@@ -1912,14 +1911,13 @@ static int auerswald_probe (struct usb_interface *intf, | |||
1912 | return -ENODEV; | 1911 | return -ENODEV; |
1913 | 1912 | ||
1914 | /* allocate memory for our device and initialize it */ | 1913 | /* allocate memory for our device and initialize it */ |
1915 | cp = kmalloc (sizeof(auerswald_t), GFP_KERNEL); | 1914 | cp = kzalloc (sizeof(auerswald_t), GFP_KERNEL); |
1916 | if (cp == NULL) { | 1915 | if (cp == NULL) { |
1917 | err ("out of memory"); | 1916 | err ("out of memory"); |
1918 | goto pfail; | 1917 | goto pfail; |
1919 | } | 1918 | } |
1920 | 1919 | ||
1921 | /* Initialize device descriptor */ | 1920 | /* Initialize device descriptor */ |
1922 | memset (cp, 0, sizeof(auerswald_t)); | ||
1923 | init_MUTEX (&cp->mutex); | 1921 | init_MUTEX (&cp->mutex); |
1924 | cp->usbdev = usbdev; | 1922 | cp->usbdev = usbdev; |
1925 | auerchain_init (&cp->controlchain); | 1923 | auerchain_init (&cp->controlchain); |
@@ -1969,7 +1967,7 @@ static int auerswald_probe (struct usb_interface *intf, | |||
1969 | info("device is a %s", cp->dev_desc); | 1967 | info("device is a %s", cp->dev_desc); |
1970 | 1968 | ||
1971 | /* get the maximum allowed control transfer length */ | 1969 | /* get the maximum allowed control transfer length */ |
1972 | pbuf = (__le16 *) kmalloc (2, GFP_KERNEL); /* use an allocated buffer because of urb target */ | 1970 | pbuf = kmalloc(2, GFP_KERNEL); /* use an allocated buffer because of urb target */ |
1973 | if (!pbuf) { | 1971 | if (!pbuf) { |
1974 | err( "out of memory"); | 1972 | err( "out of memory"); |
1975 | goto pfail; | 1973 | goto pfail; |
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index 18b1925032a8..41c0161abdb9 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c | |||
@@ -40,6 +40,7 @@ | |||
40 | #include <linux/init.h> | 40 | #include <linux/init.h> |
41 | #include <linux/list.h> | 41 | #include <linux/list.h> |
42 | #include <linux/ioctl.h> | 42 | #include <linux/ioctl.h> |
43 | #include <linux/pci_ids.h> | ||
43 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
44 | #include <linux/module.h> | 45 | #include <linux/module.h> |
45 | #include <linux/kref.h> | 46 | #include <linux/kref.h> |
@@ -51,6 +52,10 @@ MODULE_AUTHOR("Tony Olech"); | |||
51 | MODULE_DESCRIPTION("FTDI ELAN driver"); | 52 | MODULE_DESCRIPTION("FTDI ELAN driver"); |
52 | MODULE_LICENSE("GPL"); | 53 | MODULE_LICENSE("GPL"); |
53 | #define INT_MODULE_PARM(n, v) static int n = v;module_param(n, int, 0444) | 54 | #define INT_MODULE_PARM(n, v) static int n = v;module_param(n, int, 0444) |
55 | static int distrust_firmware = 1; | ||
56 | module_param(distrust_firmware, bool, 0); | ||
57 | MODULE_PARM_DESC(distrust_firmware, "true to distrust firmware power/overcurren" | ||
58 | "t setup"); | ||
54 | extern struct platform_driver u132_platform_driver; | 59 | extern struct platform_driver u132_platform_driver; |
55 | static struct workqueue_struct *status_queue; | 60 | static struct workqueue_struct *status_queue; |
56 | static struct workqueue_struct *command_queue; | 61 | static struct workqueue_struct *command_queue; |
@@ -66,7 +71,9 @@ static struct list_head ftdi_static_list; | |||
66 | * end of the global variables protected by ftdi_module_lock | 71 | * end of the global variables protected by ftdi_module_lock |
67 | */ | 72 | */ |
68 | #include "usb_u132.h" | 73 | #include "usb_u132.h" |
69 | #define TD_DEVNOTRESP 5 | 74 | #include <asm/io.h> |
75 | #include "../core/hcd.h" | ||
76 | #include "../host/ohci.h" | ||
70 | /* Define these values to match your devices*/ | 77 | /* Define these values to match your devices*/ |
71 | #define USB_FTDI_ELAN_VENDOR_ID 0x0403 | 78 | #define USB_FTDI_ELAN_VENDOR_ID 0x0403 |
72 | #define USB_FTDI_ELAN_PRODUCT_ID 0xd6ea | 79 | #define USB_FTDI_ELAN_PRODUCT_ID 0xd6ea |
@@ -551,7 +558,7 @@ static void ftdi_elan_status_work(struct work_struct *work) | |||
551 | } else { | 558 | } else { |
552 | dev_err(&ftdi->udev->dev, "initialized failed - trying " | 559 | dev_err(&ftdi->udev->dev, "initialized failed - trying " |
553 | "again in 10 seconds\n"); | 560 | "again in 10 seconds\n"); |
554 | work_delay_in_msec = 10 *1000; | 561 | work_delay_in_msec = 1 *1000; |
555 | } | 562 | } |
556 | } else if (ftdi->registered == 0) { | 563 | } else if (ftdi->registered == 0) { |
557 | work_delay_in_msec = 10; | 564 | work_delay_in_msec = 10; |
@@ -2288,82 +2295,288 @@ static int ftdi_elan_checkingPCI(struct usb_ftdi *ftdi) | |||
2288 | } | 2295 | } |
2289 | } | 2296 | } |
2290 | 2297 | ||
2291 | static int ftdi_elan_enumeratePCI(struct usb_ftdi *ftdi) | 2298 | |
2299 | #define ftdi_read_pcimem(ftdi, member, data) ftdi_elan_read_pcimem(ftdi, \ | ||
2300 | offsetof(struct ohci_regs, member), 0, data); | ||
2301 | #define ftdi_write_pcimem(ftdi, member, data) ftdi_elan_write_pcimem(ftdi, \ | ||
2302 | offsetof(struct ohci_regs, member), 0, data); | ||
2303 | #define OHCI_QUIRK_AMD756 0x01 | ||
2304 | #define OHCI_QUIRK_SUPERIO 0x02 | ||
2305 | #define OHCI_QUIRK_INITRESET 0x04 | ||
2306 | #define OHCI_BIG_ENDIAN 0x08 | ||
2307 | #define OHCI_QUIRK_ZFMICRO 0x10 | ||
2308 | #define OHCI_CONTROL_INIT OHCI_CTRL_CBSR | ||
2309 | #define OHCI_INTR_INIT (OHCI_INTR_MIE | OHCI_INTR_UE | OHCI_INTR_RD | \ | ||
2310 | OHCI_INTR_WDH) | ||
2311 | static int ftdi_elan_check_controller(struct usb_ftdi *ftdi, int quirk) | ||
2312 | { | ||
2313 | int devices = 0; | ||
2314 | int retval; | ||
2315 | u32 hc_control; | ||
2316 | int num_ports; | ||
2317 | u32 control; | ||
2318 | u32 rh_a = -1; | ||
2319 | u32 status; | ||
2320 | u32 fminterval; | ||
2321 | u32 hc_fminterval; | ||
2322 | u32 periodicstart; | ||
2323 | u32 cmdstatus; | ||
2324 | u32 roothub_a; | ||
2325 | int mask = OHCI_INTR_INIT; | ||
2326 | int sleep_time = 0; | ||
2327 | int reset_timeout = 30; /* ... allow extra time */ | ||
2328 | int temp; | ||
2329 | retval = ftdi_write_pcimem(ftdi, intrdisable, OHCI_INTR_MIE); | ||
2330 | if (retval) | ||
2331 | return retval; | ||
2332 | retval = ftdi_read_pcimem(ftdi, control, &control); | ||
2333 | if (retval) | ||
2334 | return retval; | ||
2335 | retval = ftdi_read_pcimem(ftdi, roothub.a, &rh_a); | ||
2336 | if (retval) | ||
2337 | return retval; | ||
2338 | num_ports = rh_a & RH_A_NDP; | ||
2339 | retval = ftdi_read_pcimem(ftdi, fminterval, &hc_fminterval); | ||
2340 | if (retval) | ||
2341 | return retval; | ||
2342 | hc_fminterval &= 0x3fff; | ||
2343 | if (hc_fminterval != FI) { | ||
2344 | } | ||
2345 | hc_fminterval |= FSMP(hc_fminterval) << 16; | ||
2346 | retval = ftdi_read_pcimem(ftdi, control, &hc_control); | ||
2347 | if (retval) | ||
2348 | return retval; | ||
2349 | switch (hc_control & OHCI_CTRL_HCFS) { | ||
2350 | case OHCI_USB_OPER: | ||
2351 | sleep_time = 0; | ||
2352 | break; | ||
2353 | case OHCI_USB_SUSPEND: | ||
2354 | case OHCI_USB_RESUME: | ||
2355 | hc_control &= OHCI_CTRL_RWC; | ||
2356 | hc_control |= OHCI_USB_RESUME; | ||
2357 | sleep_time = 10; | ||
2358 | break; | ||
2359 | default: | ||
2360 | hc_control &= OHCI_CTRL_RWC; | ||
2361 | hc_control |= OHCI_USB_RESET; | ||
2362 | sleep_time = 50; | ||
2363 | break; | ||
2364 | } | ||
2365 | retval = ftdi_write_pcimem(ftdi, control, hc_control); | ||
2366 | if (retval) | ||
2367 | return retval; | ||
2368 | retval = ftdi_read_pcimem(ftdi, control, &control); | ||
2369 | if (retval) | ||
2370 | return retval; | ||
2371 | msleep(sleep_time); | ||
2372 | retval = ftdi_read_pcimem(ftdi, roothub.a, &roothub_a); | ||
2373 | if (retval) | ||
2374 | return retval; | ||
2375 | if (!(roothub_a & RH_A_NPS)) { /* power down each port */ | ||
2376 | for (temp = 0; temp < num_ports; temp++) { | ||
2377 | retval = ftdi_write_pcimem(ftdi, | ||
2378 | roothub.portstatus[temp], RH_PS_LSDA); | ||
2379 | if (retval) | ||
2380 | return retval; | ||
2381 | } | ||
2382 | } | ||
2383 | retval = ftdi_read_pcimem(ftdi, control, &control); | ||
2384 | if (retval) | ||
2385 | return retval; | ||
2386 | retry:retval = ftdi_read_pcimem(ftdi, cmdstatus, &status); | ||
2387 | if (retval) | ||
2388 | return retval; | ||
2389 | retval = ftdi_write_pcimem(ftdi, cmdstatus, OHCI_HCR); | ||
2390 | if (retval) | ||
2391 | return retval; | ||
2392 | extra:{ | ||
2393 | retval = ftdi_read_pcimem(ftdi, cmdstatus, &status); | ||
2394 | if (retval) | ||
2395 | return retval; | ||
2396 | if (0 != (status & OHCI_HCR)) { | ||
2397 | if (--reset_timeout == 0) { | ||
2398 | dev_err(&ftdi->udev->dev, "USB HC reset timed o" | ||
2399 | "ut!\n"); | ||
2400 | return -ENODEV; | ||
2401 | } else { | ||
2402 | msleep(5); | ||
2403 | goto extra; | ||
2404 | } | ||
2405 | } | ||
2406 | } | ||
2407 | if (quirk & OHCI_QUIRK_INITRESET) { | ||
2408 | retval = ftdi_write_pcimem(ftdi, control, hc_control); | ||
2409 | if (retval) | ||
2410 | return retval; | ||
2411 | retval = ftdi_read_pcimem(ftdi, control, &control); | ||
2412 | if (retval) | ||
2413 | return retval; | ||
2414 | } | ||
2415 | retval = ftdi_write_pcimem(ftdi, ed_controlhead, 0x00000000); | ||
2416 | if (retval) | ||
2417 | return retval; | ||
2418 | retval = ftdi_write_pcimem(ftdi, ed_bulkhead, 0x11000000); | ||
2419 | if (retval) | ||
2420 | return retval; | ||
2421 | retval = ftdi_write_pcimem(ftdi, hcca, 0x00000000); | ||
2422 | if (retval) | ||
2423 | return retval; | ||
2424 | retval = ftdi_read_pcimem(ftdi, fminterval, &fminterval); | ||
2425 | if (retval) | ||
2426 | return retval; | ||
2427 | retval = ftdi_write_pcimem(ftdi, fminterval, | ||
2428 | ((fminterval & FIT) ^ FIT) | hc_fminterval); | ||
2429 | if (retval) | ||
2430 | return retval; | ||
2431 | retval = ftdi_write_pcimem(ftdi, periodicstart, | ||
2432 | ((9 *hc_fminterval) / 10) & 0x3fff); | ||
2433 | if (retval) | ||
2434 | return retval; | ||
2435 | retval = ftdi_read_pcimem(ftdi, fminterval, &fminterval); | ||
2436 | if (retval) | ||
2437 | return retval; | ||
2438 | retval = ftdi_read_pcimem(ftdi, periodicstart, &periodicstart); | ||
2439 | if (retval) | ||
2440 | return retval; | ||
2441 | if (0 == (fminterval & 0x3fff0000) || 0 == periodicstart) { | ||
2442 | if (!(quirk & OHCI_QUIRK_INITRESET)) { | ||
2443 | quirk |= OHCI_QUIRK_INITRESET; | ||
2444 | goto retry; | ||
2445 | } else | ||
2446 | dev_err(&ftdi->udev->dev, "init err(%08x %04x)\n", | ||
2447 | fminterval, periodicstart); | ||
2448 | } /* start controller operations */ | ||
2449 | hc_control &= OHCI_CTRL_RWC; | ||
2450 | hc_control |= OHCI_CONTROL_INIT | OHCI_CTRL_BLE | OHCI_USB_OPER; | ||
2451 | retval = ftdi_write_pcimem(ftdi, control, hc_control); | ||
2452 | if (retval) | ||
2453 | return retval; | ||
2454 | retval = ftdi_write_pcimem(ftdi, cmdstatus, OHCI_BLF); | ||
2455 | if (retval) | ||
2456 | return retval; | ||
2457 | retval = ftdi_read_pcimem(ftdi, cmdstatus, &cmdstatus); | ||
2458 | if (retval) | ||
2459 | return retval; | ||
2460 | retval = ftdi_read_pcimem(ftdi, control, &control); | ||
2461 | if (retval) | ||
2462 | return retval; | ||
2463 | retval = ftdi_write_pcimem(ftdi, roothub.status, RH_HS_DRWE); | ||
2464 | if (retval) | ||
2465 | return retval; | ||
2466 | retval = ftdi_write_pcimem(ftdi, intrstatus, mask); | ||
2467 | if (retval) | ||
2468 | return retval; | ||
2469 | retval = ftdi_write_pcimem(ftdi, intrdisable, | ||
2470 | OHCI_INTR_MIE | OHCI_INTR_OC | OHCI_INTR_RHSC | OHCI_INTR_FNO | | ||
2471 | OHCI_INTR_UE | OHCI_INTR_RD | OHCI_INTR_SF | OHCI_INTR_WDH | | ||
2472 | OHCI_INTR_SO); | ||
2473 | if (retval) | ||
2474 | return retval; /* handle root hub init quirks ... */ | ||
2475 | retval = ftdi_read_pcimem(ftdi, roothub.a, &roothub_a); | ||
2476 | if (retval) | ||
2477 | return retval; | ||
2478 | roothub_a &= ~(RH_A_PSM | RH_A_OCPM); | ||
2479 | if (quirk & OHCI_QUIRK_SUPERIO) { | ||
2480 | roothub_a |= RH_A_NOCP; | ||
2481 | roothub_a &= ~(RH_A_POTPGT | RH_A_NPS); | ||
2482 | retval = ftdi_write_pcimem(ftdi, roothub.a, roothub_a); | ||
2483 | if (retval) | ||
2484 | return retval; | ||
2485 | } else if ((quirk & OHCI_QUIRK_AMD756) || distrust_firmware) { | ||
2486 | roothub_a |= RH_A_NPS; | ||
2487 | retval = ftdi_write_pcimem(ftdi, roothub.a, roothub_a); | ||
2488 | if (retval) | ||
2489 | return retval; | ||
2490 | } | ||
2491 | retval = ftdi_write_pcimem(ftdi, roothub.status, RH_HS_LPSC); | ||
2492 | if (retval) | ||
2493 | return retval; | ||
2494 | retval = ftdi_write_pcimem(ftdi, roothub.b, | ||
2495 | (roothub_a & RH_A_NPS) ? 0 : RH_B_PPCM); | ||
2496 | if (retval) | ||
2497 | return retval; | ||
2498 | retval = ftdi_read_pcimem(ftdi, control, &control); | ||
2499 | if (retval) | ||
2500 | return retval; | ||
2501 | mdelay((roothub_a >> 23) & 0x1fe); | ||
2502 | for (temp = 0; temp < num_ports; temp++) { | ||
2503 | u32 portstatus; | ||
2504 | retval = ftdi_read_pcimem(ftdi, roothub.portstatus[temp], | ||
2505 | &portstatus); | ||
2506 | if (retval) | ||
2507 | return retval; | ||
2508 | if (1 & portstatus) | ||
2509 | devices += 1; | ||
2510 | } | ||
2511 | return devices; | ||
2512 | } | ||
2513 | |||
2514 | static int ftdi_elan_setup_controller(struct usb_ftdi *ftdi, int fn) | ||
2292 | { | 2515 | { |
2293 | u32 latence_timer; | 2516 | u32 latence_timer; |
2294 | u32 controlreg; | ||
2295 | int UxxxStatus; | 2517 | int UxxxStatus; |
2296 | u32 pcidata; | 2518 | u32 pcidata; |
2297 | int reg = 0; | 2519 | int reg = 0; |
2298 | int foundOHCI = 0; | 2520 | int activePCIfn = fn << 8; |
2299 | u8 fn; | 2521 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x2800); |
2300 | int activePCIfn = 0; | ||
2301 | u32 pciVID = 0; | ||
2302 | u32 pciPID = 0; | ||
2303 | UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); | ||
2304 | if (UxxxStatus) | ||
2305 | return UxxxStatus; | ||
2306 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000000L); | ||
2307 | if (UxxxStatus) | ||
2308 | return UxxxStatus; | ||
2309 | msleep(750); | ||
2310 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000200L | 0x100); | ||
2311 | if (UxxxStatus) | 2522 | if (UxxxStatus) |
2312 | return UxxxStatus; | 2523 | return UxxxStatus; |
2313 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000200L | 0x500); | 2524 | reg = 16; |
2525 | UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0, | ||
2526 | 0xFFFFFFFF); | ||
2314 | if (UxxxStatus) | 2527 | if (UxxxStatus) |
2315 | return UxxxStatus; | 2528 | return UxxxStatus; |
2316 | UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); | 2529 | UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, |
2530 | &pcidata); | ||
2317 | if (UxxxStatus) | 2531 | if (UxxxStatus) |
2318 | return UxxxStatus; | 2532 | return UxxxStatus; |
2319 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020CL | 0x000); | 2533 | UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0, |
2534 | 0xF0000000); | ||
2320 | if (UxxxStatus) | 2535 | if (UxxxStatus) |
2321 | return UxxxStatus; | 2536 | return UxxxStatus; |
2322 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020DL | 0x000); | 2537 | UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, |
2538 | &pcidata); | ||
2323 | if (UxxxStatus) | 2539 | if (UxxxStatus) |
2324 | return UxxxStatus; | 2540 | return UxxxStatus; |
2325 | msleep(250); | 2541 | reg = 12; |
2326 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020FL | 0x000); | 2542 | UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, |
2543 | &latence_timer); | ||
2327 | if (UxxxStatus) | 2544 | if (UxxxStatus) |
2328 | return UxxxStatus; | 2545 | return UxxxStatus; |
2329 | UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); | 2546 | latence_timer &= 0xFFFF00FF; |
2547 | latence_timer |= 0x00001600; | ||
2548 | UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0x00, | ||
2549 | latence_timer); | ||
2330 | if (UxxxStatus) | 2550 | if (UxxxStatus) |
2331 | return UxxxStatus; | 2551 | return UxxxStatus; |
2332 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x800); | 2552 | UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, |
2553 | &pcidata); | ||
2333 | if (UxxxStatus) | 2554 | if (UxxxStatus) |
2334 | return UxxxStatus; | 2555 | return UxxxStatus; |
2335 | UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); | 2556 | reg = 4; |
2557 | UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0x00, | ||
2558 | 0x06); | ||
2336 | if (UxxxStatus) | 2559 | if (UxxxStatus) |
2337 | return UxxxStatus; | 2560 | return UxxxStatus; |
2338 | UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); | 2561 | UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, |
2562 | &pcidata); | ||
2339 | if (UxxxStatus) | 2563 | if (UxxxStatus) |
2340 | return UxxxStatus; | 2564 | return UxxxStatus; |
2341 | msleep(1000); | 2565 | for (reg = 0; reg <= 0x54; reg += 4) { |
2342 | for (fn = 0; (fn < 4) && (!foundOHCI); fn++) { | 2566 | UxxxStatus = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); |
2343 | activePCIfn = fn << 8; | ||
2344 | ftdi->function = fn + 1; | ||
2345 | UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, | ||
2346 | &pcidata); | ||
2347 | if (UxxxStatus) | 2567 | if (UxxxStatus) |
2348 | return UxxxStatus; | 2568 | return UxxxStatus; |
2349 | pciVID = pcidata & 0xFFFF; | ||
2350 | pciPID = (pcidata >> 16) & 0xFFFF; | ||
2351 | if ((pciVID == 0x1045) && (pciPID == 0xc861)) { | ||
2352 | foundOHCI = 1; | ||
2353 | } else if ((pciVID == 0x1033) && (pciPID == 0x0035)) { | ||
2354 | foundOHCI = 1; | ||
2355 | } else if ((pciVID == 0x10b9) && (pciPID == 0x5237)) { | ||
2356 | foundOHCI = 1; | ||
2357 | } else if ((pciVID == 0x11c1) && (pciPID == 0x5802)) { | ||
2358 | foundOHCI = 1; | ||
2359 | } else if ((pciVID == 0x11AB) && (pciPID == 0x1FA6)) { | ||
2360 | } | ||
2361 | } | ||
2362 | if (foundOHCI == 0) { | ||
2363 | return -ENXIO; | ||
2364 | } | 2569 | } |
2365 | ftdi->platform_data.vendor = pciVID; | 2570 | return 0; |
2366 | ftdi->platform_data.device = pciPID; | 2571 | } |
2572 | |||
2573 | static int ftdi_elan_close_controller(struct usb_ftdi *ftdi, int fn) | ||
2574 | { | ||
2575 | u32 latence_timer; | ||
2576 | int UxxxStatus; | ||
2577 | u32 pcidata; | ||
2578 | int reg = 0; | ||
2579 | int activePCIfn = fn << 8; | ||
2367 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x2800); | 2580 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x2800); |
2368 | if (UxxxStatus) | 2581 | if (UxxxStatus) |
2369 | return UxxxStatus; | 2582 | return UxxxStatus; |
@@ -2377,7 +2590,7 @@ static int ftdi_elan_enumeratePCI(struct usb_ftdi *ftdi) | |||
2377 | if (UxxxStatus) | 2590 | if (UxxxStatus) |
2378 | return UxxxStatus; | 2591 | return UxxxStatus; |
2379 | UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0, | 2592 | UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0, |
2380 | 0xF0000000); | 2593 | 0x00000000); |
2381 | if (UxxxStatus) | 2594 | if (UxxxStatus) |
2382 | return UxxxStatus; | 2595 | return UxxxStatus; |
2383 | UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, | 2596 | UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, |
@@ -2401,7 +2614,7 @@ static int ftdi_elan_enumeratePCI(struct usb_ftdi *ftdi) | |||
2401 | return UxxxStatus; | 2614 | return UxxxStatus; |
2402 | reg = 4; | 2615 | reg = 4; |
2403 | UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0x00, | 2616 | UxxxStatus = ftdi_elan_write_config(ftdi, activePCIfn | reg, 0x00, |
2404 | 0x06); | 2617 | 0x00); |
2405 | if (UxxxStatus) | 2618 | if (UxxxStatus) |
2406 | return UxxxStatus; | 2619 | return UxxxStatus; |
2407 | UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, | 2620 | UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, |
@@ -2411,159 +2624,139 @@ static int ftdi_elan_enumeratePCI(struct usb_ftdi *ftdi) | |||
2411 | return 0; | 2624 | return 0; |
2412 | } | 2625 | } |
2413 | 2626 | ||
2627 | static int ftdi_elan_found_controller(struct usb_ftdi *ftdi, int fn, int quirk) | ||
2628 | { | ||
2629 | int result; | ||
2630 | int UxxxStatus; | ||
2631 | UxxxStatus = ftdi_elan_setup_controller(ftdi, fn); | ||
2632 | if (UxxxStatus) | ||
2633 | return UxxxStatus; | ||
2634 | result = ftdi_elan_check_controller(ftdi, quirk); | ||
2635 | UxxxStatus = ftdi_elan_close_controller(ftdi, fn); | ||
2636 | if (UxxxStatus) | ||
2637 | return UxxxStatus; | ||
2638 | return result; | ||
2639 | } | ||
2640 | |||
2641 | static int ftdi_elan_enumeratePCI(struct usb_ftdi *ftdi) | ||
2642 | { | ||
2643 | u32 controlreg; | ||
2644 | u8 sensebits; | ||
2645 | int UxxxStatus; | ||
2646 | UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); | ||
2647 | if (UxxxStatus) | ||
2648 | return UxxxStatus; | ||
2649 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000000L); | ||
2650 | if (UxxxStatus) | ||
2651 | return UxxxStatus; | ||
2652 | msleep(750); | ||
2653 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000200L | 0x100); | ||
2654 | if (UxxxStatus) | ||
2655 | return UxxxStatus; | ||
2656 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x00000200L | 0x500); | ||
2657 | if (UxxxStatus) | ||
2658 | return UxxxStatus; | ||
2659 | UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); | ||
2660 | if (UxxxStatus) | ||
2661 | return UxxxStatus; | ||
2662 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020CL | 0x000); | ||
2663 | if (UxxxStatus) | ||
2664 | return UxxxStatus; | ||
2665 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020DL | 0x000); | ||
2666 | if (UxxxStatus) | ||
2667 | return UxxxStatus; | ||
2668 | msleep(250); | ||
2669 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000020FL | 0x000); | ||
2670 | if (UxxxStatus) | ||
2671 | return UxxxStatus; | ||
2672 | UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); | ||
2673 | if (UxxxStatus) | ||
2674 | return UxxxStatus; | ||
2675 | UxxxStatus = ftdi_elan_write_reg(ftdi, 0x0000025FL | 0x800); | ||
2676 | if (UxxxStatus) | ||
2677 | return UxxxStatus; | ||
2678 | UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); | ||
2679 | if (UxxxStatus) | ||
2680 | return UxxxStatus; | ||
2681 | UxxxStatus = ftdi_elan_read_reg(ftdi, &controlreg); | ||
2682 | if (UxxxStatus) | ||
2683 | return UxxxStatus; | ||
2684 | msleep(1000); | ||
2685 | sensebits = (controlreg >> 16) & 0x000F; | ||
2686 | if (0x0D == sensebits) | ||
2687 | return 0; | ||
2688 | else | ||
2689 | return - ENXIO; | ||
2690 | } | ||
2691 | |||
2414 | static int ftdi_elan_setupOHCI(struct usb_ftdi *ftdi) | 2692 | static int ftdi_elan_setupOHCI(struct usb_ftdi *ftdi) |
2415 | { | 2693 | { |
2694 | int UxxxStatus; | ||
2416 | u32 pcidata; | 2695 | u32 pcidata; |
2417 | int U132Status; | 2696 | int reg = 0; |
2418 | int reg; | 2697 | u8 fn; |
2419 | int reset_repeat = 0; | 2698 | int activePCIfn = 0; |
2420 | do_reset:reg = 8; | 2699 | int max_devices = 0; |
2421 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x0e, 0x01); | 2700 | int controllers = 0; |
2422 | if (U132Status) | 2701 | int unrecognized = 0; |
2423 | return U132Status; | 2702 | ftdi->function = 0; |
2424 | reset_check:{ | 2703 | for (fn = 0; (fn < 4); fn++) { |
2425 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | 2704 | u32 pciVID = 0; |
2426 | if (U132Status) | 2705 | u32 pciPID = 0; |
2427 | return U132Status; | 2706 | int devices = 0; |
2428 | if (pcidata & 1) { | 2707 | activePCIfn = fn << 8; |
2429 | msleep(500); | 2708 | UxxxStatus = ftdi_elan_read_config(ftdi, activePCIfn | reg, 0, |
2430 | if (reset_repeat++ > 100) { | 2709 | &pcidata); |
2431 | reset_repeat = 0; | 2710 | if (UxxxStatus) |
2432 | goto do_reset; | 2711 | return UxxxStatus; |
2433 | } else | 2712 | pciVID = pcidata & 0xFFFF; |
2434 | goto reset_check; | 2713 | pciPID = (pcidata >> 16) & 0xFFFF; |
2714 | if ((pciVID == PCI_VENDOR_ID_OPTI) && (pciPID == 0xc861)) { | ||
2715 | devices = ftdi_elan_found_controller(ftdi, fn, 0); | ||
2716 | controllers += 1; | ||
2717 | } else if ((pciVID == PCI_VENDOR_ID_NEC) && (pciPID == 0x0035)) | ||
2718 | { | ||
2719 | devices = ftdi_elan_found_controller(ftdi, fn, 0); | ||
2720 | controllers += 1; | ||
2721 | } else if ((pciVID == PCI_VENDOR_ID_AL) && (pciPID == 0x5237)) { | ||
2722 | devices = ftdi_elan_found_controller(ftdi, fn, 0); | ||
2723 | controllers += 1; | ||
2724 | } else if ((pciVID == PCI_VENDOR_ID_ATT) && (pciPID == 0x5802)) | ||
2725 | { | ||
2726 | devices = ftdi_elan_found_controller(ftdi, fn, 0); | ||
2727 | controllers += 1; | ||
2728 | } else if (pciVID == PCI_VENDOR_ID_AMD && pciPID == 0x740c) { | ||
2729 | devices = ftdi_elan_found_controller(ftdi, fn, | ||
2730 | OHCI_QUIRK_AMD756); | ||
2731 | controllers += 1; | ||
2732 | } else if (pciVID == PCI_VENDOR_ID_COMPAQ && pciPID == 0xa0f8) { | ||
2733 | devices = ftdi_elan_found_controller(ftdi, fn, | ||
2734 | OHCI_QUIRK_ZFMICRO); | ||
2735 | controllers += 1; | ||
2736 | } else if (0 == pcidata) { | ||
2737 | } else | ||
2738 | unrecognized += 1; | ||
2739 | if (devices > max_devices) { | ||
2740 | max_devices = devices; | ||
2741 | ftdi->function = fn + 1; | ||
2742 | ftdi->platform_data.vendor = pciVID; | ||
2743 | ftdi->platform_data.device = pciPID; | ||
2435 | } | 2744 | } |
2436 | } | 2745 | } |
2437 | goto dump_regs; | 2746 | if (ftdi->function > 0) { |
2438 | msleep(500); | 2747 | UxxxStatus = ftdi_elan_setup_controller(ftdi, |
2439 | reg = 0x28; | 2748 | ftdi->function - 1); |
2440 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x11000000); | 2749 | if (UxxxStatus) |
2441 | if (U132Status) | 2750 | return UxxxStatus; |
2442 | return U132Status; | 2751 | return 0; |
2443 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | 2752 | } else if (controllers > 0) { |
2444 | if (U132Status) | 2753 | return -ENXIO; |
2445 | return U132Status; | 2754 | } else if (unrecognized > 0) { |
2446 | reg = 0x40; | 2755 | return -ENXIO; |
2447 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x2edf); | 2756 | } else { |
2448 | if (U132Status) | 2757 | ftdi->enumerated = 0; |
2449 | return U132Status; | 2758 | return -ENXIO; |
2450 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2451 | if (U132Status) | ||
2452 | return U132Status; | ||
2453 | reg = 0x34; | ||
2454 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x2edf2edf); | ||
2455 | if (U132Status) | ||
2456 | return U132Status; | ||
2457 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2458 | if (U132Status) | ||
2459 | return U132Status; | ||
2460 | reg = 4; | ||
2461 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0xA0); | ||
2462 | if (U132Status) | ||
2463 | return U132Status; | ||
2464 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2465 | if (U132Status) | ||
2466 | return U132Status; | ||
2467 | msleep(250); | ||
2468 | reg = 8; | ||
2469 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x0e, 0x04); | ||
2470 | if (U132Status) | ||
2471 | return U132Status; | ||
2472 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2473 | if (U132Status) | ||
2474 | return U132Status; | ||
2475 | reg = 0x28; | ||
2476 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2477 | if (U132Status) | ||
2478 | return U132Status; | ||
2479 | reg = 8; | ||
2480 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2481 | if (U132Status) | ||
2482 | return U132Status; | ||
2483 | reg = 0x48; | ||
2484 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x00001200); | ||
2485 | if (U132Status) | ||
2486 | return U132Status; | ||
2487 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2488 | if (U132Status) | ||
2489 | return U132Status; | ||
2490 | reg = 0x54; | ||
2491 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2492 | if (U132Status) | ||
2493 | return U132Status; | ||
2494 | reg = 0x58; | ||
2495 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2496 | if (U132Status) | ||
2497 | return U132Status; | ||
2498 | reg = 0x34; | ||
2499 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x28002edf); | ||
2500 | if (U132Status) | ||
2501 | return U132Status; | ||
2502 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2503 | if (U132Status) | ||
2504 | return U132Status; | ||
2505 | msleep(100); | ||
2506 | reg = 0x50; | ||
2507 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x10000); | ||
2508 | if (U132Status) | ||
2509 | return U132Status; | ||
2510 | reg = 0x54; | ||
2511 | power_check:U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2512 | if (U132Status) | ||
2513 | return U132Status; | ||
2514 | if (!(pcidata & 1)) { | ||
2515 | msleep(500); | ||
2516 | goto power_check; | ||
2517 | } | ||
2518 | msleep(3000); | ||
2519 | reg = 0x54; | ||
2520 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2521 | if (U132Status) | ||
2522 | return U132Status; | ||
2523 | reg = 0x58; | ||
2524 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2525 | if (U132Status) | ||
2526 | return U132Status; | ||
2527 | reg = 0x54; | ||
2528 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x02); | ||
2529 | if (U132Status) | ||
2530 | return U132Status; | ||
2531 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2532 | if (U132Status) | ||
2533 | return U132Status; | ||
2534 | reg = 0x54; | ||
2535 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x10); | ||
2536 | if (U132Status) | ||
2537 | return U132Status; | ||
2538 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2539 | if (U132Status) | ||
2540 | return U132Status; | ||
2541 | msleep(750); | ||
2542 | reg = 0x54; | ||
2543 | if (0) { | ||
2544 | U132Status = ftdi_elan_write_pcimem(ftdi, reg, 0x00, 0x02); | ||
2545 | if (U132Status) | ||
2546 | return U132Status; | ||
2547 | } | ||
2548 | if (0) { | ||
2549 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2550 | if (U132Status) | ||
2551 | return U132Status; | ||
2552 | } | ||
2553 | reg = 0x54; | ||
2554 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2555 | if (U132Status) | ||
2556 | return U132Status; | ||
2557 | reg = 0x58; | ||
2558 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2559 | if (U132Status) | ||
2560 | return U132Status; | ||
2561 | dump_regs:for (reg = 0; reg <= 0x54; reg += 4) { | ||
2562 | U132Status = ftdi_elan_read_pcimem(ftdi, reg, 0, &pcidata); | ||
2563 | if (U132Status) | ||
2564 | return U132Status; | ||
2565 | } | 2759 | } |
2566 | return 0; | ||
2567 | } | 2760 | } |
2568 | 2761 | ||
2569 | 2762 | ||
@@ -2688,6 +2881,7 @@ static void ftdi_elan_disconnect(struct usb_interface *interface) | |||
2688 | platform_device_unregister(&ftdi->platform_dev); | 2881 | platform_device_unregister(&ftdi->platform_dev); |
2689 | ftdi->synchronized = 0; | 2882 | ftdi->synchronized = 0; |
2690 | ftdi->enumerated = 0; | 2883 | ftdi->enumerated = 0; |
2884 | ftdi->initialized = 0; | ||
2691 | ftdi->registered = 0; | 2885 | ftdi->registered = 0; |
2692 | } | 2886 | } |
2693 | flush_workqueue(status_queue); | 2887 | flush_workqueue(status_queue); |
diff --git a/drivers/usb/misc/idmouse.c b/drivers/usb/misc/idmouse.c index c9418535bef8..15c70bd048c4 100644 --- a/drivers/usb/misc/idmouse.c +++ b/drivers/usb/misc/idmouse.c | |||
@@ -269,7 +269,7 @@ static int idmouse_release(struct inode *inode, struct file *file) | |||
269 | /* prevent a race condition with open() */ | 269 | /* prevent a race condition with open() */ |
270 | mutex_lock(&disconnect_mutex); | 270 | mutex_lock(&disconnect_mutex); |
271 | 271 | ||
272 | dev = (struct usb_idmouse *) file->private_data; | 272 | dev = file->private_data; |
273 | 273 | ||
274 | if (dev == NULL) { | 274 | if (dev == NULL) { |
275 | mutex_unlock(&disconnect_mutex); | 275 | mutex_unlock(&disconnect_mutex); |
@@ -304,17 +304,15 @@ static int idmouse_release(struct inode *inode, struct file *file) | |||
304 | static ssize_t idmouse_read(struct file *file, char __user *buffer, size_t count, | 304 | static ssize_t idmouse_read(struct file *file, char __user *buffer, size_t count, |
305 | loff_t * ppos) | 305 | loff_t * ppos) |
306 | { | 306 | { |
307 | struct usb_idmouse *dev; | 307 | struct usb_idmouse *dev = file->private_data; |
308 | int result; | 308 | int result; |
309 | 309 | ||
310 | dev = (struct usb_idmouse *) file->private_data; | ||
311 | |||
312 | /* lock this object */ | 310 | /* lock this object */ |
313 | down (&dev->sem); | 311 | down(&dev->sem); |
314 | 312 | ||
315 | /* verify that the device wasn't unplugged */ | 313 | /* verify that the device wasn't unplugged */ |
316 | if (!dev->present) { | 314 | if (!dev->present) { |
317 | up (&dev->sem); | 315 | up(&dev->sem); |
318 | return -ENODEV; | 316 | return -ENODEV; |
319 | } | 317 | } |
320 | 318 | ||
diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c index 7163f05c5b27..0d9de2f73930 100644 --- a/drivers/usb/misc/phidgetservo.c +++ b/drivers/usb/misc/phidgetservo.c | |||
@@ -282,6 +282,7 @@ servo_probe(struct usb_interface *interface, const struct usb_device_id *id) | |||
282 | dev->dev = NULL; | 282 | dev->dev = NULL; |
283 | goto out; | 283 | goto out; |
284 | } | 284 | } |
285 | dev_set_drvdata(dev->dev, dev); | ||
285 | 286 | ||
286 | servo_count = dev->type & SERVO_COUNT_QUAD ? 4 : 1; | 287 | servo_count = dev->type & SERVO_COUNT_QUAD ? 4 : 1; |
287 | 288 | ||
diff --git a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c index 384fa3769805..fdf68479a166 100644 --- a/drivers/usb/misc/rio500.c +++ b/drivers/usb/misc/rio500.c | |||
@@ -69,7 +69,7 @@ struct rio_usb_data { | |||
69 | char *obuf, *ibuf; /* transfer buffers */ | 69 | char *obuf, *ibuf; /* transfer buffers */ |
70 | char bulk_in_ep, bulk_out_ep; /* Endpoint assignments */ | 70 | char bulk_in_ep, bulk_out_ep; /* Endpoint assignments */ |
71 | wait_queue_head_t wait_q; /* for timeouts */ | 71 | wait_queue_head_t wait_q; /* for timeouts */ |
72 | struct semaphore lock; /* general race avoidance */ | 72 | struct mutex lock; /* general race avoidance */ |
73 | }; | 73 | }; |
74 | 74 | ||
75 | static struct rio_usb_data rio_instance; | 75 | static struct rio_usb_data rio_instance; |
@@ -78,17 +78,17 @@ static int open_rio(struct inode *inode, struct file *file) | |||
78 | { | 78 | { |
79 | struct rio_usb_data *rio = &rio_instance; | 79 | struct rio_usb_data *rio = &rio_instance; |
80 | 80 | ||
81 | down(&(rio->lock)); | 81 | mutex_lock(&(rio->lock)); |
82 | 82 | ||
83 | if (rio->isopen || !rio->present) { | 83 | if (rio->isopen || !rio->present) { |
84 | up(&(rio->lock)); | 84 | mutex_unlock(&(rio->lock)); |
85 | return -EBUSY; | 85 | return -EBUSY; |
86 | } | 86 | } |
87 | rio->isopen = 1; | 87 | rio->isopen = 1; |
88 | 88 | ||
89 | init_waitqueue_head(&rio->wait_q); | 89 | init_waitqueue_head(&rio->wait_q); |
90 | 90 | ||
91 | up(&(rio->lock)); | 91 | mutex_unlock(&(rio->lock)); |
92 | 92 | ||
93 | info("Rio opened."); | 93 | info("Rio opened."); |
94 | 94 | ||
@@ -117,7 +117,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd, | |||
117 | int retries; | 117 | int retries; |
118 | int retval=0; | 118 | int retval=0; |
119 | 119 | ||
120 | down(&(rio->lock)); | 120 | mutex_lock(&(rio->lock)); |
121 | /* Sanity check to make sure rio is connected, powered, etc */ | 121 | /* Sanity check to make sure rio is connected, powered, etc */ |
122 | if ( rio == NULL || | 122 | if ( rio == NULL || |
123 | rio->present == 0 || | 123 | rio->present == 0 || |
@@ -257,7 +257,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd, | |||
257 | 257 | ||
258 | 258 | ||
259 | err_out: | 259 | err_out: |
260 | up(&(rio->lock)); | 260 | mutex_unlock(&(rio->lock)); |
261 | return retval; | 261 | return retval; |
262 | } | 262 | } |
263 | 263 | ||
@@ -275,14 +275,17 @@ write_rio(struct file *file, const char __user *buffer, | |||
275 | int result = 0; | 275 | int result = 0; |
276 | int maxretry; | 276 | int maxretry; |
277 | int errn = 0; | 277 | int errn = 0; |
278 | int intr; | ||
278 | 279 | ||
279 | down(&(rio->lock)); | 280 | intr = mutex_lock_interruptible(&(rio->lock)); |
281 | if (intr) | ||
282 | return -EINTR; | ||
280 | /* Sanity check to make sure rio is connected, powered, etc */ | 283 | /* Sanity check to make sure rio is connected, powered, etc */ |
281 | if ( rio == NULL || | 284 | if ( rio == NULL || |
282 | rio->present == 0 || | 285 | rio->present == 0 || |
283 | rio->rio_dev == NULL ) | 286 | rio->rio_dev == NULL ) |
284 | { | 287 | { |
285 | up(&(rio->lock)); | 288 | mutex_unlock(&(rio->lock)); |
286 | return -ENODEV; | 289 | return -ENODEV; |
287 | } | 290 | } |
288 | 291 | ||
@@ -305,7 +308,7 @@ write_rio(struct file *file, const char __user *buffer, | |||
305 | goto error; | 308 | goto error; |
306 | } | 309 | } |
307 | if (signal_pending(current)) { | 310 | if (signal_pending(current)) { |
308 | up(&(rio->lock)); | 311 | mutex_unlock(&(rio->lock)); |
309 | return bytes_written ? bytes_written : -EINTR; | 312 | return bytes_written ? bytes_written : -EINTR; |
310 | } | 313 | } |
311 | 314 | ||
@@ -341,12 +344,12 @@ write_rio(struct file *file, const char __user *buffer, | |||
341 | buffer += copy_size; | 344 | buffer += copy_size; |
342 | } while (count > 0); | 345 | } while (count > 0); |
343 | 346 | ||
344 | up(&(rio->lock)); | 347 | mutex_unlock(&(rio->lock)); |
345 | 348 | ||
346 | return bytes_written ? bytes_written : -EIO; | 349 | return bytes_written ? bytes_written : -EIO; |
347 | 350 | ||
348 | error: | 351 | error: |
349 | up(&(rio->lock)); | 352 | mutex_unlock(&(rio->lock)); |
350 | return errn; | 353 | return errn; |
351 | } | 354 | } |
352 | 355 | ||
@@ -361,14 +364,17 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) | |||
361 | int result; | 364 | int result; |
362 | int maxretry = 10; | 365 | int maxretry = 10; |
363 | char *ibuf; | 366 | char *ibuf; |
367 | int intr; | ||
364 | 368 | ||
365 | down(&(rio->lock)); | 369 | intr = mutex_lock_interruptible(&(rio->lock)); |
370 | if (intr) | ||
371 | return -EINTR; | ||
366 | /* Sanity check to make sure rio is connected, powered, etc */ | 372 | /* Sanity check to make sure rio is connected, powered, etc */ |
367 | if ( rio == NULL || | 373 | if ( rio == NULL || |
368 | rio->present == 0 || | 374 | rio->present == 0 || |
369 | rio->rio_dev == NULL ) | 375 | rio->rio_dev == NULL ) |
370 | { | 376 | { |
371 | up(&(rio->lock)); | 377 | mutex_unlock(&(rio->lock)); |
372 | return -ENODEV; | 378 | return -ENODEV; |
373 | } | 379 | } |
374 | 380 | ||
@@ -379,11 +385,11 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) | |||
379 | 385 | ||
380 | while (count > 0) { | 386 | while (count > 0) { |
381 | if (signal_pending(current)) { | 387 | if (signal_pending(current)) { |
382 | up(&(rio->lock)); | 388 | mutex_unlock(&(rio->lock)); |
383 | return read_count ? read_count : -EINTR; | 389 | return read_count ? read_count : -EINTR; |
384 | } | 390 | } |
385 | if (!rio->rio_dev) { | 391 | if (!rio->rio_dev) { |
386 | up(&(rio->lock)); | 392 | mutex_unlock(&(rio->lock)); |
387 | return -ENODEV; | 393 | return -ENODEV; |
388 | } | 394 | } |
389 | this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count; | 395 | this_read = (count >= IBUF_SIZE) ? IBUF_SIZE : count; |
@@ -400,7 +406,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) | |||
400 | count = this_read = partial; | 406 | count = this_read = partial; |
401 | } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */ | 407 | } else if (result == -ETIMEDOUT || result == 15) { /* FIXME: 15 ??? */ |
402 | if (!maxretry--) { | 408 | if (!maxretry--) { |
403 | up(&(rio->lock)); | 409 | mutex_unlock(&(rio->lock)); |
404 | err("read_rio: maxretry timeout"); | 410 | err("read_rio: maxretry timeout"); |
405 | return -ETIME; | 411 | return -ETIME; |
406 | } | 412 | } |
@@ -409,18 +415,18 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) | |||
409 | finish_wait(&rio->wait_q, &wait); | 415 | finish_wait(&rio->wait_q, &wait); |
410 | continue; | 416 | continue; |
411 | } else if (result != -EREMOTEIO) { | 417 | } else if (result != -EREMOTEIO) { |
412 | up(&(rio->lock)); | 418 | mutex_unlock(&(rio->lock)); |
413 | err("Read Whoops - result:%u partial:%u this_read:%u", | 419 | err("Read Whoops - result:%u partial:%u this_read:%u", |
414 | result, partial, this_read); | 420 | result, partial, this_read); |
415 | return -EIO; | 421 | return -EIO; |
416 | } else { | 422 | } else { |
417 | up(&(rio->lock)); | 423 | mutex_unlock(&(rio->lock)); |
418 | return (0); | 424 | return (0); |
419 | } | 425 | } |
420 | 426 | ||
421 | if (this_read) { | 427 | if (this_read) { |
422 | if (copy_to_user(buffer, ibuf, this_read)) { | 428 | if (copy_to_user(buffer, ibuf, this_read)) { |
423 | up(&(rio->lock)); | 429 | mutex_unlock(&(rio->lock)); |
424 | return -EFAULT; | 430 | return -EFAULT; |
425 | } | 431 | } |
426 | count -= this_read; | 432 | count -= this_read; |
@@ -428,7 +434,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos) | |||
428 | buffer += this_read; | 434 | buffer += this_read; |
429 | } | 435 | } |
430 | } | 436 | } |
431 | up(&(rio->lock)); | 437 | mutex_unlock(&(rio->lock)); |
432 | return read_count; | 438 | return read_count; |
433 | } | 439 | } |
434 | 440 | ||
@@ -480,7 +486,7 @@ static int probe_rio(struct usb_interface *intf, | |||
480 | } | 486 | } |
481 | dbg("probe_rio: ibuf address:%p", rio->ibuf); | 487 | dbg("probe_rio: ibuf address:%p", rio->ibuf); |
482 | 488 | ||
483 | init_MUTEX(&(rio->lock)); | 489 | mutex_init(&(rio->lock)); |
484 | 490 | ||
485 | usb_set_intfdata (intf, rio); | 491 | usb_set_intfdata (intf, rio); |
486 | rio->present = 1; | 492 | rio->present = 1; |
@@ -496,12 +502,12 @@ static void disconnect_rio(struct usb_interface *intf) | |||
496 | if (rio) { | 502 | if (rio) { |
497 | usb_deregister_dev(intf, &usb_rio_class); | 503 | usb_deregister_dev(intf, &usb_rio_class); |
498 | 504 | ||
499 | down(&(rio->lock)); | 505 | mutex_lock(&(rio->lock)); |
500 | if (rio->isopen) { | 506 | if (rio->isopen) { |
501 | rio->isopen = 0; | 507 | rio->isopen = 0; |
502 | /* better let it finish - the release will do whats needed */ | 508 | /* better let it finish - the release will do whats needed */ |
503 | rio->rio_dev = NULL; | 509 | rio->rio_dev = NULL; |
504 | up(&(rio->lock)); | 510 | mutex_unlock(&(rio->lock)); |
505 | return; | 511 | return; |
506 | } | 512 | } |
507 | kfree(rio->ibuf); | 513 | kfree(rio->ibuf); |
@@ -510,7 +516,7 @@ static void disconnect_rio(struct usb_interface *intf) | |||
510 | info("USB Rio disconnected."); | 516 | info("USB Rio disconnected."); |
511 | 517 | ||
512 | rio->present = 0; | 518 | rio->present = 0; |
513 | up(&(rio->lock)); | 519 | mutex_unlock(&(rio->lock)); |
514 | } | 520 | } |
515 | } | 521 | } |
516 | 522 | ||
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index b99ca9c79821..0398908b15d4 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c | |||
@@ -3168,7 +3168,7 @@ sisusb_compat_ioctl(struct file *f, unsigned int cmd, unsigned long arg) | |||
3168 | case SISUSB_GET_CONFIG: | 3168 | case SISUSB_GET_CONFIG: |
3169 | case SISUSB_COMMAND: | 3169 | case SISUSB_COMMAND: |
3170 | lock_kernel(); | 3170 | lock_kernel(); |
3171 | retval = sisusb_ioctl(f->f_dentry->d_inode, f, cmd, arg); | 3171 | retval = sisusb_ioctl(f->f_path.dentry->d_inode, f, cmd, arg); |
3172 | unlock_kernel(); | 3172 | unlock_kernel(); |
3173 | return retval; | 3173 | return retval; |
3174 | 3174 | ||
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c index bf26c3c56990..9148694627d5 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_con.c +++ b/drivers/usb/misc/sisusbvga/sisusb_con.c | |||
@@ -403,7 +403,7 @@ sisusbcon_putc(struct vc_data *c, int ch, int y, int x) | |||
403 | 403 | ||
404 | 404 | ||
405 | sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y), | 405 | sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y), |
406 | (u32)SISUSB_HADDR(x, y), 2, &written); | 406 | (long)SISUSB_HADDR(x, y), 2, &written); |
407 | 407 | ||
408 | mutex_unlock(&sisusb->lock); | 408 | mutex_unlock(&sisusb->lock); |
409 | } | 409 | } |
@@ -438,7 +438,7 @@ sisusbcon_putcs(struct vc_data *c, const unsigned short *s, | |||
438 | } | 438 | } |
439 | 439 | ||
440 | sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y), | 440 | sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(x, y), |
441 | (u32)SISUSB_HADDR(x, y), count * 2, &written); | 441 | (long)SISUSB_HADDR(x, y), count * 2, &written); |
442 | 442 | ||
443 | mutex_unlock(&sisusb->lock); | 443 | mutex_unlock(&sisusb->lock); |
444 | } | 444 | } |
@@ -492,7 +492,7 @@ sisusbcon_clear(struct vc_data *c, int y, int x, int height, int width) | |||
492 | 492 | ||
493 | 493 | ||
494 | sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(x, y), | 494 | sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(x, y), |
495 | (u32)SISUSB_HADDR(x, y), length, &written); | 495 | (long)SISUSB_HADDR(x, y), length, &written); |
496 | 496 | ||
497 | mutex_unlock(&sisusb->lock); | 497 | mutex_unlock(&sisusb->lock); |
498 | } | 498 | } |
@@ -564,7 +564,7 @@ sisusbcon_bmove(struct vc_data *c, int sy, int sx, | |||
564 | 564 | ||
565 | 565 | ||
566 | sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(dx, dy), | 566 | sisusb_copy_memory(sisusb, (unsigned char *)SISUSB_VADDR(dx, dy), |
567 | (u32)SISUSB_HADDR(dx, dy), length, &written); | 567 | (long)SISUSB_HADDR(dx, dy), length, &written); |
568 | 568 | ||
569 | mutex_unlock(&sisusb->lock); | 569 | mutex_unlock(&sisusb->lock); |
570 | } | 570 | } |
@@ -612,7 +612,7 @@ sisusbcon_switch(struct vc_data *c) | |||
612 | length); | 612 | length); |
613 | 613 | ||
614 | sisusb_copy_memory(sisusb, (unsigned char *)c->vc_origin, | 614 | sisusb_copy_memory(sisusb, (unsigned char *)c->vc_origin, |
615 | (u32)SISUSB_HADDR(0, 0), | 615 | (long)SISUSB_HADDR(0, 0), |
616 | length, &written); | 616 | length, &written); |
617 | 617 | ||
618 | mutex_unlock(&sisusb->lock); | 618 | mutex_unlock(&sisusb->lock); |
@@ -939,7 +939,7 @@ sisusbcon_scroll_area(struct vc_data *c, struct sisusb_usb_data *sisusb, | |||
939 | } | 939 | } |
940 | 940 | ||
941 | sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(0, t), | 941 | sisusb_copy_memory(sisusb, (char *)SISUSB_VADDR(0, t), |
942 | (u32)SISUSB_HADDR(0, t), length, &written); | 942 | (long)SISUSB_HADDR(0, t), length, &written); |
943 | 943 | ||
944 | mutex_unlock(&sisusb->lock); | 944 | mutex_unlock(&sisusb->lock); |
945 | 945 | ||
diff --git a/drivers/usb/misc/trancevibrator.c b/drivers/usb/misc/trancevibrator.c index 33cd91d11eca..67e2fc20eeeb 100644 --- a/drivers/usb/misc/trancevibrator.c +++ b/drivers/usb/misc/trancevibrator.c | |||
@@ -120,8 +120,8 @@ static void tv_disconnect(struct usb_interface *interface) | |||
120 | struct trancevibrator *dev; | 120 | struct trancevibrator *dev; |
121 | 121 | ||
122 | dev = usb_get_intfdata (interface); | 122 | dev = usb_get_intfdata (interface); |
123 | usb_set_intfdata(interface, NULL); | ||
124 | device_remove_file(&interface->dev, &dev_attr_speed); | 123 | device_remove_file(&interface->dev, &dev_attr_speed); |
124 | usb_set_intfdata(interface, NULL); | ||
125 | usb_put_dev(dev->udev); | 125 | usb_put_dev(dev->udev); |
126 | kfree(dev); | 126 | kfree(dev); |
127 | } | 127 | } |
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index 7e8a0acd52ee..70250252ae2a 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c | |||
@@ -705,7 +705,7 @@ static int uss720_probe(struct usb_interface *intf, | |||
705 | /* | 705 | /* |
706 | * Allocate parport interface | 706 | * Allocate parport interface |
707 | */ | 707 | */ |
708 | if (!(priv = kcalloc(sizeof(struct parport_uss720_private), 1, GFP_KERNEL))) { | 708 | if (!(priv = kzalloc(sizeof(struct parport_uss720_private), GFP_KERNEL))) { |
709 | usb_put_dev(usbdev); | 709 | usb_put_dev(usbdev); |
710 | return -ENOMEM; | 710 | return -ENOMEM; |
711 | } | 711 | } |
diff --git a/drivers/usb/mon/Makefile b/drivers/usb/mon/Makefile index 3cf3ea3a88ed..90c59535778d 100644 --- a/drivers/usb/mon/Makefile +++ b/drivers/usb/mon/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for USB Core files and filesystem | 2 | # Makefile for USB Core files and filesystem |
3 | # | 3 | # |
4 | 4 | ||
5 | usbmon-objs := mon_main.o mon_stat.o mon_text.o mon_dma.o | 5 | usbmon-objs := mon_main.o mon_stat.o mon_text.o mon_bin.o mon_dma.o |
6 | 6 | ||
7 | # This does not use CONFIG_USB_MON because we want this to use a tristate. | 7 | # This does not use CONFIG_USB_MON because we want this to use a tristate. |
8 | obj-$(CONFIG_USB) += usbmon.o | 8 | obj-$(CONFIG_USB) += usbmon.o |
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c new file mode 100644 index 000000000000..c01dfe603672 --- /dev/null +++ b/drivers/usb/mon/mon_bin.c | |||
@@ -0,0 +1,1172 @@ | |||
1 | /* | ||
2 | * The USB Monitor, inspired by Dave Harding's USBMon. | ||
3 | * | ||
4 | * This is a binary format reader. | ||
5 | * | ||
6 | * Copyright (C) 2006 Paolo Abeni (paolo.abeni@email.it) | ||
7 | * Copyright (C) 2006 Pete Zaitcev (zaitcev@redhat.com) | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <linux/types.h> | ||
12 | #include <linux/fs.h> | ||
13 | #include <linux/cdev.h> | ||
14 | #include <linux/usb.h> | ||
15 | #include <linux/poll.h> | ||
16 | #include <linux/compat.h> | ||
17 | #include <linux/mm.h> | ||
18 | |||
19 | #include <asm/uaccess.h> | ||
20 | |||
21 | #include "usb_mon.h" | ||
22 | |||
23 | /* | ||
24 | * Defined by USB 2.0 clause 9.3, table 9.2. | ||
25 | */ | ||
26 | #define SETUP_LEN 8 | ||
27 | |||
28 | /* ioctl macros */ | ||
29 | #define MON_IOC_MAGIC 0x92 | ||
30 | |||
31 | #define MON_IOCQ_URB_LEN _IO(MON_IOC_MAGIC, 1) | ||
32 | /* #2 used to be MON_IOCX_URB, removed before it got into Linus tree */ | ||
33 | #define MON_IOCG_STATS _IOR(MON_IOC_MAGIC, 3, struct mon_bin_stats) | ||
34 | #define MON_IOCT_RING_SIZE _IO(MON_IOC_MAGIC, 4) | ||
35 | #define MON_IOCQ_RING_SIZE _IO(MON_IOC_MAGIC, 5) | ||
36 | #define MON_IOCX_GET _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get) | ||
37 | #define MON_IOCX_MFETCH _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch) | ||
38 | #define MON_IOCH_MFLUSH _IO(MON_IOC_MAGIC, 8) | ||
39 | #ifdef CONFIG_COMPAT | ||
40 | #define MON_IOCX_GET32 _IOW(MON_IOC_MAGIC, 6, struct mon_bin_get32) | ||
41 | #define MON_IOCX_MFETCH32 _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch32) | ||
42 | #endif | ||
43 | |||
44 | /* | ||
45 | * Some architectures have enormous basic pages (16KB for ia64, 64KB for ppc). | ||
46 | * But it's all right. Just use a simple way to make sure the chunk is never | ||
47 | * smaller than a page. | ||
48 | * | ||
49 | * N.B. An application does not know our chunk size. | ||
50 | * | ||
51 | * Woops, get_zeroed_page() returns a single page. I guess we're stuck with | ||
52 | * page-sized chunks for the time being. | ||
53 | */ | ||
54 | #define CHUNK_SIZE PAGE_SIZE | ||
55 | #define CHUNK_ALIGN(x) (((x)+CHUNK_SIZE-1) & ~(CHUNK_SIZE-1)) | ||
56 | |||
57 | /* | ||
58 | * The magic limit was calculated so that it allows the monitoring | ||
59 | * application to pick data once in two ticks. This way, another application, | ||
60 | * which presumably drives the bus, gets to hog CPU, yet we collect our data. | ||
61 | * If HZ is 100, a 480 mbit/s bus drives 614 KB every jiffy. USB has an | ||
62 | * enormous overhead built into the bus protocol, so we need about 1000 KB. | ||
63 | * | ||
64 | * This is still too much for most cases, where we just snoop a few | ||
65 | * descriptor fetches for enumeration. So, the default is a "reasonable" | ||
66 | * amount for systems with HZ=250 and incomplete bus saturation. | ||
67 | * | ||
68 | * XXX What about multi-megabyte URBs which take minutes to transfer? | ||
69 | */ | ||
70 | #define BUFF_MAX CHUNK_ALIGN(1200*1024) | ||
71 | #define BUFF_DFL CHUNK_ALIGN(300*1024) | ||
72 | #define BUFF_MIN CHUNK_ALIGN(8*1024) | ||
73 | |||
74 | /* | ||
75 | * The per-event API header (2 per URB). | ||
76 | * | ||
77 | * This structure is seen in userland as defined by the documentation. | ||
78 | */ | ||
79 | struct mon_bin_hdr { | ||
80 | u64 id; /* URB ID - from submission to callback */ | ||
81 | unsigned char type; /* Same as in text API; extensible. */ | ||
82 | unsigned char xfer_type; /* ISO, Intr, Control, Bulk */ | ||
83 | unsigned char epnum; /* Endpoint number and transfer direction */ | ||
84 | unsigned char devnum; /* Device address */ | ||
85 | unsigned short busnum; /* Bus number */ | ||
86 | char flag_setup; | ||
87 | char flag_data; | ||
88 | s64 ts_sec; /* gettimeofday */ | ||
89 | s32 ts_usec; /* gettimeofday */ | ||
90 | int status; | ||
91 | unsigned int len_urb; /* Length of data (submitted or actual) */ | ||
92 | unsigned int len_cap; /* Delivered length */ | ||
93 | unsigned char setup[SETUP_LEN]; /* Only for Control S-type */ | ||
94 | }; | ||
95 | |||
96 | /* per file statistic */ | ||
97 | struct mon_bin_stats { | ||
98 | u32 queued; | ||
99 | u32 dropped; | ||
100 | }; | ||
101 | |||
102 | struct mon_bin_get { | ||
103 | struct mon_bin_hdr __user *hdr; /* Only 48 bytes, not 64. */ | ||
104 | void __user *data; | ||
105 | size_t alloc; /* Length of data (can be zero) */ | ||
106 | }; | ||
107 | |||
108 | struct mon_bin_mfetch { | ||
109 | u32 __user *offvec; /* Vector of events fetched */ | ||
110 | u32 nfetch; /* Number of events to fetch (out: fetched) */ | ||
111 | u32 nflush; /* Number of events to flush */ | ||
112 | }; | ||
113 | |||
114 | #ifdef CONFIG_COMPAT | ||
115 | struct mon_bin_get32 { | ||
116 | u32 hdr32; | ||
117 | u32 data32; | ||
118 | u32 alloc32; | ||
119 | }; | ||
120 | |||
121 | struct mon_bin_mfetch32 { | ||
122 | u32 offvec32; | ||
123 | u32 nfetch32; | ||
124 | u32 nflush32; | ||
125 | }; | ||
126 | #endif | ||
127 | |||
128 | /* Having these two values same prevents wrapping of the mon_bin_hdr */ | ||
129 | #define PKT_ALIGN 64 | ||
130 | #define PKT_SIZE 64 | ||
131 | |||
132 | /* max number of USB bus supported */ | ||
133 | #define MON_BIN_MAX_MINOR 128 | ||
134 | |||
135 | /* | ||
136 | * The buffer: map of used pages. | ||
137 | */ | ||
138 | struct mon_pgmap { | ||
139 | struct page *pg; | ||
140 | unsigned char *ptr; /* XXX just use page_to_virt everywhere? */ | ||
141 | }; | ||
142 | |||
143 | /* | ||
144 | * This gets associated with an open file struct. | ||
145 | */ | ||
146 | struct mon_reader_bin { | ||
147 | /* The buffer: one per open. */ | ||
148 | spinlock_t b_lock; /* Protect b_cnt, b_in */ | ||
149 | unsigned int b_size; /* Current size of the buffer - bytes */ | ||
150 | unsigned int b_cnt; /* Bytes used */ | ||
151 | unsigned int b_in, b_out; /* Offsets into buffer - bytes */ | ||
152 | unsigned int b_read; /* Amount of read data in curr. pkt. */ | ||
153 | struct mon_pgmap *b_vec; /* The map array */ | ||
154 | wait_queue_head_t b_wait; /* Wait for data here */ | ||
155 | |||
156 | struct mutex fetch_lock; /* Protect b_read, b_out */ | ||
157 | int mmap_active; | ||
158 | |||
159 | /* A list of these is needed for "bus 0". Some time later. */ | ||
160 | struct mon_reader r; | ||
161 | |||
162 | /* Stats */ | ||
163 | unsigned int cnt_lost; | ||
164 | }; | ||
165 | |||
166 | static inline struct mon_bin_hdr *MON_OFF2HDR(const struct mon_reader_bin *rp, | ||
167 | unsigned int offset) | ||
168 | { | ||
169 | return (struct mon_bin_hdr *) | ||
170 | (rp->b_vec[offset / CHUNK_SIZE].ptr + offset % CHUNK_SIZE); | ||
171 | } | ||
172 | |||
173 | #define MON_RING_EMPTY(rp) ((rp)->b_cnt == 0) | ||
174 | |||
175 | static dev_t mon_bin_dev0; | ||
176 | static struct cdev mon_bin_cdev; | ||
177 | |||
178 | static void mon_buff_area_fill(const struct mon_reader_bin *rp, | ||
179 | unsigned int offset, unsigned int size); | ||
180 | static int mon_bin_wait_event(struct file *file, struct mon_reader_bin *rp); | ||
181 | static int mon_alloc_buff(struct mon_pgmap *map, int npages); | ||
182 | static void mon_free_buff(struct mon_pgmap *map, int npages); | ||
183 | |||
184 | /* | ||
185 | * This is a "chunked memcpy". It does not manipulate any counters. | ||
186 | * But it returns the new offset for repeated application. | ||
187 | */ | ||
188 | unsigned int mon_copy_to_buff(const struct mon_reader_bin *this, | ||
189 | unsigned int off, const unsigned char *from, unsigned int length) | ||
190 | { | ||
191 | unsigned int step_len; | ||
192 | unsigned char *buf; | ||
193 | unsigned int in_page; | ||
194 | |||
195 | while (length) { | ||
196 | /* | ||
197 | * Determine step_len. | ||
198 | */ | ||
199 | step_len = length; | ||
200 | in_page = CHUNK_SIZE - (off & (CHUNK_SIZE-1)); | ||
201 | if (in_page < step_len) | ||
202 | step_len = in_page; | ||
203 | |||
204 | /* | ||
205 | * Copy data and advance pointers. | ||
206 | */ | ||
207 | buf = this->b_vec[off / CHUNK_SIZE].ptr + off % CHUNK_SIZE; | ||
208 | memcpy(buf, from, step_len); | ||
209 | if ((off += step_len) >= this->b_size) off = 0; | ||
210 | from += step_len; | ||
211 | length -= step_len; | ||
212 | } | ||
213 | return off; | ||
214 | } | ||
215 | |||
216 | /* | ||
217 | * This is a little worse than the above because it's "chunked copy_to_user". | ||
218 | * The return value is an error code, not an offset. | ||
219 | */ | ||
220 | static int copy_from_buf(const struct mon_reader_bin *this, unsigned int off, | ||
221 | char __user *to, int length) | ||
222 | { | ||
223 | unsigned int step_len; | ||
224 | unsigned char *buf; | ||
225 | unsigned int in_page; | ||
226 | |||
227 | while (length) { | ||
228 | /* | ||
229 | * Determine step_len. | ||
230 | */ | ||
231 | step_len = length; | ||
232 | in_page = CHUNK_SIZE - (off & (CHUNK_SIZE-1)); | ||
233 | if (in_page < step_len) | ||
234 | step_len = in_page; | ||
235 | |||
236 | /* | ||
237 | * Copy data and advance pointers. | ||
238 | */ | ||
239 | buf = this->b_vec[off / CHUNK_SIZE].ptr + off % CHUNK_SIZE; | ||
240 | if (copy_to_user(to, buf, step_len)) | ||
241 | return -EINVAL; | ||
242 | if ((off += step_len) >= this->b_size) off = 0; | ||
243 | to += step_len; | ||
244 | length -= step_len; | ||
245 | } | ||
246 | return 0; | ||
247 | } | ||
248 | |||
249 | /* | ||
250 | * Allocate an (aligned) area in the buffer. | ||
251 | * This is called under b_lock. | ||
252 | * Returns ~0 on failure. | ||
253 | */ | ||
254 | static unsigned int mon_buff_area_alloc(struct mon_reader_bin *rp, | ||
255 | unsigned int size) | ||
256 | { | ||
257 | unsigned int offset; | ||
258 | |||
259 | size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1); | ||
260 | if (rp->b_cnt + size > rp->b_size) | ||
261 | return ~0; | ||
262 | offset = rp->b_in; | ||
263 | rp->b_cnt += size; | ||
264 | if ((rp->b_in += size) >= rp->b_size) | ||
265 | rp->b_in -= rp->b_size; | ||
266 | return offset; | ||
267 | } | ||
268 | |||
269 | /* | ||
270 | * This is the same thing as mon_buff_area_alloc, only it does not allow | ||
271 | * buffers to wrap. This is needed by applications which pass references | ||
272 | * into mmap-ed buffers up their stacks (libpcap can do that). | ||
273 | * | ||
274 | * Currently, we always have the header stuck with the data, although | ||
275 | * it is not strictly speaking necessary. | ||
276 | * | ||
277 | * When a buffer would wrap, we place a filler packet to mark the space. | ||
278 | */ | ||
279 | static unsigned int mon_buff_area_alloc_contiguous(struct mon_reader_bin *rp, | ||
280 | unsigned int size) | ||
281 | { | ||
282 | unsigned int offset; | ||
283 | unsigned int fill_size; | ||
284 | |||
285 | size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1); | ||
286 | if (rp->b_cnt + size > rp->b_size) | ||
287 | return ~0; | ||
288 | if (rp->b_in + size > rp->b_size) { | ||
289 | /* | ||
290 | * This would wrap. Find if we still have space after | ||
291 | * skipping to the end of the buffer. If we do, place | ||
292 | * a filler packet and allocate a new packet. | ||
293 | */ | ||
294 | fill_size = rp->b_size - rp->b_in; | ||
295 | if (rp->b_cnt + size + fill_size > rp->b_size) | ||
296 | return ~0; | ||
297 | mon_buff_area_fill(rp, rp->b_in, fill_size); | ||
298 | |||
299 | offset = 0; | ||
300 | rp->b_in = size; | ||
301 | rp->b_cnt += size + fill_size; | ||
302 | } else if (rp->b_in + size == rp->b_size) { | ||
303 | offset = rp->b_in; | ||
304 | rp->b_in = 0; | ||
305 | rp->b_cnt += size; | ||
306 | } else { | ||
307 | offset = rp->b_in; | ||
308 | rp->b_in += size; | ||
309 | rp->b_cnt += size; | ||
310 | } | ||
311 | return offset; | ||
312 | } | ||
313 | |||
314 | /* | ||
315 | * Return a few (kilo-)bytes to the head of the buffer. | ||
316 | * This is used if a DMA fetch fails. | ||
317 | */ | ||
318 | static void mon_buff_area_shrink(struct mon_reader_bin *rp, unsigned int size) | ||
319 | { | ||
320 | |||
321 | size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1); | ||
322 | rp->b_cnt -= size; | ||
323 | if (rp->b_in < size) | ||
324 | rp->b_in += rp->b_size; | ||
325 | rp->b_in -= size; | ||
326 | } | ||
327 | |||
328 | /* | ||
329 | * This has to be called under both b_lock and fetch_lock, because | ||
330 | * it accesses both b_cnt and b_out. | ||
331 | */ | ||
332 | static void mon_buff_area_free(struct mon_reader_bin *rp, unsigned int size) | ||
333 | { | ||
334 | |||
335 | size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1); | ||
336 | rp->b_cnt -= size; | ||
337 | if ((rp->b_out += size) >= rp->b_size) | ||
338 | rp->b_out -= rp->b_size; | ||
339 | } | ||
340 | |||
341 | static void mon_buff_area_fill(const struct mon_reader_bin *rp, | ||
342 | unsigned int offset, unsigned int size) | ||
343 | { | ||
344 | struct mon_bin_hdr *ep; | ||
345 | |||
346 | ep = MON_OFF2HDR(rp, offset); | ||
347 | memset(ep, 0, PKT_SIZE); | ||
348 | ep->type = '@'; | ||
349 | ep->len_cap = size - PKT_SIZE; | ||
350 | } | ||
351 | |||
352 | static inline char mon_bin_get_setup(unsigned char *setupb, | ||
353 | const struct urb *urb, char ev_type) | ||
354 | { | ||
355 | |||
356 | if (!usb_pipecontrol(urb->pipe) || ev_type != 'S') | ||
357 | return '-'; | ||
358 | |||
359 | if (urb->transfer_flags & URB_NO_SETUP_DMA_MAP) | ||
360 | return mon_dmapeek(setupb, urb->setup_dma, SETUP_LEN); | ||
361 | if (urb->setup_packet == NULL) | ||
362 | return 'Z'; | ||
363 | |||
364 | memcpy(setupb, urb->setup_packet, SETUP_LEN); | ||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | static char mon_bin_get_data(const struct mon_reader_bin *rp, | ||
369 | unsigned int offset, struct urb *urb, unsigned int length) | ||
370 | { | ||
371 | |||
372 | if (urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP) { | ||
373 | mon_dmapeek_vec(rp, offset, urb->transfer_dma, length); | ||
374 | return 0; | ||
375 | } | ||
376 | |||
377 | if (urb->transfer_buffer == NULL) | ||
378 | return 'Z'; | ||
379 | |||
380 | mon_copy_to_buff(rp, offset, urb->transfer_buffer, length); | ||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | ||
385 | char ev_type) | ||
386 | { | ||
387 | unsigned long flags; | ||
388 | struct timeval ts; | ||
389 | unsigned int urb_length; | ||
390 | unsigned int offset; | ||
391 | unsigned int length; | ||
392 | struct mon_bin_hdr *ep; | ||
393 | char data_tag = 0; | ||
394 | |||
395 | do_gettimeofday(&ts); | ||
396 | |||
397 | spin_lock_irqsave(&rp->b_lock, flags); | ||
398 | |||
399 | /* | ||
400 | * Find the maximum allowable length, then allocate space. | ||
401 | */ | ||
402 | urb_length = (ev_type == 'S') ? | ||
403 | urb->transfer_buffer_length : urb->actual_length; | ||
404 | length = urb_length; | ||
405 | |||
406 | if (length >= rp->b_size/5) | ||
407 | length = rp->b_size/5; | ||
408 | |||
409 | if (usb_pipein(urb->pipe)) { | ||
410 | if (ev_type == 'S') { | ||
411 | length = 0; | ||
412 | data_tag = '<'; | ||
413 | } | ||
414 | } else { | ||
415 | if (ev_type == 'C') { | ||
416 | length = 0; | ||
417 | data_tag = '>'; | ||
418 | } | ||
419 | } | ||
420 | |||
421 | if (rp->mmap_active) | ||
422 | offset = mon_buff_area_alloc_contiguous(rp, length + PKT_SIZE); | ||
423 | else | ||
424 | offset = mon_buff_area_alloc(rp, length + PKT_SIZE); | ||
425 | if (offset == ~0) { | ||
426 | rp->cnt_lost++; | ||
427 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
428 | return; | ||
429 | } | ||
430 | |||
431 | ep = MON_OFF2HDR(rp, offset); | ||
432 | if ((offset += PKT_SIZE) >= rp->b_size) offset = 0; | ||
433 | |||
434 | /* | ||
435 | * Fill the allocated area. | ||
436 | */ | ||
437 | memset(ep, 0, PKT_SIZE); | ||
438 | ep->type = ev_type; | ||
439 | ep->xfer_type = usb_pipetype(urb->pipe); | ||
440 | /* We use the fact that usb_pipein() returns 0x80 */ | ||
441 | ep->epnum = usb_pipeendpoint(urb->pipe) | usb_pipein(urb->pipe); | ||
442 | ep->devnum = usb_pipedevice(urb->pipe); | ||
443 | ep->busnum = rp->r.m_bus->u_bus->busnum; | ||
444 | ep->id = (unsigned long) urb; | ||
445 | ep->ts_sec = ts.tv_sec; | ||
446 | ep->ts_usec = ts.tv_usec; | ||
447 | ep->status = urb->status; | ||
448 | ep->len_urb = urb_length; | ||
449 | ep->len_cap = length; | ||
450 | |||
451 | ep->flag_setup = mon_bin_get_setup(ep->setup, urb, ev_type); | ||
452 | if (length != 0) { | ||
453 | ep->flag_data = mon_bin_get_data(rp, offset, urb, length); | ||
454 | if (ep->flag_data != 0) { /* Yes, it's 0x00, not '0' */ | ||
455 | ep->len_cap = 0; | ||
456 | mon_buff_area_shrink(rp, length); | ||
457 | } | ||
458 | } else { | ||
459 | ep->flag_data = data_tag; | ||
460 | } | ||
461 | |||
462 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
463 | |||
464 | wake_up(&rp->b_wait); | ||
465 | } | ||
466 | |||
467 | static void mon_bin_submit(void *data, struct urb *urb) | ||
468 | { | ||
469 | struct mon_reader_bin *rp = data; | ||
470 | mon_bin_event(rp, urb, 'S'); | ||
471 | } | ||
472 | |||
473 | static void mon_bin_complete(void *data, struct urb *urb) | ||
474 | { | ||
475 | struct mon_reader_bin *rp = data; | ||
476 | mon_bin_event(rp, urb, 'C'); | ||
477 | } | ||
478 | |||
479 | static void mon_bin_error(void *data, struct urb *urb, int error) | ||
480 | { | ||
481 | struct mon_reader_bin *rp = data; | ||
482 | unsigned long flags; | ||
483 | unsigned int offset; | ||
484 | struct mon_bin_hdr *ep; | ||
485 | |||
486 | spin_lock_irqsave(&rp->b_lock, flags); | ||
487 | |||
488 | offset = mon_buff_area_alloc(rp, PKT_SIZE); | ||
489 | if (offset == ~0) { | ||
490 | /* Not incrementing cnt_lost. Just because. */ | ||
491 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
492 | return; | ||
493 | } | ||
494 | |||
495 | ep = MON_OFF2HDR(rp, offset); | ||
496 | |||
497 | memset(ep, 0, PKT_SIZE); | ||
498 | ep->type = 'E'; | ||
499 | ep->xfer_type = usb_pipetype(urb->pipe); | ||
500 | /* We use the fact that usb_pipein() returns 0x80 */ | ||
501 | ep->epnum = usb_pipeendpoint(urb->pipe) | usb_pipein(urb->pipe); | ||
502 | ep->devnum = usb_pipedevice(urb->pipe); | ||
503 | ep->busnum = rp->r.m_bus->u_bus->busnum; | ||
504 | ep->id = (unsigned long) urb; | ||
505 | ep->status = error; | ||
506 | |||
507 | ep->flag_setup = '-'; | ||
508 | ep->flag_data = 'E'; | ||
509 | |||
510 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
511 | |||
512 | wake_up(&rp->b_wait); | ||
513 | } | ||
514 | |||
515 | static int mon_bin_open(struct inode *inode, struct file *file) | ||
516 | { | ||
517 | struct mon_bus *mbus; | ||
518 | struct usb_bus *ubus; | ||
519 | struct mon_reader_bin *rp; | ||
520 | size_t size; | ||
521 | int rc; | ||
522 | |||
523 | mutex_lock(&mon_lock); | ||
524 | if ((mbus = mon_bus_lookup(iminor(inode))) == NULL) { | ||
525 | mutex_unlock(&mon_lock); | ||
526 | return -ENODEV; | ||
527 | } | ||
528 | if ((ubus = mbus->u_bus) == NULL) { | ||
529 | printk(KERN_ERR TAG ": consistency error on open\n"); | ||
530 | mutex_unlock(&mon_lock); | ||
531 | return -ENODEV; | ||
532 | } | ||
533 | |||
534 | rp = kzalloc(sizeof(struct mon_reader_bin), GFP_KERNEL); | ||
535 | if (rp == NULL) { | ||
536 | rc = -ENOMEM; | ||
537 | goto err_alloc; | ||
538 | } | ||
539 | spin_lock_init(&rp->b_lock); | ||
540 | init_waitqueue_head(&rp->b_wait); | ||
541 | mutex_init(&rp->fetch_lock); | ||
542 | |||
543 | rp->b_size = BUFF_DFL; | ||
544 | |||
545 | size = sizeof(struct mon_pgmap) * (rp->b_size/CHUNK_SIZE); | ||
546 | if ((rp->b_vec = kzalloc(size, GFP_KERNEL)) == NULL) { | ||
547 | rc = -ENOMEM; | ||
548 | goto err_allocvec; | ||
549 | } | ||
550 | |||
551 | if ((rc = mon_alloc_buff(rp->b_vec, rp->b_size/CHUNK_SIZE)) < 0) | ||
552 | goto err_allocbuff; | ||
553 | |||
554 | rp->r.m_bus = mbus; | ||
555 | rp->r.r_data = rp; | ||
556 | rp->r.rnf_submit = mon_bin_submit; | ||
557 | rp->r.rnf_error = mon_bin_error; | ||
558 | rp->r.rnf_complete = mon_bin_complete; | ||
559 | |||
560 | mon_reader_add(mbus, &rp->r); | ||
561 | |||
562 | file->private_data = rp; | ||
563 | mutex_unlock(&mon_lock); | ||
564 | return 0; | ||
565 | |||
566 | err_allocbuff: | ||
567 | kfree(rp->b_vec); | ||
568 | err_allocvec: | ||
569 | kfree(rp); | ||
570 | err_alloc: | ||
571 | mutex_unlock(&mon_lock); | ||
572 | return rc; | ||
573 | } | ||
574 | |||
575 | /* | ||
576 | * Extract an event from buffer and copy it to user space. | ||
577 | * Wait if there is no event ready. | ||
578 | * Returns zero or error. | ||
579 | */ | ||
580 | static int mon_bin_get_event(struct file *file, struct mon_reader_bin *rp, | ||
581 | struct mon_bin_hdr __user *hdr, void __user *data, unsigned int nbytes) | ||
582 | { | ||
583 | unsigned long flags; | ||
584 | struct mon_bin_hdr *ep; | ||
585 | size_t step_len; | ||
586 | unsigned int offset; | ||
587 | int rc; | ||
588 | |||
589 | mutex_lock(&rp->fetch_lock); | ||
590 | |||
591 | if ((rc = mon_bin_wait_event(file, rp)) < 0) { | ||
592 | mutex_unlock(&rp->fetch_lock); | ||
593 | return rc; | ||
594 | } | ||
595 | |||
596 | ep = MON_OFF2HDR(rp, rp->b_out); | ||
597 | |||
598 | if (copy_to_user(hdr, ep, sizeof(struct mon_bin_hdr))) { | ||
599 | mutex_unlock(&rp->fetch_lock); | ||
600 | return -EFAULT; | ||
601 | } | ||
602 | |||
603 | step_len = min(ep->len_cap, nbytes); | ||
604 | if ((offset = rp->b_out + PKT_SIZE) >= rp->b_size) offset = 0; | ||
605 | |||
606 | if (copy_from_buf(rp, offset, data, step_len)) { | ||
607 | mutex_unlock(&rp->fetch_lock); | ||
608 | return -EFAULT; | ||
609 | } | ||
610 | |||
611 | spin_lock_irqsave(&rp->b_lock, flags); | ||
612 | mon_buff_area_free(rp, PKT_SIZE + ep->len_cap); | ||
613 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
614 | rp->b_read = 0; | ||
615 | |||
616 | mutex_unlock(&rp->fetch_lock); | ||
617 | return 0; | ||
618 | } | ||
619 | |||
620 | static int mon_bin_release(struct inode *inode, struct file *file) | ||
621 | { | ||
622 | struct mon_reader_bin *rp = file->private_data; | ||
623 | struct mon_bus* mbus = rp->r.m_bus; | ||
624 | |||
625 | mutex_lock(&mon_lock); | ||
626 | |||
627 | if (mbus->nreaders <= 0) { | ||
628 | printk(KERN_ERR TAG ": consistency error on close\n"); | ||
629 | mutex_unlock(&mon_lock); | ||
630 | return 0; | ||
631 | } | ||
632 | mon_reader_del(mbus, &rp->r); | ||
633 | |||
634 | mon_free_buff(rp->b_vec, rp->b_size/CHUNK_SIZE); | ||
635 | kfree(rp->b_vec); | ||
636 | kfree(rp); | ||
637 | |||
638 | mutex_unlock(&mon_lock); | ||
639 | return 0; | ||
640 | } | ||
641 | |||
642 | static ssize_t mon_bin_read(struct file *file, char __user *buf, | ||
643 | size_t nbytes, loff_t *ppos) | ||
644 | { | ||
645 | struct mon_reader_bin *rp = file->private_data; | ||
646 | unsigned long flags; | ||
647 | struct mon_bin_hdr *ep; | ||
648 | unsigned int offset; | ||
649 | size_t step_len; | ||
650 | char *ptr; | ||
651 | ssize_t done = 0; | ||
652 | int rc; | ||
653 | |||
654 | mutex_lock(&rp->fetch_lock); | ||
655 | |||
656 | if ((rc = mon_bin_wait_event(file, rp)) < 0) { | ||
657 | mutex_unlock(&rp->fetch_lock); | ||
658 | return rc; | ||
659 | } | ||
660 | |||
661 | ep = MON_OFF2HDR(rp, rp->b_out); | ||
662 | |||
663 | if (rp->b_read < sizeof(struct mon_bin_hdr)) { | ||
664 | step_len = min(nbytes, sizeof(struct mon_bin_hdr) - rp->b_read); | ||
665 | ptr = ((char *)ep) + rp->b_read; | ||
666 | if (step_len && copy_to_user(buf, ptr, step_len)) { | ||
667 | mutex_unlock(&rp->fetch_lock); | ||
668 | return -EFAULT; | ||
669 | } | ||
670 | nbytes -= step_len; | ||
671 | buf += step_len; | ||
672 | rp->b_read += step_len; | ||
673 | done += step_len; | ||
674 | } | ||
675 | |||
676 | if (rp->b_read >= sizeof(struct mon_bin_hdr)) { | ||
677 | step_len = min(nbytes, (size_t)ep->len_cap); | ||
678 | offset = rp->b_out + PKT_SIZE; | ||
679 | offset += rp->b_read - sizeof(struct mon_bin_hdr); | ||
680 | if (offset >= rp->b_size) | ||
681 | offset -= rp->b_size; | ||
682 | if (copy_from_buf(rp, offset, buf, step_len)) { | ||
683 | mutex_unlock(&rp->fetch_lock); | ||
684 | return -EFAULT; | ||
685 | } | ||
686 | nbytes -= step_len; | ||
687 | buf += step_len; | ||
688 | rp->b_read += step_len; | ||
689 | done += step_len; | ||
690 | } | ||
691 | |||
692 | /* | ||
693 | * Check if whole packet was read, and if so, jump to the next one. | ||
694 | */ | ||
695 | if (rp->b_read >= sizeof(struct mon_bin_hdr) + ep->len_cap) { | ||
696 | spin_lock_irqsave(&rp->b_lock, flags); | ||
697 | mon_buff_area_free(rp, PKT_SIZE + ep->len_cap); | ||
698 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
699 | rp->b_read = 0; | ||
700 | } | ||
701 | |||
702 | mutex_unlock(&rp->fetch_lock); | ||
703 | return done; | ||
704 | } | ||
705 | |||
706 | /* | ||
707 | * Remove at most nevents from chunked buffer. | ||
708 | * Returns the number of removed events. | ||
709 | */ | ||
710 | static int mon_bin_flush(struct mon_reader_bin *rp, unsigned nevents) | ||
711 | { | ||
712 | unsigned long flags; | ||
713 | struct mon_bin_hdr *ep; | ||
714 | int i; | ||
715 | |||
716 | mutex_lock(&rp->fetch_lock); | ||
717 | spin_lock_irqsave(&rp->b_lock, flags); | ||
718 | for (i = 0; i < nevents; ++i) { | ||
719 | if (MON_RING_EMPTY(rp)) | ||
720 | break; | ||
721 | |||
722 | ep = MON_OFF2HDR(rp, rp->b_out); | ||
723 | mon_buff_area_free(rp, PKT_SIZE + ep->len_cap); | ||
724 | } | ||
725 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
726 | rp->b_read = 0; | ||
727 | mutex_unlock(&rp->fetch_lock); | ||
728 | return i; | ||
729 | } | ||
730 | |||
731 | /* | ||
732 | * Fetch at most max event offsets into the buffer and put them into vec. | ||
733 | * The events are usually freed later with mon_bin_flush. | ||
734 | * Return the effective number of events fetched. | ||
735 | */ | ||
736 | static int mon_bin_fetch(struct file *file, struct mon_reader_bin *rp, | ||
737 | u32 __user *vec, unsigned int max) | ||
738 | { | ||
739 | unsigned int cur_out; | ||
740 | unsigned int bytes, avail; | ||
741 | unsigned int size; | ||
742 | unsigned int nevents; | ||
743 | struct mon_bin_hdr *ep; | ||
744 | unsigned long flags; | ||
745 | int rc; | ||
746 | |||
747 | mutex_lock(&rp->fetch_lock); | ||
748 | |||
749 | if ((rc = mon_bin_wait_event(file, rp)) < 0) { | ||
750 | mutex_unlock(&rp->fetch_lock); | ||
751 | return rc; | ||
752 | } | ||
753 | |||
754 | spin_lock_irqsave(&rp->b_lock, flags); | ||
755 | avail = rp->b_cnt; | ||
756 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
757 | |||
758 | cur_out = rp->b_out; | ||
759 | nevents = 0; | ||
760 | bytes = 0; | ||
761 | while (bytes < avail) { | ||
762 | if (nevents >= max) | ||
763 | break; | ||
764 | |||
765 | ep = MON_OFF2HDR(rp, cur_out); | ||
766 | if (put_user(cur_out, &vec[nevents])) { | ||
767 | mutex_unlock(&rp->fetch_lock); | ||
768 | return -EFAULT; | ||
769 | } | ||
770 | |||
771 | nevents++; | ||
772 | size = ep->len_cap + PKT_SIZE; | ||
773 | size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1); | ||
774 | if ((cur_out += size) >= rp->b_size) | ||
775 | cur_out -= rp->b_size; | ||
776 | bytes += size; | ||
777 | } | ||
778 | |||
779 | mutex_unlock(&rp->fetch_lock); | ||
780 | return nevents; | ||
781 | } | ||
782 | |||
783 | /* | ||
784 | * Count events. This is almost the same as the above mon_bin_fetch, | ||
785 | * only we do not store offsets into user vector, and we have no limit. | ||
786 | */ | ||
787 | static int mon_bin_queued(struct mon_reader_bin *rp) | ||
788 | { | ||
789 | unsigned int cur_out; | ||
790 | unsigned int bytes, avail; | ||
791 | unsigned int size; | ||
792 | unsigned int nevents; | ||
793 | struct mon_bin_hdr *ep; | ||
794 | unsigned long flags; | ||
795 | |||
796 | mutex_lock(&rp->fetch_lock); | ||
797 | |||
798 | spin_lock_irqsave(&rp->b_lock, flags); | ||
799 | avail = rp->b_cnt; | ||
800 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
801 | |||
802 | cur_out = rp->b_out; | ||
803 | nevents = 0; | ||
804 | bytes = 0; | ||
805 | while (bytes < avail) { | ||
806 | ep = MON_OFF2HDR(rp, cur_out); | ||
807 | |||
808 | nevents++; | ||
809 | size = ep->len_cap + PKT_SIZE; | ||
810 | size = (size + PKT_ALIGN-1) & ~(PKT_ALIGN-1); | ||
811 | if ((cur_out += size) >= rp->b_size) | ||
812 | cur_out -= rp->b_size; | ||
813 | bytes += size; | ||
814 | } | ||
815 | |||
816 | mutex_unlock(&rp->fetch_lock); | ||
817 | return nevents; | ||
818 | } | ||
819 | |||
820 | /* | ||
821 | */ | ||
822 | static int mon_bin_ioctl(struct inode *inode, struct file *file, | ||
823 | unsigned int cmd, unsigned long arg) | ||
824 | { | ||
825 | struct mon_reader_bin *rp = file->private_data; | ||
826 | // struct mon_bus* mbus = rp->r.m_bus; | ||
827 | int ret = 0; | ||
828 | struct mon_bin_hdr *ep; | ||
829 | unsigned long flags; | ||
830 | |||
831 | switch (cmd) { | ||
832 | |||
833 | case MON_IOCQ_URB_LEN: | ||
834 | /* | ||
835 | * N.B. This only returns the size of data, without the header. | ||
836 | */ | ||
837 | spin_lock_irqsave(&rp->b_lock, flags); | ||
838 | if (!MON_RING_EMPTY(rp)) { | ||
839 | ep = MON_OFF2HDR(rp, rp->b_out); | ||
840 | ret = ep->len_cap; | ||
841 | } | ||
842 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
843 | break; | ||
844 | |||
845 | case MON_IOCQ_RING_SIZE: | ||
846 | ret = rp->b_size; | ||
847 | break; | ||
848 | |||
849 | case MON_IOCT_RING_SIZE: | ||
850 | /* | ||
851 | * Changing the buffer size will flush it's contents; the new | ||
852 | * buffer is allocated before releasing the old one to be sure | ||
853 | * the device will stay functional also in case of memory | ||
854 | * pressure. | ||
855 | */ | ||
856 | { | ||
857 | int size; | ||
858 | struct mon_pgmap *vec; | ||
859 | |||
860 | if (arg < BUFF_MIN || arg > BUFF_MAX) | ||
861 | return -EINVAL; | ||
862 | |||
863 | size = CHUNK_ALIGN(arg); | ||
864 | if ((vec = kzalloc(sizeof(struct mon_pgmap) * (size/CHUNK_SIZE), | ||
865 | GFP_KERNEL)) == NULL) { | ||
866 | ret = -ENOMEM; | ||
867 | break; | ||
868 | } | ||
869 | |||
870 | ret = mon_alloc_buff(vec, size/CHUNK_SIZE); | ||
871 | if (ret < 0) { | ||
872 | kfree(vec); | ||
873 | break; | ||
874 | } | ||
875 | |||
876 | mutex_lock(&rp->fetch_lock); | ||
877 | spin_lock_irqsave(&rp->b_lock, flags); | ||
878 | mon_free_buff(rp->b_vec, size/CHUNK_SIZE); | ||
879 | kfree(rp->b_vec); | ||
880 | rp->b_vec = vec; | ||
881 | rp->b_size = size; | ||
882 | rp->b_read = rp->b_in = rp->b_out = rp->b_cnt = 0; | ||
883 | rp->cnt_lost = 0; | ||
884 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
885 | mutex_unlock(&rp->fetch_lock); | ||
886 | } | ||
887 | break; | ||
888 | |||
889 | case MON_IOCH_MFLUSH: | ||
890 | ret = mon_bin_flush(rp, arg); | ||
891 | break; | ||
892 | |||
893 | case MON_IOCX_GET: | ||
894 | { | ||
895 | struct mon_bin_get getb; | ||
896 | |||
897 | if (copy_from_user(&getb, (void __user *)arg, | ||
898 | sizeof(struct mon_bin_get))) | ||
899 | return -EFAULT; | ||
900 | |||
901 | if (getb.alloc > 0x10000000) /* Want to cast to u32 */ | ||
902 | return -EINVAL; | ||
903 | ret = mon_bin_get_event(file, rp, | ||
904 | getb.hdr, getb.data, (unsigned int)getb.alloc); | ||
905 | } | ||
906 | break; | ||
907 | |||
908 | #ifdef CONFIG_COMPAT | ||
909 | case MON_IOCX_GET32: { | ||
910 | struct mon_bin_get32 getb; | ||
911 | |||
912 | if (copy_from_user(&getb, (void __user *)arg, | ||
913 | sizeof(struct mon_bin_get32))) | ||
914 | return -EFAULT; | ||
915 | |||
916 | ret = mon_bin_get_event(file, rp, | ||
917 | compat_ptr(getb.hdr32), compat_ptr(getb.data32), | ||
918 | getb.alloc32); | ||
919 | } | ||
920 | break; | ||
921 | #endif | ||
922 | |||
923 | case MON_IOCX_MFETCH: | ||
924 | { | ||
925 | struct mon_bin_mfetch mfetch; | ||
926 | struct mon_bin_mfetch __user *uptr; | ||
927 | |||
928 | uptr = (struct mon_bin_mfetch __user *)arg; | ||
929 | |||
930 | if (copy_from_user(&mfetch, uptr, sizeof(mfetch))) | ||
931 | return -EFAULT; | ||
932 | |||
933 | if (mfetch.nflush) { | ||
934 | ret = mon_bin_flush(rp, mfetch.nflush); | ||
935 | if (ret < 0) | ||
936 | return ret; | ||
937 | if (put_user(ret, &uptr->nflush)) | ||
938 | return -EFAULT; | ||
939 | } | ||
940 | ret = mon_bin_fetch(file, rp, mfetch.offvec, mfetch.nfetch); | ||
941 | if (ret < 0) | ||
942 | return ret; | ||
943 | if (put_user(ret, &uptr->nfetch)) | ||
944 | return -EFAULT; | ||
945 | ret = 0; | ||
946 | } | ||
947 | break; | ||
948 | |||
949 | #ifdef CONFIG_COMPAT | ||
950 | case MON_IOCX_MFETCH32: | ||
951 | { | ||
952 | struct mon_bin_mfetch32 mfetch; | ||
953 | struct mon_bin_mfetch32 __user *uptr; | ||
954 | |||
955 | uptr = (struct mon_bin_mfetch32 __user *) compat_ptr(arg); | ||
956 | |||
957 | if (copy_from_user(&mfetch, uptr, sizeof(mfetch))) | ||
958 | return -EFAULT; | ||
959 | |||
960 | if (mfetch.nflush32) { | ||
961 | ret = mon_bin_flush(rp, mfetch.nflush32); | ||
962 | if (ret < 0) | ||
963 | return ret; | ||
964 | if (put_user(ret, &uptr->nflush32)) | ||
965 | return -EFAULT; | ||
966 | } | ||
967 | ret = mon_bin_fetch(file, rp, compat_ptr(mfetch.offvec32), | ||
968 | mfetch.nfetch32); | ||
969 | if (ret < 0) | ||
970 | return ret; | ||
971 | if (put_user(ret, &uptr->nfetch32)) | ||
972 | return -EFAULT; | ||
973 | ret = 0; | ||
974 | } | ||
975 | break; | ||
976 | #endif | ||
977 | |||
978 | case MON_IOCG_STATS: { | ||
979 | struct mon_bin_stats __user *sp; | ||
980 | unsigned int nevents; | ||
981 | unsigned int ndropped; | ||
982 | |||
983 | spin_lock_irqsave(&rp->b_lock, flags); | ||
984 | ndropped = rp->cnt_lost; | ||
985 | rp->cnt_lost = 0; | ||
986 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
987 | nevents = mon_bin_queued(rp); | ||
988 | |||
989 | sp = (struct mon_bin_stats __user *)arg; | ||
990 | if (put_user(rp->cnt_lost, &sp->dropped)) | ||
991 | return -EFAULT; | ||
992 | if (put_user(nevents, &sp->queued)) | ||
993 | return -EFAULT; | ||
994 | |||
995 | } | ||
996 | break; | ||
997 | |||
998 | default: | ||
999 | return -ENOTTY; | ||
1000 | } | ||
1001 | |||
1002 | return ret; | ||
1003 | } | ||
1004 | |||
1005 | static unsigned int | ||
1006 | mon_bin_poll(struct file *file, struct poll_table_struct *wait) | ||
1007 | { | ||
1008 | struct mon_reader_bin *rp = file->private_data; | ||
1009 | unsigned int mask = 0; | ||
1010 | unsigned long flags; | ||
1011 | |||
1012 | if (file->f_mode & FMODE_READ) | ||
1013 | poll_wait(file, &rp->b_wait, wait); | ||
1014 | |||
1015 | spin_lock_irqsave(&rp->b_lock, flags); | ||
1016 | if (!MON_RING_EMPTY(rp)) | ||
1017 | mask |= POLLIN | POLLRDNORM; /* readable */ | ||
1018 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
1019 | return mask; | ||
1020 | } | ||
1021 | |||
1022 | /* | ||
1023 | * open and close: just keep track of how many times the device is | ||
1024 | * mapped, to use the proper memory allocation function. | ||
1025 | */ | ||
1026 | static void mon_bin_vma_open(struct vm_area_struct *vma) | ||
1027 | { | ||
1028 | struct mon_reader_bin *rp = vma->vm_private_data; | ||
1029 | rp->mmap_active++; | ||
1030 | } | ||
1031 | |||
1032 | static void mon_bin_vma_close(struct vm_area_struct *vma) | ||
1033 | { | ||
1034 | struct mon_reader_bin *rp = vma->vm_private_data; | ||
1035 | rp->mmap_active--; | ||
1036 | } | ||
1037 | |||
1038 | /* | ||
1039 | * Map ring pages to user space. | ||
1040 | */ | ||
1041 | struct page *mon_bin_vma_nopage(struct vm_area_struct *vma, | ||
1042 | unsigned long address, int *type) | ||
1043 | { | ||
1044 | struct mon_reader_bin *rp = vma->vm_private_data; | ||
1045 | unsigned long offset, chunk_idx; | ||
1046 | struct page *pageptr; | ||
1047 | |||
1048 | offset = (address - vma->vm_start) + (vma->vm_pgoff << PAGE_SHIFT); | ||
1049 | if (offset >= rp->b_size) | ||
1050 | return NOPAGE_SIGBUS; | ||
1051 | chunk_idx = offset / CHUNK_SIZE; | ||
1052 | pageptr = rp->b_vec[chunk_idx].pg; | ||
1053 | get_page(pageptr); | ||
1054 | if (type) | ||
1055 | *type = VM_FAULT_MINOR; | ||
1056 | return pageptr; | ||
1057 | } | ||
1058 | |||
1059 | struct vm_operations_struct mon_bin_vm_ops = { | ||
1060 | .open = mon_bin_vma_open, | ||
1061 | .close = mon_bin_vma_close, | ||
1062 | .nopage = mon_bin_vma_nopage, | ||
1063 | }; | ||
1064 | |||
1065 | int mon_bin_mmap(struct file *filp, struct vm_area_struct *vma) | ||
1066 | { | ||
1067 | /* don't do anything here: "nopage" will set up page table entries */ | ||
1068 | vma->vm_ops = &mon_bin_vm_ops; | ||
1069 | vma->vm_flags |= VM_RESERVED; | ||
1070 | vma->vm_private_data = filp->private_data; | ||
1071 | mon_bin_vma_open(vma); | ||
1072 | return 0; | ||
1073 | } | ||
1074 | |||
1075 | struct file_operations mon_fops_binary = { | ||
1076 | .owner = THIS_MODULE, | ||
1077 | .open = mon_bin_open, | ||
1078 | .llseek = no_llseek, | ||
1079 | .read = mon_bin_read, | ||
1080 | /* .write = mon_text_write, */ | ||
1081 | .poll = mon_bin_poll, | ||
1082 | .ioctl = mon_bin_ioctl, | ||
1083 | .release = mon_bin_release, | ||
1084 | }; | ||
1085 | |||
1086 | static int mon_bin_wait_event(struct file *file, struct mon_reader_bin *rp) | ||
1087 | { | ||
1088 | DECLARE_WAITQUEUE(waita, current); | ||
1089 | unsigned long flags; | ||
1090 | |||
1091 | add_wait_queue(&rp->b_wait, &waita); | ||
1092 | set_current_state(TASK_INTERRUPTIBLE); | ||
1093 | |||
1094 | spin_lock_irqsave(&rp->b_lock, flags); | ||
1095 | while (MON_RING_EMPTY(rp)) { | ||
1096 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
1097 | |||
1098 | if (file->f_flags & O_NONBLOCK) { | ||
1099 | set_current_state(TASK_RUNNING); | ||
1100 | remove_wait_queue(&rp->b_wait, &waita); | ||
1101 | return -EWOULDBLOCK; /* Same as EAGAIN in Linux */ | ||
1102 | } | ||
1103 | schedule(); | ||
1104 | if (signal_pending(current)) { | ||
1105 | remove_wait_queue(&rp->b_wait, &waita); | ||
1106 | return -EINTR; | ||
1107 | } | ||
1108 | set_current_state(TASK_INTERRUPTIBLE); | ||
1109 | |||
1110 | spin_lock_irqsave(&rp->b_lock, flags); | ||
1111 | } | ||
1112 | spin_unlock_irqrestore(&rp->b_lock, flags); | ||
1113 | |||
1114 | set_current_state(TASK_RUNNING); | ||
1115 | remove_wait_queue(&rp->b_wait, &waita); | ||
1116 | return 0; | ||
1117 | } | ||
1118 | |||
1119 | static int mon_alloc_buff(struct mon_pgmap *map, int npages) | ||
1120 | { | ||
1121 | int n; | ||
1122 | unsigned long vaddr; | ||
1123 | |||
1124 | for (n = 0; n < npages; n++) { | ||
1125 | vaddr = get_zeroed_page(GFP_KERNEL); | ||
1126 | if (vaddr == 0) { | ||
1127 | while (n-- != 0) | ||
1128 | free_page((unsigned long) map[n].ptr); | ||
1129 | return -ENOMEM; | ||
1130 | } | ||
1131 | map[n].ptr = (unsigned char *) vaddr; | ||
1132 | map[n].pg = virt_to_page(vaddr); | ||
1133 | } | ||
1134 | return 0; | ||
1135 | } | ||
1136 | |||
1137 | static void mon_free_buff(struct mon_pgmap *map, int npages) | ||
1138 | { | ||
1139 | int n; | ||
1140 | |||
1141 | for (n = 0; n < npages; n++) | ||
1142 | free_page((unsigned long) map[n].ptr); | ||
1143 | } | ||
1144 | |||
1145 | int __init mon_bin_init(void) | ||
1146 | { | ||
1147 | int rc; | ||
1148 | |||
1149 | rc = alloc_chrdev_region(&mon_bin_dev0, 0, MON_BIN_MAX_MINOR, "usbmon"); | ||
1150 | if (rc < 0) | ||
1151 | goto err_dev; | ||
1152 | |||
1153 | cdev_init(&mon_bin_cdev, &mon_fops_binary); | ||
1154 | mon_bin_cdev.owner = THIS_MODULE; | ||
1155 | |||
1156 | rc = cdev_add(&mon_bin_cdev, mon_bin_dev0, MON_BIN_MAX_MINOR); | ||
1157 | if (rc < 0) | ||
1158 | goto err_add; | ||
1159 | |||
1160 | return 0; | ||
1161 | |||
1162 | err_add: | ||
1163 | unregister_chrdev_region(mon_bin_dev0, MON_BIN_MAX_MINOR); | ||
1164 | err_dev: | ||
1165 | return rc; | ||
1166 | } | ||
1167 | |||
1168 | void __exit mon_bin_exit(void) | ||
1169 | { | ||
1170 | cdev_del(&mon_bin_cdev); | ||
1171 | unregister_chrdev_region(mon_bin_dev0, MON_BIN_MAX_MINOR); | ||
1172 | } | ||
diff --git a/drivers/usb/mon/mon_dma.c b/drivers/usb/mon/mon_dma.c index ddcfc01e77a0..140cc80bd2b1 100644 --- a/drivers/usb/mon/mon_dma.c +++ b/drivers/usb/mon/mon_dma.c | |||
@@ -48,6 +48,36 @@ char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len) | |||
48 | local_irq_restore(flags); | 48 | local_irq_restore(flags); |
49 | return 0; | 49 | return 0; |
50 | } | 50 | } |
51 | |||
52 | void mon_dmapeek_vec(const struct mon_reader_bin *rp, | ||
53 | unsigned int offset, dma_addr_t dma_addr, unsigned int length) | ||
54 | { | ||
55 | unsigned long flags; | ||
56 | unsigned int step_len; | ||
57 | struct page *pg; | ||
58 | unsigned char *map; | ||
59 | unsigned long page_off, page_len; | ||
60 | |||
61 | local_irq_save(flags); | ||
62 | while (length) { | ||
63 | /* compute number of bytes we are going to copy in this page */ | ||
64 | step_len = length; | ||
65 | page_off = dma_addr & (PAGE_SIZE-1); | ||
66 | page_len = PAGE_SIZE - page_off; | ||
67 | if (page_len < step_len) | ||
68 | step_len = page_len; | ||
69 | |||
70 | /* copy data and advance pointers */ | ||
71 | pg = phys_to_page(dma_addr); | ||
72 | map = kmap_atomic(pg, KM_IRQ0); | ||
73 | offset = mon_copy_to_buff(rp, offset, map + page_off, step_len); | ||
74 | kunmap_atomic(map, KM_IRQ0); | ||
75 | dma_addr += step_len; | ||
76 | length -= step_len; | ||
77 | } | ||
78 | local_irq_restore(flags); | ||
79 | } | ||
80 | |||
51 | #endif /* __i386__ */ | 81 | #endif /* __i386__ */ |
52 | 82 | ||
53 | #ifndef MON_HAS_UNMAP | 83 | #ifndef MON_HAS_UNMAP |
@@ -55,4 +85,11 @@ char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len) | |||
55 | { | 85 | { |
56 | return 'D'; | 86 | return 'D'; |
57 | } | 87 | } |
58 | #endif | 88 | |
89 | void mon_dmapeek_vec(const struct mon_reader_bin *rp, | ||
90 | unsigned int offset, dma_addr_t dma_addr, unsigned int length) | ||
91 | { | ||
92 | ; | ||
93 | } | ||
94 | |||
95 | #endif /* MON_HAS_UNMAP */ | ||
diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c index 394bbf2f68d4..c9739e7b35e5 100644 --- a/drivers/usb/mon/mon_main.c +++ b/drivers/usb/mon/mon_main.c | |||
@@ -9,7 +9,6 @@ | |||
9 | #include <linux/kernel.h> | 9 | #include <linux/kernel.h> |
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/usb.h> | 11 | #include <linux/usb.h> |
12 | #include <linux/debugfs.h> | ||
13 | #include <linux/smp_lock.h> | 12 | #include <linux/smp_lock.h> |
14 | #include <linux/notifier.h> | 13 | #include <linux/notifier.h> |
15 | #include <linux/mutex.h> | 14 | #include <linux/mutex.h> |
@@ -22,11 +21,10 @@ static void mon_complete(struct usb_bus *ubus, struct urb *urb); | |||
22 | static void mon_stop(struct mon_bus *mbus); | 21 | static void mon_stop(struct mon_bus *mbus); |
23 | static void mon_dissolve(struct mon_bus *mbus, struct usb_bus *ubus); | 22 | static void mon_dissolve(struct mon_bus *mbus, struct usb_bus *ubus); |
24 | static void mon_bus_drop(struct kref *r); | 23 | static void mon_bus_drop(struct kref *r); |
25 | static void mon_bus_init(struct dentry *mondir, struct usb_bus *ubus); | 24 | static void mon_bus_init(struct usb_bus *ubus); |
26 | 25 | ||
27 | DEFINE_MUTEX(mon_lock); | 26 | DEFINE_MUTEX(mon_lock); |
28 | 27 | ||
29 | static struct dentry *mon_dir; /* /dbg/usbmon */ | ||
30 | static LIST_HEAD(mon_buses); /* All buses we know: struct mon_bus */ | 28 | static LIST_HEAD(mon_buses); /* All buses we know: struct mon_bus */ |
31 | 29 | ||
32 | /* | 30 | /* |
@@ -200,7 +198,7 @@ static void mon_stop(struct mon_bus *mbus) | |||
200 | */ | 198 | */ |
201 | static void mon_bus_add(struct usb_bus *ubus) | 199 | static void mon_bus_add(struct usb_bus *ubus) |
202 | { | 200 | { |
203 | mon_bus_init(mon_dir, ubus); | 201 | mon_bus_init(ubus); |
204 | } | 202 | } |
205 | 203 | ||
206 | /* | 204 | /* |
@@ -212,8 +210,8 @@ static void mon_bus_remove(struct usb_bus *ubus) | |||
212 | 210 | ||
213 | mutex_lock(&mon_lock); | 211 | mutex_lock(&mon_lock); |
214 | list_del(&mbus->bus_link); | 212 | list_del(&mbus->bus_link); |
215 | debugfs_remove(mbus->dent_t); | 213 | if (mbus->text_inited) |
216 | debugfs_remove(mbus->dent_s); | 214 | mon_text_del(mbus); |
217 | 215 | ||
218 | mon_dissolve(mbus, ubus); | 216 | mon_dissolve(mbus, ubus); |
219 | kref_put(&mbus->ref, mon_bus_drop); | 217 | kref_put(&mbus->ref, mon_bus_drop); |
@@ -281,13 +279,9 @@ static void mon_bus_drop(struct kref *r) | |||
281 | * - refcount USB bus struct | 279 | * - refcount USB bus struct |
282 | * - link | 280 | * - link |
283 | */ | 281 | */ |
284 | static void mon_bus_init(struct dentry *mondir, struct usb_bus *ubus) | 282 | static void mon_bus_init(struct usb_bus *ubus) |
285 | { | 283 | { |
286 | struct dentry *d; | ||
287 | struct mon_bus *mbus; | 284 | struct mon_bus *mbus; |
288 | enum { NAMESZ = 10 }; | ||
289 | char name[NAMESZ]; | ||
290 | int rc; | ||
291 | 285 | ||
292 | if ((mbus = kzalloc(sizeof(struct mon_bus), GFP_KERNEL)) == NULL) | 286 | if ((mbus = kzalloc(sizeof(struct mon_bus), GFP_KERNEL)) == NULL) |
293 | goto err_alloc; | 287 | goto err_alloc; |
@@ -303,57 +297,54 @@ static void mon_bus_init(struct dentry *mondir, struct usb_bus *ubus) | |||
303 | ubus->mon_bus = mbus; | 297 | ubus->mon_bus = mbus; |
304 | mbus->uses_dma = ubus->uses_dma; | 298 | mbus->uses_dma = ubus->uses_dma; |
305 | 299 | ||
306 | rc = snprintf(name, NAMESZ, "%dt", ubus->busnum); | 300 | mbus->text_inited = mon_text_add(mbus, ubus); |
307 | if (rc <= 0 || rc >= NAMESZ) | 301 | // mon_bin_add(...) |
308 | goto err_print_t; | ||
309 | d = debugfs_create_file(name, 0600, mondir, mbus, &mon_fops_text); | ||
310 | if (d == NULL) | ||
311 | goto err_create_t; | ||
312 | mbus->dent_t = d; | ||
313 | |||
314 | rc = snprintf(name, NAMESZ, "%ds", ubus->busnum); | ||
315 | if (rc <= 0 || rc >= NAMESZ) | ||
316 | goto err_print_s; | ||
317 | d = debugfs_create_file(name, 0600, mondir, mbus, &mon_fops_stat); | ||
318 | if (d == NULL) | ||
319 | goto err_create_s; | ||
320 | mbus->dent_s = d; | ||
321 | 302 | ||
322 | mutex_lock(&mon_lock); | 303 | mutex_lock(&mon_lock); |
323 | list_add_tail(&mbus->bus_link, &mon_buses); | 304 | list_add_tail(&mbus->bus_link, &mon_buses); |
324 | mutex_unlock(&mon_lock); | 305 | mutex_unlock(&mon_lock); |
325 | return; | 306 | return; |
326 | 307 | ||
327 | err_create_s: | ||
328 | err_print_s: | ||
329 | debugfs_remove(mbus->dent_t); | ||
330 | err_create_t: | ||
331 | err_print_t: | ||
332 | kfree(mbus); | ||
333 | err_alloc: | 308 | err_alloc: |
334 | return; | 309 | return; |
335 | } | 310 | } |
336 | 311 | ||
312 | /* | ||
313 | * Search a USB bus by number. Notice that USB bus numbers start from one, | ||
314 | * which we may later use to identify "all" with zero. | ||
315 | * | ||
316 | * This function must be called with mon_lock held. | ||
317 | * | ||
318 | * This is obviously inefficient and may be revised in the future. | ||
319 | */ | ||
320 | struct mon_bus *mon_bus_lookup(unsigned int num) | ||
321 | { | ||
322 | struct list_head *p; | ||
323 | struct mon_bus *mbus; | ||
324 | |||
325 | list_for_each (p, &mon_buses) { | ||
326 | mbus = list_entry(p, struct mon_bus, bus_link); | ||
327 | if (mbus->u_bus->busnum == num) { | ||
328 | return mbus; | ||
329 | } | ||
330 | } | ||
331 | return NULL; | ||
332 | } | ||
333 | |||
337 | static int __init mon_init(void) | 334 | static int __init mon_init(void) |
338 | { | 335 | { |
339 | struct usb_bus *ubus; | 336 | struct usb_bus *ubus; |
340 | struct dentry *mondir; | 337 | int rc; |
341 | 338 | ||
342 | mondir = debugfs_create_dir("usbmon", NULL); | 339 | if ((rc = mon_text_init()) != 0) |
343 | if (IS_ERR(mondir)) { | 340 | goto err_text; |
344 | printk(KERN_NOTICE TAG ": debugfs is not available\n"); | 341 | if ((rc = mon_bin_init()) != 0) |
345 | return -ENODEV; | 342 | goto err_bin; |
346 | } | ||
347 | if (mondir == NULL) { | ||
348 | printk(KERN_NOTICE TAG ": unable to create usbmon directory\n"); | ||
349 | return -ENODEV; | ||
350 | } | ||
351 | mon_dir = mondir; | ||
352 | 343 | ||
353 | if (usb_mon_register(&mon_ops_0) != 0) { | 344 | if (usb_mon_register(&mon_ops_0) != 0) { |
354 | printk(KERN_NOTICE TAG ": unable to register with the core\n"); | 345 | printk(KERN_NOTICE TAG ": unable to register with the core\n"); |
355 | debugfs_remove(mondir); | 346 | rc = -ENODEV; |
356 | return -ENODEV; | 347 | goto err_reg; |
357 | } | 348 | } |
358 | // MOD_INC_USE_COUNT(which_module?); | 349 | // MOD_INC_USE_COUNT(which_module?); |
359 | 350 | ||
@@ -361,10 +352,17 @@ static int __init mon_init(void) | |||
361 | 352 | ||
362 | mutex_lock(&usb_bus_list_lock); | 353 | mutex_lock(&usb_bus_list_lock); |
363 | list_for_each_entry (ubus, &usb_bus_list, bus_list) { | 354 | list_for_each_entry (ubus, &usb_bus_list, bus_list) { |
364 | mon_bus_init(mondir, ubus); | 355 | mon_bus_init(ubus); |
365 | } | 356 | } |
366 | mutex_unlock(&usb_bus_list_lock); | 357 | mutex_unlock(&usb_bus_list_lock); |
367 | return 0; | 358 | return 0; |
359 | |||
360 | err_reg: | ||
361 | mon_bin_exit(); | ||
362 | err_bin: | ||
363 | mon_text_exit(); | ||
364 | err_text: | ||
365 | return rc; | ||
368 | } | 366 | } |
369 | 367 | ||
370 | static void __exit mon_exit(void) | 368 | static void __exit mon_exit(void) |
@@ -381,8 +379,8 @@ static void __exit mon_exit(void) | |||
381 | mbus = list_entry(p, struct mon_bus, bus_link); | 379 | mbus = list_entry(p, struct mon_bus, bus_link); |
382 | list_del(p); | 380 | list_del(p); |
383 | 381 | ||
384 | debugfs_remove(mbus->dent_t); | 382 | if (mbus->text_inited) |
385 | debugfs_remove(mbus->dent_s); | 383 | mon_text_del(mbus); |
386 | 384 | ||
387 | /* | 385 | /* |
388 | * This never happens, because the open/close paths in | 386 | * This never happens, because the open/close paths in |
@@ -401,7 +399,8 @@ static void __exit mon_exit(void) | |||
401 | } | 399 | } |
402 | mutex_unlock(&mon_lock); | 400 | mutex_unlock(&mon_lock); |
403 | 401 | ||
404 | debugfs_remove(mon_dir); | 402 | mon_text_exit(); |
403 | mon_bin_exit(); | ||
405 | } | 404 | } |
406 | 405 | ||
407 | module_init(mon_init); | 406 | module_init(mon_init); |
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index 05cf2c9a8f84..d38a1279d9d9 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/usb.h> | 9 | #include <linux/usb.h> |
10 | #include <linux/time.h> | 10 | #include <linux/time.h> |
11 | #include <linux/mutex.h> | 11 | #include <linux/mutex.h> |
12 | #include <linux/debugfs.h> | ||
12 | #include <asm/uaccess.h> | 13 | #include <asm/uaccess.h> |
13 | 14 | ||
14 | #include "usb_mon.h" | 15 | #include "usb_mon.h" |
@@ -63,6 +64,8 @@ struct mon_reader_text { | |||
63 | char slab_name[SLAB_NAME_SZ]; | 64 | char slab_name[SLAB_NAME_SZ]; |
64 | }; | 65 | }; |
65 | 66 | ||
67 | static struct dentry *mon_dir; /* Usually /sys/kernel/debug/usbmon */ | ||
68 | |||
66 | static void mon_text_ctor(void *, struct kmem_cache *, unsigned long); | 69 | static void mon_text_ctor(void *, struct kmem_cache *, unsigned long); |
67 | 70 | ||
68 | /* | 71 | /* |
@@ -436,7 +439,7 @@ static int mon_text_release(struct inode *inode, struct file *file) | |||
436 | return 0; | 439 | return 0; |
437 | } | 440 | } |
438 | 441 | ||
439 | const struct file_operations mon_fops_text = { | 442 | static const struct file_operations mon_fops_text = { |
440 | .owner = THIS_MODULE, | 443 | .owner = THIS_MODULE, |
441 | .open = mon_text_open, | 444 | .open = mon_text_open, |
442 | .llseek = no_llseek, | 445 | .llseek = no_llseek, |
@@ -447,6 +450,47 @@ const struct file_operations mon_fops_text = { | |||
447 | .release = mon_text_release, | 450 | .release = mon_text_release, |
448 | }; | 451 | }; |
449 | 452 | ||
453 | int mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus) | ||
454 | { | ||
455 | struct dentry *d; | ||
456 | enum { NAMESZ = 10 }; | ||
457 | char name[NAMESZ]; | ||
458 | int rc; | ||
459 | |||
460 | rc = snprintf(name, NAMESZ, "%dt", ubus->busnum); | ||
461 | if (rc <= 0 || rc >= NAMESZ) | ||
462 | goto err_print_t; | ||
463 | d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_text); | ||
464 | if (d == NULL) | ||
465 | goto err_create_t; | ||
466 | mbus->dent_t = d; | ||
467 | |||
468 | /* XXX The stats do not belong to here (text API), but oh well... */ | ||
469 | rc = snprintf(name, NAMESZ, "%ds", ubus->busnum); | ||
470 | if (rc <= 0 || rc >= NAMESZ) | ||
471 | goto err_print_s; | ||
472 | d = debugfs_create_file(name, 0600, mon_dir, mbus, &mon_fops_stat); | ||
473 | if (d == NULL) | ||
474 | goto err_create_s; | ||
475 | mbus->dent_s = d; | ||
476 | |||
477 | return 1; | ||
478 | |||
479 | err_create_s: | ||
480 | err_print_s: | ||
481 | debugfs_remove(mbus->dent_t); | ||
482 | mbus->dent_t = NULL; | ||
483 | err_create_t: | ||
484 | err_print_t: | ||
485 | return 0; | ||
486 | } | ||
487 | |||
488 | void mon_text_del(struct mon_bus *mbus) | ||
489 | { | ||
490 | debugfs_remove(mbus->dent_t); | ||
491 | debugfs_remove(mbus->dent_s); | ||
492 | } | ||
493 | |||
450 | /* | 494 | /* |
451 | * Slab interface: constructor. | 495 | * Slab interface: constructor. |
452 | */ | 496 | */ |
@@ -459,3 +503,24 @@ static void mon_text_ctor(void *mem, struct kmem_cache *slab, unsigned long sfla | |||
459 | memset(mem, 0xe5, sizeof(struct mon_event_text)); | 503 | memset(mem, 0xe5, sizeof(struct mon_event_text)); |
460 | } | 504 | } |
461 | 505 | ||
506 | int __init mon_text_init(void) | ||
507 | { | ||
508 | struct dentry *mondir; | ||
509 | |||
510 | mondir = debugfs_create_dir("usbmon", NULL); | ||
511 | if (IS_ERR(mondir)) { | ||
512 | printk(KERN_NOTICE TAG ": debugfs is not available\n"); | ||
513 | return -ENODEV; | ||
514 | } | ||
515 | if (mondir == NULL) { | ||
516 | printk(KERN_NOTICE TAG ": unable to create usbmon directory\n"); | ||
517 | return -ENODEV; | ||
518 | } | ||
519 | mon_dir = mondir; | ||
520 | return 0; | ||
521 | } | ||
522 | |||
523 | void __exit mon_text_exit(void) | ||
524 | { | ||
525 | debugfs_remove(mon_dir); | ||
526 | } | ||
diff --git a/drivers/usb/mon/usb_mon.h b/drivers/usb/mon/usb_mon.h index ab9d02d5df77..4f949ce8a7f3 100644 --- a/drivers/usb/mon/usb_mon.h +++ b/drivers/usb/mon/usb_mon.h | |||
@@ -17,9 +17,11 @@ | |||
17 | struct mon_bus { | 17 | struct mon_bus { |
18 | struct list_head bus_link; | 18 | struct list_head bus_link; |
19 | spinlock_t lock; | 19 | spinlock_t lock; |
20 | struct usb_bus *u_bus; | ||
21 | |||
22 | int text_inited; | ||
20 | struct dentry *dent_s; /* Debugging file */ | 23 | struct dentry *dent_s; /* Debugging file */ |
21 | struct dentry *dent_t; /* Text interface file */ | 24 | struct dentry *dent_t; /* Text interface file */ |
22 | struct usb_bus *u_bus; | ||
23 | int uses_dma; | 25 | int uses_dma; |
24 | 26 | ||
25 | /* Ref */ | 27 | /* Ref */ |
@@ -48,13 +50,35 @@ struct mon_reader { | |||
48 | void mon_reader_add(struct mon_bus *mbus, struct mon_reader *r); | 50 | void mon_reader_add(struct mon_bus *mbus, struct mon_reader *r); |
49 | void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r); | 51 | void mon_reader_del(struct mon_bus *mbus, struct mon_reader *r); |
50 | 52 | ||
53 | struct mon_bus *mon_bus_lookup(unsigned int num); | ||
54 | |||
55 | int /*bool*/ mon_text_add(struct mon_bus *mbus, const struct usb_bus *ubus); | ||
56 | void mon_text_del(struct mon_bus *mbus); | ||
57 | // void mon_bin_add(struct mon_bus *); | ||
58 | |||
59 | int __init mon_text_init(void); | ||
60 | void __exit mon_text_exit(void); | ||
61 | int __init mon_bin_init(void); | ||
62 | void __exit mon_bin_exit(void); | ||
63 | |||
51 | /* | 64 | /* |
52 | */ | 65 | * DMA interface. |
66 | * | ||
67 | * XXX The vectored side needs a serious re-thinking. Abstracting vectors, | ||
68 | * like in Paolo's original patch, produces a double pkmap. We need an idea. | ||
69 | */ | ||
53 | extern char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len); | 70 | extern char mon_dmapeek(unsigned char *dst, dma_addr_t dma_addr, int len); |
54 | 71 | ||
72 | struct mon_reader_bin; | ||
73 | extern void mon_dmapeek_vec(const struct mon_reader_bin *rp, | ||
74 | unsigned int offset, dma_addr_t dma_addr, unsigned int len); | ||
75 | extern unsigned int mon_copy_to_buff(const struct mon_reader_bin *rp, | ||
76 | unsigned int offset, const unsigned char *from, unsigned int len); | ||
77 | |||
78 | /* | ||
79 | */ | ||
55 | extern struct mutex mon_lock; | 80 | extern struct mutex mon_lock; |
56 | 81 | ||
57 | extern const struct file_operations mon_fops_text; | ||
58 | extern const struct file_operations mon_fops_stat; | 82 | extern const struct file_operations mon_fops_stat; |
59 | 83 | ||
60 | #endif /* __USB_MON_H */ | 84 | #endif /* __USB_MON_H */ |
diff --git a/drivers/usb/net/Kconfig b/drivers/usb/net/Kconfig index e081836014ac..a2b94ef512bc 100644 --- a/drivers/usb/net/Kconfig +++ b/drivers/usb/net/Kconfig | |||
@@ -222,13 +222,15 @@ config USB_NET_MCS7830 | |||
222 | adapters marketed under the DeLOCK brand. | 222 | adapters marketed under the DeLOCK brand. |
223 | 223 | ||
224 | config USB_NET_RNDIS_HOST | 224 | config USB_NET_RNDIS_HOST |
225 | tristate "Host for RNDIS devices (EXPERIMENTAL)" | 225 | tristate "Host for RNDIS and ActiveSync devices (EXPERIMENTAL)" |
226 | depends on USB_USBNET && EXPERIMENTAL | 226 | depends on USB_USBNET && EXPERIMENTAL |
227 | select USB_NET_CDCETHER | 227 | select USB_NET_CDCETHER |
228 | help | 228 | help |
229 | This option enables hosting "Remote NDIS" USB networking links, | 229 | This option enables hosting "Remote NDIS" USB networking links, |
230 | as encouraged by Microsoft (instead of CDC Ethernet!) for use in | 230 | as encouraged by Microsoft (instead of CDC Ethernet!) for use in |
231 | various devices that may only support this protocol. | 231 | various devices that may only support this protocol. A variant |
232 | of this protocol (with even less public documentation) seems to | ||
233 | be at the root of Microsoft's "ActiveSync" too. | ||
232 | 234 | ||
233 | Avoid using this protocol unless you have no better options. | 235 | Avoid using this protocol unless you have no better options. |
234 | The protocol specification is incomplete, and is controlled by | 236 | The protocol specification is incomplete, and is controlled by |
diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c index 95e682e2c9d6..4206df2d61b7 100644 --- a/drivers/usb/net/asix.c +++ b/drivers/usb/net/asix.c | |||
@@ -898,7 +898,7 @@ static int ax88772_link_reset(struct usbnet *dev) | |||
898 | 898 | ||
899 | static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) | 899 | static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) |
900 | { | 900 | { |
901 | int ret; | 901 | int ret, embd_phy; |
902 | void *buf; | 902 | void *buf; |
903 | u16 rx_ctl; | 903 | u16 rx_ctl; |
904 | struct asix_data *data = (struct asix_data *)&dev->data; | 904 | struct asix_data *data = (struct asix_data *)&dev->data; |
@@ -919,13 +919,15 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) | |||
919 | AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5)) < 0) | 919 | AX_GPIO_RSE | AX_GPIO_GPO_2 | AX_GPIO_GPO2EN, 5)) < 0) |
920 | goto out2; | 920 | goto out2; |
921 | 921 | ||
922 | /* 0x10 is the phy id of the embedded 10/100 ethernet phy */ | ||
923 | embd_phy = ((asix_get_phy_addr(dev) & 0x1f) == 0x10 ? 1 : 0); | ||
922 | if ((ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, | 924 | if ((ret = asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, |
923 | 0x0000, 0, 0, buf)) < 0) { | 925 | embd_phy, 0, 0, buf)) < 0) { |
924 | dbg("Select PHY #1 failed: %d", ret); | 926 | dbg("Select PHY #1 failed: %d", ret); |
925 | goto out2; | 927 | goto out2; |
926 | } | 928 | } |
927 | 929 | ||
928 | if ((ret = asix_sw_reset(dev, AX_SWRESET_IPPD)) < 0) | 930 | if ((ret = asix_sw_reset(dev, AX_SWRESET_IPPD | AX_SWRESET_PRL)) < 0) |
929 | goto out2; | 931 | goto out2; |
930 | 932 | ||
931 | msleep(150); | 933 | msleep(150); |
@@ -933,8 +935,14 @@ static int ax88772_bind(struct usbnet *dev, struct usb_interface *intf) | |||
933 | goto out2; | 935 | goto out2; |
934 | 936 | ||
935 | msleep(150); | 937 | msleep(150); |
936 | if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL | AX_SWRESET_PRL)) < 0) | 938 | if (embd_phy) { |
937 | goto out2; | 939 | if ((ret = asix_sw_reset(dev, AX_SWRESET_IPRL)) < 0) |
940 | goto out2; | ||
941 | } | ||
942 | else { | ||
943 | if ((ret = asix_sw_reset(dev, AX_SWRESET_PRTE)) < 0) | ||
944 | goto out2; | ||
945 | } | ||
938 | 946 | ||
939 | msleep(150); | 947 | msleep(150); |
940 | rx_ctl = asix_read_rx_ctl(dev); | 948 | rx_ctl = asix_read_rx_ctl(dev); |
@@ -1441,6 +1449,10 @@ static const struct usb_device_id products [] = { | |||
1441 | // Linksys USB1000 | 1449 | // Linksys USB1000 |
1442 | USB_DEVICE (0x1737, 0x0039), | 1450 | USB_DEVICE (0x1737, 0x0039), |
1443 | .driver_info = (unsigned long) &ax88178_info, | 1451 | .driver_info = (unsigned long) &ax88178_info, |
1452 | }, { | ||
1453 | // IO-DATA ETG-US2 | ||
1454 | USB_DEVICE (0x04bb, 0x0930), | ||
1455 | .driver_info = (unsigned long) &ax88178_info, | ||
1444 | }, | 1456 | }, |
1445 | { }, // END | 1457 | { }, // END |
1446 | }; | 1458 | }; |
diff --git a/drivers/usb/net/cdc_ether.c b/drivers/usb/net/cdc_ether.c index 44a91547146e..e5cdafa258dd 100644 --- a/drivers/usb/net/cdc_ether.c +++ b/drivers/usb/net/cdc_ether.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * CDC Ethernet based networking peripherals | 2 | * CDC Ethernet based networking peripherals |
3 | * Copyright (C) 2003-2005 by David Brownell | 3 | * Copyright (C) 2003-2005 by David Brownell |
4 | * Copyright (C) 2006 by Ole Andre Vadla Ravnas (ActiveSync) | ||
4 | * | 5 | * |
5 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
@@ -35,6 +36,29 @@ | |||
35 | #include "usbnet.h" | 36 | #include "usbnet.h" |
36 | 37 | ||
37 | 38 | ||
39 | #if defined(CONFIG_USB_NET_RNDIS_HOST) || defined(CONFIG_USB_NET_RNDIS_HOST_MODULE) | ||
40 | |||
41 | static int is_rndis(struct usb_interface_descriptor *desc) | ||
42 | { | ||
43 | return desc->bInterfaceClass == USB_CLASS_COMM | ||
44 | && desc->bInterfaceSubClass == 2 | ||
45 | && desc->bInterfaceProtocol == 0xff; | ||
46 | } | ||
47 | |||
48 | static int is_activesync(struct usb_interface_descriptor *desc) | ||
49 | { | ||
50 | return desc->bInterfaceClass == USB_CLASS_MISC | ||
51 | && desc->bInterfaceSubClass == 1 | ||
52 | && desc->bInterfaceProtocol == 1; | ||
53 | } | ||
54 | |||
55 | #else | ||
56 | |||
57 | #define is_rndis(desc) 0 | ||
58 | #define is_activesync(desc) 0 | ||
59 | |||
60 | #endif | ||
61 | |||
38 | /* | 62 | /* |
39 | * probes control interface, claims data interface, collects the bulk | 63 | * probes control interface, claims data interface, collects the bulk |
40 | * endpoints, activates data interface (if needed), maybe sets MTU. | 64 | * endpoints, activates data interface (if needed), maybe sets MTU. |
@@ -71,7 +95,8 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) | |||
71 | /* this assumes that if there's a non-RNDIS vendor variant | 95 | /* this assumes that if there's a non-RNDIS vendor variant |
72 | * of cdc-acm, it'll fail RNDIS requests cleanly. | 96 | * of cdc-acm, it'll fail RNDIS requests cleanly. |
73 | */ | 97 | */ |
74 | rndis = (intf->cur_altsetting->desc.bInterfaceProtocol == 0xff); | 98 | rndis = is_rndis(&intf->cur_altsetting->desc) |
99 | || is_activesync(&intf->cur_altsetting->desc); | ||
75 | 100 | ||
76 | memset(info, 0, sizeof *info); | 101 | memset(info, 0, sizeof *info); |
77 | info->control = intf; | 102 | info->control = intf; |
@@ -99,6 +124,23 @@ int usbnet_generic_cdc_bind(struct usbnet *dev, struct usb_interface *intf) | |||
99 | goto bad_desc; | 124 | goto bad_desc; |
100 | } | 125 | } |
101 | break; | 126 | break; |
127 | case USB_CDC_ACM_TYPE: | ||
128 | /* paranoia: disambiguate a "real" vendor-specific | ||
129 | * modem interface from an RNDIS non-modem. | ||
130 | */ | ||
131 | if (rndis) { | ||
132 | struct usb_cdc_acm_descriptor *d; | ||
133 | |||
134 | d = (void *) buf; | ||
135 | if (d->bmCapabilities) { | ||
136 | dev_dbg(&intf->dev, | ||
137 | "ACM capabilities %02x, " | ||
138 | "not really RNDIS?\n", | ||
139 | d->bmCapabilities); | ||
140 | goto bad_desc; | ||
141 | } | ||
142 | } | ||
143 | break; | ||
102 | case USB_CDC_UNION_TYPE: | 144 | case USB_CDC_UNION_TYPE: |
103 | if (info->u) { | 145 | if (info->u) { |
104 | dev_dbg(&intf->dev, "extra CDC union\n"); | 146 | dev_dbg(&intf->dev, "extra CDC union\n"); |
@@ -171,7 +213,21 @@ next_desc: | |||
171 | buf += buf [0]; | 213 | buf += buf [0]; |
172 | } | 214 | } |
173 | 215 | ||
174 | if (!info->header || !info->u || (!rndis && !info->ether)) { | 216 | /* Microsoft ActiveSync based RNDIS devices lack the CDC descriptors, |
217 | * so we'll hard-wire the interfaces and not check for descriptors. | ||
218 | */ | ||
219 | if (is_activesync(&intf->cur_altsetting->desc) && !info->u) { | ||
220 | info->control = usb_ifnum_to_if(dev->udev, 0); | ||
221 | info->data = usb_ifnum_to_if(dev->udev, 1); | ||
222 | if (!info->control || !info->data) { | ||
223 | dev_dbg(&intf->dev, | ||
224 | "activesync: master #0/%p slave #1/%p\n", | ||
225 | info->control, | ||
226 | info->data); | ||
227 | goto bad_desc; | ||
228 | } | ||
229 | |||
230 | } else if (!info->header || !info->u || (!rndis && !info->ether)) { | ||
175 | dev_dbg(&intf->dev, "missing cdc %s%s%sdescriptor\n", | 231 | dev_dbg(&intf->dev, "missing cdc %s%s%sdescriptor\n", |
176 | info->header ? "" : "header ", | 232 | info->header ? "" : "header ", |
177 | info->u ? "" : "union ", | 233 | info->u ? "" : "union ", |
diff --git a/drivers/usb/net/gl620a.c b/drivers/usb/net/gl620a.c index a3242be21959..31e5fe363fdc 100644 --- a/drivers/usb/net/gl620a.c +++ b/drivers/usb/net/gl620a.c | |||
@@ -70,184 +70,29 @@ | |||
70 | (((GL_MAX_PACKET_LEN + 4) * GL_MAX_TRANSMIT_PACKETS) + 4) | 70 | (((GL_MAX_PACKET_LEN + 4) * GL_MAX_TRANSMIT_PACKETS) + 4) |
71 | 71 | ||
72 | struct gl_packet { | 72 | struct gl_packet { |
73 | u32 packet_length; | 73 | __le32 packet_length; |
74 | char packet_data [1]; | 74 | char packet_data [1]; |
75 | }; | 75 | }; |
76 | 76 | ||
77 | struct gl_header { | 77 | struct gl_header { |
78 | u32 packet_count; | 78 | __le32 packet_count; |
79 | struct gl_packet packets; | 79 | struct gl_packet packets; |
80 | }; | 80 | }; |
81 | 81 | ||
82 | #ifdef GENELINK_ACK | ||
83 | |||
84 | // FIXME: this code is incomplete, not debugged; it doesn't | ||
85 | // handle interrupts correctly; it should use the generic | ||
86 | // status IRQ code (which didn't exist back in 2001). | ||
87 | |||
88 | struct gl_priv { | ||
89 | struct urb *irq_urb; | ||
90 | char irq_buf [INTERRUPT_BUFSIZE]; | ||
91 | }; | ||
92 | |||
93 | static inline int gl_control_write(struct usbnet *dev, u8 request, u16 value) | ||
94 | { | ||
95 | int retval; | ||
96 | |||
97 | retval = usb_control_msg(dev->udev, | ||
98 | usb_sndctrlpipe(dev->udev, 0), | ||
99 | request, | ||
100 | USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | ||
101 | value, | ||
102 | 0, // index | ||
103 | 0, // data buffer | ||
104 | 0, // size | ||
105 | USB_CTRL_SET_TIMEOUT); | ||
106 | return retval; | ||
107 | } | ||
108 | |||
109 | static void gl_interrupt_complete(struct urb *urb) | ||
110 | { | ||
111 | int status = urb->status; | ||
112 | |||
113 | switch (status) { | ||
114 | case 0: | ||
115 | /* success */ | ||
116 | break; | ||
117 | case -ECONNRESET: | ||
118 | case -ENOENT: | ||
119 | case -ESHUTDOWN: | ||
120 | /* this urb is terminated, clean up */ | ||
121 | dbg("%s - urb shutting down with status: %d", | ||
122 | __FUNCTION__, status); | ||
123 | return; | ||
124 | default: | ||
125 | dbg("%s - nonzero urb status received: %d", | ||
126 | __FUNCTION__, urb->status); | ||
127 | } | ||
128 | |||
129 | status = usb_submit_urb(urb, GFP_ATOMIC); | ||
130 | if (status) | ||
131 | err("%s - usb_submit_urb failed with result %d", | ||
132 | __FUNCTION__, status); | ||
133 | } | ||
134 | |||
135 | static int gl_interrupt_read(struct usbnet *dev) | ||
136 | { | ||
137 | struct gl_priv *priv = dev->priv_data; | ||
138 | int retval; | ||
139 | |||
140 | // issue usb interrupt read | ||
141 | if (priv && priv->irq_urb) { | ||
142 | // submit urb | ||
143 | if ((retval = usb_submit_urb(priv->irq_urb, GFP_KERNEL)) != 0) | ||
144 | dbg("gl_interrupt_read: submit fail - %X...", retval); | ||
145 | else | ||
146 | dbg("gl_interrupt_read: submit success..."); | ||
147 | } | ||
148 | |||
149 | return 0; | ||
150 | } | ||
151 | |||
152 | // check whether another side is connected | ||
153 | static int genelink_check_connect(struct usbnet *dev) | ||
154 | { | ||
155 | int retval; | ||
156 | |||
157 | dbg("genelink_check_connect..."); | ||
158 | |||
159 | // detect whether another side is connected | ||
160 | if ((retval = gl_control_write(dev, GENELINK_CONNECT_WRITE, 0)) != 0) { | ||
161 | dbg("%s: genelink_check_connect write fail - %X", | ||
162 | dev->net->name, retval); | ||
163 | return retval; | ||
164 | } | ||
165 | |||
166 | // usb interrupt read to ack another side | ||
167 | if ((retval = gl_interrupt_read(dev)) != 0) { | ||
168 | dbg("%s: genelink_check_connect read fail - %X", | ||
169 | dev->net->name, retval); | ||
170 | return retval; | ||
171 | } | ||
172 | |||
173 | dbg("%s: genelink_check_connect read success", dev->net->name); | ||
174 | return 0; | ||
175 | } | ||
176 | |||
177 | // allocate and initialize the private data for genelink | ||
178 | static int genelink_init(struct usbnet *dev) | ||
179 | { | ||
180 | struct gl_priv *priv; | ||
181 | |||
182 | // allocate the private data structure | ||
183 | if ((priv = kmalloc(sizeof *priv, GFP_KERNEL)) == 0) { | ||
184 | dbg("%s: cannot allocate private data per device", | ||
185 | dev->net->name); | ||
186 | return -ENOMEM; | ||
187 | } | ||
188 | |||
189 | // allocate irq urb | ||
190 | if ((priv->irq_urb = usb_alloc_urb(0, GFP_KERNEL)) == 0) { | ||
191 | dbg("%s: cannot allocate private irq urb per device", | ||
192 | dev->net->name); | ||
193 | kfree(priv); | ||
194 | return -ENOMEM; | ||
195 | } | ||
196 | |||
197 | // fill irq urb | ||
198 | usb_fill_int_urb(priv->irq_urb, dev->udev, | ||
199 | usb_rcvintpipe(dev->udev, GENELINK_INTERRUPT_PIPE), | ||
200 | priv->irq_buf, INTERRUPT_BUFSIZE, | ||
201 | gl_interrupt_complete, 0, | ||
202 | GENELINK_INTERRUPT_INTERVAL); | ||
203 | |||
204 | // set private data pointer | ||
205 | dev->priv_data = priv; | ||
206 | |||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | // release the private data | ||
211 | static int genelink_free(struct usbnet *dev) | ||
212 | { | ||
213 | struct gl_priv *priv = dev->priv_data; | ||
214 | |||
215 | if (!priv) | ||
216 | return 0; | ||
217 | |||
218 | // FIXME: can't cancel here; it's synchronous, and | ||
219 | // should have happened earlier in any case (interrupt | ||
220 | // handling needs to be generic) | ||
221 | |||
222 | // cancel irq urb first | ||
223 | usb_kill_urb(priv->irq_urb); | ||
224 | |||
225 | // free irq urb | ||
226 | usb_free_urb(priv->irq_urb); | ||
227 | |||
228 | // free the private data structure | ||
229 | kfree(priv); | ||
230 | |||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | #endif | ||
235 | |||
236 | static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | 82 | static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb) |
237 | { | 83 | { |
238 | struct gl_header *header; | 84 | struct gl_header *header; |
239 | struct gl_packet *packet; | 85 | struct gl_packet *packet; |
240 | struct sk_buff *gl_skb; | 86 | struct sk_buff *gl_skb; |
241 | u32 size; | 87 | u32 size; |
88 | u32 count; | ||
242 | 89 | ||
243 | header = (struct gl_header *) skb->data; | 90 | header = (struct gl_header *) skb->data; |
244 | 91 | ||
245 | // get the packet count of the received skb | 92 | // get the packet count of the received skb |
246 | le32_to_cpus(&header->packet_count); | 93 | count = le32_to_cpu(header->packet_count); |
247 | if ((header->packet_count > GL_MAX_TRANSMIT_PACKETS) | 94 | if (count > GL_MAX_TRANSMIT_PACKETS) { |
248 | || (header->packet_count < 0)) { | 95 | dbg("genelink: invalid received packet count %u", count); |
249 | dbg("genelink: invalid received packet count %d", | ||
250 | header->packet_count); | ||
251 | return 0; | 96 | return 0; |
252 | } | 97 | } |
253 | 98 | ||
@@ -257,7 +102,7 @@ static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
257 | // decrement the length for the packet count size 4 bytes | 102 | // decrement the length for the packet count size 4 bytes |
258 | skb_pull(skb, 4); | 103 | skb_pull(skb, 4); |
259 | 104 | ||
260 | while (header->packet_count > 1) { | 105 | while (count > 1) { |
261 | // get the packet length | 106 | // get the packet length |
262 | size = le32_to_cpu(packet->packet_length); | 107 | size = le32_to_cpu(packet->packet_length); |
263 | 108 | ||
@@ -278,9 +123,8 @@ static int genelink_rx_fixup(struct usbnet *dev, struct sk_buff *skb) | |||
278 | } | 123 | } |
279 | 124 | ||
280 | // advance to the next packet | 125 | // advance to the next packet |
281 | packet = (struct gl_packet *) | 126 | packet = (struct gl_packet *)&packet->packet_data[size]; |
282 | &packet->packet_data [size]; | 127 | count--; |
283 | header->packet_count--; | ||
284 | 128 | ||
285 | // shift the data pointer to the next gl_packet | 129 | // shift the data pointer to the next gl_packet |
286 | skb_pull(skb, size + 4); | 130 | skb_pull(skb, size + 4); |
@@ -303,8 +147,8 @@ genelink_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) | |||
303 | int length = skb->len; | 147 | int length = skb->len; |
304 | int headroom = skb_headroom(skb); | 148 | int headroom = skb_headroom(skb); |
305 | int tailroom = skb_tailroom(skb); | 149 | int tailroom = skb_tailroom(skb); |
306 | u32 *packet_count; | 150 | __le32 *packet_count; |
307 | u32 *packet_len; | 151 | __le32 *packet_len; |
308 | 152 | ||
309 | // FIXME: magic numbers, bleech | 153 | // FIXME: magic numbers, bleech |
310 | padlen = ((skb->len + (4 + 4*1)) % 64) ? 0 : 1; | 154 | padlen = ((skb->len + (4 + 4*1)) % 64) ? 0 : 1; |
@@ -326,7 +170,7 @@ genelink_tx_fixup(struct usbnet *dev, struct sk_buff *skb, gfp_t flags) | |||
326 | } | 170 | } |
327 | 171 | ||
328 | // attach the packet count to the header | 172 | // attach the packet count to the header |
329 | packet_count = (u32 *) skb_push(skb, (4 + 4*1)); | 173 | packet_count = (__le32 *) skb_push(skb, (4 + 4*1)); |
330 | packet_len = packet_count + 1; | 174 | packet_len = packet_count + 1; |
331 | 175 | ||
332 | *packet_count = cpu_to_le32(1); | 176 | *packet_count = cpu_to_le32(1); |
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c index fa78326d0bf0..36a989160a68 100644 --- a/drivers/usb/net/kaweth.c +++ b/drivers/usb/net/kaweth.c | |||
@@ -179,6 +179,7 @@ static struct usb_driver kaweth_driver = { | |||
179 | .suspend = kaweth_suspend, | 179 | .suspend = kaweth_suspend, |
180 | .resume = kaweth_resume, | 180 | .resume = kaweth_resume, |
181 | .id_table = usb_klsi_table, | 181 | .id_table = usb_klsi_table, |
182 | .supports_autosuspend = 1, | ||
182 | }; | 183 | }; |
183 | 184 | ||
184 | typedef __u8 eth_addr_t[6]; | 185 | typedef __u8 eth_addr_t[6]; |
@@ -225,6 +226,7 @@ struct kaweth_device | |||
225 | struct delayed_work lowmem_work; | 226 | struct delayed_work lowmem_work; |
226 | 227 | ||
227 | struct usb_device *dev; | 228 | struct usb_device *dev; |
229 | struct usb_interface *intf; | ||
228 | struct net_device *net; | 230 | struct net_device *net; |
229 | wait_queue_head_t term_wait; | 231 | wait_queue_head_t term_wait; |
230 | 232 | ||
@@ -662,9 +664,14 @@ static int kaweth_open(struct net_device *net) | |||
662 | 664 | ||
663 | dbg("Opening network device."); | 665 | dbg("Opening network device."); |
664 | 666 | ||
667 | res = usb_autopm_get_interface(kaweth->intf); | ||
668 | if (res) { | ||
669 | err("Interface cannot be resumed."); | ||
670 | return -EIO; | ||
671 | } | ||
665 | res = kaweth_resubmit_rx_urb(kaweth, GFP_KERNEL); | 672 | res = kaweth_resubmit_rx_urb(kaweth, GFP_KERNEL); |
666 | if (res) | 673 | if (res) |
667 | return -EIO; | 674 | goto err_out; |
668 | 675 | ||
669 | usb_fill_int_urb( | 676 | usb_fill_int_urb( |
670 | kaweth->irq_urb, | 677 | kaweth->irq_urb, |
@@ -681,7 +688,7 @@ static int kaweth_open(struct net_device *net) | |||
681 | res = usb_submit_urb(kaweth->irq_urb, GFP_KERNEL); | 688 | res = usb_submit_urb(kaweth->irq_urb, GFP_KERNEL); |
682 | if (res) { | 689 | if (res) { |
683 | usb_kill_urb(kaweth->rx_urb); | 690 | usb_kill_urb(kaweth->rx_urb); |
684 | return -EIO; | 691 | goto err_out; |
685 | } | 692 | } |
686 | kaweth->opened = 1; | 693 | kaweth->opened = 1; |
687 | 694 | ||
@@ -689,10 +696,14 @@ static int kaweth_open(struct net_device *net) | |||
689 | 696 | ||
690 | kaweth_async_set_rx_mode(kaweth); | 697 | kaweth_async_set_rx_mode(kaweth); |
691 | return 0; | 698 | return 0; |
699 | |||
700 | err_out: | ||
701 | usb_autopm_enable(kaweth->intf); | ||
702 | return -EIO; | ||
692 | } | 703 | } |
693 | 704 | ||
694 | /**************************************************************** | 705 | /**************************************************************** |
695 | * kaweth_close | 706 | * kaweth_kill_urbs |
696 | ****************************************************************/ | 707 | ****************************************************************/ |
697 | static void kaweth_kill_urbs(struct kaweth_device *kaweth) | 708 | static void kaweth_kill_urbs(struct kaweth_device *kaweth) |
698 | { | 709 | { |
@@ -724,17 +735,29 @@ static int kaweth_close(struct net_device *net) | |||
724 | 735 | ||
725 | kaweth->status &= ~KAWETH_STATUS_CLOSING; | 736 | kaweth->status &= ~KAWETH_STATUS_CLOSING; |
726 | 737 | ||
738 | usb_autopm_enable(kaweth->intf); | ||
739 | |||
727 | return 0; | 740 | return 0; |
728 | } | 741 | } |
729 | 742 | ||
730 | static void kaweth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) | 743 | static void kaweth_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) |
731 | { | 744 | { |
745 | struct kaweth_device *kaweth = netdev_priv(dev); | ||
732 | 746 | ||
733 | strlcpy(info->driver, driver_name, sizeof(info->driver)); | 747 | strlcpy(info->driver, driver_name, sizeof(info->driver)); |
748 | usb_make_path(kaweth->dev, info->bus_info, sizeof (info->bus_info)); | ||
749 | } | ||
750 | |||
751 | static u32 kaweth_get_link(struct net_device *dev) | ||
752 | { | ||
753 | struct kaweth_device *kaweth = netdev_priv(dev); | ||
754 | |||
755 | return kaweth->linkstate; | ||
734 | } | 756 | } |
735 | 757 | ||
736 | static struct ethtool_ops ops = { | 758 | static struct ethtool_ops ops = { |
737 | .get_drvinfo = kaweth_get_drvinfo | 759 | .get_drvinfo = kaweth_get_drvinfo, |
760 | .get_link = kaweth_get_link | ||
738 | }; | 761 | }; |
739 | 762 | ||
740 | /**************************************************************** | 763 | /**************************************************************** |
@@ -908,6 +931,7 @@ static int kaweth_suspend(struct usb_interface *intf, pm_message_t message) | |||
908 | struct kaweth_device *kaweth = usb_get_intfdata(intf); | 931 | struct kaweth_device *kaweth = usb_get_intfdata(intf); |
909 | unsigned long flags; | 932 | unsigned long flags; |
910 | 933 | ||
934 | dbg("Suspending device"); | ||
911 | spin_lock_irqsave(&kaweth->device_lock, flags); | 935 | spin_lock_irqsave(&kaweth->device_lock, flags); |
912 | kaweth->status |= KAWETH_STATUS_SUSPENDING; | 936 | kaweth->status |= KAWETH_STATUS_SUSPENDING; |
913 | spin_unlock_irqrestore(&kaweth->device_lock, flags); | 937 | spin_unlock_irqrestore(&kaweth->device_lock, flags); |
@@ -924,6 +948,7 @@ static int kaweth_resume(struct usb_interface *intf) | |||
924 | struct kaweth_device *kaweth = usb_get_intfdata(intf); | 948 | struct kaweth_device *kaweth = usb_get_intfdata(intf); |
925 | unsigned long flags; | 949 | unsigned long flags; |
926 | 950 | ||
951 | dbg("Resuming device"); | ||
927 | spin_lock_irqsave(&kaweth->device_lock, flags); | 952 | spin_lock_irqsave(&kaweth->device_lock, flags); |
928 | kaweth->status &= ~KAWETH_STATUS_SUSPENDING; | 953 | kaweth->status &= ~KAWETH_STATUS_SUSPENDING; |
929 | spin_unlock_irqrestore(&kaweth->device_lock, flags); | 954 | spin_unlock_irqrestore(&kaweth->device_lock, flags); |
@@ -1086,6 +1111,8 @@ err_fw: | |||
1086 | 1111 | ||
1087 | dbg("Initializing net device."); | 1112 | dbg("Initializing net device."); |
1088 | 1113 | ||
1114 | kaweth->intf = intf; | ||
1115 | |||
1089 | kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL); | 1116 | kaweth->tx_urb = usb_alloc_urb(0, GFP_KERNEL); |
1090 | if (!kaweth->tx_urb) | 1117 | if (!kaweth->tx_urb) |
1091 | goto err_free_netdev; | 1118 | goto err_free_netdev; |
@@ -1265,7 +1292,7 @@ static int kaweth_internal_control_msg(struct usb_device *usb_dev, | |||
1265 | { | 1292 | { |
1266 | struct urb *urb; | 1293 | struct urb *urb; |
1267 | int retv; | 1294 | int retv; |
1268 | int length; | 1295 | int length = 0; /* shut up GCC */ |
1269 | 1296 | ||
1270 | urb = usb_alloc_urb(0, GFP_NOIO); | 1297 | urb = usb_alloc_urb(0, GFP_NOIO); |
1271 | if (!urb) | 1298 | if (!urb) |
diff --git a/drivers/usb/net/pegasus.h b/drivers/usb/net/pegasus.h index 98f6898cae1f..c7467823cd1c 100644 --- a/drivers/usb/net/pegasus.h +++ b/drivers/usb/net/pegasus.h | |||
@@ -214,9 +214,9 @@ PEGASUS_DEV( "Billionton USBEL-100", VENDOR_BILLIONTON, 0x0988, | |||
214 | DEFAULT_GPIO_RESET ) | 214 | DEFAULT_GPIO_RESET ) |
215 | PEGASUS_DEV( "Billionton USBE-100", VENDOR_BILLIONTON, 0x8511, | 215 | PEGASUS_DEV( "Billionton USBE-100", VENDOR_BILLIONTON, 0x8511, |
216 | DEFAULT_GPIO_RESET | PEGASUS_II ) | 216 | DEFAULT_GPIO_RESET | PEGASUS_II ) |
217 | PEGASUS_DEV( "Corega FEter USB-TX", VENDOR_COREGA, 0x0004, | 217 | PEGASUS_DEV( "Corega FEther USB-TX", VENDOR_COREGA, 0x0004, |
218 | DEFAULT_GPIO_RESET ) | 218 | DEFAULT_GPIO_RESET ) |
219 | PEGASUS_DEV( "Corega FEter USB-TXS", VENDOR_COREGA, 0x000d, | 219 | PEGASUS_DEV( "Corega FEther USB-TXS", VENDOR_COREGA, 0x000d, |
220 | DEFAULT_GPIO_RESET | PEGASUS_II ) | 220 | DEFAULT_GPIO_RESET | PEGASUS_II ) |
221 | PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4001, | 221 | PEGASUS_DEV( "D-Link DSB-650TX", VENDOR_DLINK, 0x4001, |
222 | DEFAULT_GPIO_RESET ) | 222 | DEFAULT_GPIO_RESET ) |
diff --git a/drivers/usb/net/rndis_host.c b/drivers/usb/net/rndis_host.c index 99f26b3e502f..be888d2d813c 100644 --- a/drivers/usb/net/rndis_host.c +++ b/drivers/usb/net/rndis_host.c | |||
@@ -49,6 +49,8 @@ | |||
49 | * - In some cases, MS-Windows will emit undocumented requests; this | 49 | * - In some cases, MS-Windows will emit undocumented requests; this |
50 | * matters more to peripheral implementations than host ones. | 50 | * matters more to peripheral implementations than host ones. |
51 | * | 51 | * |
52 | * Moreover there's a no-open-specs variant of RNDIS called "ActiveSync". | ||
53 | * | ||
52 | * For these reasons and others, ** USE OF RNDIS IS STRONGLY DISCOURAGED ** in | 54 | * For these reasons and others, ** USE OF RNDIS IS STRONGLY DISCOURAGED ** in |
53 | * favor of such non-proprietary alternatives as CDC Ethernet or the newer (and | 55 | * favor of such non-proprietary alternatives as CDC Ethernet or the newer (and |
54 | * currently rare) "Ethernet Emulation Model" (EEM). | 56 | * currently rare) "Ethernet Emulation Model" (EEM). |
@@ -61,6 +63,9 @@ | |||
61 | * - control-in: GET_ENCAPSULATED | 63 | * - control-in: GET_ENCAPSULATED |
62 | * | 64 | * |
63 | * We'll try to ignore the RESPONSE_AVAILABLE notifications. | 65 | * We'll try to ignore the RESPONSE_AVAILABLE notifications. |
66 | * | ||
67 | * REVISIT some RNDIS implementations seem to have curious issues still | ||
68 | * to be resolved. | ||
64 | */ | 69 | */ |
65 | struct rndis_msg_hdr { | 70 | struct rndis_msg_hdr { |
66 | __le32 msg_type; /* RNDIS_MSG_* */ | 71 | __le32 msg_type; /* RNDIS_MSG_* */ |
@@ -71,8 +76,14 @@ struct rndis_msg_hdr { | |||
71 | // ... and more | 76 | // ... and more |
72 | } __attribute__ ((packed)); | 77 | } __attribute__ ((packed)); |
73 | 78 | ||
74 | /* RNDIS defines this (absurdly huge) control timeout */ | 79 | /* MS-Windows uses this strange size, but RNDIS spec says 1024 minimum */ |
75 | #define RNDIS_CONTROL_TIMEOUT_MS (10 * 1000) | 80 | #define CONTROL_BUFFER_SIZE 1025 |
81 | |||
82 | /* RNDIS defines an (absurdly huge) 10 second control timeout, | ||
83 | * but ActiveSync seems to use a more usual 5 second timeout | ||
84 | * (which matches the USB 2.0 spec). | ||
85 | */ | ||
86 | #define RNDIS_CONTROL_TIMEOUT_MS (5 * 1000) | ||
76 | 87 | ||
77 | 88 | ||
78 | #define ccpu2 __constant_cpu_to_le32 | 89 | #define ccpu2 __constant_cpu_to_le32 |
@@ -270,6 +281,7 @@ static void rndis_status(struct usbnet *dev, struct urb *urb) | |||
270 | static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf) | 281 | static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf) |
271 | { | 282 | { |
272 | struct cdc_state *info = (void *) &dev->data; | 283 | struct cdc_state *info = (void *) &dev->data; |
284 | int master_ifnum; | ||
273 | int retval; | 285 | int retval; |
274 | unsigned count; | 286 | unsigned count; |
275 | __le32 rsp; | 287 | __le32 rsp; |
@@ -279,7 +291,7 @@ static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf) | |||
279 | * disconnect(): either serialize, or dispatch responses on xid | 291 | * disconnect(): either serialize, or dispatch responses on xid |
280 | */ | 292 | */ |
281 | 293 | ||
282 | /* Issue the request; don't bother byteswapping our xid */ | 294 | /* Issue the request; xid is unique, don't bother byteswapping it */ |
283 | if (likely(buf->msg_type != RNDIS_MSG_HALT | 295 | if (likely(buf->msg_type != RNDIS_MSG_HALT |
284 | && buf->msg_type != RNDIS_MSG_RESET)) { | 296 | && buf->msg_type != RNDIS_MSG_RESET)) { |
285 | xid = dev->xid++; | 297 | xid = dev->xid++; |
@@ -287,11 +299,12 @@ static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf) | |||
287 | xid = dev->xid++; | 299 | xid = dev->xid++; |
288 | buf->request_id = (__force __le32) xid; | 300 | buf->request_id = (__force __le32) xid; |
289 | } | 301 | } |
302 | master_ifnum = info->control->cur_altsetting->desc.bInterfaceNumber; | ||
290 | retval = usb_control_msg(dev->udev, | 303 | retval = usb_control_msg(dev->udev, |
291 | usb_sndctrlpipe(dev->udev, 0), | 304 | usb_sndctrlpipe(dev->udev, 0), |
292 | USB_CDC_SEND_ENCAPSULATED_COMMAND, | 305 | USB_CDC_SEND_ENCAPSULATED_COMMAND, |
293 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 306 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
294 | 0, info->u->bMasterInterface0, | 307 | 0, master_ifnum, |
295 | buf, le32_to_cpu(buf->msg_len), | 308 | buf, le32_to_cpu(buf->msg_len), |
296 | RNDIS_CONTROL_TIMEOUT_MS); | 309 | RNDIS_CONTROL_TIMEOUT_MS); |
297 | if (unlikely(retval < 0 || xid == 0)) | 310 | if (unlikely(retval < 0 || xid == 0)) |
@@ -306,13 +319,13 @@ static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf) | |||
306 | */ | 319 | */ |
307 | rsp = buf->msg_type | RNDIS_MSG_COMPLETION; | 320 | rsp = buf->msg_type | RNDIS_MSG_COMPLETION; |
308 | for (count = 0; count < 10; count++) { | 321 | for (count = 0; count < 10; count++) { |
309 | memset(buf, 0, 1024); | 322 | memset(buf, 0, CONTROL_BUFFER_SIZE); |
310 | retval = usb_control_msg(dev->udev, | 323 | retval = usb_control_msg(dev->udev, |
311 | usb_rcvctrlpipe(dev->udev, 0), | 324 | usb_rcvctrlpipe(dev->udev, 0), |
312 | USB_CDC_GET_ENCAPSULATED_RESPONSE, | 325 | USB_CDC_GET_ENCAPSULATED_RESPONSE, |
313 | USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 326 | USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
314 | 0, info->u->bMasterInterface0, | 327 | 0, master_ifnum, |
315 | buf, 1024, | 328 | buf, CONTROL_BUFFER_SIZE, |
316 | RNDIS_CONTROL_TIMEOUT_MS); | 329 | RNDIS_CONTROL_TIMEOUT_MS); |
317 | if (likely(retval >= 8)) { | 330 | if (likely(retval >= 8)) { |
318 | msg_len = le32_to_cpu(buf->msg_len); | 331 | msg_len = le32_to_cpu(buf->msg_len); |
@@ -350,7 +363,7 @@ static int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf) | |||
350 | usb_sndctrlpipe(dev->udev, 0), | 363 | usb_sndctrlpipe(dev->udev, 0), |
351 | USB_CDC_SEND_ENCAPSULATED_COMMAND, | 364 | USB_CDC_SEND_ENCAPSULATED_COMMAND, |
352 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, | 365 | USB_TYPE_CLASS | USB_RECIP_INTERFACE, |
353 | 0, info->u->bMasterInterface0, | 366 | 0, master_ifnum, |
354 | msg, sizeof *msg, | 367 | msg, sizeof *msg, |
355 | RNDIS_CONTROL_TIMEOUT_MS); | 368 | RNDIS_CONTROL_TIMEOUT_MS); |
356 | if (unlikely(retval < 0)) | 369 | if (unlikely(retval < 0)) |
@@ -379,6 +392,7 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf) | |||
379 | { | 392 | { |
380 | int retval; | 393 | int retval; |
381 | struct net_device *net = dev->net; | 394 | struct net_device *net = dev->net; |
395 | struct cdc_state *info = (void *) &dev->data; | ||
382 | union { | 396 | union { |
383 | void *buf; | 397 | void *buf; |
384 | struct rndis_msg_hdr *header; | 398 | struct rndis_msg_hdr *header; |
@@ -392,54 +406,77 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf) | |||
392 | u32 tmp; | 406 | u32 tmp; |
393 | 407 | ||
394 | /* we can't rely on i/o from stack working, or stack allocation */ | 408 | /* we can't rely on i/o from stack working, or stack allocation */ |
395 | u.buf = kmalloc(1024, GFP_KERNEL); | 409 | u.buf = kmalloc(CONTROL_BUFFER_SIZE, GFP_KERNEL); |
396 | if (!u.buf) | 410 | if (!u.buf) |
397 | return -ENOMEM; | 411 | return -ENOMEM; |
398 | retval = usbnet_generic_cdc_bind(dev, intf); | 412 | retval = usbnet_generic_cdc_bind(dev, intf); |
399 | if (retval < 0) | 413 | if (retval < 0) |
400 | goto done; | 414 | goto fail; |
401 | |||
402 | net->hard_header_len += sizeof (struct rndis_data_hdr); | ||
403 | 415 | ||
404 | /* initialize; max transfer is 16KB at full speed */ | ||
405 | u.init->msg_type = RNDIS_MSG_INIT; | 416 | u.init->msg_type = RNDIS_MSG_INIT; |
406 | u.init->msg_len = ccpu2(sizeof *u.init); | 417 | u.init->msg_len = ccpu2(sizeof *u.init); |
407 | u.init->major_version = ccpu2(1); | 418 | u.init->major_version = ccpu2(1); |
408 | u.init->minor_version = ccpu2(0); | 419 | u.init->minor_version = ccpu2(0); |
409 | u.init->max_transfer_size = ccpu2(net->mtu + net->hard_header_len); | ||
410 | 420 | ||
421 | /* max transfer (in spec) is 0x4000 at full speed, but for | ||
422 | * TX we'll stick to one Ethernet packet plus RNDIS framing. | ||
423 | * For RX we handle drivers that zero-pad to end-of-packet. | ||
424 | * Don't let userspace change these settings. | ||
425 | */ | ||
426 | net->hard_header_len += sizeof (struct rndis_data_hdr); | ||
427 | dev->hard_mtu = net->mtu + net->hard_header_len; | ||
428 | |||
429 | dev->rx_urb_size = dev->hard_mtu + (dev->maxpacket + 1); | ||
430 | dev->rx_urb_size &= ~(dev->maxpacket - 1); | ||
431 | u.init->max_transfer_size = cpu_to_le32(dev->rx_urb_size); | ||
432 | |||
433 | net->change_mtu = NULL; | ||
411 | retval = rndis_command(dev, u.header); | 434 | retval = rndis_command(dev, u.header); |
412 | if (unlikely(retval < 0)) { | 435 | if (unlikely(retval < 0)) { |
413 | /* it might not even be an RNDIS device!! */ | 436 | /* it might not even be an RNDIS device!! */ |
414 | dev_err(&intf->dev, "RNDIS init failed, %d\n", retval); | 437 | dev_err(&intf->dev, "RNDIS init failed, %d\n", retval); |
415 | fail: | 438 | goto fail_and_release; |
416 | usb_driver_release_interface(driver_of(intf), | ||
417 | ((struct cdc_state *)&(dev->data))->data); | ||
418 | goto done; | ||
419 | } | 439 | } |
420 | dev->hard_mtu = le32_to_cpu(u.init_c->max_transfer_size); | 440 | tmp = le32_to_cpu(u.init_c->max_transfer_size); |
441 | if (tmp < dev->hard_mtu) { | ||
442 | dev_err(&intf->dev, | ||
443 | "dev can't take %u byte packets (max %u)\n", | ||
444 | dev->hard_mtu, tmp); | ||
445 | goto fail_and_release; | ||
446 | } | ||
447 | |||
421 | /* REVISIT: peripheral "alignment" request is ignored ... */ | 448 | /* REVISIT: peripheral "alignment" request is ignored ... */ |
422 | dev_dbg(&intf->dev, "hard mtu %u, align %d\n", dev->hard_mtu, | 449 | dev_dbg(&intf->dev, |
450 | "hard mtu %u (%u from dev), rx buflen %Zu, align %d\n", | ||
451 | dev->hard_mtu, tmp, dev->rx_urb_size, | ||
423 | 1 << le32_to_cpu(u.init_c->packet_alignment)); | 452 | 1 << le32_to_cpu(u.init_c->packet_alignment)); |
424 | 453 | ||
425 | /* get designated host ethernet address */ | 454 | /* Get designated host ethernet address. |
426 | memset(u.get, 0, sizeof *u.get); | 455 | * |
456 | * Adding a payload exactly the same size as the expected response | ||
457 | * payload is an evident requirement MSFT added for ActiveSync. | ||
458 | * This undocumented (and nonsensical) issue was found by sniffing | ||
459 | * protocol requests from the ActiveSync 4.1 Windows driver. | ||
460 | */ | ||
461 | memset(u.get, 0, sizeof *u.get + 48); | ||
427 | u.get->msg_type = RNDIS_MSG_QUERY; | 462 | u.get->msg_type = RNDIS_MSG_QUERY; |
428 | u.get->msg_len = ccpu2(sizeof *u.get); | 463 | u.get->msg_len = ccpu2(sizeof *u.get + 48); |
429 | u.get->oid = OID_802_3_PERMANENT_ADDRESS; | 464 | u.get->oid = OID_802_3_PERMANENT_ADDRESS; |
465 | u.get->len = ccpu2(48); | ||
466 | u.get->offset = ccpu2(20); | ||
430 | 467 | ||
431 | retval = rndis_command(dev, u.header); | 468 | retval = rndis_command(dev, u.header); |
432 | if (unlikely(retval < 0)) { | 469 | if (unlikely(retval < 0)) { |
433 | dev_err(&intf->dev, "rndis get ethaddr, %d\n", retval); | 470 | dev_err(&intf->dev, "rndis get ethaddr, %d\n", retval); |
434 | goto fail; | 471 | goto fail_and_release; |
435 | } | 472 | } |
436 | tmp = le32_to_cpu(u.get_c->offset); | 473 | tmp = le32_to_cpu(u.get_c->offset); |
437 | if (unlikely((tmp + 8) > (1024 - ETH_ALEN) | 474 | if (unlikely((tmp + 8) > (CONTROL_BUFFER_SIZE - ETH_ALEN) |
438 | || u.get_c->len != ccpu2(ETH_ALEN))) { | 475 | || u.get_c->len != ccpu2(ETH_ALEN))) { |
439 | dev_err(&intf->dev, "rndis ethaddr off %d len %d ?\n", | 476 | dev_err(&intf->dev, "rndis ethaddr off %d len %d ?\n", |
440 | tmp, le32_to_cpu(u.get_c->len)); | 477 | tmp, le32_to_cpu(u.get_c->len)); |
441 | retval = -EDOM; | 478 | retval = -EDOM; |
442 | goto fail; | 479 | goto fail_and_release; |
443 | } | 480 | } |
444 | memcpy(net->dev_addr, tmp + (char *)&u.get_c->request_id, ETH_ALEN); | 481 | memcpy(net->dev_addr, tmp + (char *)&u.get_c->request_id, ETH_ALEN); |
445 | 482 | ||
@@ -455,11 +492,18 @@ fail: | |||
455 | retval = rndis_command(dev, u.header); | 492 | retval = rndis_command(dev, u.header); |
456 | if (unlikely(retval < 0)) { | 493 | if (unlikely(retval < 0)) { |
457 | dev_err(&intf->dev, "rndis set packet filter, %d\n", retval); | 494 | dev_err(&intf->dev, "rndis set packet filter, %d\n", retval); |
458 | goto fail; | 495 | goto fail_and_release; |
459 | } | 496 | } |
460 | 497 | ||
461 | retval = 0; | 498 | retval = 0; |
462 | done: | 499 | |
500 | kfree(u.buf); | ||
501 | return retval; | ||
502 | |||
503 | fail_and_release: | ||
504 | usb_set_intfdata(info->data, NULL); | ||
505 | usb_driver_release_interface(driver_of(intf), info->data); | ||
506 | fail: | ||
463 | kfree(u.buf); | 507 | kfree(u.buf); |
464 | return retval; | 508 | return retval; |
465 | } | 509 | } |
@@ -469,7 +513,7 @@ static void rndis_unbind(struct usbnet *dev, struct usb_interface *intf) | |||
469 | struct rndis_halt *halt; | 513 | struct rndis_halt *halt; |
470 | 514 | ||
471 | /* try to clear any rndis state/activity (no i/o from stack!) */ | 515 | /* try to clear any rndis state/activity (no i/o from stack!) */ |
472 | halt = kcalloc(1, sizeof *halt, GFP_KERNEL); | 516 | halt = kzalloc(sizeof *halt, GFP_KERNEL); |
473 | if (halt) { | 517 | if (halt) { |
474 | halt->msg_type = RNDIS_MSG_HALT; | 518 | halt->msg_type = RNDIS_MSG_HALT; |
475 | halt->msg_len = ccpu2(sizeof *halt); | 519 | halt->msg_len = ccpu2(sizeof *halt); |
@@ -593,6 +637,10 @@ static const struct usb_device_id products [] = { | |||
593 | /* RNDIS is MSFT's un-official variant of CDC ACM */ | 637 | /* RNDIS is MSFT's un-official variant of CDC ACM */ |
594 | USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff), | 638 | USB_INTERFACE_INFO(USB_CLASS_COMM, 2 /* ACM */, 0x0ff), |
595 | .driver_info = (unsigned long) &rndis_info, | 639 | .driver_info = (unsigned long) &rndis_info, |
640 | }, { | ||
641 | /* "ActiveSync" is an undocumented variant of RNDIS, used in WM5 */ | ||
642 | USB_INTERFACE_INFO(USB_CLASS_MISC, 1, 1), | ||
643 | .driver_info = (unsigned long) &rndis_info, | ||
596 | }, | 644 | }, |
597 | { }, // END | 645 | { }, // END |
598 | }; | 646 | }; |
diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c index c54235f73cb6..670262a38a0f 100644 --- a/drivers/usb/net/rtl8150.c +++ b/drivers/usb/net/rtl8150.c | |||
@@ -124,10 +124,11 @@ | |||
124 | #define RX_URB_FAIL 3 | 124 | #define RX_URB_FAIL 3 |
125 | 125 | ||
126 | /* Define these values to match your device */ | 126 | /* Define these values to match your device */ |
127 | #define VENDOR_ID_REALTEK 0x0bda | 127 | #define VENDOR_ID_REALTEK 0x0bda |
128 | #define VENDOR_ID_MELCO 0x0411 | 128 | #define VENDOR_ID_MELCO 0x0411 |
129 | #define VENDOR_ID_MICRONET 0x3980 | 129 | #define VENDOR_ID_MICRONET 0x3980 |
130 | #define VENDOR_ID_LONGSHINE 0x07b8 | 130 | #define VENDOR_ID_LONGSHINE 0x07b8 |
131 | #define VENDOR_ID_OQO 0x1557 | ||
131 | #define VENDOR_ID_ZYXEL 0x0586 | 132 | #define VENDOR_ID_ZYXEL 0x0586 |
132 | 133 | ||
133 | #define PRODUCT_ID_RTL8150 0x8150 | 134 | #define PRODUCT_ID_RTL8150 0x8150 |
@@ -144,6 +145,7 @@ static struct usb_device_id rtl8150_table[] = { | |||
144 | {USB_DEVICE(VENDOR_ID_MELCO, PRODUCT_ID_LUAKTX)}, | 145 | {USB_DEVICE(VENDOR_ID_MELCO, PRODUCT_ID_LUAKTX)}, |
145 | {USB_DEVICE(VENDOR_ID_MICRONET, PRODUCT_ID_SP128AR)}, | 146 | {USB_DEVICE(VENDOR_ID_MICRONET, PRODUCT_ID_SP128AR)}, |
146 | {USB_DEVICE(VENDOR_ID_LONGSHINE, PRODUCT_ID_LCS8138TX)}, | 147 | {USB_DEVICE(VENDOR_ID_LONGSHINE, PRODUCT_ID_LCS8138TX)}, |
148 | {USB_DEVICE(VENDOR_ID_OQO, PRODUCT_ID_RTL8150)}, | ||
147 | {USB_DEVICE(VENDOR_ID_ZYXEL, PRODUCT_ID_PRESTIGE)}, | 149 | {USB_DEVICE(VENDOR_ID_ZYXEL, PRODUCT_ID_PRESTIGE)}, |
148 | {} | 150 | {} |
149 | }; | 151 | }; |
@@ -282,7 +284,8 @@ static int write_mii_word(rtl8150_t * dev, u8 phy, __u8 indx, u16 reg) | |||
282 | u8 data[3], tmp; | 284 | u8 data[3], tmp; |
283 | 285 | ||
284 | data[0] = phy; | 286 | data[0] = phy; |
285 | *(data + 1) = cpu_to_le16p(®); | 287 | data[1] = reg & 0xff; |
288 | data[2] = (reg >> 8) & 0xff; | ||
286 | tmp = indx | PHY_WRITE | PHY_GO; | 289 | tmp = indx | PHY_WRITE | PHY_GO; |
287 | i = 0; | 290 | i = 0; |
288 | 291 | ||
diff --git a/drivers/usb/serial/aircable.c b/drivers/usb/serial/aircable.c index 86bcf63b6ba5..11dad42c3c60 100644 --- a/drivers/usb/serial/aircable.c +++ b/drivers/usb/serial/aircable.c | |||
@@ -572,8 +572,20 @@ static void aircable_unthrottle(struct usb_serial_port *port) | |||
572 | schedule_work(&priv->rx_work); | 572 | schedule_work(&priv->rx_work); |
573 | } | 573 | } |
574 | 574 | ||
575 | static struct usb_driver aircable_driver = { | ||
576 | .name = "aircable", | ||
577 | .probe = usb_serial_probe, | ||
578 | .disconnect = usb_serial_disconnect, | ||
579 | .id_table = id_table, | ||
580 | .no_dynamic_id = 1, | ||
581 | }; | ||
582 | |||
575 | static struct usb_serial_driver aircable_device = { | 583 | static struct usb_serial_driver aircable_device = { |
576 | .description = "aircable", | 584 | .driver = { |
585 | .owner = THIS_MODULE, | ||
586 | .name = "aircable", | ||
587 | }, | ||
588 | .usb_driver = &aircable_driver, | ||
577 | .id_table = id_table, | 589 | .id_table = id_table, |
578 | .num_ports = 1, | 590 | .num_ports = 1, |
579 | .attach = aircable_attach, | 591 | .attach = aircable_attach, |
@@ -587,13 +599,6 @@ static struct usb_serial_driver aircable_device = { | |||
587 | .unthrottle = aircable_unthrottle, | 599 | .unthrottle = aircable_unthrottle, |
588 | }; | 600 | }; |
589 | 601 | ||
590 | static struct usb_driver aircable_driver = { | ||
591 | .name = "aircable", | ||
592 | .probe = usb_serial_probe, | ||
593 | .disconnect = usb_serial_disconnect, | ||
594 | .id_table = id_table, | ||
595 | }; | ||
596 | |||
597 | static int __init aircable_init (void) | 602 | static int __init aircable_init (void) |
598 | { | 603 | { |
599 | int retval; | 604 | int retval; |
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index 96c73726d74a..0af42e32fa0a 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c | |||
@@ -19,8 +19,11 @@ | |||
19 | static struct usb_device_id id_table [] = { | 19 | static struct usb_device_id id_table [] = { |
20 | { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */ | 20 | { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */ |
21 | { USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */ | 21 | { USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */ |
22 | { USB_DEVICE(0x1410, 0x1130) }, /* Novatel Wireless S720 CDMA/EV-DO */ | ||
23 | { USB_DEVICE(0x1410, 0x2110) }, /* Novatel Wireless U720 CDMA/EV-DO */ | ||
22 | { USB_DEVICE(0x1410, 0x1430) }, /* Novatel Merlin XU870 HSDPA/3G */ | 24 | { USB_DEVICE(0x1410, 0x1430) }, /* Novatel Merlin XU870 HSDPA/3G */ |
23 | { USB_DEVICE(0x1410, 0x1100) }, /* ExpressCard34 Qualcomm 3G CDMA */ | 25 | { USB_DEVICE(0x1410, 0x1100) }, /* ExpressCard34 Qualcomm 3G CDMA */ |
26 | { USB_DEVICE(0x413c, 0x8115) }, /* Dell Wireless HSDPA 5500 */ | ||
24 | { }, | 27 | { }, |
25 | }; | 28 | }; |
26 | MODULE_DEVICE_TABLE(usb, id_table); | 29 | MODULE_DEVICE_TABLE(usb, id_table); |
@@ -274,6 +277,7 @@ static struct usb_serial_driver airprime_device = { | |||
274 | .owner = THIS_MODULE, | 277 | .owner = THIS_MODULE, |
275 | .name = "airprime", | 278 | .name = "airprime", |
276 | }, | 279 | }, |
280 | .usb_driver = &airprime_driver, | ||
277 | .id_table = id_table, | 281 | .id_table = id_table, |
278 | .num_interrupt_in = NUM_DONT_CARE, | 282 | .num_interrupt_in = NUM_DONT_CARE, |
279 | .num_bulk_in = NUM_DONT_CARE, | 283 | .num_bulk_in = NUM_DONT_CARE, |
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index 863966c1c5ac..edd685791a6b 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c | |||
@@ -156,7 +156,7 @@ cleanup: | |||
156 | } | 156 | } |
157 | 157 | ||
158 | static void ark3116_set_termios(struct usb_serial_port *port, | 158 | static void ark3116_set_termios(struct usb_serial_port *port, |
159 | struct termios *old_termios) | 159 | struct ktermios *old_termios) |
160 | { | 160 | { |
161 | struct usb_serial *serial = port->serial; | 161 | struct usb_serial *serial = port->serial; |
162 | struct ark3116_private *priv = usb_get_serial_port_data(port); | 162 | struct ark3116_private *priv = usb_get_serial_port_data(port); |
@@ -326,7 +326,7 @@ static void ark3116_set_termios(struct usb_serial_port *port, | |||
326 | 326 | ||
327 | static int ark3116_open(struct usb_serial_port *port, struct file *filp) | 327 | static int ark3116_open(struct usb_serial_port *port, struct file *filp) |
328 | { | 328 | { |
329 | struct termios tmp_termios; | 329 | struct ktermios tmp_termios; |
330 | struct usb_serial *serial = port->serial; | 330 | struct usb_serial *serial = port->serial; |
331 | char *buf; | 331 | char *buf; |
332 | int result = 0; | 332 | int result = 0; |
@@ -444,6 +444,7 @@ static struct usb_driver ark3116_driver = { | |||
444 | .probe = usb_serial_probe, | 444 | .probe = usb_serial_probe, |
445 | .disconnect = usb_serial_disconnect, | 445 | .disconnect = usb_serial_disconnect, |
446 | .id_table = id_table, | 446 | .id_table = id_table, |
447 | .no_dynamic_id = 1, | ||
447 | }; | 448 | }; |
448 | 449 | ||
449 | static struct usb_serial_driver ark3116_device = { | 450 | static struct usb_serial_driver ark3116_device = { |
@@ -452,6 +453,7 @@ static struct usb_serial_driver ark3116_device = { | |||
452 | .name = "ark3116", | 453 | .name = "ark3116", |
453 | }, | 454 | }, |
454 | .id_table = id_table, | 455 | .id_table = id_table, |
456 | .usb_driver = &ark3116_driver, | ||
455 | .num_interrupt_in = 1, | 457 | .num_interrupt_in = 1, |
456 | .num_bulk_in = 1, | 458 | .num_bulk_in = 1, |
457 | .num_bulk_out = 1, | 459 | .num_bulk_out = 1, |
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 8835bb58ca9b..3b800d277c4b 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c | |||
@@ -92,7 +92,7 @@ static void belkin_sa_shutdown (struct usb_serial *serial); | |||
92 | static int belkin_sa_open (struct usb_serial_port *port, struct file *filp); | 92 | static int belkin_sa_open (struct usb_serial_port *port, struct file *filp); |
93 | static void belkin_sa_close (struct usb_serial_port *port, struct file *filp); | 93 | static void belkin_sa_close (struct usb_serial_port *port, struct file *filp); |
94 | static void belkin_sa_read_int_callback (struct urb *urb); | 94 | static void belkin_sa_read_int_callback (struct urb *urb); |
95 | static void belkin_sa_set_termios (struct usb_serial_port *port, struct termios * old); | 95 | static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios * old); |
96 | static int belkin_sa_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); | 96 | static int belkin_sa_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); |
97 | static void belkin_sa_break_ctl (struct usb_serial_port *port, int break_state ); | 97 | static void belkin_sa_break_ctl (struct usb_serial_port *port, int break_state ); |
98 | static int belkin_sa_tiocmget (struct usb_serial_port *port, struct file *file); | 98 | static int belkin_sa_tiocmget (struct usb_serial_port *port, struct file *file); |
@@ -126,6 +126,7 @@ static struct usb_serial_driver belkin_device = { | |||
126 | .name = "belkin", | 126 | .name = "belkin", |
127 | }, | 127 | }, |
128 | .description = "Belkin / Peracom / GoHubs USB Serial Adapter", | 128 | .description = "Belkin / Peracom / GoHubs USB Serial Adapter", |
129 | .usb_driver = &belkin_driver, | ||
129 | .id_table = id_table_combined, | 130 | .id_table = id_table_combined, |
130 | .num_interrupt_in = 1, | 131 | .num_interrupt_in = 1, |
131 | .num_bulk_in = 1, | 132 | .num_bulk_in = 1, |
@@ -333,7 +334,7 @@ exit: | |||
333 | __FUNCTION__, retval); | 334 | __FUNCTION__, retval); |
334 | } | 335 | } |
335 | 336 | ||
336 | static void belkin_sa_set_termios (struct usb_serial_port *port, struct termios *old_termios) | 337 | static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) |
337 | { | 338 | { |
338 | struct usb_serial *serial = port->serial; | 339 | struct usb_serial *serial = port->serial; |
339 | struct belkin_sa_private *priv = usb_get_serial_port_data(port); | 340 | struct belkin_sa_private *priv = usb_get_serial_port_data(port); |
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index 6542f220468f..c08a38402b93 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c | |||
@@ -103,11 +103,52 @@ exit: | |||
103 | return retval; | 103 | return retval; |
104 | } | 104 | } |
105 | 105 | ||
106 | #ifdef CONFIG_HOTPLUG | ||
107 | static ssize_t store_new_id(struct device_driver *driver, | ||
108 | const char *buf, size_t count) | ||
109 | { | ||
110 | struct usb_serial_driver *usb_drv = to_usb_serial_driver(driver); | ||
111 | ssize_t retval = usb_store_new_id(&usb_drv->dynids, driver, buf, count); | ||
112 | |||
113 | if (retval >= 0 && usb_drv->usb_driver != NULL) | ||
114 | retval = usb_store_new_id(&usb_drv->usb_driver->dynids, | ||
115 | &usb_drv->usb_driver->drvwrap.driver, | ||
116 | buf, count); | ||
117 | return retval; | ||
118 | } | ||
119 | |||
120 | static struct driver_attribute drv_attrs[] = { | ||
121 | __ATTR(new_id, S_IWUSR, NULL, store_new_id), | ||
122 | __ATTR_NULL, | ||
123 | }; | ||
124 | |||
125 | static void free_dynids(struct usb_serial_driver *drv) | ||
126 | { | ||
127 | struct usb_dynid *dynid, *n; | ||
128 | |||
129 | spin_lock(&drv->dynids.lock); | ||
130 | list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) { | ||
131 | list_del(&dynid->node); | ||
132 | kfree(dynid); | ||
133 | } | ||
134 | spin_unlock(&drv->dynids.lock); | ||
135 | } | ||
136 | |||
137 | #else | ||
138 | static struct driver_attribute drv_attrs[] = { | ||
139 | __ATTR_NULL, | ||
140 | }; | ||
141 | static inline void free_dynids(struct usb_driver *drv) | ||
142 | { | ||
143 | } | ||
144 | #endif | ||
145 | |||
106 | struct bus_type usb_serial_bus_type = { | 146 | struct bus_type usb_serial_bus_type = { |
107 | .name = "usb-serial", | 147 | .name = "usb-serial", |
108 | .match = usb_serial_device_match, | 148 | .match = usb_serial_device_match, |
109 | .probe = usb_serial_device_probe, | 149 | .probe = usb_serial_device_probe, |
110 | .remove = usb_serial_device_remove, | 150 | .remove = usb_serial_device_remove, |
151 | .drv_attrs = drv_attrs, | ||
111 | }; | 152 | }; |
112 | 153 | ||
113 | int usb_serial_bus_register(struct usb_serial_driver *driver) | 154 | int usb_serial_bus_register(struct usb_serial_driver *driver) |
@@ -115,6 +156,9 @@ int usb_serial_bus_register(struct usb_serial_driver *driver) | |||
115 | int retval; | 156 | int retval; |
116 | 157 | ||
117 | driver->driver.bus = &usb_serial_bus_type; | 158 | driver->driver.bus = &usb_serial_bus_type; |
159 | spin_lock_init(&driver->dynids.lock); | ||
160 | INIT_LIST_HEAD(&driver->dynids.list); | ||
161 | |||
118 | retval = driver_register(&driver->driver); | 162 | retval = driver_register(&driver->driver); |
119 | 163 | ||
120 | return retval; | 164 | return retval; |
@@ -122,6 +166,7 @@ int usb_serial_bus_register(struct usb_serial_driver *driver) | |||
122 | 166 | ||
123 | void usb_serial_bus_deregister(struct usb_serial_driver *driver) | 167 | void usb_serial_bus_deregister(struct usb_serial_driver *driver) |
124 | { | 168 | { |
169 | free_dynids(driver); | ||
125 | driver_unregister(&driver->driver); | 170 | driver_unregister(&driver->driver); |
126 | } | 171 | } |
127 | 172 | ||
diff --git a/drivers/usb/serial/console.c b/drivers/usb/serial/console.c index 7167728d764c..9386e216d681 100644 --- a/drivers/usb/serial/console.c +++ b/drivers/usb/serial/console.c | |||
@@ -65,7 +65,7 @@ static int usb_console_setup(struct console *co, char *options) | |||
65 | struct usb_serial_port *port; | 65 | struct usb_serial_port *port; |
66 | int retval = 0; | 66 | int retval = 0; |
67 | struct tty_struct *tty; | 67 | struct tty_struct *tty; |
68 | struct termios *termios; | 68 | struct ktermios *termios; |
69 | 69 | ||
70 | dbg ("%s", __FUNCTION__); | 70 | dbg ("%s", __FUNCTION__); |
71 | 71 | ||
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index f95d42c0d16a..3ec24870bca9 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c | |||
@@ -41,7 +41,7 @@ static int cp2101_open(struct usb_serial_port*, struct file*); | |||
41 | static void cp2101_cleanup(struct usb_serial_port*); | 41 | static void cp2101_cleanup(struct usb_serial_port*); |
42 | static void cp2101_close(struct usb_serial_port*, struct file*); | 42 | static void cp2101_close(struct usb_serial_port*, struct file*); |
43 | static void cp2101_get_termios(struct usb_serial_port*); | 43 | static void cp2101_get_termios(struct usb_serial_port*); |
44 | static void cp2101_set_termios(struct usb_serial_port*, struct termios*); | 44 | static void cp2101_set_termios(struct usb_serial_port*, struct ktermios*); |
45 | static int cp2101_tiocmget (struct usb_serial_port *, struct file *); | 45 | static int cp2101_tiocmget (struct usb_serial_port *, struct file *); |
46 | static int cp2101_tiocmset (struct usb_serial_port *, struct file *, | 46 | static int cp2101_tiocmset (struct usb_serial_port *, struct file *, |
47 | unsigned int, unsigned int); | 47 | unsigned int, unsigned int); |
@@ -69,6 +69,7 @@ static struct usb_device_id id_table [] = { | |||
69 | { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ | 69 | { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ |
70 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ | 70 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ |
71 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ | 71 | { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ |
72 | { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */ | ||
72 | { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ | 73 | { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ |
73 | { } /* Terminating Entry */ | 74 | { } /* Terminating Entry */ |
74 | }; | 75 | }; |
@@ -88,6 +89,7 @@ static struct usb_serial_driver cp2101_device = { | |||
88 | .owner = THIS_MODULE, | 89 | .owner = THIS_MODULE, |
89 | .name = "cp2101", | 90 | .name = "cp2101", |
90 | }, | 91 | }, |
92 | .usb_driver = &cp2101_driver, | ||
91 | .id_table = id_table, | 93 | .id_table = id_table, |
92 | .num_interrupt_in = 0, | 94 | .num_interrupt_in = 0, |
93 | .num_bulk_in = 0, | 95 | .num_bulk_in = 0, |
@@ -168,13 +170,13 @@ static int cp2101_get_config(struct usb_serial_port* port, u8 request, | |||
168 | unsigned int *data, int size) | 170 | unsigned int *data, int size) |
169 | { | 171 | { |
170 | struct usb_serial *serial = port->serial; | 172 | struct usb_serial *serial = port->serial; |
171 | u32 *buf; | 173 | __le32 *buf; |
172 | int result, i, length; | 174 | int result, i, length; |
173 | 175 | ||
174 | /* Number of integers required to contain the array */ | 176 | /* Number of integers required to contain the array */ |
175 | length = (((size - 1) | 3) + 1)/4; | 177 | length = (((size - 1) | 3) + 1)/4; |
176 | 178 | ||
177 | buf = kcalloc(length, sizeof(u32), GFP_KERNEL); | 179 | buf = kcalloc(length, sizeof(__le32), GFP_KERNEL); |
178 | if (!buf) { | 180 | if (!buf) { |
179 | dev_err(&port->dev, "%s - out of memory.\n", __FUNCTION__); | 181 | dev_err(&port->dev, "%s - out of memory.\n", __FUNCTION__); |
180 | return -ENOMEM; | 182 | return -ENOMEM; |
@@ -214,13 +216,13 @@ static int cp2101_set_config(struct usb_serial_port* port, u8 request, | |||
214 | unsigned int *data, int size) | 216 | unsigned int *data, int size) |
215 | { | 217 | { |
216 | struct usb_serial *serial = port->serial; | 218 | struct usb_serial *serial = port->serial; |
217 | u32 *buf; | 219 | __le32 *buf; |
218 | int result, i, length; | 220 | int result, i, length; |
219 | 221 | ||
220 | /* Number of integers required to contain the array */ | 222 | /* Number of integers required to contain the array */ |
221 | length = (((size - 1) | 3) + 1)/4; | 223 | length = (((size - 1) | 3) + 1)/4; |
222 | 224 | ||
223 | buf = kmalloc(length * sizeof(u32), GFP_KERNEL); | 225 | buf = kmalloc(length * sizeof(__le32), GFP_KERNEL); |
224 | if (!buf) { | 226 | if (!buf) { |
225 | dev_err(&port->dev, "%s - out of memory.\n", | 227 | dev_err(&port->dev, "%s - out of memory.\n", |
226 | __FUNCTION__); | 228 | __FUNCTION__); |
@@ -506,7 +508,7 @@ static void cp2101_get_termios (struct usb_serial_port *port) | |||
506 | } | 508 | } |
507 | 509 | ||
508 | static void cp2101_set_termios (struct usb_serial_port *port, | 510 | static void cp2101_set_termios (struct usb_serial_port *port, |
509 | struct termios *old_termios) | 511 | struct ktermios *old_termios) |
510 | { | 512 | { |
511 | unsigned int cflag, old_cflag=0; | 513 | unsigned int cflag, old_cflag=0; |
512 | int baud=0, bits; | 514 | int baud=0, bits; |
diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index a63c3286caa0..4167753ed31f 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c | |||
@@ -88,6 +88,7 @@ static struct usb_serial_driver cyberjack_device = { | |||
88 | .name = "cyberjack", | 88 | .name = "cyberjack", |
89 | }, | 89 | }, |
90 | .description = "Reiner SCT Cyberjack USB card reader", | 90 | .description = "Reiner SCT Cyberjack USB card reader", |
91 | .usb_driver = &cyberjack_driver, | ||
91 | .id_table = id_table, | 92 | .id_table = id_table, |
92 | .num_interrupt_in = 1, | 93 | .num_interrupt_in = 1, |
93 | .num_bulk_in = 1, | 94 | .num_bulk_in = 1, |
@@ -98,7 +99,7 @@ static struct usb_serial_driver cyberjack_device = { | |||
98 | .open = cyberjack_open, | 99 | .open = cyberjack_open, |
99 | .close = cyberjack_close, | 100 | .close = cyberjack_close, |
100 | .write = cyberjack_write, | 101 | .write = cyberjack_write, |
101 | .write_room = cyberjack_write_room, | 102 | .write_room = cyberjack_write_room, |
102 | .read_int_callback = cyberjack_read_int_callback, | 103 | .read_int_callback = cyberjack_read_int_callback, |
103 | .read_bulk_callback = cyberjack_read_bulk_callback, | 104 | .read_bulk_callback = cyberjack_read_bulk_callback, |
104 | .write_bulk_callback = cyberjack_write_bulk_callback, | 105 | .write_bulk_callback = cyberjack_write_bulk_callback, |
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 093f303b3189..57b8e27285fc 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c | |||
@@ -143,7 +143,7 @@ struct cypress_private { | |||
143 | wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */ | 143 | wait_queue_head_t delta_msr_wait; /* used for TIOCMIWAIT */ |
144 | char prev_status, diff_status; /* used for TIOCMIWAIT */ | 144 | char prev_status, diff_status; /* used for TIOCMIWAIT */ |
145 | /* we pass a pointer to this as the arguement sent to cypress_set_termios old_termios */ | 145 | /* we pass a pointer to this as the arguement sent to cypress_set_termios old_termios */ |
146 | struct termios tmp_termios; /* stores the old termios settings */ | 146 | struct ktermios tmp_termios; /* stores the old termios settings */ |
147 | }; | 147 | }; |
148 | 148 | ||
149 | /* write buffer structure */ | 149 | /* write buffer structure */ |
@@ -165,7 +165,7 @@ static int cypress_write (struct usb_serial_port *port, const unsigned char *b | |||
165 | static void cypress_send (struct usb_serial_port *port); | 165 | static void cypress_send (struct usb_serial_port *port); |
166 | static int cypress_write_room (struct usb_serial_port *port); | 166 | static int cypress_write_room (struct usb_serial_port *port); |
167 | static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); | 167 | static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); |
168 | static void cypress_set_termios (struct usb_serial_port *port, struct termios * old); | 168 | static void cypress_set_termios (struct usb_serial_port *port, struct ktermios * old); |
169 | static int cypress_tiocmget (struct usb_serial_port *port, struct file *file); | 169 | static int cypress_tiocmget (struct usb_serial_port *port, struct file *file); |
170 | static int cypress_tiocmset (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear); | 170 | static int cypress_tiocmset (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear); |
171 | static int cypress_chars_in_buffer (struct usb_serial_port *port); | 171 | static int cypress_chars_in_buffer (struct usb_serial_port *port); |
@@ -193,6 +193,7 @@ static struct usb_serial_driver cypress_earthmate_device = { | |||
193 | .name = "earthmate", | 193 | .name = "earthmate", |
194 | }, | 194 | }, |
195 | .description = "DeLorme Earthmate USB", | 195 | .description = "DeLorme Earthmate USB", |
196 | .usb_driver = &cypress_driver, | ||
196 | .id_table = id_table_earthmate, | 197 | .id_table = id_table_earthmate, |
197 | .num_interrupt_in = 1, | 198 | .num_interrupt_in = 1, |
198 | .num_interrupt_out = 1, | 199 | .num_interrupt_out = 1, |
@@ -222,6 +223,7 @@ static struct usb_serial_driver cypress_hidcom_device = { | |||
222 | .name = "cyphidcom", | 223 | .name = "cyphidcom", |
223 | }, | 224 | }, |
224 | .description = "HID->COM RS232 Adapter", | 225 | .description = "HID->COM RS232 Adapter", |
226 | .usb_driver = &cypress_driver, | ||
225 | .id_table = id_table_cyphidcomrs232, | 227 | .id_table = id_table_cyphidcomrs232, |
226 | .num_interrupt_in = 1, | 228 | .num_interrupt_in = 1, |
227 | .num_interrupt_out = 1, | 229 | .num_interrupt_out = 1, |
@@ -251,6 +253,7 @@ static struct usb_serial_driver cypress_ca42v2_device = { | |||
251 | .name = "nokiaca42v2", | 253 | .name = "nokiaca42v2", |
252 | }, | 254 | }, |
253 | .description = "Nokia CA-42 V2 Adapter", | 255 | .description = "Nokia CA-42 V2 Adapter", |
256 | .usb_driver = &cypress_driver, | ||
254 | .id_table = id_table_nokiaca42v2, | 257 | .id_table = id_table_nokiaca42v2, |
255 | .num_interrupt_in = 1, | 258 | .num_interrupt_in = 1, |
256 | .num_interrupt_out = 1, | 259 | .num_interrupt_out = 1, |
@@ -949,28 +952,13 @@ static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsi | |||
949 | 952 | ||
950 | switch (cmd) { | 953 | switch (cmd) { |
951 | case TIOCGSERIAL: | 954 | case TIOCGSERIAL: |
952 | if (copy_to_user((void __user *)arg, port->tty->termios, sizeof(struct termios))) { | 955 | if (copy_to_user((void __user *)arg, port->tty->termios, sizeof(struct ktermios))) { |
953 | return -EFAULT; | 956 | return -EFAULT; |
954 | } | 957 | } |
955 | return (0); | 958 | return (0); |
956 | break; | 959 | break; |
957 | case TIOCSSERIAL: | 960 | case TIOCSSERIAL: |
958 | if (copy_from_user(port->tty->termios, (void __user *)arg, sizeof(struct termios))) { | 961 | if (copy_from_user(port->tty->termios, (void __user *)arg, sizeof(struct ktermios))) { |
959 | return -EFAULT; | ||
960 | } | ||
961 | /* here we need to call cypress_set_termios to invoke the new settings */ | ||
962 | cypress_set_termios(port, &priv->tmp_termios); | ||
963 | return (0); | ||
964 | break; | ||
965 | /* these are called when setting baud rate from gpsd */ | ||
966 | case TCGETS: | ||
967 | if (copy_to_user((void __user *)arg, port->tty->termios, sizeof(struct termios))) { | ||
968 | return -EFAULT; | ||
969 | } | ||
970 | return (0); | ||
971 | break; | ||
972 | case TCSETS: | ||
973 | if (copy_from_user(port->tty->termios, (void __user *)arg, sizeof(struct termios))) { | ||
974 | return -EFAULT; | 962 | return -EFAULT; |
975 | } | 963 | } |
976 | /* here we need to call cypress_set_termios to invoke the new settings */ | 964 | /* here we need to call cypress_set_termios to invoke the new settings */ |
@@ -1019,7 +1007,7 @@ static int cypress_ioctl (struct usb_serial_port *port, struct file * file, unsi | |||
1019 | 1007 | ||
1020 | 1008 | ||
1021 | static void cypress_set_termios (struct usb_serial_port *port, | 1009 | static void cypress_set_termios (struct usb_serial_port *port, |
1022 | struct termios *old_termios) | 1010 | struct ktermios *old_termios) |
1023 | { | 1011 | { |
1024 | struct cypress_private *priv = usb_get_serial_port_data(port); | 1012 | struct cypress_private *priv = usb_get_serial_port_data(port); |
1025 | struct tty_struct *tty; | 1013 | struct tty_struct *tty; |
@@ -1493,7 +1481,7 @@ static struct cypress_buf *cypress_buf_alloc(unsigned int size) | |||
1493 | if (size == 0) | 1481 | if (size == 0) |
1494 | return NULL; | 1482 | return NULL; |
1495 | 1483 | ||
1496 | cb = (struct cypress_buf *)kmalloc(sizeof(struct cypress_buf), GFP_KERNEL); | 1484 | cb = kmalloc(sizeof(struct cypress_buf), GFP_KERNEL); |
1497 | if (cb == NULL) | 1485 | if (cb == NULL) |
1498 | return NULL; | 1486 | return NULL; |
1499 | 1487 | ||
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 83d0e21145b0..0b0fb51bad3e 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -449,7 +449,7 @@ static int digi_transmit_idle( struct usb_serial_port *port, | |||
449 | static void digi_rx_throttle (struct usb_serial_port *port); | 449 | static void digi_rx_throttle (struct usb_serial_port *port); |
450 | static void digi_rx_unthrottle (struct usb_serial_port *port); | 450 | static void digi_rx_unthrottle (struct usb_serial_port *port); |
451 | static void digi_set_termios( struct usb_serial_port *port, | 451 | static void digi_set_termios( struct usb_serial_port *port, |
452 | struct termios *old_termios ); | 452 | struct ktermios *old_termios ); |
453 | static void digi_break_ctl( struct usb_serial_port *port, int break_state ); | 453 | static void digi_break_ctl( struct usb_serial_port *port, int break_state ); |
454 | static int digi_ioctl( struct usb_serial_port *port, struct file *file, | 454 | static int digi_ioctl( struct usb_serial_port *port, struct file *file, |
455 | unsigned int cmd, unsigned long arg ); | 455 | unsigned int cmd, unsigned long arg ); |
@@ -509,6 +509,7 @@ static struct usb_serial_driver digi_acceleport_2_device = { | |||
509 | .name = "digi_2", | 509 | .name = "digi_2", |
510 | }, | 510 | }, |
511 | .description = "Digi 2 port USB adapter", | 511 | .description = "Digi 2 port USB adapter", |
512 | .usb_driver = &digi_driver, | ||
512 | .id_table = id_table_2, | 513 | .id_table = id_table_2, |
513 | .num_interrupt_in = 0, | 514 | .num_interrupt_in = 0, |
514 | .num_bulk_in = 4, | 515 | .num_bulk_in = 4, |
@@ -538,6 +539,7 @@ static struct usb_serial_driver digi_acceleport_4_device = { | |||
538 | .name = "digi_4", | 539 | .name = "digi_4", |
539 | }, | 540 | }, |
540 | .description = "Digi 4 port USB adapter", | 541 | .description = "Digi 4 port USB adapter", |
542 | .usb_driver = &digi_driver, | ||
541 | .id_table = id_table_4, | 543 | .id_table = id_table_4, |
542 | .num_interrupt_in = 0, | 544 | .num_interrupt_in = 0, |
543 | .num_bulk_in = 5, | 545 | .num_bulk_in = 5, |
@@ -976,7 +978,7 @@ dbg( "digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num ); | |||
976 | 978 | ||
977 | 979 | ||
978 | static void digi_set_termios( struct usb_serial_port *port, | 980 | static void digi_set_termios( struct usb_serial_port *port, |
979 | struct termios *old_termios ) | 981 | struct ktermios *old_termios ) |
980 | { | 982 | { |
981 | 983 | ||
982 | struct digi_port *priv = usb_get_serial_port_data(port); | 984 | struct digi_port *priv = usb_get_serial_port_data(port); |
@@ -1463,7 +1465,7 @@ static int digi_open( struct usb_serial_port *port, struct file *filp ) | |||
1463 | int ret; | 1465 | int ret; |
1464 | unsigned char buf[32]; | 1466 | unsigned char buf[32]; |
1465 | struct digi_port *priv = usb_get_serial_port_data(port); | 1467 | struct digi_port *priv = usb_get_serial_port_data(port); |
1466 | struct termios not_termios; | 1468 | struct ktermios not_termios; |
1467 | unsigned long flags = 0; | 1469 | unsigned long flags = 0; |
1468 | 1470 | ||
1469 | 1471 | ||
@@ -1681,7 +1683,7 @@ dbg( "digi_startup: TOP" ); | |||
1681 | for( i=0; i<serial->type->num_ports+1; i++ ) { | 1683 | for( i=0; i<serial->type->num_ports+1; i++ ) { |
1682 | 1684 | ||
1683 | /* allocate port private structure */ | 1685 | /* allocate port private structure */ |
1684 | priv = (struct digi_port *)kmalloc( sizeof(struct digi_port), | 1686 | priv = kmalloc( sizeof(struct digi_port), |
1685 | GFP_KERNEL ); | 1687 | GFP_KERNEL ); |
1686 | if( priv == (struct digi_port *)0 ) { | 1688 | if( priv == (struct digi_port *)0 ) { |
1687 | while( --i >= 0 ) | 1689 | while( --i >= 0 ) |
@@ -1714,7 +1716,7 @@ dbg( "digi_startup: TOP" ); | |||
1714 | } | 1716 | } |
1715 | 1717 | ||
1716 | /* allocate serial private structure */ | 1718 | /* allocate serial private structure */ |
1717 | serial_priv = (struct digi_serial *)kmalloc( sizeof(struct digi_serial), | 1719 | serial_priv = kmalloc( sizeof(struct digi_serial), |
1718 | GFP_KERNEL ); | 1720 | GFP_KERNEL ); |
1719 | if( serial_priv == (struct digi_serial *)0 ) { | 1721 | if( serial_priv == (struct digi_serial *)0 ) { |
1720 | for( i=0; i<serial->type->num_ports+1; i++ ) | 1722 | for( i=0; i<serial->type->num_ports+1; i++ ) |
diff --git a/drivers/usb/serial/empeg.c b/drivers/usb/serial/empeg.c index 4ce10a831953..4703c8f85383 100644 --- a/drivers/usb/serial/empeg.c +++ b/drivers/usb/serial/empeg.c | |||
@@ -92,7 +92,7 @@ static int empeg_ioctl (struct usb_serial_port *port, | |||
92 | struct file * file, | 92 | struct file * file, |
93 | unsigned int cmd, | 93 | unsigned int cmd, |
94 | unsigned long arg); | 94 | unsigned long arg); |
95 | static void empeg_set_termios (struct usb_serial_port *port, struct termios *old_termios); | 95 | static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *old_termios); |
96 | static void empeg_write_bulk_callback (struct urb *urb); | 96 | static void empeg_write_bulk_callback (struct urb *urb); |
97 | static void empeg_read_bulk_callback (struct urb *urb); | 97 | static void empeg_read_bulk_callback (struct urb *urb); |
98 | 98 | ||
@@ -117,6 +117,7 @@ static struct usb_serial_driver empeg_device = { | |||
117 | .name = "empeg", | 117 | .name = "empeg", |
118 | }, | 118 | }, |
119 | .id_table = id_table, | 119 | .id_table = id_table, |
120 | .usb_driver = &empeg_driver, | ||
120 | .num_interrupt_in = 0, | 121 | .num_interrupt_in = 0, |
121 | .num_bulk_in = 1, | 122 | .num_bulk_in = 1, |
122 | .num_bulk_out = 1, | 123 | .num_bulk_out = 1, |
@@ -442,7 +443,7 @@ static int empeg_ioctl (struct usb_serial_port *port, struct file * file, unsign | |||
442 | } | 443 | } |
443 | 444 | ||
444 | 445 | ||
445 | static void empeg_set_termios (struct usb_serial_port *port, struct termios *old_termios) | 446 | static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) |
446 | { | 447 | { |
447 | 448 | ||
448 | dbg("%s - port %d", __FUNCTION__, port->number); | 449 | dbg("%s - port %d", __FUNCTION__, port->number); |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 72e4d48f51e9..4695952b6470 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -452,6 +452,7 @@ static struct usb_device_id id_table_combined [] = { | |||
452 | { USB_DEVICE(FTDI_VID, LINX_FUTURE_2_PID) }, | 452 | { USB_DEVICE(FTDI_VID, LINX_FUTURE_2_PID) }, |
453 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) }, | 453 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) }, |
454 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) }, | 454 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) }, |
455 | { USB_DEVICE(FTDI_VID, FTDI_CCSMACHX_2_PID) }, | ||
455 | { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) }, | 456 | { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) }, |
456 | { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) }, | 457 | { USB_DEVICE(INTREPID_VID, INTREPID_VALUECAN_PID) }, |
457 | { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) }, | 458 | { USB_DEVICE(INTREPID_VID, INTREPID_NEOVI_PID) }, |
@@ -463,7 +464,6 @@ static struct usb_device_id id_table_combined [] = { | |||
463 | { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, | 464 | { USB_DEVICE(BANDB_VID, BANDB_USTL4_PID) }, |
464 | { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) }, | 465 | { USB_DEVICE(BANDB_VID, BANDB_USO9ML2_PID) }, |
465 | { USB_DEVICE(FTDI_VID, EVER_ECO_PRO_CDS) }, | 466 | { USB_DEVICE(FTDI_VID, EVER_ECO_PRO_CDS) }, |
466 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_0_PID) }, | ||
467 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) }, | 467 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) }, |
468 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) }, | 468 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) }, |
469 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_0_PID) }, | 469 | { USB_DEVICE(FTDI_VID, XSENS_CONVERTER_0_PID) }, |
@@ -595,7 +595,7 @@ static int ftdi_chars_in_buffer (struct usb_serial_port *port); | |||
595 | static void ftdi_write_bulk_callback (struct urb *urb); | 595 | static void ftdi_write_bulk_callback (struct urb *urb); |
596 | static void ftdi_read_bulk_callback (struct urb *urb); | 596 | static void ftdi_read_bulk_callback (struct urb *urb); |
597 | static void ftdi_process_read (struct work_struct *work); | 597 | static void ftdi_process_read (struct work_struct *work); |
598 | static void ftdi_set_termios (struct usb_serial_port *port, struct termios * old); | 598 | static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios * old); |
599 | static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file); | 599 | static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file); |
600 | static int ftdi_tiocmset (struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear); | 600 | static int ftdi_tiocmset (struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear); |
601 | static int ftdi_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); | 601 | static int ftdi_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); |
@@ -614,6 +614,7 @@ static struct usb_serial_driver ftdi_sio_device = { | |||
614 | .name = "ftdi_sio", | 614 | .name = "ftdi_sio", |
615 | }, | 615 | }, |
616 | .description = "FTDI USB Serial Device", | 616 | .description = "FTDI USB Serial Device", |
617 | .usb_driver = &ftdi_driver , | ||
617 | .id_table = id_table_combined, | 618 | .id_table = id_table_combined, |
618 | .num_interrupt_in = 0, | 619 | .num_interrupt_in = 0, |
619 | .num_bulk_in = 1, | 620 | .num_bulk_in = 1, |
@@ -1880,7 +1881,7 @@ static void ftdi_break_ctl( struct usb_serial_port *port, int break_state ) | |||
1880 | * WARNING: set_termios calls this with old_termios in kernel space | 1881 | * WARNING: set_termios calls this with old_termios in kernel space |
1881 | */ | 1882 | */ |
1882 | 1883 | ||
1883 | static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_termios) | 1884 | static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) |
1884 | { /* ftdi_termios */ | 1885 | { /* ftdi_termios */ |
1885 | struct usb_device *dev = port->serial->dev; | 1886 | struct usb_device *dev = port->serial->dev; |
1886 | unsigned int cflag = port->tty->termios->c_cflag; | 1887 | unsigned int cflag = port->tty->termios->c_cflag; |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index bae117d359af..7eff1c03ba80 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -312,8 +312,9 @@ | |||
312 | 312 | ||
313 | /* CCS Inc. ICDU/ICDU40 product ID - the FT232BM is used in an in-circuit-debugger */ | 313 | /* CCS Inc. ICDU/ICDU40 product ID - the FT232BM is used in an in-circuit-debugger */ |
314 | /* unit for PIC16's/PIC18's */ | 314 | /* unit for PIC16's/PIC18's */ |
315 | #define FTDI_CCSICDU20_0_PID 0xF9D0 | 315 | #define FTDI_CCSICDU20_0_PID 0xF9D0 |
316 | #define FTDI_CCSICDU40_1_PID 0xF9D1 | 316 | #define FTDI_CCSICDU40_1_PID 0xF9D1 |
317 | #define FTDI_CCSMACHX_2_PID 0xF9D2 | ||
317 | 318 | ||
318 | /* Inside Accesso contactless reader (http://www.insidefr.com) */ | 319 | /* Inside Accesso contactless reader (http://www.insidefr.com) */ |
319 | #define INSIDE_ACCESSO 0xFAD0 | 320 | #define INSIDE_ACCESSO 0xFAD0 |
@@ -363,7 +364,6 @@ | |||
363 | * USB-TTY activ, USB-TTY passiv. Some PIDs are used by several devices | 364 | * USB-TTY activ, USB-TTY passiv. Some PIDs are used by several devices |
364 | * and I'm not entirely sure which are used by which. | 365 | * and I'm not entirely sure which are used by which. |
365 | */ | 366 | */ |
366 | #define FTDI_4N_GALAXY_DE_0_PID 0x8372 | ||
367 | #define FTDI_4N_GALAXY_DE_1_PID 0xF3C0 | 367 | #define FTDI_4N_GALAXY_DE_1_PID 0xF3C0 |
368 | #define FTDI_4N_GALAXY_DE_2_PID 0xF3C1 | 368 | #define FTDI_4N_GALAXY_DE_2_PID 0xF3C1 |
369 | 369 | ||
diff --git a/drivers/usb/serial/funsoft.c b/drivers/usb/serial/funsoft.c index 77b977206a8c..4092f6dc9efd 100644 --- a/drivers/usb/serial/funsoft.c +++ b/drivers/usb/serial/funsoft.c | |||
@@ -14,6 +14,9 @@ | |||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/usb.h> | 15 | #include <linux/usb.h> |
16 | #include <linux/usb/serial.h> | 16 | #include <linux/usb/serial.h> |
17 | #include <asm/uaccess.h> | ||
18 | |||
19 | static int debug; | ||
17 | 20 | ||
18 | static struct usb_device_id id_table [] = { | 21 | static struct usb_device_id id_table [] = { |
19 | { USB_DEVICE(0x1404, 0xcddc) }, | 22 | { USB_DEVICE(0x1404, 0xcddc) }, |
@@ -21,6 +24,26 @@ static struct usb_device_id id_table [] = { | |||
21 | }; | 24 | }; |
22 | MODULE_DEVICE_TABLE(usb, id_table); | 25 | MODULE_DEVICE_TABLE(usb, id_table); |
23 | 26 | ||
27 | static int funsoft_ioctl(struct usb_serial_port *port, struct file *file, | ||
28 | unsigned int cmd, unsigned long arg) | ||
29 | { | ||
30 | struct ktermios t; | ||
31 | |||
32 | dbg("%s - port %d, cmd 0x%04x", __FUNCTION__, port->number, cmd); | ||
33 | |||
34 | if (cmd == TCSETSF) { | ||
35 | if (user_termios_to_kernel_termios(&t, (struct termios __user *)arg)) | ||
36 | return -EFAULT; | ||
37 | |||
38 | dbg("%s - iflag:%x oflag:%x cflag:%x lflag:%x", __FUNCTION__, | ||
39 | t.c_iflag, t.c_oflag, t.c_cflag, t.c_lflag); | ||
40 | |||
41 | if (!(t.c_lflag & ICANON)) | ||
42 | return -EINVAL; | ||
43 | } | ||
44 | return -ENOIOCTLCMD; | ||
45 | } | ||
46 | |||
24 | static struct usb_driver funsoft_driver = { | 47 | static struct usb_driver funsoft_driver = { |
25 | .name = "funsoft", | 48 | .name = "funsoft", |
26 | .probe = usb_serial_probe, | 49 | .probe = usb_serial_probe, |
@@ -35,10 +58,12 @@ static struct usb_serial_driver funsoft_device = { | |||
35 | .name = "funsoft", | 58 | .name = "funsoft", |
36 | }, | 59 | }, |
37 | .id_table = id_table, | 60 | .id_table = id_table, |
61 | .usb_driver = &funsoft_driver, | ||
38 | .num_interrupt_in = NUM_DONT_CARE, | 62 | .num_interrupt_in = NUM_DONT_CARE, |
39 | .num_bulk_in = NUM_DONT_CARE, | 63 | .num_bulk_in = NUM_DONT_CARE, |
40 | .num_bulk_out = NUM_DONT_CARE, | 64 | .num_bulk_out = NUM_DONT_CARE, |
41 | .num_ports = 1, | 65 | .num_ports = 1, |
66 | .ioctl = funsoft_ioctl, | ||
42 | }; | 67 | }; |
43 | 68 | ||
44 | static int __init funsoft_init(void) | 69 | static int __init funsoft_init(void) |
@@ -63,3 +88,6 @@ static void __exit funsoft_exit(void) | |||
63 | module_init(funsoft_init); | 88 | module_init(funsoft_init); |
64 | module_exit(funsoft_exit); | 89 | module_exit(funsoft_exit); |
65 | MODULE_LICENSE("GPL"); | 90 | MODULE_LICENSE("GPL"); |
91 | |||
92 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
93 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | ||
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 6530d391ebed..74660a3aa670 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c | |||
@@ -1566,6 +1566,7 @@ static struct usb_serial_driver garmin_device = { | |||
1566 | .name = "garmin_gps", | 1566 | .name = "garmin_gps", |
1567 | }, | 1567 | }, |
1568 | .description = "Garmin GPS usb/tty", | 1568 | .description = "Garmin GPS usb/tty", |
1569 | .usb_driver = &garmin_driver, | ||
1569 | .id_table = id_table, | 1570 | .id_table = id_table, |
1570 | .num_interrupt_in = 1, | 1571 | .num_interrupt_in = 1, |
1571 | .num_bulk_in = 1, | 1572 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index 36042937e77f..601e0648dec6 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c | |||
@@ -20,6 +20,10 @@ | |||
20 | #include <linux/usb/serial.h> | 20 | #include <linux/usb/serial.h> |
21 | #include <asm/uaccess.h> | 21 | #include <asm/uaccess.h> |
22 | 22 | ||
23 | static int generic_probe(struct usb_interface *interface, | ||
24 | const struct usb_device_id *id); | ||
25 | |||
26 | |||
23 | static int debug; | 27 | static int debug; |
24 | 28 | ||
25 | #ifdef CONFIG_USB_SERIAL_GENERIC | 29 | #ifdef CONFIG_USB_SERIAL_GENERIC |
@@ -34,6 +38,21 @@ MODULE_PARM_DESC(product, "User specified USB idProduct"); | |||
34 | 38 | ||
35 | static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ | 39 | static struct usb_device_id generic_device_ids[2]; /* Initially all zeroes. */ |
36 | 40 | ||
41 | /* we want to look at all devices, as the vendor/product id can change | ||
42 | * depending on the command line argument */ | ||
43 | static struct usb_device_id generic_serial_ids[] = { | ||
44 | {.driver_info = 42}, | ||
45 | {} | ||
46 | }; | ||
47 | |||
48 | static struct usb_driver generic_driver = { | ||
49 | .name = "usbserial_generic", | ||
50 | .probe = generic_probe, | ||
51 | .disconnect = usb_serial_disconnect, | ||
52 | .id_table = generic_serial_ids, | ||
53 | .no_dynamic_id = 1, | ||
54 | }; | ||
55 | |||
37 | /* All of the device info needed for the Generic Serial Converter */ | 56 | /* All of the device info needed for the Generic Serial Converter */ |
38 | struct usb_serial_driver usb_serial_generic_device = { | 57 | struct usb_serial_driver usb_serial_generic_device = { |
39 | .driver = { | 58 | .driver = { |
@@ -41,6 +60,7 @@ struct usb_serial_driver usb_serial_generic_device = { | |||
41 | .name = "generic", | 60 | .name = "generic", |
42 | }, | 61 | }, |
43 | .id_table = generic_device_ids, | 62 | .id_table = generic_device_ids, |
63 | .usb_driver = &generic_driver, | ||
44 | .num_interrupt_in = NUM_DONT_CARE, | 64 | .num_interrupt_in = NUM_DONT_CARE, |
45 | .num_bulk_in = NUM_DONT_CARE, | 65 | .num_bulk_in = NUM_DONT_CARE, |
46 | .num_bulk_out = NUM_DONT_CARE, | 66 | .num_bulk_out = NUM_DONT_CARE, |
@@ -48,13 +68,6 @@ struct usb_serial_driver usb_serial_generic_device = { | |||
48 | .shutdown = usb_serial_generic_shutdown, | 68 | .shutdown = usb_serial_generic_shutdown, |
49 | }; | 69 | }; |
50 | 70 | ||
51 | /* we want to look at all devices, as the vendor/product id can change | ||
52 | * depending on the command line argument */ | ||
53 | static struct usb_device_id generic_serial_ids[] = { | ||
54 | {.driver_info = 42}, | ||
55 | {} | ||
56 | }; | ||
57 | |||
58 | static int generic_probe(struct usb_interface *interface, | 71 | static int generic_probe(struct usb_interface *interface, |
59 | const struct usb_device_id *id) | 72 | const struct usb_device_id *id) |
60 | { | 73 | { |
@@ -65,14 +78,6 @@ static int generic_probe(struct usb_interface *interface, | |||
65 | return usb_serial_probe(interface, id); | 78 | return usb_serial_probe(interface, id); |
66 | return -ENODEV; | 79 | return -ENODEV; |
67 | } | 80 | } |
68 | |||
69 | static struct usb_driver generic_driver = { | ||
70 | .name = "usbserial_generic", | ||
71 | .probe = generic_probe, | ||
72 | .disconnect = usb_serial_disconnect, | ||
73 | .id_table = generic_serial_ids, | ||
74 | .no_dynamic_id = 1, | ||
75 | }; | ||
76 | #endif | 81 | #endif |
77 | 82 | ||
78 | int usb_serial_generic_register (int _debug) | 83 | int usb_serial_generic_register (int _debug) |
diff --git a/drivers/usb/serial/hp4x.c b/drivers/usb/serial/hp4x.c index ebcac701b069..6c6ebae741c9 100644 --- a/drivers/usb/serial/hp4x.c +++ b/drivers/usb/serial/hp4x.c | |||
@@ -49,6 +49,7 @@ static struct usb_serial_driver hp49gp_device = { | |||
49 | .name = "hp4X", | 49 | .name = "hp4X", |
50 | }, | 50 | }, |
51 | .id_table = id_table, | 51 | .id_table = id_table, |
52 | .usb_driver = &hp49gp_driver, | ||
52 | .num_interrupt_in = NUM_DONT_CARE, | 53 | .num_interrupt_in = NUM_DONT_CARE, |
53 | .num_bulk_in = NUM_DONT_CARE, | 54 | .num_bulk_in = NUM_DONT_CARE, |
54 | .num_bulk_out = NUM_DONT_CARE, | 55 | .num_bulk_out = NUM_DONT_CARE, |
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index d06547a13f28..6a26a2e683a6 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
@@ -146,6 +146,8 @@ struct edgeport_serial { | |||
146 | struct edge_manuf_descriptor manuf_descriptor; /* the manufacturer descriptor */ | 146 | struct edge_manuf_descriptor manuf_descriptor; /* the manufacturer descriptor */ |
147 | struct edge_boot_descriptor boot_descriptor; /* the boot firmware descriptor */ | 147 | struct edge_boot_descriptor boot_descriptor; /* the boot firmware descriptor */ |
148 | struct edgeport_product_info product_info; /* Product Info */ | 148 | struct edgeport_product_info product_info; /* Product Info */ |
149 | struct edge_compatibility_descriptor epic_descriptor; /* Edgeport compatible descriptor */ | ||
150 | int is_epic; /* flag if EPiC device or not */ | ||
149 | 151 | ||
150 | __u8 interrupt_in_endpoint; /* the interrupt endpoint handle */ | 152 | __u8 interrupt_in_endpoint; /* the interrupt endpoint handle */ |
151 | unsigned char * interrupt_in_buffer; /* the buffer we use for the interrupt endpoint */ | 153 | unsigned char * interrupt_in_buffer; /* the buffer we use for the interrupt endpoint */ |
@@ -229,7 +231,7 @@ static int edge_write_room (struct usb_serial_port *port); | |||
229 | static int edge_chars_in_buffer (struct usb_serial_port *port); | 231 | static int edge_chars_in_buffer (struct usb_serial_port *port); |
230 | static void edge_throttle (struct usb_serial_port *port); | 232 | static void edge_throttle (struct usb_serial_port *port); |
231 | static void edge_unthrottle (struct usb_serial_port *port); | 233 | static void edge_unthrottle (struct usb_serial_port *port); |
232 | static void edge_set_termios (struct usb_serial_port *port, struct termios *old_termios); | 234 | static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old_termios); |
233 | static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg); | 235 | static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg); |
234 | static void edge_break (struct usb_serial_port *port, int break_state); | 236 | static void edge_break (struct usb_serial_port *port, int break_state); |
235 | static int edge_tiocmget (struct usb_serial_port *port, struct file *file); | 237 | static int edge_tiocmget (struct usb_serial_port *port, struct file *file); |
@@ -240,14 +242,6 @@ static void edge_shutdown (struct usb_serial *serial); | |||
240 | 242 | ||
241 | #include "io_tables.h" /* all of the devices that this driver supports */ | 243 | #include "io_tables.h" /* all of the devices that this driver supports */ |
242 | 244 | ||
243 | static struct usb_driver io_driver = { | ||
244 | .name = "io_edgeport", | ||
245 | .probe = usb_serial_probe, | ||
246 | .disconnect = usb_serial_disconnect, | ||
247 | .id_table = id_table_combined, | ||
248 | .no_dynamic_id = 1, | ||
249 | }; | ||
250 | |||
251 | /* function prototypes for all of our local functions */ | 245 | /* function prototypes for all of our local functions */ |
252 | static void process_rcvd_data (struct edgeport_serial *edge_serial, unsigned char *buffer, __u16 bufferLength); | 246 | static void process_rcvd_data (struct edgeport_serial *edge_serial, unsigned char *buffer, __u16 bufferLength); |
253 | static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2, __u8 byte3); | 247 | static void process_rcvd_status (struct edgeport_serial *edge_serial, __u8 byte2, __u8 byte3); |
@@ -257,7 +251,7 @@ static void handle_new_lsr (struct edgeport_port *edge_port, __u8 lsrData, __u8 | |||
257 | static int send_iosp_ext_cmd (struct edgeport_port *edge_port, __u8 command, __u8 param); | 251 | static int send_iosp_ext_cmd (struct edgeport_port *edge_port, __u8 command, __u8 param); |
258 | static int calc_baud_rate_divisor (int baud_rate, int *divisor); | 252 | static int calc_baud_rate_divisor (int baud_rate, int *divisor); |
259 | static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRate); | 253 | static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRate); |
260 | static void change_port_settings (struct edgeport_port *edge_port, struct termios *old_termios); | 254 | static void change_port_settings (struct edgeport_port *edge_port, struct ktermios *old_termios); |
261 | static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 regNum, __u8 regValue); | 255 | static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 regNum, __u8 regValue); |
262 | static int write_cmd_usb (struct edgeport_port *edge_port, unsigned char *buffer, int writeLength); | 256 | static int write_cmd_usb (struct edgeport_port *edge_port, unsigned char *buffer, int writeLength); |
263 | static void send_more_port_data (struct edgeport_serial *edge_serial, struct edgeport_port *edge_port); | 257 | static void send_more_port_data (struct edgeport_serial *edge_serial, struct edgeport_port *edge_port); |
@@ -397,6 +391,7 @@ static int get_string (struct usb_device *dev, int Id, char *string, int buflen) | |||
397 | unicode_to_ascii(string, buflen, pStringDesc->wData, pStringDesc->bLength/2); | 391 | unicode_to_ascii(string, buflen, pStringDesc->wData, pStringDesc->bLength/2); |
398 | 392 | ||
399 | kfree(pStringDesc); | 393 | kfree(pStringDesc); |
394 | dbg("%s - USB String %s", __FUNCTION__, string); | ||
400 | return strlen(string); | 395 | return strlen(string); |
401 | } | 396 | } |
402 | 397 | ||
@@ -434,6 +429,34 @@ static int get_string_desc (struct usb_device *dev, int Id, struct usb_string_de | |||
434 | } | 429 | } |
435 | #endif | 430 | #endif |
436 | 431 | ||
432 | static void dump_product_info(struct edgeport_product_info *product_info) | ||
433 | { | ||
434 | // Dump Product Info structure | ||
435 | dbg("**Product Information:"); | ||
436 | dbg(" ProductId %x", product_info->ProductId ); | ||
437 | dbg(" NumPorts %d", product_info->NumPorts ); | ||
438 | dbg(" ProdInfoVer %d", product_info->ProdInfoVer ); | ||
439 | dbg(" IsServer %d", product_info->IsServer); | ||
440 | dbg(" IsRS232 %d", product_info->IsRS232 ); | ||
441 | dbg(" IsRS422 %d", product_info->IsRS422 ); | ||
442 | dbg(" IsRS485 %d", product_info->IsRS485 ); | ||
443 | dbg(" RomSize %d", product_info->RomSize ); | ||
444 | dbg(" RamSize %d", product_info->RamSize ); | ||
445 | dbg(" CpuRev %x", product_info->CpuRev ); | ||
446 | dbg(" BoardRev %x", product_info->BoardRev); | ||
447 | dbg(" BootMajorVersion %d.%d.%d", product_info->BootMajorVersion, | ||
448 | product_info->BootMinorVersion, | ||
449 | le16_to_cpu(product_info->BootBuildNumber)); | ||
450 | dbg(" FirmwareMajorVersion %d.%d.%d", product_info->FirmwareMajorVersion, | ||
451 | product_info->FirmwareMinorVersion, | ||
452 | le16_to_cpu(product_info->FirmwareBuildNumber)); | ||
453 | dbg(" ManufactureDescDate %d/%d/%d", product_info->ManufactureDescDate[0], | ||
454 | product_info->ManufactureDescDate[1], | ||
455 | product_info->ManufactureDescDate[2]+1900); | ||
456 | dbg(" iDownloadFile 0x%x", product_info->iDownloadFile); | ||
457 | dbg(" EpicVer %d", product_info->EpicVer); | ||
458 | } | ||
459 | |||
437 | static void get_product_info(struct edgeport_serial *edge_serial) | 460 | static void get_product_info(struct edgeport_serial *edge_serial) |
438 | { | 461 | { |
439 | struct edgeport_product_info *product_info = &edge_serial->product_info; | 462 | struct edgeport_product_info *product_info = &edge_serial->product_info; |
@@ -495,30 +518,60 @@ static void get_product_info(struct edgeport_serial *edge_serial) | |||
495 | break; | 518 | break; |
496 | } | 519 | } |
497 | 520 | ||
498 | // Dump Product Info structure | 521 | dump_product_info(product_info); |
499 | dbg("**Product Information:"); | 522 | } |
500 | dbg(" ProductId %x", product_info->ProductId ); | ||
501 | dbg(" NumPorts %d", product_info->NumPorts ); | ||
502 | dbg(" ProdInfoVer %d", product_info->ProdInfoVer ); | ||
503 | dbg(" IsServer %d", product_info->IsServer); | ||
504 | dbg(" IsRS232 %d", product_info->IsRS232 ); | ||
505 | dbg(" IsRS422 %d", product_info->IsRS422 ); | ||
506 | dbg(" IsRS485 %d", product_info->IsRS485 ); | ||
507 | dbg(" RomSize %d", product_info->RomSize ); | ||
508 | dbg(" RamSize %d", product_info->RamSize ); | ||
509 | dbg(" CpuRev %x", product_info->CpuRev ); | ||
510 | dbg(" BoardRev %x", product_info->BoardRev); | ||
511 | dbg(" BootMajorVersion %d.%d.%d", product_info->BootMajorVersion, | ||
512 | product_info->BootMinorVersion, | ||
513 | le16_to_cpu(product_info->BootBuildNumber)); | ||
514 | dbg(" FirmwareMajorVersion %d.%d.%d", product_info->FirmwareMajorVersion, | ||
515 | product_info->FirmwareMinorVersion, | ||
516 | le16_to_cpu(product_info->FirmwareBuildNumber)); | ||
517 | dbg(" ManufactureDescDate %d/%d/%d", product_info->ManufactureDescDate[0], | ||
518 | product_info->ManufactureDescDate[1], | ||
519 | product_info->ManufactureDescDate[2]+1900); | ||
520 | dbg(" iDownloadFile 0x%x", product_info->iDownloadFile); | ||
521 | 523 | ||
524 | static int get_epic_descriptor(struct edgeport_serial *ep) | ||
525 | { | ||
526 | int result; | ||
527 | struct usb_serial *serial = ep->serial; | ||
528 | struct edgeport_product_info *product_info = &ep->product_info; | ||
529 | struct edge_compatibility_descriptor *epic = &ep->epic_descriptor; | ||
530 | struct edge_compatibility_bits *bits; | ||
531 | |||
532 | ep->is_epic = 0; | ||
533 | result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), | ||
534 | USB_REQUEST_ION_GET_EPIC_DESC, | ||
535 | 0xC0, 0x00, 0x00, | ||
536 | &ep->epic_descriptor, | ||
537 | sizeof(struct edge_compatibility_descriptor), | ||
538 | 300); | ||
539 | |||
540 | dbg("%s result = %d", __FUNCTION__, result); | ||
541 | |||
542 | if (result > 0) { | ||
543 | ep->is_epic = 1; | ||
544 | memset(product_info, 0, sizeof(struct edgeport_product_info)); | ||
545 | |||
546 | product_info->NumPorts = epic->NumPorts; | ||
547 | product_info->ProdInfoVer = 0; | ||
548 | product_info->FirmwareMajorVersion = epic->MajorVersion; | ||
549 | product_info->FirmwareMinorVersion = epic->MinorVersion; | ||
550 | product_info->FirmwareBuildNumber = epic->BuildNumber; | ||
551 | product_info->iDownloadFile = epic->iDownloadFile; | ||
552 | product_info->EpicVer = epic->EpicVer; | ||
553 | product_info->Epic = epic->Supports; | ||
554 | product_info->ProductId = ION_DEVICE_ID_EDGEPORT_COMPATIBLE; | ||
555 | dump_product_info(product_info); | ||
556 | |||
557 | bits = &ep->epic_descriptor.Supports; | ||
558 | dbg("**EPIC descriptor:"); | ||
559 | dbg(" VendEnableSuspend: %s", bits->VendEnableSuspend ? "TRUE": "FALSE"); | ||
560 | dbg(" IOSPOpen : %s", bits->IOSPOpen ? "TRUE": "FALSE" ); | ||
561 | dbg(" IOSPClose : %s", bits->IOSPClose ? "TRUE": "FALSE" ); | ||
562 | dbg(" IOSPChase : %s", bits->IOSPChase ? "TRUE": "FALSE" ); | ||
563 | dbg(" IOSPSetRxFlow : %s", bits->IOSPSetRxFlow ? "TRUE": "FALSE" ); | ||
564 | dbg(" IOSPSetTxFlow : %s", bits->IOSPSetTxFlow ? "TRUE": "FALSE" ); | ||
565 | dbg(" IOSPSetXChar : %s", bits->IOSPSetXChar ? "TRUE": "FALSE" ); | ||
566 | dbg(" IOSPRxCheck : %s", bits->IOSPRxCheck ? "TRUE": "FALSE" ); | ||
567 | dbg(" IOSPSetClrBreak : %s", bits->IOSPSetClrBreak ? "TRUE": "FALSE" ); | ||
568 | dbg(" IOSPWriteMCR : %s", bits->IOSPWriteMCR ? "TRUE": "FALSE" ); | ||
569 | dbg(" IOSPWriteLCR : %s", bits->IOSPWriteLCR ? "TRUE": "FALSE" ); | ||
570 | dbg(" IOSPSetBaudRate : %s", bits->IOSPSetBaudRate ? "TRUE": "FALSE" ); | ||
571 | dbg(" TrueEdgeport : %s", bits->TrueEdgeport ? "TRUE": "FALSE" ); | ||
572 | } | ||
573 | |||
574 | return result; | ||
522 | } | 575 | } |
523 | 576 | ||
524 | 577 | ||
@@ -1017,21 +1070,29 @@ static void edge_close (struct usb_serial_port *port, struct file * filp) | |||
1017 | 1070 | ||
1018 | edge_port->closePending = TRUE; | 1071 | edge_port->closePending = TRUE; |
1019 | 1072 | ||
1020 | /* flush and chase */ | 1073 | if ((!edge_serial->is_epic) || |
1021 | edge_port->chaseResponsePending = TRUE; | 1074 | ((edge_serial->is_epic) && |
1022 | 1075 | (edge_serial->epic_descriptor.Supports.IOSPChase))) { | |
1023 | dbg("%s - Sending IOSP_CMD_CHASE_PORT", __FUNCTION__); | 1076 | /* flush and chase */ |
1024 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); | 1077 | edge_port->chaseResponsePending = TRUE; |
1025 | if (status == 0) { | 1078 | |
1026 | // block until chase finished | 1079 | dbg("%s - Sending IOSP_CMD_CHASE_PORT", __FUNCTION__); |
1027 | block_until_chase_response(edge_port); | 1080 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); |
1028 | } else { | 1081 | if (status == 0) { |
1029 | edge_port->chaseResponsePending = FALSE; | 1082 | // block until chase finished |
1083 | block_until_chase_response(edge_port); | ||
1084 | } else { | ||
1085 | edge_port->chaseResponsePending = FALSE; | ||
1086 | } | ||
1030 | } | 1087 | } |
1031 | 1088 | ||
1032 | /* close the port */ | 1089 | if ((!edge_serial->is_epic) || |
1033 | dbg("%s - Sending IOSP_CMD_CLOSE_PORT", __FUNCTION__); | 1090 | ((edge_serial->is_epic) && |
1034 | send_iosp_ext_cmd (edge_port, IOSP_CMD_CLOSE_PORT, 0); | 1091 | (edge_serial->epic_descriptor.Supports.IOSPClose))) { |
1092 | /* close the port */ | ||
1093 | dbg("%s - Sending IOSP_CMD_CLOSE_PORT", __FUNCTION__); | ||
1094 | send_iosp_ext_cmd (edge_port, IOSP_CMD_CLOSE_PORT, 0); | ||
1095 | } | ||
1035 | 1096 | ||
1036 | //port->close = TRUE; | 1097 | //port->close = TRUE; |
1037 | edge_port->closePending = FALSE; | 1098 | edge_port->closePending = FALSE; |
@@ -1431,7 +1492,7 @@ static void edge_unthrottle (struct usb_serial_port *port) | |||
1431 | * SerialSetTermios | 1492 | * SerialSetTermios |
1432 | * this function is called by the tty driver when it wants to change the termios structure | 1493 | * this function is called by the tty driver when it wants to change the termios structure |
1433 | *****************************************************************************/ | 1494 | *****************************************************************************/ |
1434 | static void edge_set_termios (struct usb_serial_port *port, struct termios *old_termios) | 1495 | static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) |
1435 | { | 1496 | { |
1436 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); | 1497 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); |
1437 | struct tty_struct *tty = port->tty; | 1498 | struct tty_struct *tty = port->tty; |
@@ -1694,29 +1755,38 @@ static int edge_ioctl (struct usb_serial_port *port, struct file *file, unsigned | |||
1694 | static void edge_break (struct usb_serial_port *port, int break_state) | 1755 | static void edge_break (struct usb_serial_port *port, int break_state) |
1695 | { | 1756 | { |
1696 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); | 1757 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); |
1758 | struct edgeport_serial *edge_serial = usb_get_serial_data(port->serial); | ||
1697 | int status; | 1759 | int status; |
1698 | 1760 | ||
1699 | /* flush and chase */ | 1761 | if ((!edge_serial->is_epic) || |
1700 | edge_port->chaseResponsePending = TRUE; | 1762 | ((edge_serial->is_epic) && |
1701 | 1763 | (edge_serial->epic_descriptor.Supports.IOSPChase))) { | |
1702 | dbg("%s - Sending IOSP_CMD_CHASE_PORT", __FUNCTION__); | 1764 | /* flush and chase */ |
1703 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); | 1765 | edge_port->chaseResponsePending = TRUE; |
1704 | if (status == 0) { | 1766 | |
1705 | // block until chase finished | 1767 | dbg("%s - Sending IOSP_CMD_CHASE_PORT", __FUNCTION__); |
1706 | block_until_chase_response(edge_port); | 1768 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CHASE_PORT, 0); |
1707 | } else { | 1769 | if (status == 0) { |
1708 | edge_port->chaseResponsePending = FALSE; | 1770 | // block until chase finished |
1771 | block_until_chase_response(edge_port); | ||
1772 | } else { | ||
1773 | edge_port->chaseResponsePending = FALSE; | ||
1774 | } | ||
1709 | } | 1775 | } |
1710 | 1776 | ||
1711 | if (break_state == -1) { | 1777 | if ((!edge_serial->is_epic) || |
1712 | dbg("%s - Sending IOSP_CMD_SET_BREAK", __FUNCTION__); | 1778 | ((edge_serial->is_epic) && |
1713 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_BREAK, 0); | 1779 | (edge_serial->epic_descriptor.Supports.IOSPSetClrBreak))) { |
1714 | } else { | 1780 | if (break_state == -1) { |
1715 | dbg("%s - Sending IOSP_CMD_CLEAR_BREAK", __FUNCTION__); | 1781 | dbg("%s - Sending IOSP_CMD_SET_BREAK", __FUNCTION__); |
1716 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CLEAR_BREAK, 0); | 1782 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_BREAK, 0); |
1717 | } | 1783 | } else { |
1718 | if (status) { | 1784 | dbg("%s - Sending IOSP_CMD_CLEAR_BREAK", __FUNCTION__); |
1719 | dbg("%s - error sending break set/clear command.", __FUNCTION__); | 1785 | status = send_iosp_ext_cmd (edge_port, IOSP_CMD_CLEAR_BREAK, 0); |
1786 | } | ||
1787 | if (status) { | ||
1788 | dbg("%s - error sending break set/clear command.", __FUNCTION__); | ||
1789 | } | ||
1720 | } | 1790 | } |
1721 | 1791 | ||
1722 | return; | 1792 | return; |
@@ -2288,6 +2358,7 @@ static int write_cmd_usb (struct edgeport_port *edge_port, unsigned char *buffer | |||
2288 | *****************************************************************************/ | 2358 | *****************************************************************************/ |
2289 | static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRate) | 2359 | static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRate) |
2290 | { | 2360 | { |
2361 | struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial); | ||
2291 | unsigned char *cmdBuffer; | 2362 | unsigned char *cmdBuffer; |
2292 | unsigned char *currCmd; | 2363 | unsigned char *currCmd; |
2293 | int cmdLen = 0; | 2364 | int cmdLen = 0; |
@@ -2295,6 +2366,14 @@ static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRa | |||
2295 | int status; | 2366 | int status; |
2296 | unsigned char number = edge_port->port->number - edge_port->port->serial->minor; | 2367 | unsigned char number = edge_port->port->number - edge_port->port->serial->minor; |
2297 | 2368 | ||
2369 | if ((!edge_serial->is_epic) || | ||
2370 | ((edge_serial->is_epic) && | ||
2371 | (!edge_serial->epic_descriptor.Supports.IOSPSetBaudRate))) { | ||
2372 | dbg("SendCmdWriteBaudRate - NOT Setting baud rate for port = %d, baud = %d", | ||
2373 | edge_port->port->number, baudRate); | ||
2374 | return 0; | ||
2375 | } | ||
2376 | |||
2298 | dbg("%s - port = %d, baud = %d", __FUNCTION__, edge_port->port->number, baudRate); | 2377 | dbg("%s - port = %d, baud = %d", __FUNCTION__, edge_port->port->number, baudRate); |
2299 | 2378 | ||
2300 | status = calc_baud_rate_divisor (baudRate, &divisor); | 2379 | status = calc_baud_rate_divisor (baudRate, &divisor); |
@@ -2374,6 +2453,7 @@ static int calc_baud_rate_divisor (int baudrate, int *divisor) | |||
2374 | *****************************************************************************/ | 2453 | *****************************************************************************/ |
2375 | static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 regNum, __u8 regValue) | 2454 | static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 regNum, __u8 regValue) |
2376 | { | 2455 | { |
2456 | struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial); | ||
2377 | unsigned char *cmdBuffer; | 2457 | unsigned char *cmdBuffer; |
2378 | unsigned char *currCmd; | 2458 | unsigned char *currCmd; |
2379 | unsigned long cmdLen = 0; | 2459 | unsigned long cmdLen = 0; |
@@ -2381,6 +2461,22 @@ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 r | |||
2381 | 2461 | ||
2382 | dbg("%s - write to %s register 0x%02x", (regNum == MCR) ? "MCR" : "LCR", __FUNCTION__, regValue); | 2462 | dbg("%s - write to %s register 0x%02x", (regNum == MCR) ? "MCR" : "LCR", __FUNCTION__, regValue); |
2383 | 2463 | ||
2464 | if ((!edge_serial->is_epic) || | ||
2465 | ((edge_serial->is_epic) && | ||
2466 | (!edge_serial->epic_descriptor.Supports.IOSPWriteMCR) && | ||
2467 | (regNum == MCR))) { | ||
2468 | dbg("SendCmdWriteUartReg - Not writting to MCR Register"); | ||
2469 | return 0; | ||
2470 | } | ||
2471 | |||
2472 | if ((!edge_serial->is_epic) || | ||
2473 | ((edge_serial->is_epic) && | ||
2474 | (!edge_serial->epic_descriptor.Supports.IOSPWriteLCR) && | ||
2475 | (regNum == LCR))) { | ||
2476 | dbg ("SendCmdWriteUartReg - Not writting to LCR Register"); | ||
2477 | return 0; | ||
2478 | } | ||
2479 | |||
2384 | // Alloc memory for the string of commands. | 2480 | // Alloc memory for the string of commands. |
2385 | cmdBuffer = kmalloc (0x10, GFP_ATOMIC); | 2481 | cmdBuffer = kmalloc (0x10, GFP_ATOMIC); |
2386 | if (cmdBuffer == NULL ) { | 2482 | if (cmdBuffer == NULL ) { |
@@ -2412,8 +2508,9 @@ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 r | |||
2412 | #ifndef CMSPAR | 2508 | #ifndef CMSPAR |
2413 | #define CMSPAR 0 | 2509 | #define CMSPAR 0 |
2414 | #endif | 2510 | #endif |
2415 | static void change_port_settings (struct edgeport_port *edge_port, struct termios *old_termios) | 2511 | static void change_port_settings (struct edgeport_port *edge_port, struct ktermios *old_termios) |
2416 | { | 2512 | { |
2513 | struct edgeport_serial *edge_serial = usb_get_serial_data(edge_port->port->serial); | ||
2417 | struct tty_struct *tty; | 2514 | struct tty_struct *tty; |
2418 | int baud; | 2515 | int baud; |
2419 | unsigned cflag; | 2516 | unsigned cflag; |
@@ -2494,8 +2591,12 @@ static void change_port_settings (struct edgeport_port *edge_port, struct termio | |||
2494 | unsigned char stop_char = STOP_CHAR(tty); | 2591 | unsigned char stop_char = STOP_CHAR(tty); |
2495 | unsigned char start_char = START_CHAR(tty); | 2592 | unsigned char start_char = START_CHAR(tty); |
2496 | 2593 | ||
2497 | send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_XON_CHAR, start_char); | 2594 | if ((!edge_serial->is_epic) || |
2498 | send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_XOFF_CHAR, stop_char); | 2595 | ((edge_serial->is_epic) && |
2596 | (edge_serial->epic_descriptor.Supports.IOSPSetXChar))) { | ||
2597 | send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_XON_CHAR, start_char); | ||
2598 | send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_XOFF_CHAR, stop_char); | ||
2599 | } | ||
2499 | 2600 | ||
2500 | /* if we are implementing INBOUND XON/XOFF */ | 2601 | /* if we are implementing INBOUND XON/XOFF */ |
2501 | if (I_IXOFF(tty)) { | 2602 | if (I_IXOFF(tty)) { |
@@ -2515,8 +2616,14 @@ static void change_port_settings (struct edgeport_port *edge_port, struct termio | |||
2515 | } | 2616 | } |
2516 | 2617 | ||
2517 | /* Set flow control to the configured value */ | 2618 | /* Set flow control to the configured value */ |
2518 | send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_RX_FLOW, rxFlow); | 2619 | if ((!edge_serial->is_epic) || |
2519 | send_iosp_ext_cmd (edge_port, IOSP_CMD_SET_TX_FLOW, txFlow); | 2620 | ((edge_serial->is_epic) && |
2621 | (edge_serial->epic_descriptor.Supports.IOSPSetRxFlow))) | ||
2622 | send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_RX_FLOW, rxFlow); | ||
2623 | if ((!edge_serial->is_epic) || | ||
2624 | ((edge_serial->is_epic) && | ||
2625 | (edge_serial->epic_descriptor.Supports.IOSPSetTxFlow))) | ||
2626 | send_iosp_ext_cmd(edge_port, IOSP_CMD_SET_TX_FLOW, txFlow); | ||
2520 | 2627 | ||
2521 | 2628 | ||
2522 | edge_port->shadowLCR &= ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK); | 2629 | edge_port->shadowLCR &= ~(LCR_BITS_MASK | LCR_STOP_MASK | LCR_PAR_MASK); |
@@ -2728,6 +2835,13 @@ static int edge_startup (struct usb_serial *serial) | |||
2728 | struct edgeport_port *edge_port; | 2835 | struct edgeport_port *edge_port; |
2729 | struct usb_device *dev; | 2836 | struct usb_device *dev; |
2730 | int i, j; | 2837 | int i, j; |
2838 | int response; | ||
2839 | int interrupt_in_found; | ||
2840 | int bulk_in_found; | ||
2841 | int bulk_out_found; | ||
2842 | static __u32 descriptor[3] = { EDGE_COMPATIBILITY_MASK0, | ||
2843 | EDGE_COMPATIBILITY_MASK1, | ||
2844 | EDGE_COMPATIBILITY_MASK2 }; | ||
2731 | 2845 | ||
2732 | dev = serial->dev; | 2846 | dev = serial->dev; |
2733 | 2847 | ||
@@ -2750,38 +2864,50 @@ static int edge_startup (struct usb_serial *serial) | |||
2750 | 2864 | ||
2751 | dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name); | 2865 | dev_info(&serial->dev->dev, "%s detected\n", edge_serial->name); |
2752 | 2866 | ||
2753 | /* get the manufacturing descriptor for this device */ | 2867 | /* Read the epic descriptor */ |
2754 | get_manufacturing_desc (edge_serial); | 2868 | if (get_epic_descriptor(edge_serial) <= 0) { |
2869 | /* memcpy descriptor to Supports structures */ | ||
2870 | memcpy(&edge_serial->epic_descriptor.Supports, descriptor, | ||
2871 | sizeof(struct edge_compatibility_bits)); | ||
2872 | |||
2873 | /* get the manufacturing descriptor for this device */ | ||
2874 | get_manufacturing_desc (edge_serial); | ||
2755 | 2875 | ||
2756 | /* get the boot descriptor */ | 2876 | /* get the boot descriptor */ |
2757 | get_boot_desc (edge_serial); | 2877 | get_boot_desc (edge_serial); |
2758 | 2878 | ||
2759 | get_product_info(edge_serial); | 2879 | get_product_info(edge_serial); |
2880 | } | ||
2760 | 2881 | ||
2761 | /* set the number of ports from the manufacturing description */ | 2882 | /* set the number of ports from the manufacturing description */ |
2762 | /* serial->num_ports = serial->product_info.NumPorts; */ | 2883 | /* serial->num_ports = serial->product_info.NumPorts; */ |
2763 | if (edge_serial->product_info.NumPorts != serial->num_ports) { | 2884 | if ((!edge_serial->is_epic) && |
2764 | warn("%s - Device Reported %d serial ports vs core " | 2885 | (edge_serial->product_info.NumPorts != serial->num_ports)) { |
2765 | "thinking we have %d ports, email greg@kroah.com this info.", | 2886 | dev_warn(&serial->dev->dev, "Device Reported %d serial ports " |
2766 | __FUNCTION__, edge_serial->product_info.NumPorts, | 2887 | "vs. core thinking we have %d ports, email " |
2767 | serial->num_ports); | 2888 | "greg@kroah.com this information.", |
2889 | edge_serial->product_info.NumPorts, | ||
2890 | serial->num_ports); | ||
2768 | } | 2891 | } |
2769 | 2892 | ||
2770 | dbg("%s - time 1 %ld", __FUNCTION__, jiffies); | 2893 | dbg("%s - time 1 %ld", __FUNCTION__, jiffies); |
2771 | 2894 | ||
2772 | /* now load the application firmware into this device */ | 2895 | /* If not an EPiC device */ |
2773 | load_application_firmware (edge_serial); | 2896 | if (!edge_serial->is_epic) { |
2897 | /* now load the application firmware into this device */ | ||
2898 | load_application_firmware (edge_serial); | ||
2774 | 2899 | ||
2775 | dbg("%s - time 2 %ld", __FUNCTION__, jiffies); | 2900 | dbg("%s - time 2 %ld", __FUNCTION__, jiffies); |
2776 | 2901 | ||
2777 | /* Check current Edgeport EEPROM and update if necessary */ | 2902 | /* Check current Edgeport EEPROM and update if necessary */ |
2778 | update_edgeport_E2PROM (edge_serial); | 2903 | update_edgeport_E2PROM (edge_serial); |
2779 | |||
2780 | dbg("%s - time 3 %ld", __FUNCTION__, jiffies); | ||
2781 | 2904 | ||
2782 | /* set the configuration to use #1 */ | 2905 | dbg("%s - time 3 %ld", __FUNCTION__, jiffies); |
2783 | // dbg("set_configuration 1"); | 2906 | |
2784 | // usb_set_configuration (dev, 1); | 2907 | /* set the configuration to use #1 */ |
2908 | // dbg("set_configuration 1"); | ||
2909 | // usb_set_configuration (dev, 1); | ||
2910 | } | ||
2785 | 2911 | ||
2786 | /* we set up the pointers to the endpoints in the edge_open function, | 2912 | /* we set up the pointers to the endpoints in the edge_open function, |
2787 | * as the structures aren't created yet. */ | 2913 | * as the structures aren't created yet. */ |
@@ -2804,8 +2930,101 @@ static int edge_startup (struct usb_serial *serial) | |||
2804 | edge_port->port = serial->port[i]; | 2930 | edge_port->port = serial->port[i]; |
2805 | usb_set_serial_port_data(serial->port[i], edge_port); | 2931 | usb_set_serial_port_data(serial->port[i], edge_port); |
2806 | } | 2932 | } |
2807 | 2933 | ||
2808 | return 0; | 2934 | response = 0; |
2935 | |||
2936 | if (edge_serial->is_epic) { | ||
2937 | /* EPIC thing, set up our interrupt polling now and our read urb, so | ||
2938 | * that the device knows it really is connected. */ | ||
2939 | interrupt_in_found = bulk_in_found = bulk_out_found = FALSE; | ||
2940 | for (i = 0; i < serial->interface->altsetting[0].desc.bNumEndpoints; ++i) { | ||
2941 | struct usb_endpoint_descriptor *endpoint; | ||
2942 | int buffer_size; | ||
2943 | |||
2944 | endpoint = &serial->interface->altsetting[0].endpoint[i].desc; | ||
2945 | buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); | ||
2946 | if ((!interrupt_in_found) && | ||
2947 | (usb_endpoint_is_int_in(endpoint))) { | ||
2948 | /* we found a interrupt in endpoint */ | ||
2949 | dbg("found interrupt in"); | ||
2950 | |||
2951 | /* not set up yet, so do it now */ | ||
2952 | edge_serial->interrupt_read_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
2953 | if (!edge_serial->interrupt_read_urb) { | ||
2954 | err("out of memory"); | ||
2955 | return -ENOMEM; | ||
2956 | } | ||
2957 | edge_serial->interrupt_in_buffer = kmalloc(buffer_size, GFP_KERNEL); | ||
2958 | if (!edge_serial->interrupt_in_buffer) { | ||
2959 | err("out of memory"); | ||
2960 | usb_free_urb(edge_serial->interrupt_read_urb); | ||
2961 | return -ENOMEM; | ||
2962 | } | ||
2963 | edge_serial->interrupt_in_endpoint = endpoint->bEndpointAddress; | ||
2964 | |||
2965 | /* set up our interrupt urb */ | ||
2966 | usb_fill_int_urb(edge_serial->interrupt_read_urb, | ||
2967 | dev, | ||
2968 | usb_rcvintpipe(dev, endpoint->bEndpointAddress), | ||
2969 | edge_serial->interrupt_in_buffer, | ||
2970 | buffer_size, | ||
2971 | edge_interrupt_callback, | ||
2972 | edge_serial, | ||
2973 | endpoint->bInterval); | ||
2974 | |||
2975 | interrupt_in_found = TRUE; | ||
2976 | } | ||
2977 | |||
2978 | if ((!bulk_in_found) && | ||
2979 | (usb_endpoint_is_bulk_in(endpoint))) { | ||
2980 | /* we found a bulk in endpoint */ | ||
2981 | dbg("found bulk in"); | ||
2982 | |||
2983 | /* not set up yet, so do it now */ | ||
2984 | edge_serial->read_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
2985 | if (!edge_serial->read_urb) { | ||
2986 | err("out of memory"); | ||
2987 | return -ENOMEM; | ||
2988 | } | ||
2989 | edge_serial->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL); | ||
2990 | if (!edge_serial->bulk_in_buffer) { | ||
2991 | err ("out of memory"); | ||
2992 | usb_free_urb(edge_serial->read_urb); | ||
2993 | return -ENOMEM; | ||
2994 | } | ||
2995 | edge_serial->bulk_in_endpoint = endpoint->bEndpointAddress; | ||
2996 | |||
2997 | /* set up our bulk in urb */ | ||
2998 | usb_fill_bulk_urb(edge_serial->read_urb, dev, | ||
2999 | usb_rcvbulkpipe(dev, endpoint->bEndpointAddress), | ||
3000 | edge_serial->bulk_in_buffer, | ||
3001 | endpoint->wMaxPacketSize, | ||
3002 | edge_bulk_in_callback, | ||
3003 | edge_serial); | ||
3004 | bulk_in_found = TRUE; | ||
3005 | } | ||
3006 | |||
3007 | if ((!bulk_out_found) && | ||
3008 | (usb_endpoint_is_bulk_out(endpoint))) { | ||
3009 | /* we found a bulk out endpoint */ | ||
3010 | dbg("found bulk out"); | ||
3011 | edge_serial->bulk_out_endpoint = endpoint->bEndpointAddress; | ||
3012 | bulk_out_found = TRUE; | ||
3013 | } | ||
3014 | } | ||
3015 | |||
3016 | if ((!interrupt_in_found) || (!bulk_in_found) || (!bulk_out_found)) { | ||
3017 | err ("Error - the proper endpoints were not found!"); | ||
3018 | return -ENODEV; | ||
3019 | } | ||
3020 | |||
3021 | /* start interrupt read for this edgeport this interrupt will | ||
3022 | * continue as long as the edgeport is connected */ | ||
3023 | response = usb_submit_urb(edge_serial->interrupt_read_urb, GFP_KERNEL); | ||
3024 | if (response) | ||
3025 | err("%s - Error %d submitting control urb", __FUNCTION__, response); | ||
3026 | } | ||
3027 | return response; | ||
2809 | } | 3028 | } |
2810 | 3029 | ||
2811 | 3030 | ||
@@ -2815,6 +3034,7 @@ static int edge_startup (struct usb_serial *serial) | |||
2815 | ****************************************************************************/ | 3034 | ****************************************************************************/ |
2816 | static void edge_shutdown (struct usb_serial *serial) | 3035 | static void edge_shutdown (struct usb_serial *serial) |
2817 | { | 3036 | { |
3037 | struct edgeport_serial *edge_serial = usb_get_serial_data(serial); | ||
2818 | int i; | 3038 | int i; |
2819 | 3039 | ||
2820 | dbg("%s", __FUNCTION__); | 3040 | dbg("%s", __FUNCTION__); |
@@ -2824,7 +3044,18 @@ static void edge_shutdown (struct usb_serial *serial) | |||
2824 | kfree (usb_get_serial_port_data(serial->port[i])); | 3044 | kfree (usb_get_serial_port_data(serial->port[i])); |
2825 | usb_set_serial_port_data(serial->port[i], NULL); | 3045 | usb_set_serial_port_data(serial->port[i], NULL); |
2826 | } | 3046 | } |
2827 | kfree (usb_get_serial_data(serial)); | 3047 | /* free up our endpoint stuff */ |
3048 | if (edge_serial->is_epic) { | ||
3049 | usb_unlink_urb(edge_serial->interrupt_read_urb); | ||
3050 | usb_free_urb(edge_serial->interrupt_read_urb); | ||
3051 | kfree(edge_serial->interrupt_in_buffer); | ||
3052 | |||
3053 | usb_unlink_urb(edge_serial->read_urb); | ||
3054 | usb_free_urb(edge_serial->read_urb); | ||
3055 | kfree(edge_serial->bulk_in_buffer); | ||
3056 | } | ||
3057 | |||
3058 | kfree(edge_serial); | ||
2828 | usb_set_serial_data(serial, NULL); | 3059 | usb_set_serial_data(serial, NULL); |
2829 | } | 3060 | } |
2830 | 3061 | ||
@@ -2846,6 +3077,9 @@ static int __init edgeport_init(void) | |||
2846 | retval = usb_serial_register(&edgeport_8port_device); | 3077 | retval = usb_serial_register(&edgeport_8port_device); |
2847 | if (retval) | 3078 | if (retval) |
2848 | goto failed_8port_device_register; | 3079 | goto failed_8port_device_register; |
3080 | retval = usb_serial_register(&epic_device); | ||
3081 | if (retval) | ||
3082 | goto failed_epic_device_register; | ||
2849 | retval = usb_register(&io_driver); | 3083 | retval = usb_register(&io_driver); |
2850 | if (retval) | 3084 | if (retval) |
2851 | goto failed_usb_register; | 3085 | goto failed_usb_register; |
@@ -2853,6 +3087,8 @@ static int __init edgeport_init(void) | |||
2853 | return 0; | 3087 | return 0; |
2854 | 3088 | ||
2855 | failed_usb_register: | 3089 | failed_usb_register: |
3090 | usb_serial_deregister(&epic_device); | ||
3091 | failed_epic_device_register: | ||
2856 | usb_serial_deregister(&edgeport_8port_device); | 3092 | usb_serial_deregister(&edgeport_8port_device); |
2857 | failed_8port_device_register: | 3093 | failed_8port_device_register: |
2858 | usb_serial_deregister(&edgeport_4port_device); | 3094 | usb_serial_deregister(&edgeport_4port_device); |
@@ -2873,6 +3109,7 @@ static void __exit edgeport_exit (void) | |||
2873 | usb_serial_deregister (&edgeport_2port_device); | 3109 | usb_serial_deregister (&edgeport_2port_device); |
2874 | usb_serial_deregister (&edgeport_4port_device); | 3110 | usb_serial_deregister (&edgeport_4port_device); |
2875 | usb_serial_deregister (&edgeport_8port_device); | 3111 | usb_serial_deregister (&edgeport_8port_device); |
3112 | usb_serial_deregister (&epic_device); | ||
2876 | } | 3113 | } |
2877 | 3114 | ||
2878 | module_init(edgeport_init); | 3115 | module_init(edgeport_init); |
diff --git a/drivers/usb/serial/io_edgeport.h b/drivers/usb/serial/io_edgeport.h index 123fa8a904e6..29a913a6daca 100644 --- a/drivers/usb/serial/io_edgeport.h +++ b/drivers/usb/serial/io_edgeport.h | |||
@@ -111,10 +111,12 @@ struct edgeport_product_info { | |||
111 | __le16 FirmwareBuildNumber; /* zzzz (LE format) */ | 111 | __le16 FirmwareBuildNumber; /* zzzz (LE format) */ |
112 | 112 | ||
113 | __u8 ManufactureDescDate[3]; /* MM/DD/YY when descriptor template was compiled */ | 113 | __u8 ManufactureDescDate[3]; /* MM/DD/YY when descriptor template was compiled */ |
114 | __u8 Unused1[1]; /* Available */ | 114 | __u8 HardwareType; |
115 | 115 | ||
116 | __u8 iDownloadFile; /* What to download to EPiC device */ | 116 | __u8 iDownloadFile; /* What to download to EPiC device */ |
117 | __u8 Unused2[2]; /* Available */ | 117 | __u8 EpicVer; /* What version of EPiC spec this device supports */ |
118 | |||
119 | struct edge_compatibility_bits Epic; | ||
118 | }; | 120 | }; |
119 | 121 | ||
120 | /* | 122 | /* |
diff --git a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h index fad561c04c76..6d3008772540 100644 --- a/drivers/usb/serial/io_tables.h +++ b/drivers/usb/serial/io_tables.h | |||
@@ -47,6 +47,18 @@ static struct usb_device_id edgeport_8port_id_table [] = { | |||
47 | { } | 47 | { } |
48 | }; | 48 | }; |
49 | 49 | ||
50 | static struct usb_device_id Epic_port_id_table [] = { | ||
51 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0202) }, | ||
52 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0203) }, | ||
53 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0310) }, | ||
54 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0311) }, | ||
55 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0312) }, | ||
56 | { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A758) }, | ||
57 | { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A794) }, | ||
58 | { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A225) }, | ||
59 | { } | ||
60 | }; | ||
61 | |||
50 | /* Devices that this driver supports */ | 62 | /* Devices that this driver supports */ |
51 | static struct usb_device_id id_table_combined [] = { | 63 | static struct usb_device_id id_table_combined [] = { |
52 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4) }, | 64 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_4) }, |
@@ -70,17 +82,34 @@ static struct usb_device_id id_table_combined [] = { | |||
70 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8R) }, | 82 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8R) }, |
71 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8RR) }, | 83 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8RR) }, |
72 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_412_8) }, | 84 | { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_412_8) }, |
85 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0202) }, | ||
86 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0203) }, | ||
87 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0310) }, | ||
88 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0311) }, | ||
89 | { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0312) }, | ||
90 | { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A758) }, | ||
91 | { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A794) }, | ||
92 | { USB_DEVICE(USB_VENDOR_ID_AXIOHM, AXIOHM_DEVICE_ID_EPIC_A225) }, | ||
73 | { } /* Terminating entry */ | 93 | { } /* Terminating entry */ |
74 | }; | 94 | }; |
75 | 95 | ||
76 | MODULE_DEVICE_TABLE (usb, id_table_combined); | 96 | MODULE_DEVICE_TABLE (usb, id_table_combined); |
77 | 97 | ||
98 | static struct usb_driver io_driver = { | ||
99 | .name = "io_edgeport", | ||
100 | .probe = usb_serial_probe, | ||
101 | .disconnect = usb_serial_disconnect, | ||
102 | .id_table = id_table_combined, | ||
103 | .no_dynamic_id = 1, | ||
104 | }; | ||
105 | |||
78 | static struct usb_serial_driver edgeport_2port_device = { | 106 | static struct usb_serial_driver edgeport_2port_device = { |
79 | .driver = { | 107 | .driver = { |
80 | .owner = THIS_MODULE, | 108 | .owner = THIS_MODULE, |
81 | .name = "edgeport_2", | 109 | .name = "edgeport_2", |
82 | }, | 110 | }, |
83 | .description = "Edgeport 2 port adapter", | 111 | .description = "Edgeport 2 port adapter", |
112 | .usb_driver = &io_driver, | ||
84 | .id_table = edgeport_2port_id_table, | 113 | .id_table = edgeport_2port_id_table, |
85 | .num_interrupt_in = 1, | 114 | .num_interrupt_in = 1, |
86 | .num_bulk_in = 1, | 115 | .num_bulk_in = 1, |
@@ -111,6 +140,7 @@ static struct usb_serial_driver edgeport_4port_device = { | |||
111 | .name = "edgeport_4", | 140 | .name = "edgeport_4", |
112 | }, | 141 | }, |
113 | .description = "Edgeport 4 port adapter", | 142 | .description = "Edgeport 4 port adapter", |
143 | .usb_driver = &io_driver, | ||
114 | .id_table = edgeport_4port_id_table, | 144 | .id_table = edgeport_4port_id_table, |
115 | .num_interrupt_in = 1, | 145 | .num_interrupt_in = 1, |
116 | .num_bulk_in = 1, | 146 | .num_bulk_in = 1, |
@@ -141,6 +171,7 @@ static struct usb_serial_driver edgeport_8port_device = { | |||
141 | .name = "edgeport_8", | 171 | .name = "edgeport_8", |
142 | }, | 172 | }, |
143 | .description = "Edgeport 8 port adapter", | 173 | .description = "Edgeport 8 port adapter", |
174 | .usb_driver = &io_driver, | ||
144 | .id_table = edgeport_8port_id_table, | 175 | .id_table = edgeport_8port_id_table, |
145 | .num_interrupt_in = 1, | 176 | .num_interrupt_in = 1, |
146 | .num_bulk_in = 1, | 177 | .num_bulk_in = 1, |
@@ -165,5 +196,35 @@ static struct usb_serial_driver edgeport_8port_device = { | |||
165 | .write_bulk_callback = edge_bulk_out_data_callback, | 196 | .write_bulk_callback = edge_bulk_out_data_callback, |
166 | }; | 197 | }; |
167 | 198 | ||
199 | static struct usb_serial_driver epic_device = { | ||
200 | .driver = { | ||
201 | .owner = THIS_MODULE, | ||
202 | .name = "epic", | ||
203 | }, | ||
204 | .description = "EPiC device", | ||
205 | .id_table = Epic_port_id_table, | ||
206 | .num_interrupt_in = 1, | ||
207 | .num_bulk_in = 1, | ||
208 | .num_bulk_out = 1, | ||
209 | .num_ports = 1, | ||
210 | .open = edge_open, | ||
211 | .close = edge_close, | ||
212 | .throttle = edge_throttle, | ||
213 | .unthrottle = edge_unthrottle, | ||
214 | .attach = edge_startup, | ||
215 | .shutdown = edge_shutdown, | ||
216 | .ioctl = edge_ioctl, | ||
217 | .set_termios = edge_set_termios, | ||
218 | .tiocmget = edge_tiocmget, | ||
219 | .tiocmset = edge_tiocmset, | ||
220 | .write = edge_write, | ||
221 | .write_room = edge_write_room, | ||
222 | .chars_in_buffer = edge_chars_in_buffer, | ||
223 | .break_ctl = edge_break, | ||
224 | .read_int_callback = edge_interrupt_callback, | ||
225 | .read_bulk_callback = edge_bulk_in_callback, | ||
226 | .write_bulk_callback = edge_bulk_out_data_callback, | ||
227 | }; | ||
228 | |||
168 | #endif | 229 | #endif |
169 | 230 | ||
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index ee0c921e1520..544098d2b775 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -238,7 +238,7 @@ static void edge_tty_recv(struct device *dev, struct tty_struct *tty, unsigned c | |||
238 | static void stop_read(struct edgeport_port *edge_port); | 238 | static void stop_read(struct edgeport_port *edge_port); |
239 | static int restart_read(struct edgeport_port *edge_port); | 239 | static int restart_read(struct edgeport_port *edge_port); |
240 | 240 | ||
241 | static void edge_set_termios (struct usb_serial_port *port, struct termios *old_termios); | 241 | static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old_termios); |
242 | static void edge_send(struct usb_serial_port *port); | 242 | static void edge_send(struct usb_serial_port *port); |
243 | 243 | ||
244 | /* circular buffer */ | 244 | /* circular buffer */ |
@@ -2361,7 +2361,7 @@ static int restart_read(struct edgeport_port *edge_port) | |||
2361 | return status; | 2361 | return status; |
2362 | } | 2362 | } |
2363 | 2363 | ||
2364 | static void change_port_settings (struct edgeport_port *edge_port, struct termios *old_termios) | 2364 | static void change_port_settings (struct edgeport_port *edge_port, struct ktermios *old_termios) |
2365 | { | 2365 | { |
2366 | struct ump_uart_config *config; | 2366 | struct ump_uart_config *config; |
2367 | struct tty_struct *tty; | 2367 | struct tty_struct *tty; |
@@ -2512,7 +2512,7 @@ static void change_port_settings (struct edgeport_port *edge_port, struct termio | |||
2512 | return; | 2512 | return; |
2513 | } | 2513 | } |
2514 | 2514 | ||
2515 | static void edge_set_termios (struct usb_serial_port *port, struct termios *old_termios) | 2515 | static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) |
2516 | { | 2516 | { |
2517 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); | 2517 | struct edgeport_port *edge_port = usb_get_serial_port_data(port); |
2518 | struct tty_struct *tty = port->tty; | 2518 | struct tty_struct *tty = port->tty; |
@@ -2811,7 +2811,7 @@ static struct edge_buf *edge_buf_alloc(unsigned int size) | |||
2811 | if (size == 0) | 2811 | if (size == 0) |
2812 | return NULL; | 2812 | return NULL; |
2813 | 2813 | ||
2814 | eb = (struct edge_buf *)kmalloc(sizeof(struct edge_buf), GFP_KERNEL); | 2814 | eb = kmalloc(sizeof(struct edge_buf), GFP_KERNEL); |
2815 | if (eb == NULL) | 2815 | if (eb == NULL) |
2816 | return NULL; | 2816 | return NULL; |
2817 | 2817 | ||
@@ -2979,6 +2979,7 @@ static struct usb_serial_driver edgeport_1port_device = { | |||
2979 | .name = "edgeport_ti_1", | 2979 | .name = "edgeport_ti_1", |
2980 | }, | 2980 | }, |
2981 | .description = "Edgeport TI 1 port adapter", | 2981 | .description = "Edgeport TI 1 port adapter", |
2982 | .usb_driver = &io_driver, | ||
2982 | .id_table = edgeport_1port_id_table, | 2983 | .id_table = edgeport_1port_id_table, |
2983 | .num_interrupt_in = 1, | 2984 | .num_interrupt_in = 1, |
2984 | .num_bulk_in = 1, | 2985 | .num_bulk_in = 1, |
@@ -3009,6 +3010,7 @@ static struct usb_serial_driver edgeport_2port_device = { | |||
3009 | .name = "edgeport_ti_2", | 3010 | .name = "edgeport_ti_2", |
3010 | }, | 3011 | }, |
3011 | .description = "Edgeport TI 2 port adapter", | 3012 | .description = "Edgeport TI 2 port adapter", |
3013 | .usb_driver = &io_driver, | ||
3012 | .id_table = edgeport_2port_id_table, | 3014 | .id_table = edgeport_2port_id_table, |
3013 | .num_interrupt_in = 1, | 3015 | .num_interrupt_in = 1, |
3014 | .num_bulk_in = 2, | 3016 | .num_bulk_in = 2, |
diff --git a/drivers/usb/serial/io_usbvend.h b/drivers/usb/serial/io_usbvend.h index f1804fd5a3dd..e57fa117e486 100644 --- a/drivers/usb/serial/io_usbvend.h +++ b/drivers/usb/serial/io_usbvend.h | |||
@@ -30,6 +30,7 @@ | |||
30 | 30 | ||
31 | #define USB_VENDOR_ID_ION 0x1608 // Our VID | 31 | #define USB_VENDOR_ID_ION 0x1608 // Our VID |
32 | #define USB_VENDOR_ID_TI 0x0451 // TI VID | 32 | #define USB_VENDOR_ID_TI 0x0451 // TI VID |
33 | #define USB_VENDOR_ID_AXIOHM 0x05D9 /* Axiohm VID */ | ||
33 | 34 | ||
34 | // | 35 | // |
35 | // Definitions of USB product IDs (PID) | 36 | // Definitions of USB product IDs (PID) |
@@ -334,6 +335,10 @@ struct edge_compatibility_bits | |||
334 | 335 | ||
335 | }; | 336 | }; |
336 | 337 | ||
338 | #define EDGE_COMPATIBILITY_MASK0 0x0001 | ||
339 | #define EDGE_COMPATIBILITY_MASK1 0x3FFF | ||
340 | #define EDGE_COMPATIBILITY_MASK2 0x0001 | ||
341 | |||
337 | struct edge_compatibility_descriptor | 342 | struct edge_compatibility_descriptor |
338 | { | 343 | { |
339 | __u8 Length; // Descriptor Length (per USB spec) | 344 | __u8 Length; // Descriptor Length (per USB spec) |
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index d72cf8bc7f76..a408184334ea 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
@@ -563,6 +563,7 @@ static struct usb_serial_driver ipaq_device = { | |||
563 | .name = "ipaq", | 563 | .name = "ipaq", |
564 | }, | 564 | }, |
565 | .description = "PocketPC PDA", | 565 | .description = "PocketPC PDA", |
566 | .usb_driver = &ipaq_driver, | ||
566 | .id_table = ipaq_id_table, | 567 | .id_table = ipaq_id_table, |
567 | .num_interrupt_in = NUM_DONT_CARE, | 568 | .num_interrupt_in = NUM_DONT_CARE, |
568 | .num_bulk_in = 1, | 569 | .num_bulk_in = 1, |
@@ -595,7 +596,7 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp) | |||
595 | 596 | ||
596 | bytes_in = 0; | 597 | bytes_in = 0; |
597 | bytes_out = 0; | 598 | bytes_out = 0; |
598 | priv = (struct ipaq_private *)kmalloc(sizeof(struct ipaq_private), GFP_KERNEL); | 599 | priv = kmalloc(sizeof(struct ipaq_private), GFP_KERNEL); |
599 | if (priv == NULL) { | 600 | if (priv == NULL) { |
600 | err("%s - Out of memory", __FUNCTION__); | 601 | err("%s - Out of memory", __FUNCTION__); |
601 | return -ENOMEM; | 602 | return -ENOMEM; |
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index d3b9a351cef8..1bc586064c77 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c | |||
@@ -442,6 +442,7 @@ static struct usb_serial_driver ipw_device = { | |||
442 | .name = "ipw", | 442 | .name = "ipw", |
443 | }, | 443 | }, |
444 | .description = "IPWireless converter", | 444 | .description = "IPWireless converter", |
445 | .usb_driver = &usb_ipw_driver, | ||
445 | .id_table = usb_ipw_ids, | 446 | .id_table = usb_ipw_ids, |
446 | .num_interrupt_in = NUM_DONT_CARE, | 447 | .num_interrupt_in = NUM_DONT_CARE, |
447 | .num_bulk_in = 1, | 448 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/ir-usb.c b/drivers/usb/serial/ir-usb.c index 331bf81556fc..9d847f69291c 100644 --- a/drivers/usb/serial/ir-usb.c +++ b/drivers/usb/serial/ir-usb.c | |||
@@ -107,7 +107,7 @@ static void ir_close (struct usb_serial_port *port, struct file *filep); | |||
107 | static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int count); | 107 | static int ir_write (struct usb_serial_port *port, const unsigned char *buf, int count); |
108 | static void ir_write_bulk_callback (struct urb *urb); | 108 | static void ir_write_bulk_callback (struct urb *urb); |
109 | static void ir_read_bulk_callback (struct urb *urb); | 109 | static void ir_read_bulk_callback (struct urb *urb); |
110 | static void ir_set_termios (struct usb_serial_port *port, struct termios *old_termios); | 110 | static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios); |
111 | 111 | ||
112 | static u8 ir_baud = 0; | 112 | static u8 ir_baud = 0; |
113 | static u8 ir_xbof = 0; | 113 | static u8 ir_xbof = 0; |
@@ -138,6 +138,7 @@ static struct usb_serial_driver ir_device = { | |||
138 | .name = "ir-usb", | 138 | .name = "ir-usb", |
139 | }, | 139 | }, |
140 | .description = "IR Dongle", | 140 | .description = "IR Dongle", |
141 | .usb_driver = &ir_driver, | ||
141 | .id_table = id_table, | 142 | .id_table = id_table, |
142 | .num_interrupt_in = 1, | 143 | .num_interrupt_in = 1, |
143 | .num_bulk_in = 1, | 144 | .num_bulk_in = 1, |
@@ -497,7 +498,7 @@ static void ir_read_bulk_callback (struct urb *urb) | |||
497 | return; | 498 | return; |
498 | } | 499 | } |
499 | 500 | ||
500 | static void ir_set_termios (struct usb_serial_port *port, struct termios *old_termios) | 501 | static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) |
501 | { | 502 | { |
502 | unsigned char *transfer_buffer; | 503 | unsigned char *transfer_buffer; |
503 | unsigned int cflag; | 504 | unsigned int cflag; |
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c index 7639652cec42..e6966f12ed5a 100644 --- a/drivers/usb/serial/keyspan.c +++ b/drivers/usb/serial/keyspan.c | |||
@@ -264,7 +264,7 @@ static void keyspan_break_ctl (struct usb_serial_port *port, int break_state) | |||
264 | 264 | ||
265 | 265 | ||
266 | static void keyspan_set_termios (struct usb_serial_port *port, | 266 | static void keyspan_set_termios (struct usb_serial_port *port, |
267 | struct termios *old_termios) | 267 | struct ktermios *old_termios) |
268 | { | 268 | { |
269 | int baud_rate, device_port; | 269 | int baud_rate, device_port; |
270 | struct keyspan_port_private *p_priv; | 270 | struct keyspan_port_private *p_priv; |
@@ -1275,11 +1275,31 @@ static int keyspan_fake_startup (struct usb_serial *serial) | |||
1275 | } | 1275 | } |
1276 | 1276 | ||
1277 | /* Helper functions used by keyspan_setup_urbs */ | 1277 | /* Helper functions used by keyspan_setup_urbs */ |
1278 | static struct usb_endpoint_descriptor const *find_ep(struct usb_serial const *serial, | ||
1279 | int endpoint) | ||
1280 | { | ||
1281 | struct usb_host_interface *iface_desc; | ||
1282 | struct usb_endpoint_descriptor *ep; | ||
1283 | int i; | ||
1284 | |||
1285 | iface_desc = serial->interface->cur_altsetting; | ||
1286 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { | ||
1287 | ep = &iface_desc->endpoint[i].desc; | ||
1288 | if (ep->bEndpointAddress == endpoint) | ||
1289 | return ep; | ||
1290 | } | ||
1291 | dev_warn(&serial->interface->dev, "found no endpoint descriptor for " | ||
1292 | "endpoint %x\n", endpoint); | ||
1293 | return NULL; | ||
1294 | } | ||
1295 | |||
1278 | static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint, | 1296 | static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint, |
1279 | int dir, void *ctx, char *buf, int len, | 1297 | int dir, void *ctx, char *buf, int len, |
1280 | void (*callback)(struct urb *)) | 1298 | void (*callback)(struct urb *)) |
1281 | { | 1299 | { |
1282 | struct urb *urb; | 1300 | struct urb *urb; |
1301 | struct usb_endpoint_descriptor const *ep_desc; | ||
1302 | char const *ep_type_name; | ||
1283 | 1303 | ||
1284 | if (endpoint == -1) | 1304 | if (endpoint == -1) |
1285 | return NULL; /* endpoint not needed */ | 1305 | return NULL; /* endpoint not needed */ |
@@ -1291,11 +1311,32 @@ static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint, | |||
1291 | return NULL; | 1311 | return NULL; |
1292 | } | 1312 | } |
1293 | 1313 | ||
1294 | /* Fill URB using supplied data. */ | 1314 | ep_desc = find_ep(serial, endpoint); |
1295 | usb_fill_bulk_urb(urb, serial->dev, | 1315 | if (!ep_desc) { |
1296 | usb_sndbulkpipe(serial->dev, endpoint) | dir, | 1316 | /* leak the urb, something's wrong and the callers don't care */ |
1297 | buf, len, callback, ctx); | 1317 | return urb; |
1318 | } | ||
1319 | if (usb_endpoint_xfer_int(ep_desc)) { | ||
1320 | ep_type_name = "INT"; | ||
1321 | usb_fill_int_urb(urb, serial->dev, | ||
1322 | usb_sndintpipe(serial->dev, endpoint) | dir, | ||
1323 | buf, len, callback, ctx, | ||
1324 | ep_desc->bInterval); | ||
1325 | } else if (usb_endpoint_xfer_bulk(ep_desc)) { | ||
1326 | ep_type_name = "BULK"; | ||
1327 | usb_fill_bulk_urb(urb, serial->dev, | ||
1328 | usb_sndbulkpipe(serial->dev, endpoint) | dir, | ||
1329 | buf, len, callback, ctx); | ||
1330 | } else { | ||
1331 | dev_warn(&serial->interface->dev, | ||
1332 | "unsupported endpoint type %x\n", | ||
1333 | ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK); | ||
1334 | usb_free_urb(urb); | ||
1335 | return NULL; | ||
1336 | } | ||
1298 | 1337 | ||
1338 | dbg("%s - using urb %p for %s endpoint %x", | ||
1339 | __func__, urb, ep_type_name, endpoint); | ||
1299 | return urb; | 1340 | return urb; |
1300 | } | 1341 | } |
1301 | 1342 | ||
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h index 7472ed6bf626..c6830cbdc6df 100644 --- a/drivers/usb/serial/keyspan.h +++ b/drivers/usb/serial/keyspan.h | |||
@@ -59,7 +59,7 @@ static int keyspan_ioctl (struct usb_serial_port *port, | |||
59 | unsigned int cmd, | 59 | unsigned int cmd, |
60 | unsigned long arg); | 60 | unsigned long arg); |
61 | static void keyspan_set_termios (struct usb_serial_port *port, | 61 | static void keyspan_set_termios (struct usb_serial_port *port, |
62 | struct termios *old); | 62 | struct ktermios *old); |
63 | static void keyspan_break_ctl (struct usb_serial_port *port, | 63 | static void keyspan_break_ctl (struct usb_serial_port *port, |
64 | int break_state); | 64 | int break_state); |
65 | static int keyspan_tiocmget (struct usb_serial_port *port, | 65 | static int keyspan_tiocmget (struct usb_serial_port *port, |
@@ -229,7 +229,6 @@ struct ezusb_hex_record { | |||
229 | #define keyspan_usa28_product_id 0x010f | 229 | #define keyspan_usa28_product_id 0x010f |
230 | #define keyspan_usa28x_product_id 0x0110 | 230 | #define keyspan_usa28x_product_id 0x0110 |
231 | #define keyspan_usa28xa_product_id 0x0115 | 231 | #define keyspan_usa28xa_product_id 0x0115 |
232 | #define keyspan_usa28xb_product_id 0x0110 | ||
233 | #define keyspan_usa49w_product_id 0x010a | 232 | #define keyspan_usa49w_product_id 0x010a |
234 | #define keyspan_usa49wlc_product_id 0x012a | 233 | #define keyspan_usa49wlc_product_id 0x012a |
235 | 234 | ||
@@ -511,7 +510,6 @@ static struct usb_device_id keyspan_ids_combined[] = { | |||
511 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) }, | 510 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) }, |
512 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) }, | 511 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) }, |
513 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) }, | 512 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) }, |
514 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xb_product_id) }, | ||
515 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id)}, | 513 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49w_product_id)}, |
516 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_product_id)}, | 514 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa49wlc_product_id)}, |
517 | { } /* Terminating entry */ | 515 | { } /* Terminating entry */ |
@@ -559,7 +557,6 @@ static struct usb_device_id keyspan_2port_ids[] = { | |||
559 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) }, | 557 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) }, |
560 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) }, | 558 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) }, |
561 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) }, | 559 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xa_product_id) }, |
562 | { USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28xb_product_id) }, | ||
563 | { } /* Terminating entry */ | 560 | { } /* Terminating entry */ |
564 | }; | 561 | }; |
565 | 562 | ||
@@ -576,6 +573,7 @@ static struct usb_serial_driver keyspan_pre_device = { | |||
576 | .name = "keyspan_no_firm", | 573 | .name = "keyspan_no_firm", |
577 | }, | 574 | }, |
578 | .description = "Keyspan - (without firmware)", | 575 | .description = "Keyspan - (without firmware)", |
576 | .usb_driver = &keyspan_driver, | ||
579 | .id_table = keyspan_pre_ids, | 577 | .id_table = keyspan_pre_ids, |
580 | .num_interrupt_in = NUM_DONT_CARE, | 578 | .num_interrupt_in = NUM_DONT_CARE, |
581 | .num_bulk_in = NUM_DONT_CARE, | 579 | .num_bulk_in = NUM_DONT_CARE, |
@@ -590,6 +588,7 @@ static struct usb_serial_driver keyspan_1port_device = { | |||
590 | .name = "keyspan_1", | 588 | .name = "keyspan_1", |
591 | }, | 589 | }, |
592 | .description = "Keyspan 1 port adapter", | 590 | .description = "Keyspan 1 port adapter", |
591 | .usb_driver = &keyspan_driver, | ||
593 | .id_table = keyspan_1port_ids, | 592 | .id_table = keyspan_1port_ids, |
594 | .num_interrupt_in = NUM_DONT_CARE, | 593 | .num_interrupt_in = NUM_DONT_CARE, |
595 | .num_bulk_in = NUM_DONT_CARE, | 594 | .num_bulk_in = NUM_DONT_CARE, |
@@ -617,6 +616,7 @@ static struct usb_serial_driver keyspan_2port_device = { | |||
617 | .name = "keyspan_2", | 616 | .name = "keyspan_2", |
618 | }, | 617 | }, |
619 | .description = "Keyspan 2 port adapter", | 618 | .description = "Keyspan 2 port adapter", |
619 | .usb_driver = &keyspan_driver, | ||
620 | .id_table = keyspan_2port_ids, | 620 | .id_table = keyspan_2port_ids, |
621 | .num_interrupt_in = NUM_DONT_CARE, | 621 | .num_interrupt_in = NUM_DONT_CARE, |
622 | .num_bulk_in = NUM_DONT_CARE, | 622 | .num_bulk_in = NUM_DONT_CARE, |
@@ -644,6 +644,7 @@ static struct usb_serial_driver keyspan_4port_device = { | |||
644 | .name = "keyspan_4", | 644 | .name = "keyspan_4", |
645 | }, | 645 | }, |
646 | .description = "Keyspan 4 port adapter", | 646 | .description = "Keyspan 4 port adapter", |
647 | .usb_driver = &keyspan_driver, | ||
647 | .id_table = keyspan_4port_ids, | 648 | .id_table = keyspan_4port_ids, |
648 | .num_interrupt_in = NUM_DONT_CARE, | 649 | .num_interrupt_in = NUM_DONT_CARE, |
649 | .num_bulk_in = 5, | 650 | .num_bulk_in = 5, |
diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index e09a0bfe6231..da514cb785b3 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c | |||
@@ -365,7 +365,7 @@ static void keyspan_pda_break_ctl (struct usb_serial_port *port, int break_state | |||
365 | 365 | ||
366 | 366 | ||
367 | static void keyspan_pda_set_termios (struct usb_serial_port *port, | 367 | static void keyspan_pda_set_termios (struct usb_serial_port *port, |
368 | struct termios *old_termios) | 368 | struct ktermios *old_termios) |
369 | { | 369 | { |
370 | struct usb_serial *serial = port->serial; | 370 | struct usb_serial *serial = port->serial; |
371 | unsigned int cflag = port->tty->termios->c_cflag; | 371 | unsigned int cflag = port->tty->termios->c_cflag; |
@@ -793,6 +793,7 @@ static struct usb_serial_driver keyspan_pda_fake_device = { | |||
793 | .name = "keyspan_pda_pre", | 793 | .name = "keyspan_pda_pre", |
794 | }, | 794 | }, |
795 | .description = "Keyspan PDA - (prerenumeration)", | 795 | .description = "Keyspan PDA - (prerenumeration)", |
796 | .usb_driver = &keyspan_pda_driver, | ||
796 | .id_table = id_table_fake, | 797 | .id_table = id_table_fake, |
797 | .num_interrupt_in = NUM_DONT_CARE, | 798 | .num_interrupt_in = NUM_DONT_CARE, |
798 | .num_bulk_in = NUM_DONT_CARE, | 799 | .num_bulk_in = NUM_DONT_CARE, |
@@ -809,6 +810,7 @@ static struct usb_serial_driver xircom_pgs_fake_device = { | |||
809 | .name = "xircom_no_firm", | 810 | .name = "xircom_no_firm", |
810 | }, | 811 | }, |
811 | .description = "Xircom / Entregra PGS - (prerenumeration)", | 812 | .description = "Xircom / Entregra PGS - (prerenumeration)", |
813 | .usb_driver = &keyspan_pda_driver, | ||
812 | .id_table = id_table_fake_xircom, | 814 | .id_table = id_table_fake_xircom, |
813 | .num_interrupt_in = NUM_DONT_CARE, | 815 | .num_interrupt_in = NUM_DONT_CARE, |
814 | .num_bulk_in = NUM_DONT_CARE, | 816 | .num_bulk_in = NUM_DONT_CARE, |
@@ -824,6 +826,7 @@ static struct usb_serial_driver keyspan_pda_device = { | |||
824 | .name = "keyspan_pda", | 826 | .name = "keyspan_pda", |
825 | }, | 827 | }, |
826 | .description = "Keyspan PDA", | 828 | .description = "Keyspan PDA", |
829 | .usb_driver = &keyspan_pda_driver, | ||
827 | .id_table = id_table_std, | 830 | .id_table = id_table_std, |
828 | .num_interrupt_in = 1, | 831 | .num_interrupt_in = 1, |
829 | .num_bulk_in = 0, | 832 | .num_bulk_in = 0, |
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 17e205699c2b..b2097c45a235 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
@@ -86,11 +86,7 @@ static int klsi_105_write_room (struct usb_serial_port *port); | |||
86 | 86 | ||
87 | static void klsi_105_read_bulk_callback (struct urb *urb); | 87 | static void klsi_105_read_bulk_callback (struct urb *urb); |
88 | static void klsi_105_set_termios (struct usb_serial_port *port, | 88 | static void klsi_105_set_termios (struct usb_serial_port *port, |
89 | struct termios * old); | 89 | struct ktermios *old); |
90 | static int klsi_105_ioctl (struct usb_serial_port *port, | ||
91 | struct file * file, | ||
92 | unsigned int cmd, | ||
93 | unsigned long arg); | ||
94 | static void klsi_105_throttle (struct usb_serial_port *port); | 90 | static void klsi_105_throttle (struct usb_serial_port *port); |
95 | static void klsi_105_unthrottle (struct usb_serial_port *port); | 91 | static void klsi_105_unthrottle (struct usb_serial_port *port); |
96 | /* | 92 | /* |
@@ -128,6 +124,7 @@ static struct usb_serial_driver kl5kusb105d_device = { | |||
128 | .name = "kl5kusb105d", | 124 | .name = "kl5kusb105d", |
129 | }, | 125 | }, |
130 | .description = "KL5KUSB105D / PalmConnect", | 126 | .description = "KL5KUSB105D / PalmConnect", |
127 | .usb_driver = &kl5kusb105d_driver, | ||
131 | .id_table = id_table, | 128 | .id_table = id_table, |
132 | .num_interrupt_in = 1, | 129 | .num_interrupt_in = 1, |
133 | .num_bulk_in = 1, | 130 | .num_bulk_in = 1, |
@@ -140,7 +137,6 @@ static struct usb_serial_driver kl5kusb105d_device = { | |||
140 | .chars_in_buffer = klsi_105_chars_in_buffer, | 137 | .chars_in_buffer = klsi_105_chars_in_buffer, |
141 | .write_room = klsi_105_write_room, | 138 | .write_room = klsi_105_write_room, |
142 | .read_bulk_callback =klsi_105_read_bulk_callback, | 139 | .read_bulk_callback =klsi_105_read_bulk_callback, |
143 | .ioctl = klsi_105_ioctl, | ||
144 | .set_termios = klsi_105_set_termios, | 140 | .set_termios = klsi_105_set_termios, |
145 | /*.break_ctl = klsi_105_break_ctl,*/ | 141 | /*.break_ctl = klsi_105_break_ctl,*/ |
146 | .tiocmget = klsi_105_tiocmget, | 142 | .tiocmget = klsi_105_tiocmget, |
@@ -164,7 +160,7 @@ struct klsi_105_port_settings { | |||
164 | #define URB_TRANSFER_BUFFER_SIZE 64 | 160 | #define URB_TRANSFER_BUFFER_SIZE 64 |
165 | struct klsi_105_private { | 161 | struct klsi_105_private { |
166 | struct klsi_105_port_settings cfg; | 162 | struct klsi_105_port_settings cfg; |
167 | struct termios termios; | 163 | struct ktermios termios; |
168 | unsigned long line_state; /* modem line settings */ | 164 | unsigned long line_state; /* modem line settings */ |
169 | /* write pool */ | 165 | /* write pool */ |
170 | struct urb * write_urb_pool[NUM_URBS]; | 166 | struct urb * write_urb_pool[NUM_URBS]; |
@@ -688,7 +684,7 @@ static void klsi_105_read_bulk_callback (struct urb *urb) | |||
688 | 684 | ||
689 | 685 | ||
690 | static void klsi_105_set_termios (struct usb_serial_port *port, | 686 | static void klsi_105_set_termios (struct usb_serial_port *port, |
691 | struct termios *old_termios) | 687 | struct ktermios *old_termios) |
692 | { | 688 | { |
693 | struct klsi_105_private *priv = usb_get_serial_port_data(port); | 689 | struct klsi_105_private *priv = usb_get_serial_port_data(port); |
694 | unsigned int iflag = port->tty->termios->c_iflag; | 690 | unsigned int iflag = port->tty->termios->c_iflag; |
@@ -899,69 +895,6 @@ static int klsi_105_tiocmset (struct usb_serial_port *port, struct file *file, | |||
899 | */ | 895 | */ |
900 | return retval; | 896 | return retval; |
901 | } | 897 | } |
902 | |||
903 | static int klsi_105_ioctl (struct usb_serial_port *port, struct file * file, | ||
904 | unsigned int cmd, unsigned long arg) | ||
905 | { | ||
906 | struct klsi_105_private *priv = usb_get_serial_port_data(port); | ||
907 | void __user *user_arg = (void __user *)arg; | ||
908 | |||
909 | dbg("%scmd=0x%x", __FUNCTION__, cmd); | ||
910 | |||
911 | /* Based on code from acm.c and others */ | ||
912 | switch (cmd) { | ||
913 | case TIOCMIWAIT: | ||
914 | /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/ | ||
915 | /* TODO */ | ||
916 | dbg("%s - TIOCMIWAIT not handled", __FUNCTION__); | ||
917 | return -ENOIOCTLCMD; | ||
918 | case TIOCGICOUNT: | ||
919 | /* return count of modemline transitions */ | ||
920 | /* TODO */ | ||
921 | dbg("%s - TIOCGICOUNT not handled", __FUNCTION__); | ||
922 | return -ENOIOCTLCMD; | ||
923 | case TCGETS: | ||
924 | /* return current info to caller */ | ||
925 | dbg("%s - TCGETS data faked/incomplete", __FUNCTION__); | ||
926 | |||
927 | if (!access_ok(VERIFY_WRITE, user_arg, sizeof(struct termios))) | ||
928 | return -EFAULT; | ||
929 | |||
930 | if (kernel_termios_to_user_termios((struct termios __user *)arg, | ||
931 | &priv->termios)) | ||
932 | return -EFAULT; | ||
933 | return 0; | ||
934 | case TCSETS: | ||
935 | /* set port termios to the one given by the user */ | ||
936 | dbg("%s - TCSETS not handled", __FUNCTION__); | ||
937 | |||
938 | if (!access_ok(VERIFY_READ, user_arg, sizeof(struct termios))) | ||
939 | return -EFAULT; | ||
940 | |||
941 | if (user_termios_to_kernel_termios(&priv->termios, | ||
942 | (struct termios __user *)arg)) | ||
943 | return -EFAULT; | ||
944 | klsi_105_set_termios(port, &priv->termios); | ||
945 | return 0; | ||
946 | case TCSETSW: { | ||
947 | /* set port termios and try to wait for completion of last | ||
948 | * write operation */ | ||
949 | /* We guess here. If there are not too many write urbs | ||
950 | * outstanding, we lie. */ | ||
951 | /* what is the right way to wait here? schedule() ? */ | ||
952 | /* | ||
953 | while (klsi_105_chars_in_buffer(port) > (NUM_URBS / 4 ) * URB_TRANSFER_BUFFER_SIZE) | ||
954 | schedule(); | ||
955 | */ | ||
956 | return -ENOIOCTLCMD; | ||
957 | } | ||
958 | default: | ||
959 | dbg("%s: arg not supported - 0x%04x", __FUNCTION__,cmd); | ||
960 | return(-ENOIOCTLCMD); | ||
961 | break; | ||
962 | } | ||
963 | return 0; | ||
964 | } /* klsi_105_ioctl */ | ||
965 | 898 | ||
966 | static void klsi_105_throttle (struct usb_serial_port *port) | 899 | static void klsi_105_throttle (struct usb_serial_port *port) |
967 | { | 900 | { |
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 237289920f03..0683b51f0932 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
@@ -110,6 +110,7 @@ static struct usb_serial_driver kobil_device = { | |||
110 | .name = "kobil", | 110 | .name = "kobil", |
111 | }, | 111 | }, |
112 | .description = "KOBIL USB smart card terminal", | 112 | .description = "KOBIL USB smart card terminal", |
113 | .usb_driver = &kobil_driver, | ||
113 | .id_table = id_table, | 114 | .id_table = id_table, |
114 | .num_interrupt_in = NUM_DONT_CARE, | 115 | .num_interrupt_in = NUM_DONT_CARE, |
115 | .num_bulk_in = 0, | 116 | .num_bulk_in = 0, |
@@ -136,7 +137,7 @@ struct kobil_private { | |||
136 | int cur_pos; // index of the next char to send in buf | 137 | int cur_pos; // index of the next char to send in buf |
137 | __u16 device_type; | 138 | __u16 device_type; |
138 | int line_state; | 139 | int line_state; |
139 | struct termios internal_termios; | 140 | struct ktermios internal_termios; |
140 | }; | 141 | }; |
141 | 142 | ||
142 | 143 | ||
@@ -269,7 +270,7 @@ static int kobil_open (struct usb_serial_port *port, struct file *filp) | |||
269 | } | 270 | } |
270 | 271 | ||
271 | // allocate memory for write_urb transfer buffer | 272 | // allocate memory for write_urb transfer buffer |
272 | port->write_urb->transfer_buffer = (unsigned char *) kmalloc(write_urb_transfer_buffer_length, GFP_KERNEL); | 273 | port->write_urb->transfer_buffer = kmalloc(write_urb_transfer_buffer_length, GFP_KERNEL); |
273 | if (! port->write_urb->transfer_buffer) { | 274 | if (! port->write_urb->transfer_buffer) { |
274 | kfree(transfer_buffer); | 275 | kfree(transfer_buffer); |
275 | usb_free_urb(port->write_urb); | 276 | usb_free_urb(port->write_urb); |
@@ -624,11 +625,11 @@ static int kobil_ioctl(struct usb_serial_port *port, struct file *file, | |||
624 | 625 | ||
625 | switch (cmd) { | 626 | switch (cmd) { |
626 | case TCGETS: // 0x5401 | 627 | case TCGETS: // 0x5401 |
627 | if (!access_ok(VERIFY_WRITE, user_arg, sizeof(struct termios))) { | 628 | if (!access_ok(VERIFY_WRITE, user_arg, sizeof(struct ktermios))) { |
628 | dbg("%s - port %d Error in access_ok", __FUNCTION__, port->number); | 629 | dbg("%s - port %d Error in access_ok", __FUNCTION__, port->number); |
629 | return -EFAULT; | 630 | return -EFAULT; |
630 | } | 631 | } |
631 | if (kernel_termios_to_user_termios((struct termios __user *)arg, | 632 | if (kernel_termios_to_user_termios((struct ktermios __user *)arg, |
632 | &priv->internal_termios)) | 633 | &priv->internal_termios)) |
633 | return -EFAULT; | 634 | return -EFAULT; |
634 | return 0; | 635 | return 0; |
@@ -638,12 +639,12 @@ static int kobil_ioctl(struct usb_serial_port *port, struct file *file, | |||
638 | dbg("%s - port %d Error: port->tty->termios is NULL", __FUNCTION__, port->number); | 639 | dbg("%s - port %d Error: port->tty->termios is NULL", __FUNCTION__, port->number); |
639 | return -ENOTTY; | 640 | return -ENOTTY; |
640 | } | 641 | } |
641 | if (!access_ok(VERIFY_READ, user_arg, sizeof(struct termios))) { | 642 | if (!access_ok(VERIFY_READ, user_arg, sizeof(struct ktermios))) { |
642 | dbg("%s - port %d Error in access_ok", __FUNCTION__, port->number); | 643 | dbg("%s - port %d Error in access_ok", __FUNCTION__, port->number); |
643 | return -EFAULT; | 644 | return -EFAULT; |
644 | } | 645 | } |
645 | if (user_termios_to_kernel_termios(&priv->internal_termios, | 646 | if (user_termios_to_kernel_termios(&priv->internal_termios, |
646 | (struct termios __user *)arg)) | 647 | (struct ktermios __user *)arg)) |
647 | return -EFAULT; | 648 | return -EFAULT; |
648 | 649 | ||
649 | settings = kzalloc(50, GFP_KERNEL); | 650 | settings = kzalloc(50, GFP_KERNEL); |
@@ -696,7 +697,7 @@ static int kobil_ioctl(struct usb_serial_port *port, struct file *file, | |||
696 | return 0; | 697 | return 0; |
697 | 698 | ||
698 | case TCFLSH: // 0x540B | 699 | case TCFLSH: // 0x540B |
699 | transfer_buffer = (unsigned char *) kmalloc(transfer_buffer_length, GFP_KERNEL); | 700 | transfer_buffer = kmalloc(transfer_buffer_length, GFP_KERNEL); |
700 | if (! transfer_buffer) { | 701 | if (! transfer_buffer) { |
701 | return -ENOBUFS; | 702 | return -ENOBUFS; |
702 | } | 703 | } |
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index a906e500a02b..4cd839b1407f 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
@@ -98,7 +98,7 @@ static void mct_u232_close (struct usb_serial_port *port, | |||
98 | struct file *filp); | 98 | struct file *filp); |
99 | static void mct_u232_read_int_callback (struct urb *urb); | 99 | static void mct_u232_read_int_callback (struct urb *urb); |
100 | static void mct_u232_set_termios (struct usb_serial_port *port, | 100 | static void mct_u232_set_termios (struct usb_serial_port *port, |
101 | struct termios * old); | 101 | struct ktermios * old); |
102 | static int mct_u232_ioctl (struct usb_serial_port *port, | 102 | static int mct_u232_ioctl (struct usb_serial_port *port, |
103 | struct file * file, | 103 | struct file * file, |
104 | unsigned int cmd, | 104 | unsigned int cmd, |
@@ -137,6 +137,7 @@ static struct usb_serial_driver mct_u232_device = { | |||
137 | .name = "mct_u232", | 137 | .name = "mct_u232", |
138 | }, | 138 | }, |
139 | .description = "MCT U232", | 139 | .description = "MCT U232", |
140 | .usb_driver = &mct_u232_driver, | ||
140 | .id_table = id_table_combined, | 141 | .id_table = id_table_combined, |
141 | .num_interrupt_in = 2, | 142 | .num_interrupt_in = 2, |
142 | .num_bulk_in = 0, | 143 | .num_bulk_in = 0, |
@@ -556,7 +557,7 @@ exit: | |||
556 | } /* mct_u232_read_int_callback */ | 557 | } /* mct_u232_read_int_callback */ |
557 | 558 | ||
558 | static void mct_u232_set_termios (struct usb_serial_port *port, | 559 | static void mct_u232_set_termios (struct usb_serial_port *port, |
559 | struct termios *old_termios) | 560 | struct ktermios *old_termios) |
560 | { | 561 | { |
561 | struct usb_serial *serial = port->serial; | 562 | struct usb_serial *serial = port->serial; |
562 | struct mct_u232_private *priv = usb_get_serial_port_data(port); | 563 | struct mct_u232_private *priv = usb_get_serial_port_data(port); |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 70f93b18292f..6109c6704a73 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
@@ -1014,7 +1014,7 @@ static int send_cmd_write_baud_rate(struct moschip_port *mos7720_port, | |||
1014 | * the specified new settings. | 1014 | * the specified new settings. |
1015 | */ | 1015 | */ |
1016 | static void change_port_settings(struct moschip_port *mos7720_port, | 1016 | static void change_port_settings(struct moschip_port *mos7720_port, |
1017 | struct termios *old_termios) | 1017 | struct ktermios *old_termios) |
1018 | { | 1018 | { |
1019 | struct usb_serial_port *port; | 1019 | struct usb_serial_port *port; |
1020 | struct usb_serial *serial; | 1020 | struct usb_serial *serial; |
@@ -1203,7 +1203,7 @@ static void change_port_settings(struct moschip_port *mos7720_port, | |||
1203 | * termios structure. | 1203 | * termios structure. |
1204 | */ | 1204 | */ |
1205 | static void mos7720_set_termios(struct usb_serial_port *port, | 1205 | static void mos7720_set_termios(struct usb_serial_port *port, |
1206 | struct termios *old_termios) | 1206 | struct ktermios *old_termios) |
1207 | { | 1207 | { |
1208 | int status; | 1208 | int status; |
1209 | unsigned int cflag; | 1209 | unsigned int cflag; |
@@ -1605,12 +1605,21 @@ static void mos7720_shutdown(struct usb_serial *serial) | |||
1605 | usb_set_serial_data(serial, NULL); | 1605 | usb_set_serial_data(serial, NULL); |
1606 | } | 1606 | } |
1607 | 1607 | ||
1608 | static struct usb_driver usb_driver = { | ||
1609 | .name = "moschip7720", | ||
1610 | .probe = usb_serial_probe, | ||
1611 | .disconnect = usb_serial_disconnect, | ||
1612 | .id_table = moschip_port_id_table, | ||
1613 | .no_dynamic_id = 1, | ||
1614 | }; | ||
1615 | |||
1608 | static struct usb_serial_driver moschip7720_2port_driver = { | 1616 | static struct usb_serial_driver moschip7720_2port_driver = { |
1609 | .driver = { | 1617 | .driver = { |
1610 | .owner = THIS_MODULE, | 1618 | .owner = THIS_MODULE, |
1611 | .name = "moschip7720", | 1619 | .name = "moschip7720", |
1612 | }, | 1620 | }, |
1613 | .description = "Moschip 2 port adapter", | 1621 | .description = "Moschip 2 port adapter", |
1622 | .usb_driver = &usb_driver, | ||
1614 | .id_table = moschip_port_id_table, | 1623 | .id_table = moschip_port_id_table, |
1615 | .num_interrupt_in = 1, | 1624 | .num_interrupt_in = 1, |
1616 | .num_bulk_in = 2, | 1625 | .num_bulk_in = 2, |
@@ -1631,13 +1640,6 @@ static struct usb_serial_driver moschip7720_2port_driver = { | |||
1631 | .read_bulk_callback = mos7720_bulk_in_callback, | 1640 | .read_bulk_callback = mos7720_bulk_in_callback, |
1632 | }; | 1641 | }; |
1633 | 1642 | ||
1634 | static struct usb_driver usb_driver = { | ||
1635 | .name = "moschip7720", | ||
1636 | .probe = usb_serial_probe, | ||
1637 | .disconnect = usb_serial_disconnect, | ||
1638 | .id_table = moschip_port_id_table, | ||
1639 | }; | ||
1640 | |||
1641 | static int __init moschip7720_init(void) | 1643 | static int __init moschip7720_init(void) |
1642 | { | 1644 | { |
1643 | int retval; | 1645 | int retval; |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 5432c6340086..b2264a87617b 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -1931,7 +1931,7 @@ static int mos7840_send_cmd_write_baud_rate(struct moschip_port *mos7840_port, | |||
1931 | *****************************************************************************/ | 1931 | *****************************************************************************/ |
1932 | 1932 | ||
1933 | static void mos7840_change_port_settings(struct moschip_port *mos7840_port, | 1933 | static void mos7840_change_port_settings(struct moschip_port *mos7840_port, |
1934 | struct termios *old_termios) | 1934 | struct ktermios *old_termios) |
1935 | { | 1935 | { |
1936 | struct tty_struct *tty; | 1936 | struct tty_struct *tty; |
1937 | int baud; | 1937 | int baud; |
@@ -2118,7 +2118,7 @@ static void mos7840_change_port_settings(struct moschip_port *mos7840_port, | |||
2118 | *****************************************************************************/ | 2118 | *****************************************************************************/ |
2119 | 2119 | ||
2120 | static void mos7840_set_termios(struct usb_serial_port *port, | 2120 | static void mos7840_set_termios(struct usb_serial_port *port, |
2121 | struct termios *old_termios) | 2121 | struct ktermios *old_termios) |
2122 | { | 2122 | { |
2123 | int status; | 2123 | int status; |
2124 | unsigned int cflag; | 2124 | unsigned int cflag; |
@@ -2460,12 +2460,6 @@ static int mos7840_ioctl(struct usb_serial_port *port, struct file *file, | |||
2460 | tty_ldisc_deref(ld); | 2460 | tty_ldisc_deref(ld); |
2461 | return 0; | 2461 | return 0; |
2462 | 2462 | ||
2463 | case TCGETS: | ||
2464 | if (kernel_termios_to_user_termios | ||
2465 | ((struct termios __user *)argp, tty->termios)) | ||
2466 | return -EFAULT; | ||
2467 | return 0; | ||
2468 | |||
2469 | case TIOCSERGETLSR: | 2463 | case TIOCSERGETLSR: |
2470 | dbg("%s (%d) TIOCSERGETLSR", __FUNCTION__, port->number); | 2464 | dbg("%s (%d) TIOCSERGETLSR", __FUNCTION__, port->number); |
2471 | return mos7840_get_lsr_info(mos7840_port, argp); | 2465 | return mos7840_get_lsr_info(mos7840_port, argp); |
@@ -2840,12 +2834,21 @@ static void mos7840_shutdown(struct usb_serial *serial) | |||
2840 | 2834 | ||
2841 | } | 2835 | } |
2842 | 2836 | ||
2837 | static struct usb_driver io_driver = { | ||
2838 | .name = "mos7840", | ||
2839 | .probe = usb_serial_probe, | ||
2840 | .disconnect = usb_serial_disconnect, | ||
2841 | .id_table = moschip_id_table_combined, | ||
2842 | .no_dynamic_id = 1, | ||
2843 | }; | ||
2844 | |||
2843 | static struct usb_serial_driver moschip7840_4port_device = { | 2845 | static struct usb_serial_driver moschip7840_4port_device = { |
2844 | .driver = { | 2846 | .driver = { |
2845 | .owner = THIS_MODULE, | 2847 | .owner = THIS_MODULE, |
2846 | .name = "mos7840", | 2848 | .name = "mos7840", |
2847 | }, | 2849 | }, |
2848 | .description = DRIVER_DESC, | 2850 | .description = DRIVER_DESC, |
2851 | .usb_driver = &io_driver, | ||
2849 | .id_table = moschip_port_id_table, | 2852 | .id_table = moschip_port_id_table, |
2850 | .num_interrupt_in = 1, //NUM_DONT_CARE,//1, | 2853 | .num_interrupt_in = 1, //NUM_DONT_CARE,//1, |
2851 | #ifdef check | 2854 | #ifdef check |
@@ -2875,13 +2878,6 @@ static struct usb_serial_driver moschip7840_4port_device = { | |||
2875 | .read_int_callback = mos7840_interrupt_callback, | 2878 | .read_int_callback = mos7840_interrupt_callback, |
2876 | }; | 2879 | }; |
2877 | 2880 | ||
2878 | static struct usb_driver io_driver = { | ||
2879 | .name = "mos7840", | ||
2880 | .probe = usb_serial_probe, | ||
2881 | .disconnect = usb_serial_disconnect, | ||
2882 | .id_table = moschip_id_table_combined, | ||
2883 | }; | ||
2884 | |||
2885 | /**************************************************************************** | 2881 | /**************************************************************************** |
2886 | * moschip7840_init | 2882 | * moschip7840_init |
2887 | * This is called by the module subsystem, or on startup to initialize us | 2883 | * This is called by the module subsystem, or on startup to initialize us |
diff --git a/drivers/usb/serial/navman.c b/drivers/usb/serial/navman.c index 054abee81652..90701111d746 100644 --- a/drivers/usb/serial/navman.c +++ b/drivers/usb/serial/navman.c | |||
@@ -119,6 +119,7 @@ static struct usb_serial_driver navman_device = { | |||
119 | .name = "navman", | 119 | .name = "navman", |
120 | }, | 120 | }, |
121 | .id_table = id_table, | 121 | .id_table = id_table, |
122 | .usb_driver = &navman_driver, | ||
122 | .num_interrupt_in = NUM_DONT_CARE, | 123 | .num_interrupt_in = NUM_DONT_CARE, |
123 | .num_bulk_in = NUM_DONT_CARE, | 124 | .num_bulk_in = NUM_DONT_CARE, |
124 | .num_bulk_out = NUM_DONT_CARE, | 125 | .num_bulk_out = NUM_DONT_CARE, |
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index bc91d3b726fc..0216ac12a27d 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c | |||
@@ -93,6 +93,7 @@ static struct usb_serial_driver zyxel_omninet_device = { | |||
93 | .name = "omninet", | 93 | .name = "omninet", |
94 | }, | 94 | }, |
95 | .description = "ZyXEL - omni.net lcd plus usb", | 95 | .description = "ZyXEL - omni.net lcd plus usb", |
96 | .usb_driver = &omninet_driver, | ||
96 | .id_table = id_table, | 97 | .id_table = id_table, |
97 | .num_interrupt_in = 1, | 98 | .num_interrupt_in = 1, |
98 | .num_bulk_in = 1, | 99 | .num_bulk_in = 1, |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 130afbbd3fca..ced9f32b29d9 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -59,7 +59,7 @@ static int option_chars_in_buffer(struct usb_serial_port *port); | |||
59 | static int option_ioctl(struct usb_serial_port *port, struct file *file, | 59 | static int option_ioctl(struct usb_serial_port *port, struct file *file, |
60 | unsigned int cmd, unsigned long arg); | 60 | unsigned int cmd, unsigned long arg); |
61 | static void option_set_termios(struct usb_serial_port *port, | 61 | static void option_set_termios(struct usb_serial_port *port, |
62 | struct termios *old); | 62 | struct ktermios *old); |
63 | static void option_break_ctl(struct usb_serial_port *port, int break_state); | 63 | static void option_break_ctl(struct usb_serial_port *port, int break_state); |
64 | static int option_tiocmget(struct usb_serial_port *port, struct file *file); | 64 | static int option_tiocmget(struct usb_serial_port *port, struct file *file); |
65 | static int option_tiocmset(struct usb_serial_port *port, struct file *file, | 65 | static int option_tiocmset(struct usb_serial_port *port, struct file *file, |
@@ -78,7 +78,9 @@ static int option_send_setup(struct usb_serial_port *port); | |||
78 | #define OPTION_PRODUCT_FUSION2 0x6300 | 78 | #define OPTION_PRODUCT_FUSION2 0x6300 |
79 | #define OPTION_PRODUCT_COBRA 0x6500 | 79 | #define OPTION_PRODUCT_COBRA 0x6500 |
80 | #define OPTION_PRODUCT_COBRA2 0x6600 | 80 | #define OPTION_PRODUCT_COBRA2 0x6600 |
81 | #define OPTION_PRODUCT_GTMAX36 0x6701 | ||
81 | #define HUAWEI_PRODUCT_E600 0x1001 | 82 | #define HUAWEI_PRODUCT_E600 0x1001 |
83 | #define HUAWEI_PRODUCT_E220 0x1003 | ||
82 | #define AUDIOVOX_PRODUCT_AIRCARD 0x0112 | 84 | #define AUDIOVOX_PRODUCT_AIRCARD 0x0112 |
83 | #define NOVATELWIRELESS_PRODUCT_U740 0x1400 | 85 | #define NOVATELWIRELESS_PRODUCT_U740 0x1400 |
84 | #define ANYDATA_PRODUCT_ID 0x6501 | 86 | #define ANYDATA_PRODUCT_ID 0x6501 |
@@ -89,7 +91,9 @@ static struct usb_device_id option_ids[] = { | |||
89 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) }, | 91 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) }, |
90 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) }, | 92 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) }, |
91 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) }, | 93 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) }, |
94 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) }, | ||
92 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, | 95 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, |
96 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) }, | ||
93 | { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, | 97 | { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, |
94 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, | 98 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, |
95 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, | 99 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, |
@@ -102,7 +106,9 @@ static struct usb_device_id option_ids1[] = { | |||
102 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) }, | 106 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) }, |
103 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) }, | 107 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA) }, |
104 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) }, | 108 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COBRA2) }, |
109 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) }, | ||
105 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, | 110 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, |
111 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) }, | ||
106 | { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, | 112 | { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, |
107 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, | 113 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, |
108 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, | 114 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, |
@@ -129,6 +135,7 @@ static struct usb_serial_driver option_1port_device = { | |||
129 | .name = "option1", | 135 | .name = "option1", |
130 | }, | 136 | }, |
131 | .description = "GSM modem (1-port)", | 137 | .description = "GSM modem (1-port)", |
138 | .usb_driver = &option_driver, | ||
132 | .id_table = option_ids1, | 139 | .id_table = option_ids1, |
133 | .num_interrupt_in = NUM_DONT_CARE, | 140 | .num_interrupt_in = NUM_DONT_CARE, |
134 | .num_bulk_in = NUM_DONT_CARE, | 141 | .num_bulk_in = NUM_DONT_CARE, |
@@ -230,7 +237,7 @@ static void option_break_ctl(struct usb_serial_port *port, int break_state) | |||
230 | } | 237 | } |
231 | 238 | ||
232 | static void option_set_termios(struct usb_serial_port *port, | 239 | static void option_set_termios(struct usb_serial_port *port, |
233 | struct termios *old_termios) | 240 | struct ktermios *old_termios) |
234 | { | 241 | { |
235 | dbg("%s", __FUNCTION__); | 242 | dbg("%s", __FUNCTION__); |
236 | 243 | ||
@@ -622,6 +629,9 @@ static int option_send_setup(struct usb_serial_port *port) | |||
622 | 629 | ||
623 | dbg("%s", __FUNCTION__); | 630 | dbg("%s", __FUNCTION__); |
624 | 631 | ||
632 | if (port->number != 0) | ||
633 | return 0; | ||
634 | |||
625 | portdata = usb_get_serial_port_data(port); | 635 | portdata = usb_get_serial_port_data(port); |
626 | 636 | ||
627 | if (port->tty) { | 637 | if (port->tty) { |
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index bc800c8787a8..6c083d4e2c9b 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -159,7 +159,7 @@ static struct pl2303_buf *pl2303_buf_alloc(unsigned int size) | |||
159 | if (size == 0) | 159 | if (size == 0) |
160 | return NULL; | 160 | return NULL; |
161 | 161 | ||
162 | pb = (struct pl2303_buf *)kmalloc(sizeof(struct pl2303_buf), GFP_KERNEL); | 162 | pb = kmalloc(sizeof(struct pl2303_buf), GFP_KERNEL); |
163 | if (pb == NULL) | 163 | if (pb == NULL) |
164 | return NULL; | 164 | return NULL; |
165 | 165 | ||
@@ -455,7 +455,7 @@ static int pl2303_chars_in_buffer(struct usb_serial_port *port) | |||
455 | } | 455 | } |
456 | 456 | ||
457 | static void pl2303_set_termios(struct usb_serial_port *port, | 457 | static void pl2303_set_termios(struct usb_serial_port *port, |
458 | struct termios *old_termios) | 458 | struct ktermios *old_termios) |
459 | { | 459 | { |
460 | struct usb_serial *serial = port->serial; | 460 | struct usb_serial *serial = port->serial; |
461 | struct pl2303_private *priv = usb_get_serial_port_data(port); | 461 | struct pl2303_private *priv = usb_get_serial_port_data(port); |
@@ -687,7 +687,7 @@ static void pl2303_close(struct usb_serial_port *port, struct file *filp) | |||
687 | 687 | ||
688 | static int pl2303_open(struct usb_serial_port *port, struct file *filp) | 688 | static int pl2303_open(struct usb_serial_port *port, struct file *filp) |
689 | { | 689 | { |
690 | struct termios tmp_termios; | 690 | struct ktermios tmp_termios; |
691 | struct usb_serial *serial = port->serial; | 691 | struct usb_serial *serial = port->serial; |
692 | struct pl2303_private *priv = usb_get_serial_port_data(port); | 692 | struct pl2303_private *priv = usb_get_serial_port_data(port); |
693 | unsigned char *buf; | 693 | unsigned char *buf; |
@@ -1118,6 +1118,7 @@ static struct usb_serial_driver pl2303_device = { | |||
1118 | .name = "pl2303", | 1118 | .name = "pl2303", |
1119 | }, | 1119 | }, |
1120 | .id_table = id_table, | 1120 | .id_table = id_table, |
1121 | .usb_driver = &pl2303_driver, | ||
1121 | .num_interrupt_in = NUM_DONT_CARE, | 1122 | .num_interrupt_in = NUM_DONT_CARE, |
1122 | .num_bulk_in = 1, | 1123 | .num_bulk_in = 1, |
1123 | .num_bulk_out = 1, | 1124 | .num_bulk_out = 1, |
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 30b7ebc8d45d..5a03a3fc9386 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c | |||
@@ -402,6 +402,7 @@ static struct usb_serial_driver safe_device = { | |||
402 | .name = "safe_serial", | 402 | .name = "safe_serial", |
403 | }, | 403 | }, |
404 | .id_table = id_table, | 404 | .id_table = id_table, |
405 | .usb_driver = &safe_driver, | ||
405 | .num_interrupt_in = NUM_DONT_CARE, | 406 | .num_interrupt_in = NUM_DONT_CARE, |
406 | .num_bulk_in = NUM_DONT_CARE, | 407 | .num_bulk_in = NUM_DONT_CARE, |
407 | .num_bulk_out = NUM_DONT_CARE, | 408 | .num_bulk_out = NUM_DONT_CARE, |
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 4b5097fa48d7..ecedd833818d 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -13,10 +13,9 @@ | |||
13 | Portions based on the option driver by Matthias Urlichs <smurf@smurf.noris.de> | 13 | Portions based on the option driver by Matthias Urlichs <smurf@smurf.noris.de> |
14 | Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> | 14 | Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> |
15 | 15 | ||
16 | History: | ||
17 | */ | 16 | */ |
18 | 17 | ||
19 | #define DRIVER_VERSION "v.1.0.5" | 18 | #define DRIVER_VERSION "v.1.0.6" |
20 | #define DRIVER_AUTHOR "Kevin Lloyd <linux@sierrawireless.com>" | 19 | #define DRIVER_AUTHOR "Kevin Lloyd <linux@sierrawireless.com>" |
21 | #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" | 20 | #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" |
22 | 21 | ||
@@ -31,14 +30,15 @@ | |||
31 | 30 | ||
32 | 31 | ||
33 | static struct usb_device_id id_table [] = { | 32 | static struct usb_device_id id_table [] = { |
33 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ | ||
34 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ | 34 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ |
35 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ | ||
35 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ | 36 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ |
36 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ | ||
37 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ | 37 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ |
38 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ | 38 | { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ |
39 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ | 39 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ |
40 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ | ||
40 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ | 41 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ |
41 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 for Europe */ | ||
42 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ | 42 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ |
43 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ | 43 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ |
44 | 44 | ||
@@ -55,14 +55,15 @@ static struct usb_device_id id_table_1port [] = { | |||
55 | }; | 55 | }; |
56 | 56 | ||
57 | static struct usb_device_id id_table_3port [] = { | 57 | static struct usb_device_id id_table_3port [] = { |
58 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ | ||
58 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ | 59 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ |
60 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ | ||
59 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ | 61 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ |
60 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ | ||
61 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ | 62 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ |
62 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ | 63 | { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ |
63 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ | 64 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ |
65 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ | ||
64 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ | 66 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ |
65 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 for Europe */ | ||
66 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ | 67 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ |
67 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ | 68 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ |
68 | { } | 69 | { } |
@@ -81,7 +82,7 @@ static int debug; | |||
81 | 82 | ||
82 | /* per port private data */ | 83 | /* per port private data */ |
83 | #define N_IN_URB 4 | 84 | #define N_IN_URB 4 |
84 | #define N_OUT_URB 1 | 85 | #define N_OUT_URB 4 |
85 | #define IN_BUFLEN 4096 | 86 | #define IN_BUFLEN 4096 |
86 | #define OUT_BUFLEN 128 | 87 | #define OUT_BUFLEN 128 |
87 | 88 | ||
@@ -145,7 +146,7 @@ static void sierra_break_ctl(struct usb_serial_port *port, int break_state) | |||
145 | } | 146 | } |
146 | 147 | ||
147 | static void sierra_set_termios(struct usb_serial_port *port, | 148 | static void sierra_set_termios(struct usb_serial_port *port, |
148 | struct termios *old_termios) | 149 | struct ktermios *old_termios) |
149 | { | 150 | { |
150 | dbg("%s", __FUNCTION__); | 151 | dbg("%s", __FUNCTION__); |
151 | 152 | ||
@@ -396,6 +397,8 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp) | |||
396 | struct usb_serial *serial = port->serial; | 397 | struct usb_serial *serial = port->serial; |
397 | int i, err; | 398 | int i, err; |
398 | struct urb *urb; | 399 | struct urb *urb; |
400 | int result; | ||
401 | __u16 set_mode_dzero = 0x0000; | ||
399 | 402 | ||
400 | portdata = usb_get_serial_port_data(port); | 403 | portdata = usb_get_serial_port_data(port); |
401 | 404 | ||
@@ -442,6 +445,12 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp) | |||
442 | 445 | ||
443 | port->tty->low_latency = 1; | 446 | port->tty->low_latency = 1; |
444 | 447 | ||
448 | /* set mode to D0 */ | ||
449 | result = usb_control_msg(serial->dev, | ||
450 | usb_rcvctrlpipe(serial->dev, 0), | ||
451 | 0x00, 0x40, set_mode_dzero, 0, NULL, | ||
452 | 0, USB_CTRL_SET_TIMEOUT); | ||
453 | |||
445 | sierra_send_setup(port); | 454 | sierra_send_setup(port); |
446 | 455 | ||
447 | return (0); | 456 | return (0); |
@@ -614,6 +623,7 @@ static struct usb_serial_driver sierra_1port_device = { | |||
614 | }, | 623 | }, |
615 | .description = "Sierra USB modem (1 port)", | 624 | .description = "Sierra USB modem (1 port)", |
616 | .id_table = id_table_1port, | 625 | .id_table = id_table_1port, |
626 | .usb_driver = &sierra_driver, | ||
617 | .num_interrupt_in = NUM_DONT_CARE, | 627 | .num_interrupt_in = NUM_DONT_CARE, |
618 | .num_bulk_in = 1, | 628 | .num_bulk_in = 1, |
619 | .num_bulk_out = 1, | 629 | .num_bulk_out = 1, |
@@ -642,6 +652,7 @@ static struct usb_serial_driver sierra_3port_device = { | |||
642 | }, | 652 | }, |
643 | .description = "Sierra USB modem (3 port)", | 653 | .description = "Sierra USB modem (3 port)", |
644 | .id_table = id_table_3port, | 654 | .id_table = id_table_3port, |
655 | .usb_driver = &sierra_driver, | ||
645 | .num_interrupt_in = NUM_DONT_CARE, | 656 | .num_interrupt_in = NUM_DONT_CARE, |
646 | .num_bulk_in = 3, | 657 | .num_bulk_in = 3, |
647 | .num_bulk_out = 3, | 658 | .num_bulk_out = 3, |
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index ae98d8cbdbb8..4203e2b1a761 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c | |||
@@ -161,7 +161,7 @@ static void ti_throttle(struct usb_serial_port *port); | |||
161 | static void ti_unthrottle(struct usb_serial_port *port); | 161 | static void ti_unthrottle(struct usb_serial_port *port); |
162 | static int ti_ioctl(struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg); | 162 | static int ti_ioctl(struct usb_serial_port *port, struct file *file, unsigned int cmd, unsigned long arg); |
163 | static void ti_set_termios(struct usb_serial_port *port, | 163 | static void ti_set_termios(struct usb_serial_port *port, |
164 | struct termios *old_termios); | 164 | struct ktermios *old_termios); |
165 | static int ti_tiocmget(struct usb_serial_port *port, struct file *file); | 165 | static int ti_tiocmget(struct usb_serial_port *port, struct file *file); |
166 | static int ti_tiocmset(struct usb_serial_port *port, struct file *file, | 166 | static int ti_tiocmset(struct usb_serial_port *port, struct file *file, |
167 | unsigned int set, unsigned int clear); | 167 | unsigned int set, unsigned int clear); |
@@ -262,6 +262,7 @@ static struct usb_serial_driver ti_1port_device = { | |||
262 | .name = "ti_usb_3410_5052_1", | 262 | .name = "ti_usb_3410_5052_1", |
263 | }, | 263 | }, |
264 | .description = "TI USB 3410 1 port adapter", | 264 | .description = "TI USB 3410 1 port adapter", |
265 | .usb_driver = &ti_usb_driver, | ||
265 | .id_table = ti_id_table_3410, | 266 | .id_table = ti_id_table_3410, |
266 | .num_interrupt_in = 1, | 267 | .num_interrupt_in = 1, |
267 | .num_bulk_in = 1, | 268 | .num_bulk_in = 1, |
@@ -292,6 +293,7 @@ static struct usb_serial_driver ti_2port_device = { | |||
292 | .name = "ti_usb_3410_5052_2", | 293 | .name = "ti_usb_3410_5052_2", |
293 | }, | 294 | }, |
294 | .description = "TI USB 5052 2 port adapter", | 295 | .description = "TI USB 5052 2 port adapter", |
296 | .usb_driver = &ti_usb_driver, | ||
295 | .id_table = ti_id_table_5052, | 297 | .id_table = ti_id_table_5052, |
296 | .num_interrupt_in = 1, | 298 | .num_interrupt_in = 1, |
297 | .num_bulk_in = 2, | 299 | .num_bulk_in = 2, |
@@ -881,7 +883,7 @@ static int ti_ioctl(struct usb_serial_port *port, struct file *file, | |||
881 | 883 | ||
882 | 884 | ||
883 | static void ti_set_termios(struct usb_serial_port *port, | 885 | static void ti_set_termios(struct usb_serial_port *port, |
884 | struct termios *old_termios) | 886 | struct ktermios *old_termios) |
885 | { | 887 | { |
886 | struct ti_port *tport = usb_get_serial_port_data(port); | 888 | struct ti_port *tport = usb_get_serial_port_data(port); |
887 | struct tty_struct *tty = port->tty; | 889 | struct tty_struct *tty = port->tty; |
@@ -1710,7 +1712,7 @@ static struct circ_buf *ti_buf_alloc(void) | |||
1710 | { | 1712 | { |
1711 | struct circ_buf *cb; | 1713 | struct circ_buf *cb; |
1712 | 1714 | ||
1713 | cb = (struct circ_buf *)kmalloc(sizeof(struct circ_buf), GFP_KERNEL); | 1715 | cb = kmalloc(sizeof(struct circ_buf), GFP_KERNEL); |
1714 | if (cb == NULL) | 1716 | if (cb == NULL) |
1715 | return NULL; | 1717 | return NULL; |
1716 | 1718 | ||
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 3d5072f14b8d..6bf22a28adb8 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -59,14 +59,19 @@ static struct usb_driver usb_serial_driver = { | |||
59 | 59 | ||
60 | static int debug; | 60 | static int debug; |
61 | static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */ | 61 | static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */ |
62 | static spinlock_t table_lock; | ||
62 | static LIST_HEAD(usb_serial_driver_list); | 63 | static LIST_HEAD(usb_serial_driver_list); |
63 | 64 | ||
64 | struct usb_serial *usb_serial_get_by_index(unsigned index) | 65 | struct usb_serial *usb_serial_get_by_index(unsigned index) |
65 | { | 66 | { |
66 | struct usb_serial *serial = serial_table[index]; | 67 | struct usb_serial *serial; |
68 | |||
69 | spin_lock(&table_lock); | ||
70 | serial = serial_table[index]; | ||
67 | 71 | ||
68 | if (serial) | 72 | if (serial) |
69 | kref_get(&serial->kref); | 73 | kref_get(&serial->kref); |
74 | spin_unlock(&table_lock); | ||
70 | return serial; | 75 | return serial; |
71 | } | 76 | } |
72 | 77 | ||
@@ -78,6 +83,7 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po | |||
78 | dbg("%s %d", __FUNCTION__, num_ports); | 83 | dbg("%s %d", __FUNCTION__, num_ports); |
79 | 84 | ||
80 | *minor = 0; | 85 | *minor = 0; |
86 | spin_lock(&table_lock); | ||
81 | for (i = 0; i < SERIAL_TTY_MINORS; ++i) { | 87 | for (i = 0; i < SERIAL_TTY_MINORS; ++i) { |
82 | if (serial_table[i]) | 88 | if (serial_table[i]) |
83 | continue; | 89 | continue; |
@@ -96,8 +102,10 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po | |||
96 | dbg("%s - minor base = %d", __FUNCTION__, *minor); | 102 | dbg("%s - minor base = %d", __FUNCTION__, *minor); |
97 | for (i = *minor; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i) | 103 | for (i = *minor; (i < (*minor + num_ports)) && (i < SERIAL_TTY_MINORS); ++i) |
98 | serial_table[i] = serial; | 104 | serial_table[i] = serial; |
105 | spin_unlock(&table_lock); | ||
99 | return serial; | 106 | return serial; |
100 | } | 107 | } |
108 | spin_unlock(&table_lock); | ||
101 | return NULL; | 109 | return NULL; |
102 | } | 110 | } |
103 | 111 | ||
@@ -110,9 +118,11 @@ static void return_serial(struct usb_serial *serial) | |||
110 | if (serial == NULL) | 118 | if (serial == NULL) |
111 | return; | 119 | return; |
112 | 120 | ||
121 | spin_lock(&table_lock); | ||
113 | for (i = 0; i < serial->num_ports; ++i) { | 122 | for (i = 0; i < serial->num_ports; ++i) { |
114 | serial_table[serial->minor + i] = NULL; | 123 | serial_table[serial->minor + i] = NULL; |
115 | } | 124 | } |
125 | spin_unlock(&table_lock); | ||
116 | } | 126 | } |
117 | 127 | ||
118 | static void destroy_serial(struct kref *kref) | 128 | static void destroy_serial(struct kref *kref) |
@@ -271,7 +281,7 @@ static void serial_close(struct tty_struct *tty, struct file * filp) | |||
271 | static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count) | 281 | static int serial_write (struct tty_struct * tty, const unsigned char *buf, int count) |
272 | { | 282 | { |
273 | struct usb_serial_port *port = tty->driver_data; | 283 | struct usb_serial_port *port = tty->driver_data; |
274 | int retval = -EINVAL; | 284 | int retval = -ENODEV; |
275 | 285 | ||
276 | if (!port || port->serial->dev->state == USB_STATE_NOTATTACHED) | 286 | if (!port || port->serial->dev->state == USB_STATE_NOTATTACHED) |
277 | goto exit; | 287 | goto exit; |
@@ -279,6 +289,7 @@ static int serial_write (struct tty_struct * tty, const unsigned char *buf, int | |||
279 | dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); | 289 | dbg("%s - port %d, %d byte(s)", __FUNCTION__, port->number, count); |
280 | 290 | ||
281 | if (!port->open_count) { | 291 | if (!port->open_count) { |
292 | retval = -EINVAL; | ||
282 | dbg("%s - port not opened", __FUNCTION__); | 293 | dbg("%s - port not opened", __FUNCTION__); |
283 | goto exit; | 294 | goto exit; |
284 | } | 295 | } |
@@ -397,7 +408,7 @@ exit: | |||
397 | return retval; | 408 | return retval; |
398 | } | 409 | } |
399 | 410 | ||
400 | static void serial_set_termios (struct tty_struct *tty, struct termios * old) | 411 | static void serial_set_termios (struct tty_struct *tty, struct ktermios * old) |
401 | { | 412 | { |
402 | struct usb_serial_port *port = tty->driver_data; | 413 | struct usb_serial_port *port = tty->driver_data; |
403 | 414 | ||
@@ -559,15 +570,20 @@ static void port_release(struct device *dev) | |||
559 | port_free(port); | 570 | port_free(port); |
560 | } | 571 | } |
561 | 572 | ||
562 | static void port_free(struct usb_serial_port *port) | 573 | static void kill_traffic(struct usb_serial_port *port) |
563 | { | 574 | { |
564 | usb_kill_urb(port->read_urb); | 575 | usb_kill_urb(port->read_urb); |
565 | usb_free_urb(port->read_urb); | ||
566 | usb_kill_urb(port->write_urb); | 576 | usb_kill_urb(port->write_urb); |
567 | usb_free_urb(port->write_urb); | ||
568 | usb_kill_urb(port->interrupt_in_urb); | 577 | usb_kill_urb(port->interrupt_in_urb); |
569 | usb_free_urb(port->interrupt_in_urb); | ||
570 | usb_kill_urb(port->interrupt_out_urb); | 578 | usb_kill_urb(port->interrupt_out_urb); |
579 | } | ||
580 | |||
581 | static void port_free(struct usb_serial_port *port) | ||
582 | { | ||
583 | kill_traffic(port); | ||
584 | usb_free_urb(port->read_urb); | ||
585 | usb_free_urb(port->write_urb); | ||
586 | usb_free_urb(port->interrupt_in_urb); | ||
571 | usb_free_urb(port->interrupt_out_urb); | 587 | usb_free_urb(port->interrupt_out_urb); |
572 | kfree(port->bulk_in_buffer); | 588 | kfree(port->bulk_in_buffer); |
573 | kfree(port->bulk_out_buffer); | 589 | kfree(port->bulk_out_buffer); |
@@ -596,6 +612,39 @@ static struct usb_serial * create_serial (struct usb_device *dev, | |||
596 | return serial; | 612 | return serial; |
597 | } | 613 | } |
598 | 614 | ||
615 | static const struct usb_device_id *match_dynamic_id(struct usb_interface *intf, | ||
616 | struct usb_serial_driver *drv) | ||
617 | { | ||
618 | struct usb_dynid *dynid; | ||
619 | |||
620 | spin_lock(&drv->dynids.lock); | ||
621 | list_for_each_entry(dynid, &drv->dynids.list, node) { | ||
622 | if (usb_match_one_id(intf, &dynid->id)) { | ||
623 | spin_unlock(&drv->dynids.lock); | ||
624 | return &dynid->id; | ||
625 | } | ||
626 | } | ||
627 | spin_unlock(&drv->dynids.lock); | ||
628 | return NULL; | ||
629 | } | ||
630 | |||
631 | static const struct usb_device_id *get_iface_id(struct usb_serial_driver *drv, | ||
632 | struct usb_interface *intf) | ||
633 | { | ||
634 | const struct usb_device_id *id; | ||
635 | |||
636 | id = usb_match_id(intf, drv->id_table); | ||
637 | if (id) { | ||
638 | dbg("static descriptor matches"); | ||
639 | goto exit; | ||
640 | } | ||
641 | id = match_dynamic_id(intf, drv); | ||
642 | if (id) | ||
643 | dbg("dynamic descriptor matches"); | ||
644 | exit: | ||
645 | return id; | ||
646 | } | ||
647 | |||
599 | static struct usb_serial_driver *search_serial_device(struct usb_interface *iface) | 648 | static struct usb_serial_driver *search_serial_device(struct usb_interface *iface) |
600 | { | 649 | { |
601 | struct list_head *p; | 650 | struct list_head *p; |
@@ -605,11 +654,9 @@ static struct usb_serial_driver *search_serial_device(struct usb_interface *ifac | |||
605 | /* Check if the usb id matches a known device */ | 654 | /* Check if the usb id matches a known device */ |
606 | list_for_each(p, &usb_serial_driver_list) { | 655 | list_for_each(p, &usb_serial_driver_list) { |
607 | t = list_entry(p, struct usb_serial_driver, driver_list); | 656 | t = list_entry(p, struct usb_serial_driver, driver_list); |
608 | id = usb_match_id(iface, t->id_table); | 657 | id = get_iface_id(t, iface); |
609 | if (id != NULL) { | 658 | if (id) |
610 | dbg("descriptor matches"); | ||
611 | return t; | 659 | return t; |
612 | } | ||
613 | } | 660 | } |
614 | 661 | ||
615 | return NULL; | 662 | return NULL; |
@@ -639,14 +686,17 @@ int usb_serial_probe(struct usb_interface *interface, | |||
639 | int num_ports = 0; | 686 | int num_ports = 0; |
640 | int max_endpoints; | 687 | int max_endpoints; |
641 | 688 | ||
689 | lock_kernel(); /* guard against unloading a serial driver module */ | ||
642 | type = search_serial_device(interface); | 690 | type = search_serial_device(interface); |
643 | if (!type) { | 691 | if (!type) { |
692 | unlock_kernel(); | ||
644 | dbg("none matched"); | 693 | dbg("none matched"); |
645 | return -ENODEV; | 694 | return -ENODEV; |
646 | } | 695 | } |
647 | 696 | ||
648 | serial = create_serial (dev, interface, type); | 697 | serial = create_serial (dev, interface, type); |
649 | if (!serial) { | 698 | if (!serial) { |
699 | unlock_kernel(); | ||
650 | dev_err(&interface->dev, "%s - out of memory\n", __FUNCTION__); | 700 | dev_err(&interface->dev, "%s - out of memory\n", __FUNCTION__); |
651 | return -ENOMEM; | 701 | return -ENOMEM; |
652 | } | 702 | } |
@@ -656,16 +706,18 @@ int usb_serial_probe(struct usb_interface *interface, | |||
656 | const struct usb_device_id *id; | 706 | const struct usb_device_id *id; |
657 | 707 | ||
658 | if (!try_module_get(type->driver.owner)) { | 708 | if (!try_module_get(type->driver.owner)) { |
709 | unlock_kernel(); | ||
659 | dev_err(&interface->dev, "module get failed, exiting\n"); | 710 | dev_err(&interface->dev, "module get failed, exiting\n"); |
660 | kfree (serial); | 711 | kfree (serial); |
661 | return -EIO; | 712 | return -EIO; |
662 | } | 713 | } |
663 | 714 | ||
664 | id = usb_match_id(interface, type->id_table); | 715 | id = get_iface_id(type, interface); |
665 | retval = type->probe(serial, id); | 716 | retval = type->probe(serial, id); |
666 | module_put(type->driver.owner); | 717 | module_put(type->driver.owner); |
667 | 718 | ||
668 | if (retval) { | 719 | if (retval) { |
720 | unlock_kernel(); | ||
669 | dbg ("sub driver rejected device"); | 721 | dbg ("sub driver rejected device"); |
670 | kfree (serial); | 722 | kfree (serial); |
671 | return retval; | 723 | return retval; |
@@ -735,6 +787,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
735 | * properly during a later invocation of usb_serial_probe | 787 | * properly during a later invocation of usb_serial_probe |
736 | */ | 788 | */ |
737 | if (num_bulk_in == 0 || num_bulk_out == 0) { | 789 | if (num_bulk_in == 0 || num_bulk_out == 0) { |
790 | unlock_kernel(); | ||
738 | dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n"); | 791 | dev_info(&interface->dev, "PL-2303 hack: descriptors matched but endpoints did not\n"); |
739 | kfree (serial); | 792 | kfree (serial); |
740 | return -ENODEV; | 793 | return -ENODEV; |
@@ -750,6 +803,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
750 | if (type == &usb_serial_generic_device) { | 803 | if (type == &usb_serial_generic_device) { |
751 | num_ports = num_bulk_out; | 804 | num_ports = num_bulk_out; |
752 | if (num_ports == 0) { | 805 | if (num_ports == 0) { |
806 | unlock_kernel(); | ||
753 | dev_err(&interface->dev, "Generic device with no bulk out, not allowed.\n"); | 807 | dev_err(&interface->dev, "Generic device with no bulk out, not allowed.\n"); |
754 | kfree (serial); | 808 | kfree (serial); |
755 | return -EIO; | 809 | return -EIO; |
@@ -760,6 +814,7 @@ int usb_serial_probe(struct usb_interface *interface, | |||
760 | /* if this device type has a calc_num_ports function, call it */ | 814 | /* if this device type has a calc_num_ports function, call it */ |
761 | if (type->calc_num_ports) { | 815 | if (type->calc_num_ports) { |
762 | if (!try_module_get(type->driver.owner)) { | 816 | if (!try_module_get(type->driver.owner)) { |
817 | unlock_kernel(); | ||
763 | dev_err(&interface->dev, "module get failed, exiting\n"); | 818 | dev_err(&interface->dev, "module get failed, exiting\n"); |
764 | kfree (serial); | 819 | kfree (serial); |
765 | return -EIO; | 820 | return -EIO; |
@@ -771,12 +826,6 @@ int usb_serial_probe(struct usb_interface *interface, | |||
771 | num_ports = type->num_ports; | 826 | num_ports = type->num_ports; |
772 | } | 827 | } |
773 | 828 | ||
774 | if (get_free_serial (serial, num_ports, &minor) == NULL) { | ||
775 | dev_err(&interface->dev, "No more free serial devices\n"); | ||
776 | kfree (serial); | ||
777 | return -ENOMEM; | ||
778 | } | ||
779 | |||
780 | serial->minor = minor; | 829 | serial->minor = minor; |
781 | serial->num_ports = num_ports; | 830 | serial->num_ports = num_ports; |
782 | serial->num_bulk_in = num_bulk_in; | 831 | serial->num_bulk_in = num_bulk_in; |
@@ -791,6 +840,8 @@ int usb_serial_probe(struct usb_interface *interface, | |||
791 | max_endpoints = max(max_endpoints, num_interrupt_out); | 840 | max_endpoints = max(max_endpoints, num_interrupt_out); |
792 | max_endpoints = max(max_endpoints, (int)serial->num_ports); | 841 | max_endpoints = max(max_endpoints, (int)serial->num_ports); |
793 | serial->num_port_pointers = max_endpoints; | 842 | serial->num_port_pointers = max_endpoints; |
843 | unlock_kernel(); | ||
844 | |||
794 | dbg("%s - setting up %d port structures for this device", __FUNCTION__, max_endpoints); | 845 | dbg("%s - setting up %d port structures for this device", __FUNCTION__, max_endpoints); |
795 | for (i = 0; i < max_endpoints; ++i) { | 846 | for (i = 0; i < max_endpoints; ++i) { |
796 | port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL); | 847 | port = kzalloc(sizeof(struct usb_serial_port), GFP_KERNEL); |
@@ -925,6 +976,11 @@ int usb_serial_probe(struct usb_interface *interface, | |||
925 | } | 976 | } |
926 | } | 977 | } |
927 | 978 | ||
979 | if (get_free_serial (serial, num_ports, &minor) == NULL) { | ||
980 | dev_err(&interface->dev, "No more free serial devices\n"); | ||
981 | goto probe_error; | ||
982 | } | ||
983 | |||
928 | /* register all of the individual ports with the driver core */ | 984 | /* register all of the individual ports with the driver core */ |
929 | for (i = 0; i < num_ports; ++i) { | 985 | for (i = 0; i < num_ports; ++i) { |
930 | port = serial->port[i]; | 986 | port = serial->port[i]; |
@@ -1002,8 +1058,11 @@ void usb_serial_disconnect(struct usb_interface *interface) | |||
1002 | if (serial) { | 1058 | if (serial) { |
1003 | for (i = 0; i < serial->num_ports; ++i) { | 1059 | for (i = 0; i < serial->num_ports; ++i) { |
1004 | port = serial->port[i]; | 1060 | port = serial->port[i]; |
1005 | if (port && port->tty) | 1061 | if (port) { |
1006 | tty_hangup(port->tty); | 1062 | if (port->tty) |
1063 | tty_hangup(port->tty); | ||
1064 | kill_traffic(port); | ||
1065 | } | ||
1007 | } | 1066 | } |
1008 | /* let the last holder of this object | 1067 | /* let the last holder of this object |
1009 | * cause it to be cleaned up */ | 1068 | * cause it to be cleaned up */ |
@@ -1040,6 +1099,7 @@ static int __init usb_serial_init(void) | |||
1040 | return -ENOMEM; | 1099 | return -ENOMEM; |
1041 | 1100 | ||
1042 | /* Initialize our global data */ | 1101 | /* Initialize our global data */ |
1102 | spin_lock_init(&table_lock); | ||
1043 | for (i = 0; i < SERIAL_TTY_MINORS; ++i) { | 1103 | for (i = 0; i < SERIAL_TTY_MINORS; ++i) { |
1044 | serial_table[i] = NULL; | 1104 | serial_table[i] = NULL; |
1045 | } | 1105 | } |
@@ -1138,7 +1198,7 @@ static void fixup_generic(struct usb_serial_driver *device) | |||
1138 | set_to_generic_if_null(device, shutdown); | 1198 | set_to_generic_if_null(device, shutdown); |
1139 | } | 1199 | } |
1140 | 1200 | ||
1141 | int usb_serial_register(struct usb_serial_driver *driver) | 1201 | int usb_serial_register(struct usb_serial_driver *driver) /* must be called with BKL held */ |
1142 | { | 1202 | { |
1143 | int retval; | 1203 | int retval; |
1144 | 1204 | ||
@@ -1162,7 +1222,7 @@ int usb_serial_register(struct usb_serial_driver *driver) | |||
1162 | } | 1222 | } |
1163 | 1223 | ||
1164 | 1224 | ||
1165 | void usb_serial_deregister(struct usb_serial_driver *device) | 1225 | void usb_serial_deregister(struct usb_serial_driver *device) /* must be called with BKL held */ |
1166 | { | 1226 | { |
1167 | info("USB Serial deregistering driver %s", device->description); | 1227 | info("USB Serial deregistering driver %s", device->description); |
1168 | list_del(&device->driver_list); | 1228 | list_del(&device->driver_list); |
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index eef5eaa5fa0b..2f59ff226e2c 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c | |||
@@ -46,7 +46,7 @@ static int visor_probe (struct usb_serial *serial, const struct usb_device_id | |||
46 | static int visor_calc_num_ports(struct usb_serial *serial); | 46 | static int visor_calc_num_ports(struct usb_serial *serial); |
47 | static void visor_shutdown (struct usb_serial *serial); | 47 | static void visor_shutdown (struct usb_serial *serial); |
48 | static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); | 48 | static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); |
49 | static void visor_set_termios (struct usb_serial_port *port, struct termios *old_termios); | 49 | static void visor_set_termios (struct usb_serial_port *port, struct ktermios *old_termios); |
50 | static void visor_write_bulk_callback (struct urb *urb); | 50 | static void visor_write_bulk_callback (struct urb *urb); |
51 | static void visor_read_bulk_callback (struct urb *urb); | 51 | static void visor_read_bulk_callback (struct urb *urb); |
52 | static void visor_read_int_callback (struct urb *urb); | 52 | static void visor_read_int_callback (struct urb *urb); |
@@ -90,8 +90,6 @@ static struct usb_device_id id_table [] = { | |||
90 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, | 90 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, |
91 | { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID), | 91 | { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID), |
92 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, | 92 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, |
93 | { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE31_ID), | ||
94 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, | ||
95 | { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID), | 93 | { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID), |
96 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, | 94 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, |
97 | { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID), | 95 | { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID), |
@@ -151,7 +149,6 @@ static struct usb_device_id id_table_combined [] = { | |||
151 | { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID) }, | 149 | { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID) }, |
152 | { USB_DEVICE(PALM_VENDOR_ID, PALM_TREO_650) }, | 150 | { USB_DEVICE(PALM_VENDOR_ID, PALM_TREO_650) }, |
153 | { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID) }, | 151 | { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID) }, |
154 | { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE31_ID) }, | ||
155 | { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID) }, | 152 | { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID) }, |
156 | { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) }, | 153 | { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) }, |
157 | { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) }, | 154 | { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) }, |
@@ -189,6 +186,7 @@ static struct usb_serial_driver handspring_device = { | |||
189 | .name = "visor", | 186 | .name = "visor", |
190 | }, | 187 | }, |
191 | .description = "Handspring Visor / Palm OS", | 188 | .description = "Handspring Visor / Palm OS", |
189 | .usb_driver = &visor_driver, | ||
192 | .id_table = id_table, | 190 | .id_table = id_table, |
193 | .num_interrupt_in = NUM_DONT_CARE, | 191 | .num_interrupt_in = NUM_DONT_CARE, |
194 | .num_bulk_in = 2, | 192 | .num_bulk_in = 2, |
@@ -219,6 +217,7 @@ static struct usb_serial_driver clie_5_device = { | |||
219 | .name = "clie_5", | 217 | .name = "clie_5", |
220 | }, | 218 | }, |
221 | .description = "Sony Clie 5.0", | 219 | .description = "Sony Clie 5.0", |
220 | .usb_driver = &visor_driver, | ||
222 | .id_table = clie_id_5_table, | 221 | .id_table = clie_id_5_table, |
223 | .num_interrupt_in = NUM_DONT_CARE, | 222 | .num_interrupt_in = NUM_DONT_CARE, |
224 | .num_bulk_in = 2, | 223 | .num_bulk_in = 2, |
@@ -249,6 +248,7 @@ static struct usb_serial_driver clie_3_5_device = { | |||
249 | .name = "clie_3.5", | 248 | .name = "clie_3.5", |
250 | }, | 249 | }, |
251 | .description = "Sony Clie 3.5", | 250 | .description = "Sony Clie 3.5", |
251 | .usb_driver = &visor_driver, | ||
252 | .id_table = clie_id_3_5_table, | 252 | .id_table = clie_id_3_5_table, |
253 | .num_interrupt_in = 0, | 253 | .num_interrupt_in = 0, |
254 | .num_bulk_in = 1, | 254 | .num_bulk_in = 1, |
@@ -916,7 +916,7 @@ static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsign | |||
916 | 916 | ||
917 | 917 | ||
918 | /* This function is all nice and good, but we don't change anything based on it :) */ | 918 | /* This function is all nice and good, but we don't change anything based on it :) */ |
919 | static void visor_set_termios (struct usb_serial_port *port, struct termios *old_termios) | 919 | static void visor_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) |
920 | { | 920 | { |
921 | unsigned int cflag; | 921 | unsigned int cflag; |
922 | 922 | ||
diff --git a/drivers/usb/serial/visor.h b/drivers/usb/serial/visor.h index 765118d83fb6..4ce6f62a6f39 100644 --- a/drivers/usb/serial/visor.h +++ b/drivers/usb/serial/visor.h | |||
@@ -32,7 +32,6 @@ | |||
32 | #define PALM_TUNGSTEN_T_ID 0x0060 | 32 | #define PALM_TUNGSTEN_T_ID 0x0060 |
33 | #define PALM_TREO_650 0x0061 | 33 | #define PALM_TREO_650 0x0061 |
34 | #define PALM_TUNGSTEN_Z_ID 0x0031 | 34 | #define PALM_TUNGSTEN_Z_ID 0x0031 |
35 | #define PALM_ZIRE31_ID 0x0061 | ||
36 | #define PALM_ZIRE_ID 0x0070 | 35 | #define PALM_ZIRE_ID 0x0070 |
37 | #define PALM_M100_ID 0x0080 | 36 | #define PALM_M100_ID 0x0080 |
38 | 37 | ||
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 154c7d290597..bf16e9e1d84e 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c | |||
@@ -145,7 +145,7 @@ static void whiteheat_close (struct usb_serial_port *port, struct file *filp); | |||
145 | static int whiteheat_write (struct usb_serial_port *port, const unsigned char *buf, int count); | 145 | static int whiteheat_write (struct usb_serial_port *port, const unsigned char *buf, int count); |
146 | static int whiteheat_write_room (struct usb_serial_port *port); | 146 | static int whiteheat_write_room (struct usb_serial_port *port); |
147 | static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); | 147 | static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); |
148 | static void whiteheat_set_termios (struct usb_serial_port *port, struct termios * old); | 148 | static void whiteheat_set_termios (struct usb_serial_port *port, struct ktermios * old); |
149 | static int whiteheat_tiocmget (struct usb_serial_port *port, struct file *file); | 149 | static int whiteheat_tiocmget (struct usb_serial_port *port, struct file *file); |
150 | static int whiteheat_tiocmset (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear); | 150 | static int whiteheat_tiocmset (struct usb_serial_port *port, struct file *file, unsigned int set, unsigned int clear); |
151 | static void whiteheat_break_ctl (struct usb_serial_port *port, int break_state); | 151 | static void whiteheat_break_ctl (struct usb_serial_port *port, int break_state); |
@@ -161,6 +161,7 @@ static struct usb_serial_driver whiteheat_fake_device = { | |||
161 | .name = "whiteheatnofirm", | 161 | .name = "whiteheatnofirm", |
162 | }, | 162 | }, |
163 | .description = "Connect Tech - WhiteHEAT - (prerenumeration)", | 163 | .description = "Connect Tech - WhiteHEAT - (prerenumeration)", |
164 | .usb_driver = &whiteheat_driver, | ||
164 | .id_table = id_table_prerenumeration, | 165 | .id_table = id_table_prerenumeration, |
165 | .num_interrupt_in = NUM_DONT_CARE, | 166 | .num_interrupt_in = NUM_DONT_CARE, |
166 | .num_bulk_in = NUM_DONT_CARE, | 167 | .num_bulk_in = NUM_DONT_CARE, |
@@ -176,6 +177,7 @@ static struct usb_serial_driver whiteheat_device = { | |||
176 | .name = "whiteheat", | 177 | .name = "whiteheat", |
177 | }, | 178 | }, |
178 | .description = "Connect Tech - WhiteHEAT", | 179 | .description = "Connect Tech - WhiteHEAT", |
180 | .usb_driver = &whiteheat_driver, | ||
179 | .id_table = id_table_std, | 181 | .id_table = id_table_std, |
180 | .num_interrupt_in = NUM_DONT_CARE, | 182 | .num_interrupt_in = NUM_DONT_CARE, |
181 | .num_bulk_in = NUM_DONT_CARE, | 183 | .num_bulk_in = NUM_DONT_CARE, |
@@ -416,7 +418,7 @@ static int whiteheat_attach (struct usb_serial *serial) | |||
416 | for (i = 0; i < serial->num_ports; i++) { | 418 | for (i = 0; i < serial->num_ports; i++) { |
417 | port = serial->port[i]; | 419 | port = serial->port[i]; |
418 | 420 | ||
419 | info = (struct whiteheat_private *)kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL); | 421 | info = kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL); |
420 | if (info == NULL) { | 422 | if (info == NULL) { |
421 | err("%s: Out of memory for port structures\n", serial->type->description); | 423 | err("%s: Out of memory for port structures\n", serial->type->description); |
422 | goto no_private; | 424 | goto no_private; |
@@ -487,7 +489,7 @@ static int whiteheat_attach (struct usb_serial *serial) | |||
487 | usb_set_serial_port_data(port, info); | 489 | usb_set_serial_port_data(port, info); |
488 | } | 490 | } |
489 | 491 | ||
490 | command_info = (struct whiteheat_command_private *)kmalloc(sizeof(struct whiteheat_command_private), GFP_KERNEL); | 492 | command_info = kmalloc(sizeof(struct whiteheat_command_private), GFP_KERNEL); |
491 | if (command_info == NULL) { | 493 | if (command_info == NULL) { |
492 | err("%s: Out of memory for port structures\n", serial->type->description); | 494 | err("%s: Out of memory for port structures\n", serial->type->description); |
493 | goto no_command_private; | 495 | goto no_command_private; |
@@ -597,7 +599,7 @@ static void whiteheat_shutdown (struct usb_serial *serial) | |||
597 | static int whiteheat_open (struct usb_serial_port *port, struct file *filp) | 599 | static int whiteheat_open (struct usb_serial_port *port, struct file *filp) |
598 | { | 600 | { |
599 | int retval = 0; | 601 | int retval = 0; |
600 | struct termios old_term; | 602 | struct ktermios old_term; |
601 | 603 | ||
602 | dbg("%s - port %d", __FUNCTION__, port->number); | 604 | dbg("%s - port %d", __FUNCTION__, port->number); |
603 | 605 | ||
@@ -870,7 +872,7 @@ static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, un | |||
870 | } | 872 | } |
871 | 873 | ||
872 | 874 | ||
873 | static void whiteheat_set_termios (struct usb_serial_port *port, struct termios *old_termios) | 875 | static void whiteheat_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) |
874 | { | 876 | { |
875 | dbg("%s -port %d", __FUNCTION__, port->number); | 877 | dbg("%s -port %d", __FUNCTION__, port->number); |
876 | 878 | ||
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index e565d3d2ab29..6d3dad3d1dae 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c | |||
@@ -33,7 +33,6 @@ | |||
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/slab.h> | 34 | #include <linux/slab.h> |
35 | #include <linux/module.h> | 35 | #include <linux/module.h> |
36 | #include <linux/usb_ch9.h> | ||
37 | #include <linux/usb/input.h> | 36 | #include <linux/usb/input.h> |
38 | #include "usb.h" | 37 | #include "usb.h" |
39 | #include "onetouch.h" | 38 | #include "onetouch.h" |
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index e1072d52d641..70234f5dbeeb 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c | |||
@@ -110,23 +110,6 @@ static int slave_configure(struct scsi_device *sdev) | |||
110 | * the end, scatter-gather buffers follow page boundaries. */ | 110 | * the end, scatter-gather buffers follow page boundaries. */ |
111 | blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); | 111 | blk_queue_dma_alignment(sdev->request_queue, (512 - 1)); |
112 | 112 | ||
113 | /* Set the SCSI level to at least 2. We'll leave it at 3 if that's | ||
114 | * what is originally reported. We need this to avoid confusing | ||
115 | * the SCSI layer with devices that report 0 or 1, but need 10-byte | ||
116 | * commands (ala ATAPI devices behind certain bridges, or devices | ||
117 | * which simply have broken INQUIRY data). | ||
118 | * | ||
119 | * NOTE: This means /dev/sg programs (ala cdrecord) will get the | ||
120 | * actual information. This seems to be the preference for | ||
121 | * programs like that. | ||
122 | * | ||
123 | * NOTE: This also means that /proc/scsi/scsi and sysfs may report | ||
124 | * the actual value or the modified one, depending on where the | ||
125 | * data comes from. | ||
126 | */ | ||
127 | if (sdev->scsi_level < SCSI_2) | ||
128 | sdev->scsi_level = sdev->sdev_target->scsi_level = SCSI_2; | ||
129 | |||
130 | /* Many devices have trouble transfering more than 32KB at a time, | 113 | /* Many devices have trouble transfering more than 32KB at a time, |
131 | * while others have trouble with more than 64K. At this time we | 114 | * while others have trouble with more than 64K. At this time we |
132 | * are limiting both to 32K (64 sectores). | 115 | * are limiting both to 32K (64 sectores). |
@@ -176,7 +159,9 @@ static int slave_configure(struct scsi_device *sdev) | |||
176 | * a Get-Max-LUN request, we won't lose much by setting the | 159 | * a Get-Max-LUN request, we won't lose much by setting the |
177 | * revision level down to 2. The only devices that would be | 160 | * revision level down to 2. The only devices that would be |
178 | * affected are those with sparse LUNs. */ | 161 | * affected are those with sparse LUNs. */ |
179 | sdev->scsi_level = sdev->sdev_target->scsi_level = SCSI_2; | 162 | if (sdev->scsi_level > SCSI_2) |
163 | sdev->sdev_target->scsi_level = | ||
164 | sdev->scsi_level = SCSI_2; | ||
180 | 165 | ||
181 | /* USB-IDE bridges tend to report SK = 0x04 (Non-recoverable | 166 | /* USB-IDE bridges tend to report SK = 0x04 (Non-recoverable |
182 | * Hardware Error) when any low-level error occurs, | 167 | * Hardware Error) when any low-level error occurs, |
@@ -194,6 +179,16 @@ static int slave_configure(struct scsi_device *sdev) | |||
194 | sdev->use_10_for_ms = 1; | 179 | sdev->use_10_for_ms = 1; |
195 | } | 180 | } |
196 | 181 | ||
182 | /* The CB and CBI transports have no way to pass LUN values | ||
183 | * other than the bits in the second byte of a CDB. But those | ||
184 | * bits don't get set to the LUN value if the device reports | ||
185 | * scsi_level == 0 (UNKNOWN). Hence such devices must necessarily | ||
186 | * be single-LUN. | ||
187 | */ | ||
188 | if ((us->protocol == US_PR_CB || us->protocol == US_PR_CBI) && | ||
189 | sdev->scsi_level == SCSI_UNKNOWN) | ||
190 | us->max_lun = 0; | ||
191 | |||
197 | /* Some devices choke when they receive a PREVENT-ALLOW MEDIUM | 192 | /* Some devices choke when they receive a PREVENT-ALLOW MEDIUM |
198 | * REMOVAL command, so suppress those commands. */ | 193 | * REMOVAL command, so suppress those commands. */ |
199 | if (us->flags & US_FL_NOT_LOCKABLE) | 194 | if (us->flags & US_FL_NOT_LOCKABLE) |
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index fb8bacaae27c..e3528eca29a5 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c | |||
@@ -646,7 +646,7 @@ sddr09_read_sg_test_only(struct us_data *us) { | |||
646 | return result; | 646 | return result; |
647 | } | 647 | } |
648 | 648 | ||
649 | buf = (unsigned char *) kmalloc(bulklen, GFP_NOIO); | 649 | buf = kmalloc(bulklen, GFP_NOIO); |
650 | if (!buf) | 650 | if (!buf) |
651 | return -ENOMEM; | 651 | return -ENOMEM; |
652 | 652 | ||
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index db8b26012c75..f49a62fc32d2 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -153,6 +153,13 @@ UNUSUAL_DEV( 0x0421, 0x042e, 0x0100, 0x0100, | |||
153 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 153 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
154 | US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), | 154 | US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), |
155 | 155 | ||
156 | /* Reported by <honkkis@gmail.com> */ | ||
157 | UNUSUAL_DEV( 0x0421, 0x0433, 0x0100, 0x0100, | ||
158 | "Nokia", | ||
159 | "E70", | ||
160 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
161 | US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), | ||
162 | |||
156 | /* Reported by Jon Hart <Jon.Hart@web.de> */ | 163 | /* Reported by Jon Hart <Jon.Hart@web.de> */ |
157 | UNUSUAL_DEV( 0x0421, 0x0434, 0x0100, 0x0100, | 164 | UNUSUAL_DEV( 0x0421, 0x0434, 0x0100, 0x0100, |
158 | "Nokia", | 165 | "Nokia", |
@@ -190,6 +197,13 @@ UNUSUAL_DEV( 0x0421, 0x047c, 0x0370, 0x0370, | |||
190 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 197 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
191 | US_FL_MAX_SECTORS_64 ), | 198 | US_FL_MAX_SECTORS_64 ), |
192 | 199 | ||
200 | /* Reported by Manuel Osdoba <manuel.osdoba@tu-ilmenau.de> */ | ||
201 | UNUSUAL_DEV( 0x0421, 0x0492, 0x0452, 0x0452, | ||
202 | "Nokia", | ||
203 | "Nokia 6233", | ||
204 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
205 | US_FL_MAX_SECTORS_64 ), | ||
206 | |||
193 | /* Reported by Alex Corcoles <alex@corcoles.net> */ | 207 | /* Reported by Alex Corcoles <alex@corcoles.net> */ |
194 | UNUSUAL_DEV( 0x0421, 0x0495, 0x0370, 0x0370, | 208 | UNUSUAL_DEV( 0x0421, 0x0495, 0x0370, 0x0370, |
195 | "Nokia", | 209 | "Nokia", |
@@ -247,6 +261,18 @@ UNUSUAL_DEV( 0x045a, 0x5210, 0x0101, 0x0101, | |||
247 | US_SC_SCSI, US_PR_KARMA, rio_karma_init, 0), | 261 | US_SC_SCSI, US_PR_KARMA, rio_karma_init, 0), |
248 | #endif | 262 | #endif |
249 | 263 | ||
264 | /* | ||
265 | * This virtual floppy is found in Sun equipment (x4600, x4200m2, etc.) | ||
266 | * Reported by Pete Zaitcev <zaitcev@redhat.com> | ||
267 | * This device chokes on both version of MODE SENSE which we have, so | ||
268 | * use_10_for_ms is not effective, and we use US_FL_NO_WP_DETECT. | ||
269 | */ | ||
270 | UNUSUAL_DEV( 0x046b, 0xff40, 0x0100, 0x0100, | ||
271 | "AMI", | ||
272 | "Virtual Floppy", | ||
273 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
274 | US_FL_NO_WP_DETECT), | ||
275 | |||
250 | /* Patch submitted by Philipp Friedrich <philipp@void.at> */ | 276 | /* Patch submitted by Philipp Friedrich <philipp@void.at> */ |
251 | UNUSUAL_DEV( 0x0482, 0x0100, 0x0100, 0x0100, | 277 | UNUSUAL_DEV( 0x0482, 0x0100, 0x0100, 0x0100, |
252 | "Kyocera", | 278 | "Kyocera", |
@@ -547,7 +573,7 @@ UNUSUAL_DEV( 0x054c, 0x002b, 0x0100, 0x0110, | |||
547 | #endif | 573 | #endif |
548 | 574 | ||
549 | /* Submitted by Olaf Hering, <olh@suse.de> SuSE Bugzilla #49049 */ | 575 | /* Submitted by Olaf Hering, <olh@suse.de> SuSE Bugzilla #49049 */ |
550 | UNUSUAL_DEV( 0x054c, 0x002c, 0x0501, 0x0501, | 576 | UNUSUAL_DEV( 0x054c, 0x002c, 0x0501, 0x2000, |
551 | "Sony", | 577 | "Sony", |
552 | "USB Floppy Drive", | 578 | "USB Floppy Drive", |
553 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 579 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
@@ -721,7 +747,7 @@ UNUSUAL_DEV( 0x05ac, 0x1204, 0x0000, 0x9999, | |||
721 | "Apple", | 747 | "Apple", |
722 | "iPod", | 748 | "iPod", |
723 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 749 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
724 | US_FL_FIX_CAPACITY ), | 750 | US_FL_FIX_CAPACITY | US_FL_NOT_LOCKABLE ), |
725 | 751 | ||
726 | UNUSUAL_DEV( 0x05ac, 0x1205, 0x0000, 0x9999, | 752 | UNUSUAL_DEV( 0x05ac, 0x1205, 0x0000, 0x9999, |
727 | "Apple", | 753 | "Apple", |
@@ -1299,13 +1325,6 @@ UNUSUAL_DEV( 0x0fce, 0xe031, 0x0000, 0x0000, | |||
1299 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1325 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1300 | US_FL_FIX_CAPACITY ), | 1326 | US_FL_FIX_CAPACITY ), |
1301 | 1327 | ||
1302 | /* Reported by Jan Mate <mate@fiit.stuba.sk> */ | ||
1303 | UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000, | ||
1304 | "Sony Ericsson", | ||
1305 | "P990i", | ||
1306 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1307 | US_FL_FIX_CAPACITY ), | ||
1308 | |||
1309 | /* Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu> | 1328 | /* Reported by Kevin Cernekee <kpc-usbdev@gelato.uiuc.edu> |
1310 | * Tested on hardware version 1.10. | 1329 | * Tested on hardware version 1.10. |
1311 | * Entry is needed only for the initializer function override. | 1330 | * Entry is needed only for the initializer function override. |
@@ -1328,6 +1347,15 @@ UNUSUAL_DEV( 0x1210, 0x0003, 0x0100, 0x0100, | |||
1328 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1347 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1329 | US_FL_IGNORE_RESIDUE ), | 1348 | US_FL_IGNORE_RESIDUE ), |
1330 | 1349 | ||
1350 | /* This prevents the kernel from detecting the virtual cd-drive with the | ||
1351 | * Windows drivers. <johann.wilhelm@student.tugraz.at> | ||
1352 | */ | ||
1353 | UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0xffff, | ||
1354 | "HUAWEI", | ||
1355 | "E220 USB-UMTS Install", | ||
1356 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1357 | US_FL_IGNORE_DEVICE), | ||
1358 | |||
1331 | /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */ | 1359 | /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */ |
1332 | UNUSUAL_DEV( 0x132b, 0x000b, 0x0001, 0x0001, | 1360 | UNUSUAL_DEV( 0x132b, 0x000b, 0x0001, 0x0001, |
1333 | "Minolta", | 1361 | "Minolta", |
@@ -1342,6 +1370,21 @@ UNUSUAL_DEV( 0x1370, 0x6828, 0x0110, 0x0110, | |||
1342 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1370 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1343 | US_FL_IGNORE_RESIDUE ), | 1371 | US_FL_IGNORE_RESIDUE ), |
1344 | 1372 | ||
1373 | /* Reported by Francesco Foresti <frafore@tiscali.it> */ | ||
1374 | UNUSUAL_DEV( 0x14cd, 0x6600, 0x0201, 0x0201, | ||
1375 | "Super Top", | ||
1376 | "IDE DEVICE", | ||
1377 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1378 | US_FL_IGNORE_RESIDUE ), | ||
1379 | |||
1380 | /* Reported by Robert Schedel <r.schedel@yahoo.de> | ||
1381 | * Note: this is a 'super top' device like the above 14cd/6600 device */ | ||
1382 | UNUSUAL_DEV( 0x1652, 0x6600, 0x0201, 0x0201, | ||
1383 | "Teac", | ||
1384 | "HD-35PUK-B", | ||
1385 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1386 | US_FL_IGNORE_RESIDUE ), | ||
1387 | |||
1345 | /* patch submitted by Davide Perini <perini.davide@dpsoftware.org> | 1388 | /* patch submitted by Davide Perini <perini.davide@dpsoftware.org> |
1346 | * and Renato Perini <rperini@email.it> | 1389 | * and Renato Perini <rperini@email.it> |
1347 | */ | 1390 | */ |
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 70644506651f..7e7ec29782f1 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -731,26 +731,27 @@ static int get_pipes(struct us_data *us) | |||
731 | struct usb_endpoint_descriptor *ep_int = NULL; | 731 | struct usb_endpoint_descriptor *ep_int = NULL; |
732 | 732 | ||
733 | /* | 733 | /* |
734 | * Find the endpoints we need. | 734 | * Find the first endpoint of each type we need. |
735 | * We are expecting a minimum of 2 endpoints - in and out (bulk). | 735 | * We are expecting a minimum of 2 endpoints - in and out (bulk). |
736 | * An optional interrupt is OK (necessary for CBI protocol). | 736 | * An optional interrupt-in is OK (necessary for CBI protocol). |
737 | * We will ignore any others. | 737 | * We will ignore any others. |
738 | */ | 738 | */ |
739 | for (i = 0; i < altsetting->desc.bNumEndpoints; i++) { | 739 | for (i = 0; i < altsetting->desc.bNumEndpoints; i++) { |
740 | ep = &altsetting->endpoint[i].desc; | 740 | ep = &altsetting->endpoint[i].desc; |
741 | 741 | ||
742 | /* Is it a BULK endpoint? */ | ||
743 | if (usb_endpoint_xfer_bulk(ep)) { | 742 | if (usb_endpoint_xfer_bulk(ep)) { |
744 | /* BULK in or out? */ | 743 | if (usb_endpoint_dir_in(ep)) { |
745 | if (usb_endpoint_dir_in(ep)) | 744 | if (!ep_in) |
746 | ep_in = ep; | 745 | ep_in = ep; |
747 | else | 746 | } else { |
748 | ep_out = ep; | 747 | if (!ep_out) |
748 | ep_out = ep; | ||
749 | } | ||
749 | } | 750 | } |
750 | 751 | ||
751 | /* Is it an interrupt endpoint? */ | 752 | else if (usb_endpoint_is_int_in(ep)) { |
752 | else if (usb_endpoint_xfer_int(ep)) { | 753 | if (!ep_int) |
753 | ep_int = ep; | 754 | ep_int = ep; |
754 | } | 755 | } |
755 | } | 756 | } |
756 | 757 | ||