diff options
Diffstat (limited to 'drivers/usb')
37 files changed, 1865 insertions, 525 deletions
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c index ef0b35731ff0..83e815d3cd52 100644 --- a/drivers/usb/core/devices.c +++ b/drivers/usb/core/devices.c | |||
@@ -239,7 +239,7 @@ static char *usb_dump_interface_descriptor(char *start, char *end, | |||
239 | int setno) | 239 | int setno) |
240 | { | 240 | { |
241 | const struct usb_interface_descriptor *desc = &intfc->altsetting[setno].desc; | 241 | const struct usb_interface_descriptor *desc = &intfc->altsetting[setno].desc; |
242 | char *driver_name = ""; | 242 | const char *driver_name = ""; |
243 | 243 | ||
244 | if (start > end) | 244 | if (start > end) |
245 | return start; | 245 | return start; |
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c index 38ed2220c9fc..65ca131cc44c 100644 --- a/drivers/usb/core/file.c +++ b/drivers/usb/core/file.c | |||
@@ -68,7 +68,7 @@ static struct file_operations usb_fops = { | |||
68 | .open = usb_open, | 68 | .open = usb_open, |
69 | }; | 69 | }; |
70 | 70 | ||
71 | static struct class_simple *usb_class; | 71 | static struct class *usb_class; |
72 | 72 | ||
73 | int usb_major_init(void) | 73 | int usb_major_init(void) |
74 | { | 74 | { |
@@ -80,9 +80,10 @@ int usb_major_init(void) | |||
80 | goto out; | 80 | goto out; |
81 | } | 81 | } |
82 | 82 | ||
83 | usb_class = class_simple_create(THIS_MODULE, "usb"); | 83 | usb_class = class_create(THIS_MODULE, "usb"); |
84 | if (IS_ERR(usb_class)) { | 84 | if (IS_ERR(usb_class)) { |
85 | err("class_simple_create failed for usb devices"); | 85 | error = PTR_ERR(usb_class); |
86 | err("class_create failed for usb devices"); | ||
86 | unregister_chrdev(USB_MAJOR, "usb"); | 87 | unregister_chrdev(USB_MAJOR, "usb"); |
87 | goto out; | 88 | goto out; |
88 | } | 89 | } |
@@ -95,7 +96,7 @@ out: | |||
95 | 96 | ||
96 | void usb_major_cleanup(void) | 97 | void usb_major_cleanup(void) |
97 | { | 98 | { |
98 | class_simple_destroy(usb_class); | 99 | class_destroy(usb_class); |
99 | devfs_remove("usb"); | 100 | devfs_remove("usb"); |
100 | unregister_chrdev(USB_MAJOR, "usb"); | 101 | unregister_chrdev(USB_MAJOR, "usb"); |
101 | } | 102 | } |
@@ -171,7 +172,7 @@ int usb_register_dev(struct usb_interface *intf, | |||
171 | ++temp; | 172 | ++temp; |
172 | else | 173 | else |
173 | temp = name; | 174 | temp = name; |
174 | intf->class_dev = class_simple_device_add(usb_class, MKDEV(USB_MAJOR, minor), &intf->dev, "%s", temp); | 175 | intf->class_dev = class_device_create(usb_class, MKDEV(USB_MAJOR, minor), &intf->dev, "%s", temp); |
175 | if (IS_ERR(intf->class_dev)) { | 176 | if (IS_ERR(intf->class_dev)) { |
176 | spin_lock (&minor_lock); | 177 | spin_lock (&minor_lock); |
177 | usb_minors[intf->minor] = NULL; | 178 | usb_minors[intf->minor] = NULL; |
@@ -220,7 +221,7 @@ void usb_deregister_dev(struct usb_interface *intf, | |||
220 | 221 | ||
221 | snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); | 222 | snprintf(name, BUS_ID_SIZE, class_driver->name, intf->minor - minor_base); |
222 | devfs_remove (name); | 223 | devfs_remove (name); |
223 | class_simple_device_remove(MKDEV(USB_MAJOR, intf->minor)); | 224 | class_device_destroy(usb_class, MKDEV(USB_MAJOR, intf->minor)); |
224 | intf->class_dev = NULL; | 225 | intf->class_dev = NULL; |
225 | intf->minor = -1; | 226 | intf->minor = -1; |
226 | } | 227 | } |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 266e9e06a9f5..d041782e0c8b 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -651,50 +651,45 @@ static int usb_rh_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) | |||
651 | /*-------------------------------------------------------------------------*/ | 651 | /*-------------------------------------------------------------------------*/ |
652 | 652 | ||
653 | /* exported only within usbcore */ | 653 | /* exported only within usbcore */ |
654 | struct usb_bus *usb_bus_get (struct usb_bus *bus) | 654 | struct usb_bus *usb_bus_get(struct usb_bus *bus) |
655 | { | 655 | { |
656 | struct class_device *tmp; | 656 | if (bus) |
657 | kref_get(&bus->kref); | ||
658 | return bus; | ||
659 | } | ||
657 | 660 | ||
658 | if (!bus) | 661 | static void usb_host_release(struct kref *kref) |
659 | return NULL; | 662 | { |
663 | struct usb_bus *bus = container_of(kref, struct usb_bus, kref); | ||
660 | 664 | ||
661 | tmp = class_device_get(&bus->class_dev); | 665 | if (bus->release) |
662 | if (tmp) | 666 | bus->release(bus); |
663 | return to_usb_bus(tmp); | ||
664 | else | ||
665 | return NULL; | ||
666 | } | 667 | } |
667 | 668 | ||
668 | /* exported only within usbcore */ | 669 | /* exported only within usbcore */ |
669 | void usb_bus_put (struct usb_bus *bus) | 670 | void usb_bus_put(struct usb_bus *bus) |
670 | { | 671 | { |
671 | if (bus) | 672 | if (bus) |
672 | class_device_put(&bus->class_dev); | 673 | kref_put(&bus->kref, usb_host_release); |
673 | } | 674 | } |
674 | 675 | ||
675 | /*-------------------------------------------------------------------------*/ | 676 | /*-------------------------------------------------------------------------*/ |
676 | 677 | ||
677 | static void usb_host_release(struct class_device *class_dev) | 678 | static struct class *usb_host_class; |
678 | { | ||
679 | struct usb_bus *bus = to_usb_bus(class_dev); | ||
680 | |||
681 | if (bus->release) | ||
682 | bus->release(bus); | ||
683 | } | ||
684 | |||
685 | static struct class usb_host_class = { | ||
686 | .name = "usb_host", | ||
687 | .release = &usb_host_release, | ||
688 | }; | ||
689 | 679 | ||
690 | int usb_host_init(void) | 680 | int usb_host_init(void) |
691 | { | 681 | { |
692 | return class_register(&usb_host_class); | 682 | int retval = 0; |
683 | |||
684 | usb_host_class = class_create(THIS_MODULE, "usb_host"); | ||
685 | if (IS_ERR(usb_host_class)) | ||
686 | retval = PTR_ERR(usb_host_class); | ||
687 | return retval; | ||
693 | } | 688 | } |
694 | 689 | ||
695 | void usb_host_cleanup(void) | 690 | void usb_host_cleanup(void) |
696 | { | 691 | { |
697 | class_unregister(&usb_host_class); | 692 | class_destroy(usb_host_class); |
698 | } | 693 | } |
699 | 694 | ||
700 | /** | 695 | /** |
@@ -719,8 +714,7 @@ static void usb_bus_init (struct usb_bus *bus) | |||
719 | 714 | ||
720 | INIT_LIST_HEAD (&bus->bus_list); | 715 | INIT_LIST_HEAD (&bus->bus_list); |
721 | 716 | ||
722 | class_device_initialize(&bus->class_dev); | 717 | kref_init(&bus->kref); |
723 | bus->class_dev.class = &usb_host_class; | ||
724 | } | 718 | } |
725 | 719 | ||
726 | /** | 720 | /** |
@@ -761,7 +755,6 @@ struct usb_bus *usb_alloc_bus (struct usb_operations *op) | |||
761 | static int usb_register_bus(struct usb_bus *bus) | 755 | static int usb_register_bus(struct usb_bus *bus) |
762 | { | 756 | { |
763 | int busnum; | 757 | int busnum; |
764 | int retval; | ||
765 | 758 | ||
766 | down (&usb_bus_list_lock); | 759 | down (&usb_bus_list_lock); |
767 | busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1); | 760 | busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1); |
@@ -774,15 +767,15 @@ static int usb_register_bus(struct usb_bus *bus) | |||
774 | return -E2BIG; | 767 | return -E2BIG; |
775 | } | 768 | } |
776 | 769 | ||
777 | snprintf(bus->class_dev.class_id, BUS_ID_SIZE, "usb%d", busnum); | 770 | bus->class_dev = class_device_create(usb_host_class, MKDEV(0,0), bus->controller, "usb%d", busnum); |
778 | bus->class_dev.dev = bus->controller; | 771 | if (IS_ERR(bus->class_dev)) { |
779 | retval = class_device_add(&bus->class_dev); | ||
780 | if (retval) { | ||
781 | clear_bit(busnum, busmap.busmap); | 772 | clear_bit(busnum, busmap.busmap); |
782 | up(&usb_bus_list_lock); | 773 | up(&usb_bus_list_lock); |
783 | return retval; | 774 | return PTR_ERR(bus->class_dev); |
784 | } | 775 | } |
785 | 776 | ||
777 | class_set_devdata(bus->class_dev, bus); | ||
778 | |||
786 | /* Add it to the local list of buses */ | 779 | /* Add it to the local list of buses */ |
787 | list_add (&bus->bus_list, &usb_bus_list); | 780 | list_add (&bus->bus_list, &usb_bus_list); |
788 | up (&usb_bus_list_lock); | 781 | up (&usb_bus_list_lock); |
@@ -820,7 +813,7 @@ static void usb_deregister_bus (struct usb_bus *bus) | |||
820 | 813 | ||
821 | clear_bit (bus->busnum, busmap.busmap); | 814 | clear_bit (bus->busnum, busmap.busmap); |
822 | 815 | ||
823 | class_device_del(&bus->class_dev); | 816 | class_device_unregister(bus->class_dev); |
824 | } | 817 | } |
825 | 818 | ||
826 | /** | 819 | /** |
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 4ab50009291d..740cb4c668df 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -24,7 +24,7 @@ | |||
24 | 24 | ||
25 | /* Active configuration fields */ | 25 | /* Active configuration fields */ |
26 | #define usb_actconfig_show(field, multiplier, format_string) \ | 26 | #define usb_actconfig_show(field, multiplier, format_string) \ |
27 | static ssize_t show_##field (struct device *dev, char *buf) \ | 27 | static ssize_t show_##field (struct device *dev, struct device_attribute *attr, char *buf) \ |
28 | { \ | 28 | { \ |
29 | struct usb_device *udev; \ | 29 | struct usb_device *udev; \ |
30 | struct usb_host_config *actconfig; \ | 30 | struct usb_host_config *actconfig; \ |
@@ -46,7 +46,7 @@ usb_actconfig_attr (bNumInterfaces, 1, "%2d\n") | |||
46 | usb_actconfig_attr (bmAttributes, 1, "%2x\n") | 46 | usb_actconfig_attr (bmAttributes, 1, "%2x\n") |
47 | usb_actconfig_attr (bMaxPower, 2, "%3dmA\n") | 47 | usb_actconfig_attr (bMaxPower, 2, "%3dmA\n") |
48 | 48 | ||
49 | static ssize_t show_configuration_string(struct device *dev, char *buf) | 49 | static ssize_t show_configuration_string(struct device *dev, struct device_attribute *attr, char *buf) |
50 | { | 50 | { |
51 | struct usb_device *udev; | 51 | struct usb_device *udev; |
52 | struct usb_host_config *actconfig; | 52 | struct usb_host_config *actconfig; |
@@ -69,7 +69,7 @@ static DEVICE_ATTR(configuration, S_IRUGO, show_configuration_string, NULL); | |||
69 | usb_actconfig_show(bConfigurationValue, 1, "%u\n"); | 69 | usb_actconfig_show(bConfigurationValue, 1, "%u\n"); |
70 | 70 | ||
71 | static ssize_t | 71 | static ssize_t |
72 | set_bConfigurationValue (struct device *dev, const char *buf, size_t count) | 72 | set_bConfigurationValue (struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
73 | { | 73 | { |
74 | struct usb_device *udev = udev = to_usb_device (dev); | 74 | struct usb_device *udev = udev = to_usb_device (dev); |
75 | int config, value; | 75 | int config, value; |
@@ -87,7 +87,7 @@ static DEVICE_ATTR(bConfigurationValue, S_IRUGO | S_IWUSR, | |||
87 | 87 | ||
88 | /* String fields */ | 88 | /* String fields */ |
89 | #define usb_string_attr(name) \ | 89 | #define usb_string_attr(name) \ |
90 | static ssize_t show_##name(struct device *dev, char *buf) \ | 90 | static ssize_t show_##name(struct device *dev, struct device_attribute *attr, char *buf) \ |
91 | { \ | 91 | { \ |
92 | struct usb_device *udev; \ | 92 | struct usb_device *udev; \ |
93 | int len; \ | 93 | int len; \ |
@@ -107,7 +107,7 @@ usb_string_attr(manufacturer); | |||
107 | usb_string_attr(serial); | 107 | usb_string_attr(serial); |
108 | 108 | ||
109 | static ssize_t | 109 | static ssize_t |
110 | show_speed (struct device *dev, char *buf) | 110 | show_speed (struct device *dev, struct device_attribute *attr, char *buf) |
111 | { | 111 | { |
112 | struct usb_device *udev; | 112 | struct usb_device *udev; |
113 | char *speed; | 113 | char *speed; |
@@ -133,7 +133,7 @@ show_speed (struct device *dev, char *buf) | |||
133 | static DEVICE_ATTR(speed, S_IRUGO, show_speed, NULL); | 133 | static DEVICE_ATTR(speed, S_IRUGO, show_speed, NULL); |
134 | 134 | ||
135 | static ssize_t | 135 | static ssize_t |
136 | show_devnum (struct device *dev, char *buf) | 136 | show_devnum (struct device *dev, struct device_attribute *attr, char *buf) |
137 | { | 137 | { |
138 | struct usb_device *udev; | 138 | struct usb_device *udev; |
139 | 139 | ||
@@ -143,7 +143,7 @@ show_devnum (struct device *dev, char *buf) | |||
143 | static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL); | 143 | static DEVICE_ATTR(devnum, S_IRUGO, show_devnum, NULL); |
144 | 144 | ||
145 | static ssize_t | 145 | static ssize_t |
146 | show_version (struct device *dev, char *buf) | 146 | show_version (struct device *dev, struct device_attribute *attr, char *buf) |
147 | { | 147 | { |
148 | struct usb_device *udev; | 148 | struct usb_device *udev; |
149 | u16 bcdUSB; | 149 | u16 bcdUSB; |
@@ -155,7 +155,7 @@ show_version (struct device *dev, char *buf) | |||
155 | static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); | 155 | static DEVICE_ATTR(version, S_IRUGO, show_version, NULL); |
156 | 156 | ||
157 | static ssize_t | 157 | static ssize_t |
158 | show_maxchild (struct device *dev, char *buf) | 158 | show_maxchild (struct device *dev, struct device_attribute *attr, char *buf) |
159 | { | 159 | { |
160 | struct usb_device *udev; | 160 | struct usb_device *udev; |
161 | 161 | ||
@@ -167,7 +167,7 @@ static DEVICE_ATTR(maxchild, S_IRUGO, show_maxchild, NULL); | |||
167 | /* Descriptor fields */ | 167 | /* Descriptor fields */ |
168 | #define usb_descriptor_attr_le16(field, format_string) \ | 168 | #define usb_descriptor_attr_le16(field, format_string) \ |
169 | static ssize_t \ | 169 | static ssize_t \ |
170 | show_##field (struct device *dev, char *buf) \ | 170 | show_##field (struct device *dev, struct device_attribute *attr, char *buf) \ |
171 | { \ | 171 | { \ |
172 | struct usb_device *udev; \ | 172 | struct usb_device *udev; \ |
173 | \ | 173 | \ |
@@ -183,7 +183,7 @@ usb_descriptor_attr_le16(bcdDevice, "%04x\n") | |||
183 | 183 | ||
184 | #define usb_descriptor_attr(field, format_string) \ | 184 | #define usb_descriptor_attr(field, format_string) \ |
185 | static ssize_t \ | 185 | static ssize_t \ |
186 | show_##field (struct device *dev, char *buf) \ | 186 | show_##field (struct device *dev, struct device_attribute *attr, char *buf) \ |
187 | { \ | 187 | { \ |
188 | struct usb_device *udev; \ | 188 | struct usb_device *udev; \ |
189 | \ | 189 | \ |
@@ -254,7 +254,7 @@ void usb_remove_sysfs_dev_files (struct usb_device *udev) | |||
254 | /* Interface fields */ | 254 | /* Interface fields */ |
255 | #define usb_intf_attr(field, format_string) \ | 255 | #define usb_intf_attr(field, format_string) \ |
256 | static ssize_t \ | 256 | static ssize_t \ |
257 | show_##field (struct device *dev, char *buf) \ | 257 | show_##field (struct device *dev, struct device_attribute *attr, char *buf) \ |
258 | { \ | 258 | { \ |
259 | struct usb_interface *intf = to_usb_interface (dev); \ | 259 | struct usb_interface *intf = to_usb_interface (dev); \ |
260 | \ | 260 | \ |
@@ -269,7 +269,7 @@ usb_intf_attr (bInterfaceClass, "%02x\n") | |||
269 | usb_intf_attr (bInterfaceSubClass, "%02x\n") | 269 | usb_intf_attr (bInterfaceSubClass, "%02x\n") |
270 | usb_intf_attr (bInterfaceProtocol, "%02x\n") | 270 | usb_intf_attr (bInterfaceProtocol, "%02x\n") |
271 | 271 | ||
272 | static ssize_t show_interface_string(struct device *dev, char *buf) | 272 | static ssize_t show_interface_string(struct device *dev, struct device_attribute *attr, char *buf) |
273 | { | 273 | { |
274 | struct usb_interface *intf; | 274 | struct usb_interface *intf; |
275 | struct usb_device *udev; | 275 | struct usb_device *udev; |
@@ -286,36 +286,34 @@ static ssize_t show_interface_string(struct device *dev, char *buf) | |||
286 | } | 286 | } |
287 | static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL); | 287 | static DEVICE_ATTR(interface, S_IRUGO, show_interface_string, NULL); |
288 | 288 | ||
289 | static ssize_t show_modalias(struct device *dev, char *buf) | 289 | static ssize_t show_modalias(struct device *dev, struct device_attribute *attr, char *buf) |
290 | { | 290 | { |
291 | struct usb_interface *intf; | 291 | struct usb_interface *intf; |
292 | struct usb_device *udev; | 292 | struct usb_device *udev; |
293 | int len; | ||
293 | 294 | ||
294 | intf = to_usb_interface(dev); | 295 | intf = to_usb_interface(dev); |
295 | udev = interface_to_usbdev(intf); | 296 | udev = interface_to_usbdev(intf); |
296 | if (udev->descriptor.bDeviceClass == 0) { | ||
297 | struct usb_host_interface *alt = intf->cur_altsetting; | ||
298 | 297 | ||
299 | return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X\n", | 298 | len = sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic", |
300 | le16_to_cpu(udev->descriptor.idVendor), | 299 | le16_to_cpu(udev->descriptor.idVendor), |
301 | le16_to_cpu(udev->descriptor.idProduct), | 300 | le16_to_cpu(udev->descriptor.idProduct), |
302 | le16_to_cpu(udev->descriptor.bcdDevice), | 301 | le16_to_cpu(udev->descriptor.bcdDevice), |
303 | udev->descriptor.bDeviceClass, | 302 | udev->descriptor.bDeviceClass, |
304 | udev->descriptor.bDeviceSubClass, | 303 | udev->descriptor.bDeviceSubClass, |
305 | udev->descriptor.bDeviceProtocol, | 304 | udev->descriptor.bDeviceProtocol); |
305 | buf += len; | ||
306 | |||
307 | if (udev->descriptor.bDeviceClass == 0) { | ||
308 | struct usb_host_interface *alt = intf->cur_altsetting; | ||
309 | |||
310 | return len + sprintf(buf, "%02Xisc%02Xip%02X\n", | ||
306 | alt->desc.bInterfaceClass, | 311 | alt->desc.bInterfaceClass, |
307 | alt->desc.bInterfaceSubClass, | 312 | alt->desc.bInterfaceSubClass, |
308 | alt->desc.bInterfaceProtocol); | 313 | alt->desc.bInterfaceProtocol); |
309 | } else { | 314 | } else { |
310 | return sprintf(buf, "usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic*isc*ip*\n", | 315 | return len + sprintf(buf, "*isc*ip*\n"); |
311 | le16_to_cpu(udev->descriptor.idVendor), | ||
312 | le16_to_cpu(udev->descriptor.idProduct), | ||
313 | le16_to_cpu(udev->descriptor.bcdDevice), | ||
314 | udev->descriptor.bDeviceClass, | ||
315 | udev->descriptor.bDeviceSubClass, | ||
316 | udev->descriptor.bDeviceProtocol); | ||
317 | } | 316 | } |
318 | |||
319 | } | 317 | } |
320 | static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); | 318 | static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL); |
321 | 319 | ||
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 25cf7e9eccfa..a3c42203213a 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -293,7 +293,7 @@ int usb_driver_claim_interface(struct usb_driver *driver, | |||
293 | /* if interface was already added, bind now; else let | 293 | /* if interface was already added, bind now; else let |
294 | * the future device_add() bind it, bypassing probe() | 294 | * the future device_add() bind it, bypassing probe() |
295 | */ | 295 | */ |
296 | if (!list_empty (&dev->bus_list)) | 296 | if (klist_node_attached(&dev->knode_bus)) |
297 | device_bind_driver(dev); | 297 | device_bind_driver(dev); |
298 | 298 | ||
299 | return 0; | 299 | return 0; |
@@ -322,9 +322,15 @@ void usb_driver_release_interface(struct usb_driver *driver, | |||
322 | if (!dev->driver || dev->driver != &driver->driver) | 322 | if (!dev->driver || dev->driver != &driver->driver) |
323 | return; | 323 | return; |
324 | 324 | ||
325 | /* don't disconnect from disconnect(), or before dev_add() */ | 325 | /* don't release from within disconnect() */ |
326 | if (!list_empty (&dev->driver_list) && !list_empty (&dev->bus_list)) | 326 | if (iface->condition != USB_INTERFACE_BOUND) |
327 | return; | ||
328 | |||
329 | /* release only after device_add() */ | ||
330 | if (klist_node_attached(&dev->knode_bus)) { | ||
331 | iface->condition = USB_INTERFACE_UNBINDING; | ||
327 | device_release_driver(dev); | 332 | device_release_driver(dev); |
333 | } | ||
328 | 334 | ||
329 | dev->driver = NULL; | 335 | dev->driver = NULL; |
330 | usb_set_intfdata(iface, NULL); | 336 | usb_set_intfdata(iface, NULL); |
@@ -462,6 +468,25 @@ usb_match_id(struct usb_interface *interface, const struct usb_device_id *id) | |||
462 | return NULL; | 468 | return NULL; |
463 | } | 469 | } |
464 | 470 | ||
471 | |||
472 | static int __find_interface(struct device * dev, void * data) | ||
473 | { | ||
474 | struct usb_interface ** ret = (struct usb_interface **)data; | ||
475 | struct usb_interface * intf = *ret; | ||
476 | int *minor = (int *)data; | ||
477 | |||
478 | /* can't look at usb devices, only interfaces */ | ||
479 | if (dev->driver == &usb_generic_driver) | ||
480 | return 0; | ||
481 | |||
482 | intf = to_usb_interface(dev); | ||
483 | if (intf->minor != -1 && intf->minor == *minor) { | ||
484 | *ret = intf; | ||
485 | return 1; | ||
486 | } | ||
487 | return 0; | ||
488 | } | ||
489 | |||
465 | /** | 490 | /** |
466 | * usb_find_interface - find usb_interface pointer for driver and device | 491 | * usb_find_interface - find usb_interface pointer for driver and device |
467 | * @drv: the driver whose current configuration is considered | 492 | * @drv: the driver whose current configuration is considered |
@@ -473,26 +498,12 @@ usb_match_id(struct usb_interface *interface, const struct usb_device_id *id) | |||
473 | */ | 498 | */ |
474 | struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor) | 499 | struct usb_interface *usb_find_interface(struct usb_driver *drv, int minor) |
475 | { | 500 | { |
476 | struct list_head *entry; | 501 | struct usb_interface *intf = (struct usb_interface *)(long)minor; |
477 | struct device *dev; | 502 | int ret; |
478 | struct usb_interface *intf; | ||
479 | 503 | ||
480 | list_for_each(entry, &drv->driver.devices) { | 504 | ret = driver_for_each_device(&drv->driver, NULL, &intf, __find_interface); |
481 | dev = container_of(entry, struct device, driver_list); | ||
482 | |||
483 | /* can't look at usb devices, only interfaces */ | ||
484 | if (dev->driver == &usb_generic_driver) | ||
485 | continue; | ||
486 | |||
487 | intf = to_usb_interface(dev); | ||
488 | if (intf->minor == -1) | ||
489 | continue; | ||
490 | if (intf->minor == minor) | ||
491 | return intf; | ||
492 | } | ||
493 | 505 | ||
494 | /* no device found that matches */ | 506 | return ret ? intf : NULL; |
495 | return NULL; | ||
496 | } | 507 | } |
497 | 508 | ||
498 | static int usb_device_match (struct device *dev, struct device_driver *drv) | 509 | static int usb_device_match (struct device *dev, struct device_driver *drv) |
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 8ef8a9cd9ac4..c039d2fbe7ab 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -633,7 +633,7 @@ static const struct usb_gadget_ops dummy_ops = { | |||
633 | 633 | ||
634 | /* "function" sysfs attribute */ | 634 | /* "function" sysfs attribute */ |
635 | static ssize_t | 635 | static ssize_t |
636 | show_function (struct device *dev, char *buf) | 636 | show_function (struct device *dev, struct device_attribute *attr, char *buf) |
637 | { | 637 | { |
638 | struct dummy *dum = gadget_dev_to_dummy (dev); | 638 | struct dummy *dum = gadget_dev_to_dummy (dev); |
639 | 639 | ||
@@ -1600,7 +1600,7 @@ show_urb (char *buf, size_t size, struct urb *urb) | |||
1600 | } | 1600 | } |
1601 | 1601 | ||
1602 | static ssize_t | 1602 | static ssize_t |
1603 | show_urbs (struct device *dev, char *buf) | 1603 | show_urbs (struct device *dev, struct device_attribute *attr, char *buf) |
1604 | { | 1604 | { |
1605 | struct usb_hcd *hcd = dev_get_drvdata (dev); | 1605 | struct usb_hcd *hcd = dev_get_drvdata (dev); |
1606 | struct dummy *dum = hcd_to_dummy (hcd); | 1606 | struct dummy *dum = hcd_to_dummy (hcd); |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index 4857f0e4ef44..037a7f163822 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -3554,14 +3554,14 @@ static void close_all_backing_files(struct fsg_dev *fsg) | |||
3554 | } | 3554 | } |
3555 | 3555 | ||
3556 | 3556 | ||
3557 | static ssize_t show_ro(struct device *dev, char *buf) | 3557 | static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char *buf) |
3558 | { | 3558 | { |
3559 | struct lun *curlun = dev_to_lun(dev); | 3559 | struct lun *curlun = dev_to_lun(dev); |
3560 | 3560 | ||
3561 | return sprintf(buf, "%d\n", curlun->ro); | 3561 | return sprintf(buf, "%d\n", curlun->ro); |
3562 | } | 3562 | } |
3563 | 3563 | ||
3564 | static ssize_t show_file(struct device *dev, char *buf) | 3564 | static ssize_t show_file(struct device *dev, struct device_attribute *attr, char *buf) |
3565 | { | 3565 | { |
3566 | struct lun *curlun = dev_to_lun(dev); | 3566 | struct lun *curlun = dev_to_lun(dev); |
3567 | struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); | 3567 | struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); |
@@ -3589,7 +3589,7 @@ static ssize_t show_file(struct device *dev, char *buf) | |||
3589 | } | 3589 | } |
3590 | 3590 | ||
3591 | 3591 | ||
3592 | static ssize_t store_ro(struct device *dev, const char *buf, size_t count) | 3592 | static ssize_t store_ro(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
3593 | { | 3593 | { |
3594 | ssize_t rc = count; | 3594 | ssize_t rc = count; |
3595 | struct lun *curlun = dev_to_lun(dev); | 3595 | struct lun *curlun = dev_to_lun(dev); |
@@ -3613,7 +3613,7 @@ static ssize_t store_ro(struct device *dev, const char *buf, size_t count) | |||
3613 | return rc; | 3613 | return rc; |
3614 | } | 3614 | } |
3615 | 3615 | ||
3616 | static ssize_t store_file(struct device *dev, const char *buf, size_t count) | 3616 | static ssize_t store_file(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
3617 | { | 3617 | { |
3618 | struct lun *curlun = dev_to_lun(dev); | 3618 | struct lun *curlun = dev_to_lun(dev); |
3619 | struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); | 3619 | struct fsg_dev *fsg = (struct fsg_dev *) dev_get_drvdata(dev); |
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index e5457f2026cc..e47e398daeb5 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -1469,7 +1469,7 @@ static const struct usb_gadget_ops net2280_ops = { | |||
1469 | 1469 | ||
1470 | /* "function" sysfs attribute */ | 1470 | /* "function" sysfs attribute */ |
1471 | static ssize_t | 1471 | static ssize_t |
1472 | show_function (struct device *_dev, char *buf) | 1472 | show_function (struct device *_dev, struct device_attribute *attr, char *buf) |
1473 | { | 1473 | { |
1474 | struct net2280 *dev = dev_get_drvdata (_dev); | 1474 | struct net2280 *dev = dev_get_drvdata (_dev); |
1475 | 1475 | ||
@@ -1482,7 +1482,7 @@ show_function (struct device *_dev, char *buf) | |||
1482 | static DEVICE_ATTR (function, S_IRUGO, show_function, NULL); | 1482 | static DEVICE_ATTR (function, S_IRUGO, show_function, NULL); |
1483 | 1483 | ||
1484 | static ssize_t | 1484 | static ssize_t |
1485 | show_registers (struct device *_dev, char *buf) | 1485 | show_registers (struct device *_dev, struct device_attribute *attr, char *buf) |
1486 | { | 1486 | { |
1487 | struct net2280 *dev; | 1487 | struct net2280 *dev; |
1488 | char *next; | 1488 | char *next; |
@@ -1637,7 +1637,7 @@ show_registers (struct device *_dev, char *buf) | |||
1637 | static DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL); | 1637 | static DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL); |
1638 | 1638 | ||
1639 | static ssize_t | 1639 | static ssize_t |
1640 | show_queues (struct device *_dev, char *buf) | 1640 | show_queues (struct device *_dev, struct device_attribute *attr, char *buf) |
1641 | { | 1641 | { |
1642 | struct net2280 *dev; | 1642 | struct net2280 *dev; |
1643 | char *next; | 1643 | char *next; |
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 6390c5726d81..b8b4524ed746 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c | |||
@@ -1429,7 +1429,7 @@ done: | |||
1429 | 1429 | ||
1430 | /* "function" sysfs attribute */ | 1430 | /* "function" sysfs attribute */ |
1431 | static ssize_t | 1431 | static ssize_t |
1432 | show_function (struct device *_dev, char *buf) | 1432 | show_function (struct device *_dev, struct device_attribute *attr, char *buf) |
1433 | { | 1433 | { |
1434 | struct pxa2xx_udc *dev = dev_get_drvdata (_dev); | 1434 | struct pxa2xx_udc *dev = dev_get_drvdata (_dev); |
1435 | 1435 | ||
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 3196c3265ff5..19e598c9641f 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -124,3 +124,14 @@ config USB_SL811_HCD | |||
124 | To compile this driver as a module, choose M here: the | 124 | To compile this driver as a module, choose M here: the |
125 | module will be called sl811-hcd. | 125 | module will be called sl811-hcd. |
126 | 126 | ||
127 | config USB_SL811_CS | ||
128 | tristate "CF/PCMCIA support for SL811HS HCD" | ||
129 | depends on USB_SL811_HCD && PCMCIA | ||
130 | default N | ||
131 | help | ||
132 | Wraps a PCMCIA driver around the SL811HS HCD, supporting the RATOC | ||
133 | REX-CFU1U CF card (often used with PDAs). If unsure, say N. | ||
134 | |||
135 | To compile this driver as a module, choose M here: the | ||
136 | module will be called "sl811_cs". | ||
137 | |||
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index a574ca06cf6b..5dbd3e7a27c7 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile | |||
@@ -7,4 +7,5 @@ obj-$(CONFIG_USB_EHCI_HCD) += ehci-hcd.o | |||
7 | obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o | 7 | obj-$(CONFIG_USB_OHCI_HCD) += ohci-hcd.o |
8 | obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o | 8 | obj-$(CONFIG_USB_UHCI_HCD) += uhci-hcd.o |
9 | obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o | 9 | obj-$(CONFIG_USB_SL811_HCD) += sl811-hcd.o |
10 | obj-$(CONFIG_USB_SL811_CS) += sl811_cs.o | ||
10 | obj-$(CONFIG_ETRAX_ARCH_V10) += hc_crisv10.o | 11 | obj-$(CONFIG_ETRAX_ARCH_V10) += hc_crisv10.o |
diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 9b347d765383..2ff11d53567b 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c | |||
@@ -450,7 +450,7 @@ show_async (struct class_device *class_dev, char *buf) | |||
450 | 450 | ||
451 | *buf = 0; | 451 | *buf = 0; |
452 | 452 | ||
453 | bus = to_usb_bus(class_dev); | 453 | bus = class_get_devdata(class_dev); |
454 | hcd = bus->hcpriv; | 454 | hcd = bus->hcpriv; |
455 | ehci = hcd_to_ehci (hcd); | 455 | ehci = hcd_to_ehci (hcd); |
456 | next = buf; | 456 | next = buf; |
@@ -496,7 +496,7 @@ show_periodic (struct class_device *class_dev, char *buf) | |||
496 | return 0; | 496 | return 0; |
497 | seen_count = 0; | 497 | seen_count = 0; |
498 | 498 | ||
499 | bus = to_usb_bus(class_dev); | 499 | bus = class_get_devdata(class_dev); |
500 | hcd = bus->hcpriv; | 500 | hcd = bus->hcpriv; |
501 | ehci = hcd_to_ehci (hcd); | 501 | ehci = hcd_to_ehci (hcd); |
502 | next = buf; | 502 | next = buf; |
@@ -633,7 +633,7 @@ show_registers (struct class_device *class_dev, char *buf) | |||
633 | static char fmt [] = "%*s\n"; | 633 | static char fmt [] = "%*s\n"; |
634 | static char label [] = ""; | 634 | static char label [] = ""; |
635 | 635 | ||
636 | bus = to_usb_bus(class_dev); | 636 | bus = class_get_devdata(class_dev); |
637 | hcd = bus->hcpriv; | 637 | hcd = bus->hcpriv; |
638 | ehci = hcd_to_ehci (hcd); | 638 | ehci = hcd_to_ehci (hcd); |
639 | next = buf; | 639 | next = buf; |
@@ -735,7 +735,7 @@ static CLASS_DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL); | |||
735 | 735 | ||
736 | static inline void create_debug_files (struct ehci_hcd *ehci) | 736 | static inline void create_debug_files (struct ehci_hcd *ehci) |
737 | { | 737 | { |
738 | struct class_device *cldev = &ehci_to_hcd(ehci)->self.class_dev; | 738 | struct class_device *cldev = ehci_to_hcd(ehci)->self.class_dev; |
739 | 739 | ||
740 | class_device_create_file(cldev, &class_device_attr_async); | 740 | class_device_create_file(cldev, &class_device_attr_async); |
741 | class_device_create_file(cldev, &class_device_attr_periodic); | 741 | class_device_create_file(cldev, &class_device_attr_periodic); |
@@ -744,7 +744,7 @@ static inline void create_debug_files (struct ehci_hcd *ehci) | |||
744 | 744 | ||
745 | static inline void remove_debug_files (struct ehci_hcd *ehci) | 745 | static inline void remove_debug_files (struct ehci_hcd *ehci) |
746 | { | 746 | { |
747 | struct class_device *cldev = &ehci_to_hcd(ehci)->self.class_dev; | 747 | struct class_device *cldev = ehci_to_hcd(ehci)->self.class_dev; |
748 | 748 | ||
749 | class_device_remove_file(cldev, &class_device_attr_async); | 749 | class_device_remove_file(cldev, &class_device_attr_async); |
750 | class_device_remove_file(cldev, &class_device_attr_periodic); | 750 | class_device_remove_file(cldev, &class_device_attr_periodic); |
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c index 429330bc38de..d7b4f7939ded 100644 --- a/drivers/usb/host/ehci-hub.c +++ b/drivers/usb/host/ehci-hub.c | |||
@@ -439,9 +439,12 @@ static int ehci_hub_control ( | |||
439 | /* force reset to complete */ | 439 | /* force reset to complete */ |
440 | writel (temp & ~PORT_RESET, | 440 | writel (temp & ~PORT_RESET, |
441 | &ehci->regs->port_status [wIndex]); | 441 | &ehci->regs->port_status [wIndex]); |
442 | /* REVISIT: some hardware needs 550+ usec to clear | ||
443 | * this bit; seems too long to spin routinely... | ||
444 | */ | ||
442 | retval = handshake ( | 445 | retval = handshake ( |
443 | &ehci->regs->port_status [wIndex], | 446 | &ehci->regs->port_status [wIndex], |
444 | PORT_RESET, 0, 500); | 447 | PORT_RESET, 0, 750); |
445 | if (retval != 0) { | 448 | if (retval != 0) { |
446 | ehci_err (ehci, "port %d reset error %d\n", | 449 | ehci_err (ehci, "port %d reset error %d\n", |
447 | wIndex + 1, retval); | 450 | wIndex + 1, retval); |
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index 62f53a213808..c58408c95c3d 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c | |||
@@ -481,7 +481,7 @@ show_async (struct class_device *class_dev, char *buf) | |||
481 | size_t temp; | 481 | size_t temp; |
482 | unsigned long flags; | 482 | unsigned long flags; |
483 | 483 | ||
484 | bus = to_usb_bus(class_dev); | 484 | bus = class_get_devdata(class_dev); |
485 | hcd = bus->hcpriv; | 485 | hcd = bus->hcpriv; |
486 | ohci = hcd_to_ohci(hcd); | 486 | ohci = hcd_to_ohci(hcd); |
487 | 487 | ||
@@ -514,7 +514,7 @@ show_periodic (struct class_device *class_dev, char *buf) | |||
514 | return 0; | 514 | return 0; |
515 | seen_count = 0; | 515 | seen_count = 0; |
516 | 516 | ||
517 | bus = to_usb_bus(class_dev); | 517 | bus = class_get_devdata(class_dev); |
518 | hcd = bus->hcpriv; | 518 | hcd = bus->hcpriv; |
519 | ohci = hcd_to_ohci(hcd); | 519 | ohci = hcd_to_ohci(hcd); |
520 | next = buf; | 520 | next = buf; |
@@ -611,7 +611,7 @@ show_registers (struct class_device *class_dev, char *buf) | |||
611 | char *next; | 611 | char *next; |
612 | u32 rdata; | 612 | u32 rdata; |
613 | 613 | ||
614 | bus = to_usb_bus(class_dev); | 614 | bus = class_get_devdata(class_dev); |
615 | hcd = bus->hcpriv; | 615 | hcd = bus->hcpriv; |
616 | ohci = hcd_to_ohci(hcd); | 616 | ohci = hcd_to_ohci(hcd); |
617 | regs = ohci->regs; | 617 | regs = ohci->regs; |
@@ -684,7 +684,7 @@ static CLASS_DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL); | |||
684 | 684 | ||
685 | static inline void create_debug_files (struct ohci_hcd *ohci) | 685 | static inline void create_debug_files (struct ohci_hcd *ohci) |
686 | { | 686 | { |
687 | struct class_device *cldev = &ohci_to_hcd(ohci)->self.class_dev; | 687 | struct class_device *cldev = ohci_to_hcd(ohci)->self.class_dev; |
688 | 688 | ||
689 | class_device_create_file(cldev, &class_device_attr_async); | 689 | class_device_create_file(cldev, &class_device_attr_async); |
690 | class_device_create_file(cldev, &class_device_attr_periodic); | 690 | class_device_create_file(cldev, &class_device_attr_periodic); |
@@ -694,7 +694,7 @@ static inline void create_debug_files (struct ohci_hcd *ohci) | |||
694 | 694 | ||
695 | static inline void remove_debug_files (struct ohci_hcd *ohci) | 695 | static inline void remove_debug_files (struct ohci_hcd *ohci) |
696 | { | 696 | { |
697 | struct class_device *cldev = &ohci_to_hcd(ohci)->self.class_dev; | 697 | struct class_device *cldev = ohci_to_hcd(ohci)->self.class_dev; |
698 | 698 | ||
699 | class_device_remove_file(cldev, &class_device_attr_async); | 699 | class_device_remove_file(cldev, &class_device_attr_async); |
700 | class_device_remove_file(cldev, &class_device_attr_periodic); | 700 | class_device_remove_file(cldev, &class_device_attr_periodic); |
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index a374b7692073..99d43f758ad0 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
@@ -2,8 +2,8 @@ | |||
2 | * SL811HS HCD (Host Controller Driver) for USB. | 2 | * SL811HS HCD (Host Controller Driver) for USB. |
3 | * | 3 | * |
4 | * Copyright (C) 2004 Psion Teklogix (for NetBook PRO) | 4 | * Copyright (C) 2004 Psion Teklogix (for NetBook PRO) |
5 | * Copyright (C) 2004 David Brownell | 5 | * Copyright (C) 2004-2005 David Brownell |
6 | * | 6 | * |
7 | * Periodic scheduling is based on Roman's OHCI code | 7 | * Periodic scheduling is based on Roman's OHCI code |
8 | * Copyright (C) 1999 Roman Weissgaerber | 8 | * Copyright (C) 1999 Roman Weissgaerber |
9 | * | 9 | * |
@@ -15,7 +15,7 @@ | |||
15 | * For documentation, see the SL811HS spec and the "SL811HS Embedded Host" | 15 | * For documentation, see the SL811HS spec and the "SL811HS Embedded Host" |
16 | * document (providing significant pieces missing from that spec); plus | 16 | * document (providing significant pieces missing from that spec); plus |
17 | * the SL811S spec if you want peripheral side info. | 17 | * the SL811S spec if you want peripheral side info. |
18 | */ | 18 | */ |
19 | 19 | ||
20 | /* | 20 | /* |
21 | * Status: Passed basic stress testing, works with hubs, mice, keyboards, | 21 | * Status: Passed basic stress testing, works with hubs, mice, keyboards, |
@@ -67,7 +67,7 @@ | |||
67 | MODULE_DESCRIPTION("SL811HS USB Host Controller Driver"); | 67 | MODULE_DESCRIPTION("SL811HS USB Host Controller Driver"); |
68 | MODULE_LICENSE("GPL"); | 68 | MODULE_LICENSE("GPL"); |
69 | 69 | ||
70 | #define DRIVER_VERSION "15 Dec 2004" | 70 | #define DRIVER_VERSION "19 May 2005" |
71 | 71 | ||
72 | 72 | ||
73 | #ifndef DEBUG | 73 | #ifndef DEBUG |
@@ -121,6 +121,10 @@ static void port_power(struct sl811 *sl811, int is_on) | |||
121 | /* reset as thoroughly as we can */ | 121 | /* reset as thoroughly as we can */ |
122 | if (sl811->board && sl811->board->reset) | 122 | if (sl811->board && sl811->board->reset) |
123 | sl811->board->reset(hcd->self.controller); | 123 | sl811->board->reset(hcd->self.controller); |
124 | else { | ||
125 | sl811_write(sl811, SL11H_CTLREG1, SL11H_CTL1MASK_SE0); | ||
126 | mdelay(20); | ||
127 | } | ||
124 | 128 | ||
125 | sl811_write(sl811, SL11H_IRQ_ENABLE, 0); | 129 | sl811_write(sl811, SL11H_IRQ_ENABLE, 0); |
126 | sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); | 130 | sl811_write(sl811, SL11H_CTLREG1, sl811->ctrl1); |
@@ -443,6 +447,7 @@ static void finish_request( | |||
443 | spin_lock(&urb->lock); | 447 | spin_lock(&urb->lock); |
444 | if (urb->status == -EINPROGRESS) | 448 | if (urb->status == -EINPROGRESS) |
445 | urb->status = status; | 449 | urb->status = status; |
450 | urb->hcpriv = NULL; | ||
446 | spin_unlock(&urb->lock); | 451 | spin_unlock(&urb->lock); |
447 | 452 | ||
448 | spin_unlock(&sl811->lock); | 453 | spin_unlock(&sl811->lock); |
@@ -472,7 +477,7 @@ static void finish_request( | |||
472 | if (*prev) | 477 | if (*prev) |
473 | *prev = ep->next; | 478 | *prev = ep->next; |
474 | sl811->load[i] -= ep->load; | 479 | sl811->load[i] -= ep->load; |
475 | } | 480 | } |
476 | ep->branch = PERIODIC_SIZE; | 481 | ep->branch = PERIODIC_SIZE; |
477 | sl811->periodic_count--; | 482 | sl811->periodic_count--; |
478 | sl811_to_hcd(sl811)->self.bandwidth_allocated | 483 | sl811_to_hcd(sl811)->self.bandwidth_allocated |
@@ -661,9 +666,9 @@ retry: | |||
661 | 666 | ||
662 | #ifdef QUIRK2 | 667 | #ifdef QUIRK2 |
663 | /* this may no longer be necessary ... */ | 668 | /* this may no longer be necessary ... */ |
664 | if (irqstat == 0 && ret == IRQ_NONE) { | 669 | if (irqstat == 0) { |
665 | irqstat = checkdone(sl811); | 670 | irqstat = checkdone(sl811); |
666 | if (irqstat /* && irq != ~0 */ ) | 671 | if (irqstat) |
667 | sl811->stat_lost++; | 672 | sl811->stat_lost++; |
668 | } | 673 | } |
669 | #endif | 674 | #endif |
@@ -722,7 +727,8 @@ retry: | |||
722 | if (sl811->active_a) { | 727 | if (sl811->active_a) { |
723 | sl811_write(sl811, SL811_EP_A(SL11H_HOSTCTLREG), 0); | 728 | sl811_write(sl811, SL811_EP_A(SL11H_HOSTCTLREG), 0); |
724 | finish_request(sl811, sl811->active_a, | 729 | finish_request(sl811, sl811->active_a, |
725 | container_of(sl811->active_a->hep->urb_list.next, | 730 | container_of(sl811->active_a |
731 | ->hep->urb_list.next, | ||
726 | struct urb, urb_list), | 732 | struct urb, urb_list), |
727 | NULL, -ESHUTDOWN); | 733 | NULL, -ESHUTDOWN); |
728 | sl811->active_a = NULL; | 734 | sl811->active_a = NULL; |
@@ -731,7 +737,8 @@ retry: | |||
731 | if (sl811->active_b) { | 737 | if (sl811->active_b) { |
732 | sl811_write(sl811, SL811_EP_B(SL11H_HOSTCTLREG), 0); | 738 | sl811_write(sl811, SL811_EP_B(SL11H_HOSTCTLREG), 0); |
733 | finish_request(sl811, sl811->active_b, | 739 | finish_request(sl811, sl811->active_b, |
734 | container_of(sl811->active_b->hep->urb_list.next, | 740 | container_of(sl811->active_b |
741 | ->hep->urb_list.next, | ||
735 | struct urb, urb_list), | 742 | struct urb, urb_list), |
736 | NULL, -ESHUTDOWN); | 743 | NULL, -ESHUTDOWN); |
737 | sl811->active_b = NULL; | 744 | sl811->active_b = NULL; |
@@ -761,7 +768,7 @@ retry: | |||
761 | goto retry; | 768 | goto retry; |
762 | } | 769 | } |
763 | 770 | ||
764 | if (sl811->periodic_count == 0 && list_empty(&sl811->async)) | 771 | if (sl811->periodic_count == 0 && list_empty(&sl811->async)) |
765 | sofirq_off(sl811); | 772 | sofirq_off(sl811); |
766 | sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); | 773 | sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); |
767 | 774 | ||
@@ -796,7 +803,7 @@ static int balance(struct sl811 *sl811, u16 period, u16 load) | |||
796 | } | 803 | } |
797 | if (j < PERIODIC_SIZE) | 804 | if (j < PERIODIC_SIZE) |
798 | continue; | 805 | continue; |
799 | branch = i; | 806 | branch = i; |
800 | } | 807 | } |
801 | } | 808 | } |
802 | return branch; | 809 | return branch; |
@@ -890,6 +897,7 @@ static int sl811h_urb_enqueue( | |||
890 | break; | 897 | break; |
891 | } | 898 | } |
892 | 899 | ||
900 | ep->hep = hep; | ||
893 | hep->hcpriv = ep; | 901 | hep->hcpriv = ep; |
894 | } | 902 | } |
895 | 903 | ||
@@ -961,15 +969,16 @@ fail: | |||
961 | static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | 969 | static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) |
962 | { | 970 | { |
963 | struct sl811 *sl811 = hcd_to_sl811(hcd); | 971 | struct sl811 *sl811 = hcd_to_sl811(hcd); |
964 | struct usb_host_endpoint *hep = urb->hcpriv; | 972 | struct usb_host_endpoint *hep; |
965 | unsigned long flags; | 973 | unsigned long flags; |
966 | struct sl811h_ep *ep; | 974 | struct sl811h_ep *ep; |
967 | int retval = 0; | 975 | int retval = 0; |
968 | 976 | ||
977 | spin_lock_irqsave(&sl811->lock, flags); | ||
978 | hep = urb->hcpriv; | ||
969 | if (!hep) | 979 | if (!hep) |
970 | return -EINVAL; | 980 | goto fail; |
971 | 981 | ||
972 | spin_lock_irqsave(&sl811->lock, flags); | ||
973 | ep = hep->hcpriv; | 982 | ep = hep->hcpriv; |
974 | if (ep) { | 983 | if (ep) { |
975 | /* finish right away if this urb can't be active ... | 984 | /* finish right away if this urb can't be active ... |
@@ -1017,6 +1026,7 @@ static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | |||
1017 | VDBG("dequeue, urb %p active %s; wait4irq\n", urb, | 1026 | VDBG("dequeue, urb %p active %s; wait4irq\n", urb, |
1018 | (sl811->active_a == ep) ? "A" : "B"); | 1027 | (sl811->active_a == ep) ? "A" : "B"); |
1019 | } else | 1028 | } else |
1029 | fail: | ||
1020 | retval = -EINVAL; | 1030 | retval = -EINVAL; |
1021 | spin_unlock_irqrestore(&sl811->lock, flags); | 1031 | spin_unlock_irqrestore(&sl811->lock, flags); |
1022 | return retval; | 1032 | return retval; |
@@ -1576,6 +1586,9 @@ sl811h_start(struct usb_hcd *hcd) | |||
1576 | if (sl811->board && sl811->board->power) | 1586 | if (sl811->board && sl811->board->power) |
1577 | hub_set_power_budget(udev, sl811->board->power * 2); | 1587 | hub_set_power_budget(udev, sl811->board->power * 2); |
1578 | 1588 | ||
1589 | /* enable power and interupts */ | ||
1590 | port_power(sl811, 1); | ||
1591 | |||
1579 | return 0; | 1592 | return 0; |
1580 | } | 1593 | } |
1581 | 1594 | ||
@@ -1618,7 +1631,7 @@ static struct hc_driver sl811h_hc_driver = { | |||
1618 | 1631 | ||
1619 | /*-------------------------------------------------------------------------*/ | 1632 | /*-------------------------------------------------------------------------*/ |
1620 | 1633 | ||
1621 | static int __init_or_module | 1634 | static int __devexit |
1622 | sl811h_remove(struct device *dev) | 1635 | sl811h_remove(struct device *dev) |
1623 | { | 1636 | { |
1624 | struct usb_hcd *hcd = dev_get_drvdata(dev); | 1637 | struct usb_hcd *hcd = dev_get_drvdata(dev); |
@@ -1631,21 +1644,20 @@ sl811h_remove(struct device *dev) | |||
1631 | remove_debug_file(sl811); | 1644 | remove_debug_file(sl811); |
1632 | usb_remove_hcd(hcd); | 1645 | usb_remove_hcd(hcd); |
1633 | 1646 | ||
1634 | iounmap(sl811->data_reg); | 1647 | /* some platforms may use IORESOURCE_IO */ |
1635 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 1648 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
1636 | release_mem_region(res->start, 1); | 1649 | if (res) |
1650 | iounmap(sl811->data_reg); | ||
1637 | 1651 | ||
1638 | iounmap(sl811->addr_reg); | ||
1639 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1652 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1640 | release_mem_region(res->start, 1); | 1653 | if (res) |
1654 | iounmap(sl811->addr_reg); | ||
1641 | 1655 | ||
1642 | usb_put_hcd(hcd); | 1656 | usb_put_hcd(hcd); |
1643 | return 0; | 1657 | return 0; |
1644 | } | 1658 | } |
1645 | 1659 | ||
1646 | #define resource_len(r) (((r)->end - (r)->start) + 1) | 1660 | static int __devinit |
1647 | |||
1648 | static int __init | ||
1649 | sl811h_probe(struct device *dev) | 1661 | sl811h_probe(struct device *dev) |
1650 | { | 1662 | { |
1651 | struct usb_hcd *hcd; | 1663 | struct usb_hcd *hcd; |
@@ -1656,7 +1668,7 @@ sl811h_probe(struct device *dev) | |||
1656 | void __iomem *addr_reg; | 1668 | void __iomem *addr_reg; |
1657 | void __iomem *data_reg; | 1669 | void __iomem *data_reg; |
1658 | int retval; | 1670 | int retval; |
1659 | u8 tmp; | 1671 | u8 tmp, ioaddr = 0; |
1660 | 1672 | ||
1661 | /* basic sanity checks first. board-specific init logic should | 1673 | /* basic sanity checks first. board-specific init logic should |
1662 | * have initialized these three resources and probably board | 1674 | * have initialized these three resources and probably board |
@@ -1664,13 +1676,8 @@ sl811h_probe(struct device *dev) | |||
1664 | * minimal sanity checking. | 1676 | * minimal sanity checking. |
1665 | */ | 1677 | */ |
1666 | pdev = container_of(dev, struct platform_device, dev); | 1678 | pdev = container_of(dev, struct platform_device, dev); |
1667 | if (pdev->num_resources < 3) | ||
1668 | return -ENODEV; | ||
1669 | |||
1670 | addr = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
1671 | data = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
1672 | irq = platform_get_irq(pdev, 0); | 1679 | irq = platform_get_irq(pdev, 0); |
1673 | if (!addr || !data || irq < 0) | 1680 | if (pdev->num_resources < 3 || irq < 0) |
1674 | return -ENODEV; | 1681 | return -ENODEV; |
1675 | 1682 | ||
1676 | /* refuse to confuse usbcore */ | 1683 | /* refuse to confuse usbcore */ |
@@ -1679,24 +1686,31 @@ sl811h_probe(struct device *dev) | |||
1679 | return -EINVAL; | 1686 | return -EINVAL; |
1680 | } | 1687 | } |
1681 | 1688 | ||
1682 | if (!request_mem_region(addr->start, 1, hcd_name)) { | 1689 | /* the chip may be wired for either kind of addressing */ |
1683 | retval = -EBUSY; | 1690 | addr = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1684 | goto err1; | 1691 | data = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
1685 | } | 1692 | retval = -EBUSY; |
1686 | addr_reg = ioremap(addr->start, resource_len(addr)); | 1693 | if (!addr || !data) { |
1687 | if (addr_reg == NULL) { | 1694 | addr = platform_get_resource(pdev, IORESOURCE_IO, 0); |
1688 | retval = -ENOMEM; | 1695 | data = platform_get_resource(pdev, IORESOURCE_IO, 1); |
1689 | goto err2; | 1696 | if (!addr || !data) |
1690 | } | 1697 | return -ENODEV; |
1698 | ioaddr = 1; | ||
1699 | |||
1700 | addr_reg = (void __iomem *) addr->start; | ||
1701 | data_reg = (void __iomem *) data->start; | ||
1702 | } else { | ||
1703 | addr_reg = ioremap(addr->start, 1); | ||
1704 | if (addr_reg == NULL) { | ||
1705 | retval = -ENOMEM; | ||
1706 | goto err2; | ||
1707 | } | ||
1691 | 1708 | ||
1692 | if (!request_mem_region(data->start, 1, hcd_name)) { | 1709 | data_reg = ioremap(data->start, 1); |
1693 | retval = -EBUSY; | 1710 | if (data_reg == NULL) { |
1694 | goto err3; | 1711 | retval = -ENOMEM; |
1695 | } | 1712 | goto err4; |
1696 | data_reg = ioremap(data->start, resource_len(addr)); | 1713 | } |
1697 | if (data_reg == NULL) { | ||
1698 | retval = -ENOMEM; | ||
1699 | goto err4; | ||
1700 | } | 1714 | } |
1701 | 1715 | ||
1702 | /* allocate and initialize hcd */ | 1716 | /* allocate and initialize hcd */ |
@@ -1737,12 +1751,14 @@ sl811h_probe(struct device *dev) | |||
1737 | goto err6; | 1751 | goto err6; |
1738 | } | 1752 | } |
1739 | 1753 | ||
1740 | /* sl811s would need a different handler for this irq */ | 1754 | /* The chip's IRQ is level triggered, active high. A requirement |
1741 | #ifdef CONFIG_ARM | 1755 | * for platform device setup is to cope with things like signal |
1742 | /* Cypress docs say the IRQ is IRQT_HIGH ... */ | 1756 | * inverters (e.g. CF is active low) or working only with edge |
1743 | set_irq_type(irq, IRQT_RISING); | 1757 | * triggers (e.g. most ARM CPUs). Initial driver stress testing |
1744 | #endif | 1758 | * was on a system with single edge triggering, so most sorts of |
1745 | retval = usb_add_hcd(hcd, irq, SA_INTERRUPT); | 1759 | * triggering arrangement should work. |
1760 | */ | ||
1761 | retval = usb_add_hcd(hcd, irq, SA_INTERRUPT | SA_SHIRQ); | ||
1746 | if (retval != 0) | 1762 | if (retval != 0) |
1747 | goto err6; | 1763 | goto err6; |
1748 | 1764 | ||
@@ -1752,14 +1768,12 @@ sl811h_probe(struct device *dev) | |||
1752 | err6: | 1768 | err6: |
1753 | usb_put_hcd(hcd); | 1769 | usb_put_hcd(hcd); |
1754 | err5: | 1770 | err5: |
1755 | iounmap(data_reg); | 1771 | if (!ioaddr) |
1772 | iounmap(data_reg); | ||
1756 | err4: | 1773 | err4: |
1757 | release_mem_region(data->start, 1); | 1774 | if (!ioaddr) |
1758 | err3: | 1775 | iounmap(addr_reg); |
1759 | iounmap(addr_reg); | ||
1760 | err2: | 1776 | err2: |
1761 | release_mem_region(addr->start, 1); | ||
1762 | err1: | ||
1763 | DBG("init error, %d\n", retval); | 1777 | DBG("init error, %d\n", retval); |
1764 | return retval; | 1778 | return retval; |
1765 | } | 1779 | } |
@@ -1767,7 +1781,7 @@ sl811h_probe(struct device *dev) | |||
1767 | #ifdef CONFIG_PM | 1781 | #ifdef CONFIG_PM |
1768 | 1782 | ||
1769 | /* for this device there's no useful distinction between the controller | 1783 | /* for this device there's no useful distinction between the controller |
1770 | * and its root hub, except that the root hub only gets direct PM calls | 1784 | * and its root hub, except that the root hub only gets direct PM calls |
1771 | * when CONFIG_USB_SUSPEND is enabled. | 1785 | * when CONFIG_USB_SUSPEND is enabled. |
1772 | */ | 1786 | */ |
1773 | 1787 | ||
@@ -1821,20 +1835,22 @@ sl811h_resume(struct device *dev, u32 phase) | |||
1821 | #endif | 1835 | #endif |
1822 | 1836 | ||
1823 | 1837 | ||
1824 | static struct device_driver sl811h_driver = { | 1838 | /* this driver is exported so sl811_cs can depend on it */ |
1839 | struct device_driver sl811h_driver = { | ||
1825 | .name = (char *) hcd_name, | 1840 | .name = (char *) hcd_name, |
1826 | .bus = &platform_bus_type, | 1841 | .bus = &platform_bus_type, |
1827 | 1842 | ||
1828 | .probe = sl811h_probe, | 1843 | .probe = sl811h_probe, |
1829 | .remove = sl811h_remove, | 1844 | .remove = __devexit_p(sl811h_remove), |
1830 | 1845 | ||
1831 | .suspend = sl811h_suspend, | 1846 | .suspend = sl811h_suspend, |
1832 | .resume = sl811h_resume, | 1847 | .resume = sl811h_resume, |
1833 | }; | 1848 | }; |
1849 | EXPORT_SYMBOL(sl811h_driver); | ||
1834 | 1850 | ||
1835 | /*-------------------------------------------------------------------------*/ | 1851 | /*-------------------------------------------------------------------------*/ |
1836 | 1852 | ||
1837 | static int __init sl811h_init(void) | 1853 | static int __init sl811h_init(void) |
1838 | { | 1854 | { |
1839 | if (usb_disabled()) | 1855 | if (usb_disabled()) |
1840 | return -ENODEV; | 1856 | return -ENODEV; |
@@ -1844,8 +1860,8 @@ static int __init sl811h_init(void) | |||
1844 | } | 1860 | } |
1845 | module_init(sl811h_init); | 1861 | module_init(sl811h_init); |
1846 | 1862 | ||
1847 | static void __exit sl811h_cleanup(void) | 1863 | static void __exit sl811h_cleanup(void) |
1848 | { | 1864 | { |
1849 | driver_unregister(&sl811h_driver); | 1865 | driver_unregister(&sl811h_driver); |
1850 | } | 1866 | } |
1851 | module_exit(sl811h_cleanup); | 1867 | module_exit(sl811h_cleanup); |
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c new file mode 100644 index 000000000000..6e173265095c --- /dev/null +++ b/drivers/usb/host/sl811_cs.c | |||
@@ -0,0 +1,442 @@ | |||
1 | /* | ||
2 | * PCMCIA driver for SL811HS (as found in REX-CFU1U) | ||
3 | * Filename: sl811_cs.c | ||
4 | * Author: Yukio Yamamoto | ||
5 | * | ||
6 | * Port to sl811-hcd and 2.6.x by | ||
7 | * Botond Botyanszki <boti@rocketmail.com> | ||
8 | * Simon Pickering | ||
9 | * | ||
10 | * Last update: 2005-05-12 | ||
11 | */ | ||
12 | |||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/sched.h> | ||
17 | #include <linux/ptrace.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/timer.h> | ||
21 | #include <linux/ioport.h> | ||
22 | |||
23 | #include <pcmcia/version.h> | ||
24 | #include <pcmcia/cs_types.h> | ||
25 | #include <pcmcia/cs.h> | ||
26 | #include <pcmcia/cistpl.h> | ||
27 | #include <pcmcia/cisreg.h> | ||
28 | #include <pcmcia/ds.h> | ||
29 | |||
30 | #include <linux/usb_sl811.h> | ||
31 | |||
32 | MODULE_AUTHOR("Botond Botyanszki"); | ||
33 | MODULE_DESCRIPTION("REX-CFU1U PCMCIA driver for 2.6"); | ||
34 | MODULE_LICENSE("GPL"); | ||
35 | |||
36 | |||
37 | /*====================================================================*/ | ||
38 | /* MACROS */ | ||
39 | /*====================================================================*/ | ||
40 | |||
41 | #if defined(DEBUG) || defined(CONFIG_USB_DEBUG) || defined(PCMCIA_DEBUG) | ||
42 | |||
43 | static int pc_debug = 0; | ||
44 | module_param(pc_debug, int, 0644); | ||
45 | |||
46 | #define DBG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG "sl811_cs: " args) | ||
47 | |||
48 | #else | ||
49 | #define DBG(n, args...) do{}while(0) | ||
50 | #endif /* no debugging */ | ||
51 | |||
52 | #define INFO(args...) printk(KERN_INFO "sl811_cs: " args) | ||
53 | |||
54 | #define INT_MODULE_PARM(n, v) static int n = v; module_param(n, int, 0444) | ||
55 | |||
56 | #define CS_CHECK(fn, ret) \ | ||
57 | do { \ | ||
58 | last_fn = (fn); \ | ||
59 | if ((last_ret = (ret)) != 0) \ | ||
60 | goto cs_failed; \ | ||
61 | } while (0) | ||
62 | |||
63 | /*====================================================================*/ | ||
64 | /* VARIABLES */ | ||
65 | /*====================================================================*/ | ||
66 | |||
67 | static const char driver_name[DEV_NAME_LEN] = "sl811_cs"; | ||
68 | |||
69 | static dev_link_t *dev_list = NULL; | ||
70 | |||
71 | static int irq_list[4] = { -1 }; | ||
72 | static int irq_list_count; | ||
73 | |||
74 | module_param_array(irq_list, int, &irq_list_count, 0444); | ||
75 | |||
76 | INT_MODULE_PARM(irq_mask, 0xdeb8); | ||
77 | |||
78 | typedef struct local_info_t { | ||
79 | dev_link_t link; | ||
80 | dev_node_t node; | ||
81 | } local_info_t; | ||
82 | |||
83 | /*====================================================================*/ | ||
84 | |||
85 | static void release_platform_dev(struct device * dev) | ||
86 | { | ||
87 | DBG(0, "sl811_cs platform_dev release\n"); | ||
88 | dev->parent = NULL; | ||
89 | } | ||
90 | |||
91 | static struct sl811_platform_data platform_data = { | ||
92 | .potpg = 100, | ||
93 | .power = 50, /* == 100mA */ | ||
94 | // .reset = ... FIXME: invoke CF reset on the card | ||
95 | }; | ||
96 | |||
97 | static struct resource resources[] = { | ||
98 | [0] = { | ||
99 | .flags = IORESOURCE_IRQ, | ||
100 | }, | ||
101 | [1] = { | ||
102 | // .name = "address", | ||
103 | .flags = IORESOURCE_IO, | ||
104 | }, | ||
105 | [2] = { | ||
106 | // .name = "data", | ||
107 | .flags = IORESOURCE_IO, | ||
108 | }, | ||
109 | }; | ||
110 | |||
111 | extern struct device_driver sl811h_driver; | ||
112 | |||
113 | static struct platform_device platform_dev = { | ||
114 | .id = -1, | ||
115 | .dev = { | ||
116 | .platform_data = &platform_data, | ||
117 | .release = release_platform_dev, | ||
118 | }, | ||
119 | .resource = resources, | ||
120 | .num_resources = ARRAY_SIZE(resources), | ||
121 | }; | ||
122 | |||
123 | static int sl811_hc_init(struct device *parent, ioaddr_t base_addr, int irq) | ||
124 | { | ||
125 | if (platform_dev.dev.parent) | ||
126 | return -EBUSY; | ||
127 | platform_dev.dev.parent = parent; | ||
128 | |||
129 | /* finish seting up the platform device */ | ||
130 | resources[0].start = irq; | ||
131 | |||
132 | resources[1].start = base_addr; | ||
133 | resources[1].end = base_addr; | ||
134 | |||
135 | resources[2].start = base_addr + 1; | ||
136 | resources[2].end = base_addr + 1; | ||
137 | |||
138 | /* The driver core will probe for us. We know sl811-hcd has been | ||
139 | * initialized already because of the link order dependency. | ||
140 | */ | ||
141 | platform_dev.name = sl811h_driver.name; | ||
142 | return platform_device_register(&platform_dev); | ||
143 | } | ||
144 | |||
145 | /*====================================================================*/ | ||
146 | |||
147 | static void sl811_cs_detach(dev_link_t *link) | ||
148 | { | ||
149 | dev_link_t **linkp; | ||
150 | |||
151 | DBG(0, "sl811_cs_detach(0x%p)\n", link); | ||
152 | |||
153 | /* Locate device structure */ | ||
154 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) { | ||
155 | if (*linkp == link) | ||
156 | break; | ||
157 | } | ||
158 | if (*linkp == NULL) | ||
159 | return; | ||
160 | |||
161 | /* Break the link with Card Services */ | ||
162 | if (link->handle) | ||
163 | pcmcia_deregister_client(link->handle); | ||
164 | |||
165 | /* Unlink device structure, and free it */ | ||
166 | *linkp = link->next; | ||
167 | /* This points to the parent local_info_t struct */ | ||
168 | kfree(link->priv); | ||
169 | } | ||
170 | |||
171 | static void sl811_cs_release(dev_link_t * link) | ||
172 | { | ||
173 | |||
174 | DBG(0, "sl811_cs_release(0x%p)\n", link); | ||
175 | |||
176 | if (link->open) { | ||
177 | DBG(1, "sl811_cs: release postponed, '%s' still open\n", | ||
178 | link->dev->dev_name); | ||
179 | link->state |= DEV_STALE_CONFIG; | ||
180 | return; | ||
181 | } | ||
182 | |||
183 | /* Unlink the device chain */ | ||
184 | link->dev = NULL; | ||
185 | |||
186 | platform_device_unregister(&platform_dev); | ||
187 | pcmcia_release_configuration(link->handle); | ||
188 | if (link->io.NumPorts1) | ||
189 | pcmcia_release_io(link->handle, &link->io); | ||
190 | if (link->irq.AssignedIRQ) | ||
191 | pcmcia_release_irq(link->handle, &link->irq); | ||
192 | link->state &= ~DEV_CONFIG; | ||
193 | |||
194 | if (link->state & DEV_STALE_LINK) | ||
195 | sl811_cs_detach(link); | ||
196 | } | ||
197 | |||
198 | static void sl811_cs_config(dev_link_t *link) | ||
199 | { | ||
200 | client_handle_t handle = link->handle; | ||
201 | struct device *parent = &handle_to_dev(handle); | ||
202 | local_info_t *dev = link->priv; | ||
203 | tuple_t tuple; | ||
204 | cisparse_t parse; | ||
205 | int last_fn, last_ret; | ||
206 | u_char buf[64]; | ||
207 | config_info_t conf; | ||
208 | cistpl_cftable_entry_t dflt = { 0 }; | ||
209 | |||
210 | DBG(0, "sl811_cs_config(0x%p)\n", link); | ||
211 | |||
212 | tuple.DesiredTuple = CISTPL_CONFIG; | ||
213 | tuple.Attributes = 0; | ||
214 | tuple.TupleData = buf; | ||
215 | tuple.TupleDataMax = sizeof(buf); | ||
216 | tuple.TupleOffset = 0; | ||
217 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); | ||
218 | CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); | ||
219 | CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); | ||
220 | link->conf.ConfigBase = parse.config.base; | ||
221 | link->conf.Present = parse.config.rmask[0]; | ||
222 | |||
223 | /* Configure card */ | ||
224 | link->state |= DEV_CONFIG; | ||
225 | |||
226 | /* Look up the current Vcc */ | ||
227 | CS_CHECK(GetConfigurationInfo, | ||
228 | pcmcia_get_configuration_info(handle, &conf)); | ||
229 | link->conf.Vcc = conf.Vcc; | ||
230 | |||
231 | tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; | ||
232 | CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); | ||
233 | while (1) { | ||
234 | cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); | ||
235 | |||
236 | if (pcmcia_get_tuple_data(handle, &tuple) != 0 | ||
237 | || pcmcia_parse_tuple(handle, &tuple, &parse) | ||
238 | != 0) | ||
239 | goto next_entry; | ||
240 | |||
241 | if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { | ||
242 | dflt = *cfg; | ||
243 | } | ||
244 | |||
245 | if (cfg->index == 0) | ||
246 | goto next_entry; | ||
247 | |||
248 | link->conf.ConfigIndex = cfg->index; | ||
249 | |||
250 | /* Use power settings for Vcc and Vpp if present */ | ||
251 | /* Note that the CIS values need to be rescaled */ | ||
252 | if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) { | ||
253 | if (cfg->vcc.param[CISTPL_POWER_VNOM]/10000 | ||
254 | != conf.Vcc) | ||
255 | goto next_entry; | ||
256 | } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) { | ||
257 | if (dflt.vcc.param[CISTPL_POWER_VNOM]/10000 | ||
258 | != conf.Vcc) | ||
259 | goto next_entry; | ||
260 | } | ||
261 | |||
262 | if (cfg->vpp1.present & (1<<CISTPL_POWER_VNOM)) | ||
263 | link->conf.Vpp1 = link->conf.Vpp2 = | ||
264 | cfg->vpp1.param[CISTPL_POWER_VNOM]/10000; | ||
265 | else if (dflt.vpp1.present & (1<<CISTPL_POWER_VNOM)) | ||
266 | link->conf.Vpp1 = link->conf.Vpp2 = | ||
267 | dflt.vpp1.param[CISTPL_POWER_VNOM]/10000; | ||
268 | |||
269 | /* we need an interrupt */ | ||
270 | if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) | ||
271 | link->conf.Attributes |= CONF_ENABLE_IRQ; | ||
272 | |||
273 | /* IO window settings */ | ||
274 | link->io.NumPorts1 = link->io.NumPorts2 = 0; | ||
275 | if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) { | ||
276 | cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io; | ||
277 | |||
278 | link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; | ||
279 | link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK; | ||
280 | link->io.BasePort1 = io->win[0].base; | ||
281 | link->io.NumPorts1 = io->win[0].len; | ||
282 | |||
283 | if (pcmcia_request_io(link->handle, &link->io) != 0) | ||
284 | goto next_entry; | ||
285 | } | ||
286 | break; | ||
287 | |||
288 | next_entry: | ||
289 | if (link->io.NumPorts1) | ||
290 | pcmcia_release_io(link->handle, &link->io); | ||
291 | last_ret = pcmcia_get_next_tuple(handle, &tuple); | ||
292 | } | ||
293 | |||
294 | /* require an IRQ and two registers */ | ||
295 | if (!link->io.NumPorts1 || link->io.NumPorts1 < 2) | ||
296 | goto cs_failed; | ||
297 | if (link->conf.Attributes & CONF_ENABLE_IRQ) | ||
298 | CS_CHECK(RequestIRQ, | ||
299 | pcmcia_request_irq(link->handle, &link->irq)); | ||
300 | else | ||
301 | goto cs_failed; | ||
302 | |||
303 | CS_CHECK(RequestConfiguration, | ||
304 | pcmcia_request_configuration(link->handle, &link->conf)); | ||
305 | |||
306 | sprintf(dev->node.dev_name, driver_name); | ||
307 | dev->node.major = dev->node.minor = 0; | ||
308 | link->dev = &dev->node; | ||
309 | |||
310 | printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", | ||
311 | dev->node.dev_name, link->conf.ConfigIndex, | ||
312 | link->conf.Vcc/10, link->conf.Vcc%10); | ||
313 | if (link->conf.Vpp1) | ||
314 | printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); | ||
315 | printk(", irq %d", link->irq.AssignedIRQ); | ||
316 | printk(", io 0x%04x-0x%04x", link->io.BasePort1, | ||
317 | link->io.BasePort1+link->io.NumPorts1-1); | ||
318 | printk("\n"); | ||
319 | |||
320 | link->state &= ~DEV_CONFIG_PENDING; | ||
321 | |||
322 | if (sl811_hc_init(parent, link->io.BasePort1, link->irq.AssignedIRQ) | ||
323 | < 0) { | ||
324 | cs_failed: | ||
325 | printk("sl811_cs_config failed\n"); | ||
326 | cs_error(link->handle, last_fn, last_ret); | ||
327 | sl811_cs_release(link); | ||
328 | link->state &= ~DEV_CONFIG_PENDING; | ||
329 | } | ||
330 | } | ||
331 | |||
332 | static int | ||
333 | sl811_cs_event(event_t event, int priority, event_callback_args_t *args) | ||
334 | { | ||
335 | dev_link_t *link = args->client_data; | ||
336 | |||
337 | DBG(1, "sl811_cs_event(0x%06x)\n", event); | ||
338 | |||
339 | switch (event) { | ||
340 | case CS_EVENT_CARD_REMOVAL: | ||
341 | link->state &= ~DEV_PRESENT; | ||
342 | if (link->state & DEV_CONFIG) | ||
343 | sl811_cs_release(link); | ||
344 | break; | ||
345 | |||
346 | case CS_EVENT_CARD_INSERTION: | ||
347 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
348 | sl811_cs_config(link); | ||
349 | break; | ||
350 | |||
351 | case CS_EVENT_PM_SUSPEND: | ||
352 | link->state |= DEV_SUSPEND; | ||
353 | /* Fall through... */ | ||
354 | case CS_EVENT_RESET_PHYSICAL: | ||
355 | if (link->state & DEV_CONFIG) | ||
356 | pcmcia_release_configuration(link->handle); | ||
357 | break; | ||
358 | |||
359 | case CS_EVENT_PM_RESUME: | ||
360 | link->state &= ~DEV_SUSPEND; | ||
361 | /* Fall through... */ | ||
362 | case CS_EVENT_CARD_RESET: | ||
363 | if (link->state & DEV_CONFIG) | ||
364 | pcmcia_request_configuration(link->handle, &link->conf); | ||
365 | DBG(0, "reset sl811-hcd here?\n"); | ||
366 | break; | ||
367 | } | ||
368 | return 0; | ||
369 | } | ||
370 | |||
371 | static dev_link_t *sl811_cs_attach(void) | ||
372 | { | ||
373 | local_info_t *local; | ||
374 | dev_link_t *link; | ||
375 | client_reg_t client_reg; | ||
376 | int ret, i; | ||
377 | |||
378 | local = kmalloc(sizeof(local_info_t), GFP_KERNEL); | ||
379 | if (!local) | ||
380 | return NULL; | ||
381 | memset(local, 0, sizeof(local_info_t)); | ||
382 | link = &local->link; | ||
383 | link->priv = local; | ||
384 | |||
385 | /* Initialize */ | ||
386 | link->irq.Attributes = IRQ_TYPE_EXCLUSIVE; | ||
387 | link->irq.IRQInfo1 = IRQ_INFO2_VALID|IRQ_LEVEL_ID; | ||
388 | if (irq_list[0] == -1) | ||
389 | link->irq.IRQInfo2 = irq_mask; | ||
390 | else | ||
391 | for (i = 0; i < irq_list_count; i++) | ||
392 | link->irq.IRQInfo2 |= 1 << irq_list[i]; | ||
393 | link->irq.Handler = NULL; | ||
394 | |||
395 | link->conf.Attributes = 0; | ||
396 | link->conf.Vcc = 33; | ||
397 | link->conf.IntType = INT_MEMORY_AND_IO; | ||
398 | |||
399 | /* Register with Card Services */ | ||
400 | link->next = dev_list; | ||
401 | dev_list = link; | ||
402 | client_reg.dev_info = (dev_info_t *) &driver_name; | ||
403 | client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; | ||
404 | client_reg.EventMask = | ||
405 | CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | | ||
406 | CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | | ||
407 | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; | ||
408 | client_reg.event_handler = &sl811_cs_event; | ||
409 | client_reg.Version = 0x0210; | ||
410 | client_reg.event_callback_args.client_data = link; | ||
411 | ret = pcmcia_register_client(&link->handle, &client_reg); | ||
412 | if (ret != CS_SUCCESS) { | ||
413 | cs_error(link->handle, RegisterClient, ret); | ||
414 | sl811_cs_detach(link); | ||
415 | return NULL; | ||
416 | } | ||
417 | |||
418 | return link; | ||
419 | } | ||
420 | |||
421 | static struct pcmcia_driver sl811_cs_driver = { | ||
422 | .owner = THIS_MODULE, | ||
423 | .drv = { | ||
424 | .name = (char *)driver_name, | ||
425 | }, | ||
426 | .attach = sl811_cs_attach, | ||
427 | .detach = sl811_cs_detach, | ||
428 | }; | ||
429 | |||
430 | /*====================================================================*/ | ||
431 | |||
432 | static int __init init_sl811_cs(void) | ||
433 | { | ||
434 | return pcmcia_register_driver(&sl811_cs_driver); | ||
435 | } | ||
436 | module_init(init_sl811_cs); | ||
437 | |||
438 | static void __exit exit_sl811_cs(void) | ||
439 | { | ||
440 | pcmcia_unregister_driver(&sl811_cs_driver); | ||
441 | } | ||
442 | module_exit(exit_sl811_cs); | ||
diff --git a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c index 94ce2a9ad50f..e991f7ed7330 100644 --- a/drivers/usb/input/aiptek.c +++ b/drivers/usb/input/aiptek.c | |||
@@ -1025,7 +1025,7 @@ static int aiptek_program_tablet(struct aiptek *aiptek) | |||
1025 | /*********************************************************************** | 1025 | /*********************************************************************** |
1026 | * support the 'size' file -- display support | 1026 | * support the 'size' file -- display support |
1027 | */ | 1027 | */ |
1028 | static ssize_t show_tabletSize(struct device *dev, char *buf) | 1028 | static ssize_t show_tabletSize(struct device *dev, struct device_attribute *attr, char *buf) |
1029 | { | 1029 | { |
1030 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1030 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1031 | 1031 | ||
@@ -1048,7 +1048,7 @@ static DEVICE_ATTR(size, S_IRUGO, show_tabletSize, NULL); | |||
1048 | /*********************************************************************** | 1048 | /*********************************************************************** |
1049 | * support routines for the 'product_id' file | 1049 | * support routines for the 'product_id' file |
1050 | */ | 1050 | */ |
1051 | static ssize_t show_tabletProductId(struct device *dev, char *buf) | 1051 | static ssize_t show_tabletProductId(struct device *dev, struct device_attribute *attr, char *buf) |
1052 | { | 1052 | { |
1053 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1053 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1054 | 1054 | ||
@@ -1064,7 +1064,7 @@ static DEVICE_ATTR(product_id, S_IRUGO, show_tabletProductId, NULL); | |||
1064 | /*********************************************************************** | 1064 | /*********************************************************************** |
1065 | * support routines for the 'vendor_id' file | 1065 | * support routines for the 'vendor_id' file |
1066 | */ | 1066 | */ |
1067 | static ssize_t show_tabletVendorId(struct device *dev, char *buf) | 1067 | static ssize_t show_tabletVendorId(struct device *dev, struct device_attribute *attr, char *buf) |
1068 | { | 1068 | { |
1069 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1069 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1070 | 1070 | ||
@@ -1079,7 +1079,7 @@ static DEVICE_ATTR(vendor_id, S_IRUGO, show_tabletVendorId, NULL); | |||
1079 | /*********************************************************************** | 1079 | /*********************************************************************** |
1080 | * support routines for the 'vendor' file | 1080 | * support routines for the 'vendor' file |
1081 | */ | 1081 | */ |
1082 | static ssize_t show_tabletManufacturer(struct device *dev, char *buf) | 1082 | static ssize_t show_tabletManufacturer(struct device *dev, struct device_attribute *attr, char *buf) |
1083 | { | 1083 | { |
1084 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1084 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1085 | int retval; | 1085 | int retval; |
@@ -1096,7 +1096,7 @@ static DEVICE_ATTR(vendor, S_IRUGO, show_tabletManufacturer, NULL); | |||
1096 | /*********************************************************************** | 1096 | /*********************************************************************** |
1097 | * support routines for the 'product' file | 1097 | * support routines for the 'product' file |
1098 | */ | 1098 | */ |
1099 | static ssize_t show_tabletProduct(struct device *dev, char *buf) | 1099 | static ssize_t show_tabletProduct(struct device *dev, struct device_attribute *attr, char *buf) |
1100 | { | 1100 | { |
1101 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1101 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1102 | int retval; | 1102 | int retval; |
@@ -1114,7 +1114,7 @@ static DEVICE_ATTR(product, S_IRUGO, show_tabletProduct, NULL); | |||
1114 | * support routines for the 'pointer_mode' file. Note that this file | 1114 | * support routines for the 'pointer_mode' file. Note that this file |
1115 | * both displays current setting and allows reprogramming. | 1115 | * both displays current setting and allows reprogramming. |
1116 | */ | 1116 | */ |
1117 | static ssize_t show_tabletPointerMode(struct device *dev, char *buf) | 1117 | static ssize_t show_tabletPointerMode(struct device *dev, struct device_attribute *attr, char *buf) |
1118 | { | 1118 | { |
1119 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1119 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1120 | char *s; | 1120 | char *s; |
@@ -1143,7 +1143,7 @@ static ssize_t show_tabletPointerMode(struct device *dev, char *buf) | |||
1143 | } | 1143 | } |
1144 | 1144 | ||
1145 | static ssize_t | 1145 | static ssize_t |
1146 | store_tabletPointerMode(struct device *dev, const char *buf, size_t count) | 1146 | store_tabletPointerMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
1147 | { | 1147 | { |
1148 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1148 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1149 | if (aiptek == NULL) | 1149 | if (aiptek == NULL) |
@@ -1168,7 +1168,7 @@ static DEVICE_ATTR(pointer_mode, | |||
1168 | * support routines for the 'coordinate_mode' file. Note that this file | 1168 | * support routines for the 'coordinate_mode' file. Note that this file |
1169 | * both displays current setting and allows reprogramming. | 1169 | * both displays current setting and allows reprogramming. |
1170 | */ | 1170 | */ |
1171 | static ssize_t show_tabletCoordinateMode(struct device *dev, char *buf) | 1171 | static ssize_t show_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, char *buf) |
1172 | { | 1172 | { |
1173 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1173 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1174 | char *s; | 1174 | char *s; |
@@ -1193,7 +1193,7 @@ static ssize_t show_tabletCoordinateMode(struct device *dev, char *buf) | |||
1193 | } | 1193 | } |
1194 | 1194 | ||
1195 | static ssize_t | 1195 | static ssize_t |
1196 | store_tabletCoordinateMode(struct device *dev, const char *buf, size_t count) | 1196 | store_tabletCoordinateMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
1197 | { | 1197 | { |
1198 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1198 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1199 | if (aiptek == NULL) | 1199 | if (aiptek == NULL) |
@@ -1217,7 +1217,7 @@ static DEVICE_ATTR(coordinate_mode, | |||
1217 | * support routines for the 'tool_mode' file. Note that this file | 1217 | * support routines for the 'tool_mode' file. Note that this file |
1218 | * both displays current setting and allows reprogramming. | 1218 | * both displays current setting and allows reprogramming. |
1219 | */ | 1219 | */ |
1220 | static ssize_t show_tabletToolMode(struct device *dev, char *buf) | 1220 | static ssize_t show_tabletToolMode(struct device *dev, struct device_attribute *attr, char *buf) |
1221 | { | 1221 | { |
1222 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1222 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1223 | char *s; | 1223 | char *s; |
@@ -1262,7 +1262,7 @@ static ssize_t show_tabletToolMode(struct device *dev, char *buf) | |||
1262 | } | 1262 | } |
1263 | 1263 | ||
1264 | static ssize_t | 1264 | static ssize_t |
1265 | store_tabletToolMode(struct device *dev, const char *buf, size_t count) | 1265 | store_tabletToolMode(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
1266 | { | 1266 | { |
1267 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1267 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1268 | if (aiptek == NULL) | 1268 | if (aiptek == NULL) |
@@ -1295,7 +1295,7 @@ static DEVICE_ATTR(tool_mode, | |||
1295 | * support routines for the 'xtilt' file. Note that this file | 1295 | * support routines for the 'xtilt' file. Note that this file |
1296 | * both displays current setting and allows reprogramming. | 1296 | * both displays current setting and allows reprogramming. |
1297 | */ | 1297 | */ |
1298 | static ssize_t show_tabletXtilt(struct device *dev, char *buf) | 1298 | static ssize_t show_tabletXtilt(struct device *dev, struct device_attribute *attr, char *buf) |
1299 | { | 1299 | { |
1300 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1300 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1301 | 1301 | ||
@@ -1311,7 +1311,7 @@ static ssize_t show_tabletXtilt(struct device *dev, char *buf) | |||
1311 | } | 1311 | } |
1312 | 1312 | ||
1313 | static ssize_t | 1313 | static ssize_t |
1314 | store_tabletXtilt(struct device *dev, const char *buf, size_t count) | 1314 | store_tabletXtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
1315 | { | 1315 | { |
1316 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1316 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1317 | int x; | 1317 | int x; |
@@ -1337,7 +1337,7 @@ static DEVICE_ATTR(xtilt, | |||
1337 | * support routines for the 'ytilt' file. Note that this file | 1337 | * support routines for the 'ytilt' file. Note that this file |
1338 | * both displays current setting and allows reprogramming. | 1338 | * both displays current setting and allows reprogramming. |
1339 | */ | 1339 | */ |
1340 | static ssize_t show_tabletYtilt(struct device *dev, char *buf) | 1340 | static ssize_t show_tabletYtilt(struct device *dev, struct device_attribute *attr, char *buf) |
1341 | { | 1341 | { |
1342 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1342 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1343 | 1343 | ||
@@ -1353,7 +1353,7 @@ static ssize_t show_tabletYtilt(struct device *dev, char *buf) | |||
1353 | } | 1353 | } |
1354 | 1354 | ||
1355 | static ssize_t | 1355 | static ssize_t |
1356 | store_tabletYtilt(struct device *dev, const char *buf, size_t count) | 1356 | store_tabletYtilt(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
1357 | { | 1357 | { |
1358 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1358 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1359 | int y; | 1359 | int y; |
@@ -1379,7 +1379,7 @@ static DEVICE_ATTR(ytilt, | |||
1379 | * support routines for the 'jitter' file. Note that this file | 1379 | * support routines for the 'jitter' file. Note that this file |
1380 | * both displays current setting and allows reprogramming. | 1380 | * both displays current setting and allows reprogramming. |
1381 | */ | 1381 | */ |
1382 | static ssize_t show_tabletJitterDelay(struct device *dev, char *buf) | 1382 | static ssize_t show_tabletJitterDelay(struct device *dev, struct device_attribute *attr, char *buf) |
1383 | { | 1383 | { |
1384 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1384 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1385 | 1385 | ||
@@ -1390,7 +1390,7 @@ static ssize_t show_tabletJitterDelay(struct device *dev, char *buf) | |||
1390 | } | 1390 | } |
1391 | 1391 | ||
1392 | static ssize_t | 1392 | static ssize_t |
1393 | store_tabletJitterDelay(struct device *dev, const char *buf, size_t count) | 1393 | store_tabletJitterDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
1394 | { | 1394 | { |
1395 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1395 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1396 | 1396 | ||
@@ -1409,7 +1409,7 @@ static DEVICE_ATTR(jitter, | |||
1409 | * support routines for the 'delay' file. Note that this file | 1409 | * support routines for the 'delay' file. Note that this file |
1410 | * both displays current setting and allows reprogramming. | 1410 | * both displays current setting and allows reprogramming. |
1411 | */ | 1411 | */ |
1412 | static ssize_t show_tabletProgrammableDelay(struct device *dev, char *buf) | 1412 | static ssize_t show_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, char *buf) |
1413 | { | 1413 | { |
1414 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1414 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1415 | 1415 | ||
@@ -1421,7 +1421,7 @@ static ssize_t show_tabletProgrammableDelay(struct device *dev, char *buf) | |||
1421 | } | 1421 | } |
1422 | 1422 | ||
1423 | static ssize_t | 1423 | static ssize_t |
1424 | store_tabletProgrammableDelay(struct device *dev, const char *buf, size_t count) | 1424 | store_tabletProgrammableDelay(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
1425 | { | 1425 | { |
1426 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1426 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1427 | 1427 | ||
@@ -1440,7 +1440,7 @@ static DEVICE_ATTR(delay, | |||
1440 | * support routines for the 'input_path' file. Note that this file | 1440 | * support routines for the 'input_path' file. Note that this file |
1441 | * only displays current setting. | 1441 | * only displays current setting. |
1442 | */ | 1442 | */ |
1443 | static ssize_t show_tabletInputDevice(struct device *dev, char *buf) | 1443 | static ssize_t show_tabletInputDevice(struct device *dev, struct device_attribute *attr, char *buf) |
1444 | { | 1444 | { |
1445 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1445 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1446 | 1446 | ||
@@ -1457,7 +1457,7 @@ static DEVICE_ATTR(input_path, S_IRUGO, show_tabletInputDevice, NULL); | |||
1457 | * support routines for the 'event_count' file. Note that this file | 1457 | * support routines for the 'event_count' file. Note that this file |
1458 | * only displays current setting. | 1458 | * only displays current setting. |
1459 | */ | 1459 | */ |
1460 | static ssize_t show_tabletEventsReceived(struct device *dev, char *buf) | 1460 | static ssize_t show_tabletEventsReceived(struct device *dev, struct device_attribute *attr, char *buf) |
1461 | { | 1461 | { |
1462 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1462 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1463 | 1463 | ||
@@ -1473,7 +1473,7 @@ static DEVICE_ATTR(event_count, S_IRUGO, show_tabletEventsReceived, NULL); | |||
1473 | * support routines for the 'diagnostic' file. Note that this file | 1473 | * support routines for the 'diagnostic' file. Note that this file |
1474 | * only displays current setting. | 1474 | * only displays current setting. |
1475 | */ | 1475 | */ |
1476 | static ssize_t show_tabletDiagnosticMessage(struct device *dev, char *buf) | 1476 | static ssize_t show_tabletDiagnosticMessage(struct device *dev, struct device_attribute *attr, char *buf) |
1477 | { | 1477 | { |
1478 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1478 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1479 | char *retMsg; | 1479 | char *retMsg; |
@@ -1515,7 +1515,7 @@ static DEVICE_ATTR(diagnostic, S_IRUGO, show_tabletDiagnosticMessage, NULL); | |||
1515 | * support routines for the 'stylus_upper' file. Note that this file | 1515 | * support routines for the 'stylus_upper' file. Note that this file |
1516 | * both displays current setting and allows for setting changing. | 1516 | * both displays current setting and allows for setting changing. |
1517 | */ | 1517 | */ |
1518 | static ssize_t show_tabletStylusUpper(struct device *dev, char *buf) | 1518 | static ssize_t show_tabletStylusUpper(struct device *dev, struct device_attribute *attr, char *buf) |
1519 | { | 1519 | { |
1520 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1520 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1521 | char *s; | 1521 | char *s; |
@@ -1540,7 +1540,7 @@ static ssize_t show_tabletStylusUpper(struct device *dev, char *buf) | |||
1540 | } | 1540 | } |
1541 | 1541 | ||
1542 | static ssize_t | 1542 | static ssize_t |
1543 | store_tabletStylusUpper(struct device *dev, const char *buf, size_t count) | 1543 | store_tabletStylusUpper(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
1544 | { | 1544 | { |
1545 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1545 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1546 | 1546 | ||
@@ -1565,7 +1565,7 @@ static DEVICE_ATTR(stylus_upper, | |||
1565 | * support routines for the 'stylus_lower' file. Note that this file | 1565 | * support routines for the 'stylus_lower' file. Note that this file |
1566 | * both displays current setting and allows for setting changing. | 1566 | * both displays current setting and allows for setting changing. |
1567 | */ | 1567 | */ |
1568 | static ssize_t show_tabletStylusLower(struct device *dev, char *buf) | 1568 | static ssize_t show_tabletStylusLower(struct device *dev, struct device_attribute *attr, char *buf) |
1569 | { | 1569 | { |
1570 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1570 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1571 | char *s; | 1571 | char *s; |
@@ -1590,7 +1590,7 @@ static ssize_t show_tabletStylusLower(struct device *dev, char *buf) | |||
1590 | } | 1590 | } |
1591 | 1591 | ||
1592 | static ssize_t | 1592 | static ssize_t |
1593 | store_tabletStylusLower(struct device *dev, const char *buf, size_t count) | 1593 | store_tabletStylusLower(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
1594 | { | 1594 | { |
1595 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1595 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1596 | 1596 | ||
@@ -1615,7 +1615,7 @@ static DEVICE_ATTR(stylus_lower, | |||
1615 | * support routines for the 'mouse_left' file. Note that this file | 1615 | * support routines for the 'mouse_left' file. Note that this file |
1616 | * both displays current setting and allows for setting changing. | 1616 | * both displays current setting and allows for setting changing. |
1617 | */ | 1617 | */ |
1618 | static ssize_t show_tabletMouseLeft(struct device *dev, char *buf) | 1618 | static ssize_t show_tabletMouseLeft(struct device *dev, struct device_attribute *attr, char *buf) |
1619 | { | 1619 | { |
1620 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1620 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1621 | char *s; | 1621 | char *s; |
@@ -1644,7 +1644,7 @@ static ssize_t show_tabletMouseLeft(struct device *dev, char *buf) | |||
1644 | } | 1644 | } |
1645 | 1645 | ||
1646 | static ssize_t | 1646 | static ssize_t |
1647 | store_tabletMouseLeft(struct device *dev, const char *buf, size_t count) | 1647 | store_tabletMouseLeft(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
1648 | { | 1648 | { |
1649 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1649 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1650 | 1650 | ||
@@ -1669,7 +1669,7 @@ static DEVICE_ATTR(mouse_left, | |||
1669 | * support routines for the 'mouse_middle' file. Note that this file | 1669 | * support routines for the 'mouse_middle' file. Note that this file |
1670 | * both displays current setting and allows for setting changing. | 1670 | * both displays current setting and allows for setting changing. |
1671 | */ | 1671 | */ |
1672 | static ssize_t show_tabletMouseMiddle(struct device *dev, char *buf) | 1672 | static ssize_t show_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, char *buf) |
1673 | { | 1673 | { |
1674 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1674 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1675 | char *s; | 1675 | char *s; |
@@ -1698,7 +1698,7 @@ static ssize_t show_tabletMouseMiddle(struct device *dev, char *buf) | |||
1698 | } | 1698 | } |
1699 | 1699 | ||
1700 | static ssize_t | 1700 | static ssize_t |
1701 | store_tabletMouseMiddle(struct device *dev, const char *buf, size_t count) | 1701 | store_tabletMouseMiddle(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
1702 | { | 1702 | { |
1703 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1703 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1704 | 1704 | ||
@@ -1725,7 +1725,7 @@ static DEVICE_ATTR(mouse_middle, | |||
1725 | * support routines for the 'mouse_right' file. Note that this file | 1725 | * support routines for the 'mouse_right' file. Note that this file |
1726 | * both displays current setting and allows for setting changing. | 1726 | * both displays current setting and allows for setting changing. |
1727 | */ | 1727 | */ |
1728 | static ssize_t show_tabletMouseRight(struct device *dev, char *buf) | 1728 | static ssize_t show_tabletMouseRight(struct device *dev, struct device_attribute *attr, char *buf) |
1729 | { | 1729 | { |
1730 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1730 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1731 | char *s; | 1731 | char *s; |
@@ -1754,7 +1754,7 @@ static ssize_t show_tabletMouseRight(struct device *dev, char *buf) | |||
1754 | } | 1754 | } |
1755 | 1755 | ||
1756 | static ssize_t | 1756 | static ssize_t |
1757 | store_tabletMouseRight(struct device *dev, const char *buf, size_t count) | 1757 | store_tabletMouseRight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
1758 | { | 1758 | { |
1759 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1759 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1760 | 1760 | ||
@@ -1780,7 +1780,7 @@ static DEVICE_ATTR(mouse_right, | |||
1780 | * support routines for the 'wheel' file. Note that this file | 1780 | * support routines for the 'wheel' file. Note that this file |
1781 | * both displays current setting and allows for setting changing. | 1781 | * both displays current setting and allows for setting changing. |
1782 | */ | 1782 | */ |
1783 | static ssize_t show_tabletWheel(struct device *dev, char *buf) | 1783 | static ssize_t show_tabletWheel(struct device *dev, struct device_attribute *attr, char *buf) |
1784 | { | 1784 | { |
1785 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1785 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1786 | 1786 | ||
@@ -1796,7 +1796,7 @@ static ssize_t show_tabletWheel(struct device *dev, char *buf) | |||
1796 | } | 1796 | } |
1797 | 1797 | ||
1798 | static ssize_t | 1798 | static ssize_t |
1799 | store_tabletWheel(struct device *dev, const char *buf, size_t count) | 1799 | store_tabletWheel(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
1800 | { | 1800 | { |
1801 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1801 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1802 | 1802 | ||
@@ -1814,7 +1814,7 @@ static DEVICE_ATTR(wheel, | |||
1814 | * support routines for the 'execute' file. Note that this file | 1814 | * support routines for the 'execute' file. Note that this file |
1815 | * both displays current setting and allows for setting changing. | 1815 | * both displays current setting and allows for setting changing. |
1816 | */ | 1816 | */ |
1817 | static ssize_t show_tabletExecute(struct device *dev, char *buf) | 1817 | static ssize_t show_tabletExecute(struct device *dev, struct device_attribute *attr, char *buf) |
1818 | { | 1818 | { |
1819 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1819 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1820 | 1820 | ||
@@ -1829,7 +1829,7 @@ static ssize_t show_tabletExecute(struct device *dev, char *buf) | |||
1829 | } | 1829 | } |
1830 | 1830 | ||
1831 | static ssize_t | 1831 | static ssize_t |
1832 | store_tabletExecute(struct device *dev, const char *buf, size_t count) | 1832 | store_tabletExecute(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
1833 | { | 1833 | { |
1834 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1834 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1835 | 1835 | ||
@@ -1855,7 +1855,7 @@ static DEVICE_ATTR(execute, | |||
1855 | * support routines for the 'odm_code' file. Note that this file | 1855 | * support routines for the 'odm_code' file. Note that this file |
1856 | * only displays current setting. | 1856 | * only displays current setting. |
1857 | */ | 1857 | */ |
1858 | static ssize_t show_tabletODMCode(struct device *dev, char *buf) | 1858 | static ssize_t show_tabletODMCode(struct device *dev, struct device_attribute *attr, char *buf) |
1859 | { | 1859 | { |
1860 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1860 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1861 | 1861 | ||
@@ -1871,7 +1871,7 @@ static DEVICE_ATTR(odm_code, S_IRUGO, show_tabletODMCode, NULL); | |||
1871 | * support routines for the 'model_code' file. Note that this file | 1871 | * support routines for the 'model_code' file. Note that this file |
1872 | * only displays current setting. | 1872 | * only displays current setting. |
1873 | */ | 1873 | */ |
1874 | static ssize_t show_tabletModelCode(struct device *dev, char *buf) | 1874 | static ssize_t show_tabletModelCode(struct device *dev, struct device_attribute *attr, char *buf) |
1875 | { | 1875 | { |
1876 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1876 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1877 | 1877 | ||
@@ -1887,7 +1887,7 @@ static DEVICE_ATTR(model_code, S_IRUGO, show_tabletModelCode, NULL); | |||
1887 | * support routines for the 'firmware_code' file. Note that this file | 1887 | * support routines for the 'firmware_code' file. Note that this file |
1888 | * only displays current setting. | 1888 | * only displays current setting. |
1889 | */ | 1889 | */ |
1890 | static ssize_t show_firmwareCode(struct device *dev, char *buf) | 1890 | static ssize_t show_firmwareCode(struct device *dev, struct device_attribute *attr, char *buf) |
1891 | { | 1891 | { |
1892 | struct aiptek *aiptek = dev_get_drvdata(dev); | 1892 | struct aiptek *aiptek = dev_get_drvdata(dev); |
1893 | 1893 | ||
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 869ff73690ac..2d8bd9dcc6ed 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c | |||
@@ -1315,6 +1315,8 @@ void hid_init_reports(struct hid_device *hid) | |||
1315 | #define USB_DEVICE_ID_WACOM_INTUOS2 0x0040 | 1315 | #define USB_DEVICE_ID_WACOM_INTUOS2 0x0040 |
1316 | #define USB_DEVICE_ID_WACOM_VOLITO 0x0060 | 1316 | #define USB_DEVICE_ID_WACOM_VOLITO 0x0060 |
1317 | #define USB_DEVICE_ID_WACOM_PTU 0x0003 | 1317 | #define USB_DEVICE_ID_WACOM_PTU 0x0003 |
1318 | #define USB_DEVICE_ID_WACOM_INTUOS3 0x00B0 | ||
1319 | #define USB_DEVICE_ID_WACOM_CINTIQ 0x003F | ||
1318 | 1320 | ||
1319 | #define USB_VENDOR_ID_KBGEAR 0x084e | 1321 | #define USB_VENDOR_ID_KBGEAR 0x084e |
1320 | #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 | 1322 | #define USB_DEVICE_ID_KBGEAR_JAMSTUDIO 0x1001 |
@@ -1401,6 +1403,7 @@ void hid_init_reports(struct hid_device *hid) | |||
1401 | 1403 | ||
1402 | #define USB_VENDOR_ID_DELORME 0x1163 | 1404 | #define USB_VENDOR_ID_DELORME 0x1163 |
1403 | #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 | 1405 | #define USB_DEVICE_ID_DELORME_EARTHMATE 0x0100 |
1406 | #define USB_DEVICE_ID_DELORME_EM_LT20 0x0200 | ||
1404 | 1407 | ||
1405 | #define USB_VENDOR_ID_MCC 0x09db | 1408 | #define USB_VENDOR_ID_MCC 0x09db |
1406 | #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 | 1409 | #define USB_DEVICE_ID_MCC_PMD1024LS 0x0076 |
@@ -1412,6 +1415,12 @@ void hid_init_reports(struct hid_device *hid) | |||
1412 | #define USB_VENDOR_ID_BTC 0x046e | 1415 | #define USB_VENDOR_ID_BTC 0x046e |
1413 | #define USB_DEVICE_ID_BTC_KEYBOARD 0x5303 | 1416 | #define USB_DEVICE_ID_BTC_KEYBOARD 0x5303 |
1414 | 1417 | ||
1418 | #define USB_VENDOR_ID_VERNIER 0x08f7 | ||
1419 | #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 | ||
1420 | #define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 | ||
1421 | #define USB_DEVICE_ID_VERNIER_SKIP 0x0003 | ||
1422 | #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 | ||
1423 | |||
1415 | 1424 | ||
1416 | /* | 1425 | /* |
1417 | * Alphabetically sorted blacklist by quirk type. | 1426 | * Alphabetically sorted blacklist by quirk type. |
@@ -1437,6 +1446,7 @@ static struct hid_blacklist { | |||
1437 | { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE }, | 1446 | { USB_VENDOR_ID_CODEMERCS, USB_DEVICE_ID_CODEMERCS_IOW28, HID_QUIRK_IGNORE }, |
1438 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE }, | 1447 | { USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_HIDCOM, HID_QUIRK_IGNORE }, |
1439 | { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE }, | 1448 | { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EARTHMATE, HID_QUIRK_IGNORE }, |
1449 | { USB_VENDOR_ID_DELORME, USB_DEVICE_ID_DELORME_EM_LT20, HID_QUIRK_IGNORE }, | ||
1440 | { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE }, | 1450 | { USB_VENDOR_ID_ESSENTIAL_REALITY, USB_DEVICE_ID_ESSENTIAL_REALITY_P5, HID_QUIRK_IGNORE }, |
1441 | { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, | 1451 | { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_4_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, |
1442 | { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, | 1452 | { USB_VENDOR_ID_GLAB, USB_DEVICE_ID_1_PHIDGETSERVO_30, HID_QUIRK_IGNORE }, |
@@ -1456,6 +1466,10 @@ static struct hid_blacklist { | |||
1456 | { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE }, | 1466 | { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 300, HID_QUIRK_IGNORE }, |
1457 | { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE }, | 1467 | { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 400, HID_QUIRK_IGNORE }, |
1458 | { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE }, | 1468 | { USB_VENDOR_ID_ONTRAK, USB_DEVICE_ID_ONTRAK_ADU100 + 500, HID_QUIRK_IGNORE }, |
1469 | { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO, HID_QUIRK_IGNORE }, | ||
1470 | { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP, HID_QUIRK_IGNORE }, | ||
1471 | { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP, HID_QUIRK_IGNORE }, | ||
1472 | { USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS, HID_QUIRK_IGNORE }, | ||
1459 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PENPARTNER, HID_QUIRK_IGNORE }, | 1473 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PENPARTNER, HID_QUIRK_IGNORE }, |
1460 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE, HID_QUIRK_IGNORE }, | 1474 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE, HID_QUIRK_IGNORE }, |
1461 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 1, HID_QUIRK_IGNORE }, | 1475 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_GRAPHIRE + 1, HID_QUIRK_IGNORE }, |
@@ -1481,6 +1495,10 @@ static struct hid_blacklist { | |||
1481 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 7, HID_QUIRK_IGNORE }, | 1495 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS2 + 7, HID_QUIRK_IGNORE }, |
1482 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO, HID_QUIRK_IGNORE }, | 1496 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_VOLITO, HID_QUIRK_IGNORE }, |
1483 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PTU, HID_QUIRK_IGNORE }, | 1497 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_PTU, HID_QUIRK_IGNORE }, |
1498 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3, HID_QUIRK_IGNORE }, | ||
1499 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 1, HID_QUIRK_IGNORE }, | ||
1500 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_INTUOS3 + 2, HID_QUIRK_IGNORE }, | ||
1501 | { USB_VENDOR_ID_WACOM, USB_DEVICE_ID_WACOM_CINTIQ, HID_QUIRK_IGNORE }, | ||
1484 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, | 1502 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_4_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, |
1485 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, | 1503 | { USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_1_PHIDGETSERVO_20, HID_QUIRK_IGNORE }, |
1486 | 1504 | ||
diff --git a/drivers/usb/media/pwc/ChangeLog b/drivers/usb/media/pwc/ChangeLog deleted file mode 100644 index b2eb71a9afb5..000000000000 --- a/drivers/usb/media/pwc/ChangeLog +++ /dev/null | |||
@@ -1,143 +0,0 @@ | |||
1 | 9.0.2 | ||
2 | |||
3 | * Adding #ifdef to compile PWC before and after 2.6.5 | ||
4 | |||
5 | 9.0.1 | ||
6 | |||
7 | 9.0 | ||
8 | |||
9 | |||
10 | 8.12 | ||
11 | |||
12 | * Implement motorized pan/tilt feature for Logitech QuickCam Orbit/Spere. | ||
13 | |||
14 | 8.11.1 | ||
15 | |||
16 | * Fix for PCVC720/40, would not be able to set videomode | ||
17 | * Fix for Samsung MPC models, appearantly they are based on a newer chipset | ||
18 | |||
19 | 8.11 | ||
20 | |||
21 | * 20 dev_hints (per request) | ||
22 | * Hot unplugging should be better, no more dangling pointers or memory leaks | ||
23 | * Added reserved Logitech webcam IDs | ||
24 | * Device now remembers size & fps between close()/open() | ||
25 | * Removed palette stuff altogether | ||
26 | |||
27 | 8.10.1 | ||
28 | |||
29 | * Added IDs for PCVC720K/40 and Creative Labs Webcam Pro | ||
30 | |||
31 | 8.10 | ||
32 | |||
33 | * Fixed ID for QuickCam Notebook pro | ||
34 | * Added GREALSIZE ioctl() call | ||
35 | * Fixed bug in case PWCX was not loaded and invalid size was set | ||
36 | |||
37 | 8.9 | ||
38 | |||
39 | * Merging with kernel 2.5.49 | ||
40 | * Adding IDs for QuickCam Zoom & QuickCam Notebook | ||
41 | |||
42 | 8.8 | ||
43 | |||
44 | * Fixing 'leds' parameter | ||
45 | * Adding IDs for Logitech QuickCam Pro 4000 | ||
46 | * Making URB init/cleanup a little nicer | ||
47 | |||
48 | 8.7 | ||
49 | |||
50 | * Incorporating changes in ioctl() parameter passing | ||
51 | * Also changes to URB mechanism | ||
52 | |||
53 | 8.6 | ||
54 | |||
55 | * Added ID's for Visionite VCS UM100 and UC300 | ||
56 | * Removed YUV420-interlaced palette altogether (was confusing) | ||
57 | * Removed MIRROR stuff as it didn't work anyway | ||
58 | * Fixed a problem with the 'leds' parameter (wouldn't blink) | ||
59 | * Added ioctl()s for advanced features: 'extended' whitebalance ioctl()s, | ||
60 | CONTOUR, BACKLIGHT, FLICKER, DYNNOISE. | ||
61 | * VIDIOCGCAP.name now contains real camera model name instead of | ||
62 | 'Philips xxx webcam' | ||
63 | * Added PROBE ioctl (see previous point & API doc) | ||
64 | |||
65 | 8.5 | ||
66 | |||
67 | * Adding IDs for Creative Labs Webcam 5 | ||
68 | * Adding IDs for SOTEC CMS-001 webcam | ||
69 | * Solving possible hang in VIDIOCSYNC when unplugging the cam | ||
70 | * Forgot to return structure in VIDIOCPWCGAWB, oops | ||
71 | * Time interval for the LEDs are now in milliseconds | ||
72 | |||
73 | 8.4 | ||
74 | |||
75 | * Fixing power_save option for Vesta range | ||
76 | * Handling new error codes in ISOC callback | ||
77 | * Adding dev_hint module parameter, to specify /dev/videoX device nodes | ||
78 | |||
79 | 8.3 | ||
80 | |||
81 | * Adding Samsung C10 and C30 cameras | ||
82 | * Removing palette module parameter | ||
83 | * Fixed typo in ID of QuickCam 3000 Pro | ||
84 | * Adding LED settings (blinking while in use) for ToUCam cameras. | ||
85 | * Turns LED off when camera is not in use. | ||
86 | |||
87 | 8.2 | ||
88 | |||
89 | * Making module more silent when trace = 0 | ||
90 | * Adding QuickCam 3000 Pro IDs | ||
91 | * Chrominance control for the Vesta cameras | ||
92 | * Hopefully fixed problems on machines with BIGMEM and > 1GB of RAM | ||
93 | * Included Oliver Neukem's lock_kernel() patch | ||
94 | * Allocates less memory for image buffers | ||
95 | * Adds ioctl()s for the whitebalancing | ||
96 | |||
97 | 8.1 | ||
98 | |||
99 | * Adding support for 750 | ||
100 | * Adding V4L GAUDIO/SAUDIO/UNIT ioctl() calls | ||
101 | |||
102 | 8.0 | ||
103 | * 'damage control' after inclusion in 2.4.5. | ||
104 | * Changed wait-queue mechanism in read/mmap/poll according to the book. | ||
105 | * Included YUV420P palette. | ||
106 | * Changed interface to decompressor module. | ||
107 | * Cleaned up pwc structure a bit. | ||
108 | |||
109 | 7.0 | ||
110 | |||
111 | * Fixed bug in vcvt_420i_yuyv; extra variables on stack were misaligned. | ||
112 | * There is now a clear error message when an image size is selected that | ||
113 | is only supported using the decompressor, and the decompressor isn't | ||
114 | loaded. | ||
115 | * When the decompressor wasn't loaded, selecting large image size | ||
116 | would create skewed or double images. | ||
117 | |||
118 | 6.3 | ||
119 | |||
120 | * Introduced spinlocks for the buffer pointer manipulation; a number of | ||
121 | reports seem to suggest the down()/up() semaphores were the cause of | ||
122 | lockups, since they are not suitable for interrupt/user locking. | ||
123 | * Separated decompressor and core code into 2 modules. | ||
124 | |||
125 | 6.2 | ||
126 | |||
127 | * Non-integral image sizes are now padded with gray or black. | ||
128 | * Added SHUTTERSPEED ioctl(). | ||
129 | * Fixed buglet in VIDIOCPWCSAGC; the function would always return an error, | ||
130 | even though the call succeeded. | ||
131 | * Added hotplug support for 2.4.*. | ||
132 | * Memory: the 645/646 uses less memory now. | ||
133 | |||
134 | 6.1 | ||
135 | |||
136 | * VIDIOCSPICT returns -EINVAL with invalid palettes. | ||
137 | * Added saturation control. | ||
138 | * Split decompressors from rest. | ||
139 | * Fixed bug that would reset the framerate to the default framerate if | ||
140 | the rate field was set to 0 (which is not what I intended, nl. do not | ||
141 | change the framerate!). | ||
142 | * VIDIOCPWCSCQUAL (setting compression quality) now takes effect immediately. | ||
143 | * Workaround for a bug in the 730 sensor. | ||
diff --git a/drivers/usb/media/pwc/pwc-ctrl.c b/drivers/usb/media/pwc/pwc-ctrl.c index 3e1e4fe20d85..53099190952c 100644 --- a/drivers/usb/media/pwc/pwc-ctrl.c +++ b/drivers/usb/media/pwc/pwc-ctrl.c | |||
@@ -48,8 +48,6 @@ | |||
48 | #include "pwc-uncompress.h" | 48 | #include "pwc-uncompress.h" |
49 | #include "pwc-kiara.h" | 49 | #include "pwc-kiara.h" |
50 | #include "pwc-timon.h" | 50 | #include "pwc-timon.h" |
51 | #include "pwc-dec1.h" | ||
52 | #include "pwc-dec23.h" | ||
53 | 51 | ||
54 | /* Request types: video */ | 52 | /* Request types: video */ |
55 | #define SET_LUM_CTL 0x01 | 53 | #define SET_LUM_CTL 0x01 |
diff --git a/drivers/usb/media/pwc/pwc-if.c b/drivers/usb/media/pwc/pwc-if.c index 5429ff3b9753..b77e65c03659 100644 --- a/drivers/usb/media/pwc/pwc-if.c +++ b/drivers/usb/media/pwc/pwc-if.c | |||
@@ -332,10 +332,6 @@ static int pwc_allocate_buffers(struct pwc_device *pdev) | |||
332 | #endif | 332 | #endif |
333 | ; | 333 | ; |
334 | } | 334 | } |
335 | if (kbuf == NULL) { | ||
336 | Err("Failed to allocate decompress table.\n"); | ||
337 | return -ENOMEM; | ||
338 | } | ||
339 | pdev->decompress_data = kbuf; | 335 | pdev->decompress_data = kbuf; |
340 | 336 | ||
341 | /* Allocate image buffer; double buffer for mmap() */ | 337 | /* Allocate image buffer; double buffer for mmap() */ |
diff --git a/drivers/usb/media/pwc/pwc-uncompress.c b/drivers/usb/media/pwc/pwc-uncompress.c index c596083f06ba..bc3b1635eab0 100644 --- a/drivers/usb/media/pwc/pwc-uncompress.c +++ b/drivers/usb/media/pwc/pwc-uncompress.c | |||
@@ -29,8 +29,6 @@ | |||
29 | 29 | ||
30 | #include "pwc.h" | 30 | #include "pwc.h" |
31 | #include "pwc-uncompress.h" | 31 | #include "pwc-uncompress.h" |
32 | #include "pwc-dec1.h" | ||
33 | #include "pwc-dec23.h" | ||
34 | 32 | ||
35 | int pwc_decompress(struct pwc_device *pdev) | 33 | int pwc_decompress(struct pwc_device *pdev) |
36 | { | 34 | { |
diff --git a/drivers/usb/misc/cytherm.c b/drivers/usb/misc/cytherm.c index 626e2b05f719..b33044d56a1e 100644 --- a/drivers/usb/misc/cytherm.c +++ b/drivers/usb/misc/cytherm.c | |||
@@ -85,7 +85,7 @@ static int vendor_command(struct usb_device *dev, unsigned char request, | |||
85 | #define BRIGHTNESS 0x2c /* RAM location for brightness value */ | 85 | #define BRIGHTNESS 0x2c /* RAM location for brightness value */ |
86 | #define BRIGHTNESS_SEM 0x2b /* RAM location for brightness semaphore */ | 86 | #define BRIGHTNESS_SEM 0x2b /* RAM location for brightness semaphore */ |
87 | 87 | ||
88 | static ssize_t show_brightness(struct device *dev, char *buf) | 88 | static ssize_t show_brightness(struct device *dev, struct device_attribute *attr, char *buf) |
89 | { | 89 | { |
90 | struct usb_interface *intf = to_usb_interface(dev); | 90 | struct usb_interface *intf = to_usb_interface(dev); |
91 | struct usb_cytherm *cytherm = usb_get_intfdata(intf); | 91 | struct usb_cytherm *cytherm = usb_get_intfdata(intf); |
@@ -93,7 +93,7 @@ static ssize_t show_brightness(struct device *dev, char *buf) | |||
93 | return sprintf(buf, "%i", cytherm->brightness); | 93 | return sprintf(buf, "%i", cytherm->brightness); |
94 | } | 94 | } |
95 | 95 | ||
96 | static ssize_t set_brightness(struct device *dev, const char *buf, | 96 | static ssize_t set_brightness(struct device *dev, struct device_attribute *attr, const char *buf, |
97 | size_t count) | 97 | size_t count) |
98 | { | 98 | { |
99 | struct usb_interface *intf = to_usb_interface(dev); | 99 | struct usb_interface *intf = to_usb_interface(dev); |
@@ -138,7 +138,7 @@ static DEVICE_ATTR(brightness, S_IRUGO | S_IWUSR | S_IWGRP, | |||
138 | #define TEMP 0x33 /* RAM location for temperature */ | 138 | #define TEMP 0x33 /* RAM location for temperature */ |
139 | #define SIGN 0x34 /* RAM location for temperature sign */ | 139 | #define SIGN 0x34 /* RAM location for temperature sign */ |
140 | 140 | ||
141 | static ssize_t show_temp(struct device *dev, char *buf) | 141 | static ssize_t show_temp(struct device *dev, struct device_attribute *attr, char *buf) |
142 | { | 142 | { |
143 | 143 | ||
144 | struct usb_interface *intf = to_usb_interface(dev); | 144 | struct usb_interface *intf = to_usb_interface(dev); |
@@ -174,7 +174,7 @@ static ssize_t show_temp(struct device *dev, char *buf) | |||
174 | } | 174 | } |
175 | 175 | ||
176 | 176 | ||
177 | static ssize_t set_temp(struct device *dev, const char *buf, size_t count) | 177 | static ssize_t set_temp(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
178 | { | 178 | { |
179 | return count; | 179 | return count; |
180 | } | 180 | } |
@@ -184,7 +184,7 @@ static DEVICE_ATTR(temp, S_IRUGO, show_temp, set_temp); | |||
184 | 184 | ||
185 | #define BUTTON 0x7a | 185 | #define BUTTON 0x7a |
186 | 186 | ||
187 | static ssize_t show_button(struct device *dev, char *buf) | 187 | static ssize_t show_button(struct device *dev, struct device_attribute *attr, char *buf) |
188 | { | 188 | { |
189 | 189 | ||
190 | struct usb_interface *intf = to_usb_interface(dev); | 190 | struct usb_interface *intf = to_usb_interface(dev); |
@@ -215,7 +215,7 @@ static ssize_t show_button(struct device *dev, char *buf) | |||
215 | } | 215 | } |
216 | 216 | ||
217 | 217 | ||
218 | static ssize_t set_button(struct device *dev, const char *buf, size_t count) | 218 | static ssize_t set_button(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
219 | { | 219 | { |
220 | return count; | 220 | return count; |
221 | } | 221 | } |
@@ -223,7 +223,7 @@ static ssize_t set_button(struct device *dev, const char *buf, size_t count) | |||
223 | static DEVICE_ATTR(button, S_IRUGO, show_button, set_button); | 223 | static DEVICE_ATTR(button, S_IRUGO, show_button, set_button); |
224 | 224 | ||
225 | 225 | ||
226 | static ssize_t show_port0(struct device *dev, char *buf) | 226 | static ssize_t show_port0(struct device *dev, struct device_attribute *attr, char *buf) |
227 | { | 227 | { |
228 | struct usb_interface *intf = to_usb_interface(dev); | 228 | struct usb_interface *intf = to_usb_interface(dev); |
229 | struct usb_cytherm *cytherm = usb_get_intfdata(intf); | 229 | struct usb_cytherm *cytherm = usb_get_intfdata(intf); |
@@ -249,7 +249,7 @@ static ssize_t show_port0(struct device *dev, char *buf) | |||
249 | } | 249 | } |
250 | 250 | ||
251 | 251 | ||
252 | static ssize_t set_port0(struct device *dev, const char *buf, size_t count) | 252 | static ssize_t set_port0(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
253 | { | 253 | { |
254 | struct usb_interface *intf = to_usb_interface(dev); | 254 | struct usb_interface *intf = to_usb_interface(dev); |
255 | struct usb_cytherm *cytherm = usb_get_intfdata(intf); | 255 | struct usb_cytherm *cytherm = usb_get_intfdata(intf); |
@@ -283,7 +283,7 @@ static ssize_t set_port0(struct device *dev, const char *buf, size_t count) | |||
283 | 283 | ||
284 | static DEVICE_ATTR(port0, S_IRUGO | S_IWUSR | S_IWGRP, show_port0, set_port0); | 284 | static DEVICE_ATTR(port0, S_IRUGO | S_IWUSR | S_IWGRP, show_port0, set_port0); |
285 | 285 | ||
286 | static ssize_t show_port1(struct device *dev, char *buf) | 286 | static ssize_t show_port1(struct device *dev, struct device_attribute *attr, char *buf) |
287 | { | 287 | { |
288 | struct usb_interface *intf = to_usb_interface(dev); | 288 | struct usb_interface *intf = to_usb_interface(dev); |
289 | struct usb_cytherm *cytherm = usb_get_intfdata(intf); | 289 | struct usb_cytherm *cytherm = usb_get_intfdata(intf); |
@@ -309,7 +309,7 @@ static ssize_t show_port1(struct device *dev, char *buf) | |||
309 | } | 309 | } |
310 | 310 | ||
311 | 311 | ||
312 | static ssize_t set_port1(struct device *dev, const char *buf, size_t count) | 312 | static ssize_t set_port1(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
313 | { | 313 | { |
314 | struct usb_interface *intf = to_usb_interface(dev); | 314 | struct usb_interface *intf = to_usb_interface(dev); |
315 | struct usb_cytherm *cytherm = usb_get_intfdata(intf); | 315 | struct usb_cytherm *cytherm = usb_get_intfdata(intf); |
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c index ddbf8e992368..067a81486921 100644 --- a/drivers/usb/misc/phidgetkit.c +++ b/drivers/usb/misc/phidgetkit.c | |||
@@ -173,7 +173,7 @@ exit: | |||
173 | } | 173 | } |
174 | 174 | ||
175 | #define set_lcd_line(number) \ | 175 | #define set_lcd_line(number) \ |
176 | static ssize_t lcd_line_##number(struct device *dev, const char *buf, size_t count) \ | 176 | static ssize_t lcd_line_##number(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ |
177 | { \ | 177 | { \ |
178 | struct usb_interface *intf = to_usb_interface(dev); \ | 178 | struct usb_interface *intf = to_usb_interface(dev); \ |
179 | struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ | 179 | struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ |
@@ -184,7 +184,7 @@ static DEVICE_ATTR(lcd_line_##number, S_IWUGO, NULL, lcd_line_##number); | |||
184 | set_lcd_line(1); | 184 | set_lcd_line(1); |
185 | set_lcd_line(2); | 185 | set_lcd_line(2); |
186 | 186 | ||
187 | static ssize_t set_backlight(struct device *dev, const char *buf, size_t count) | 187 | static ssize_t set_backlight(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
188 | { | 188 | { |
189 | struct usb_interface *intf = to_usb_interface(dev); | 189 | struct usb_interface *intf = to_usb_interface(dev); |
190 | struct phidget_interfacekit *kit = usb_get_intfdata(intf); | 190 | struct phidget_interfacekit *kit = usb_get_intfdata(intf); |
@@ -232,7 +232,7 @@ static void remove_lcd_files(struct phidget_interfacekit *kit) | |||
232 | } | 232 | } |
233 | } | 233 | } |
234 | 234 | ||
235 | static ssize_t enable_lcd_files(struct device *dev, const char *buf, size_t count) | 235 | static ssize_t enable_lcd_files(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
236 | { | 236 | { |
237 | struct usb_interface *intf = to_usb_interface(dev); | 237 | struct usb_interface *intf = to_usb_interface(dev); |
238 | struct phidget_interfacekit *kit = usb_get_intfdata(intf); | 238 | struct phidget_interfacekit *kit = usb_get_intfdata(intf); |
@@ -307,7 +307,7 @@ resubmit: | |||
307 | } | 307 | } |
308 | 308 | ||
309 | #define show_set_output(value) \ | 309 | #define show_set_output(value) \ |
310 | static ssize_t set_output##value(struct device *dev, const char *buf, \ | 310 | static ssize_t set_output##value(struct device *dev, struct device_attribute *attr, const char *buf, \ |
311 | size_t count) \ | 311 | size_t count) \ |
312 | { \ | 312 | { \ |
313 | struct usb_interface *intf = to_usb_interface(dev); \ | 313 | struct usb_interface *intf = to_usb_interface(dev); \ |
@@ -324,7 +324,7 @@ static ssize_t set_output##value(struct device *dev, const char *buf, \ | |||
324 | return retval ? retval : count; \ | 324 | return retval ? retval : count; \ |
325 | } \ | 325 | } \ |
326 | \ | 326 | \ |
327 | static ssize_t show_output##value(struct device *dev, char *buf) \ | 327 | static ssize_t show_output##value(struct device *dev, struct device_attribute *attr, char *buf) \ |
328 | { \ | 328 | { \ |
329 | struct usb_interface *intf = to_usb_interface(dev); \ | 329 | struct usb_interface *intf = to_usb_interface(dev); \ |
330 | struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ | 330 | struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ |
@@ -343,7 +343,7 @@ show_set_output(7); | |||
343 | show_set_output(8); /* should be MAX_INTERFACES - 1 */ | 343 | show_set_output(8); /* should be MAX_INTERFACES - 1 */ |
344 | 344 | ||
345 | #define show_input(value) \ | 345 | #define show_input(value) \ |
346 | static ssize_t show_input##value(struct device *dev, char *buf) \ | 346 | static ssize_t show_input##value(struct device *dev, struct device_attribute *attr, char *buf) \ |
347 | { \ | 347 | { \ |
348 | struct usb_interface *intf = to_usb_interface(dev); \ | 348 | struct usb_interface *intf = to_usb_interface(dev); \ |
349 | struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ | 349 | struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ |
@@ -362,7 +362,7 @@ show_input(7); | |||
362 | show_input(8); /* should be MAX_INTERFACES - 1 */ | 362 | show_input(8); /* should be MAX_INTERFACES - 1 */ |
363 | 363 | ||
364 | #define show_sensor(value) \ | 364 | #define show_sensor(value) \ |
365 | static ssize_t show_sensor##value(struct device *dev, char *buf) \ | 365 | static ssize_t show_sensor##value(struct device *dev, struct device_attribute *attr, char *buf) \ |
366 | { \ | 366 | { \ |
367 | struct usb_interface *intf = to_usb_interface(dev); \ | 367 | struct usb_interface *intf = to_usb_interface(dev); \ |
368 | struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ | 368 | struct phidget_interfacekit *kit = usb_get_intfdata(intf); \ |
diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c index 4bd291502a3c..b84eda631ab5 100644 --- a/drivers/usb/misc/phidgetservo.c +++ b/drivers/usb/misc/phidgetservo.c | |||
@@ -207,7 +207,7 @@ change_position_v20(struct phidget_servo *servo, int servo_no, int degrees, | |||
207 | } | 207 | } |
208 | 208 | ||
209 | #define show_set(value) \ | 209 | #define show_set(value) \ |
210 | static ssize_t set_servo##value (struct device *dev, \ | 210 | static ssize_t set_servo##value (struct device *dev, struct device_attribute *attr, \ |
211 | const char *buf, size_t count) \ | 211 | const char *buf, size_t count) \ |
212 | { \ | 212 | { \ |
213 | int degrees, minutes, retval; \ | 213 | int degrees, minutes, retval; \ |
@@ -233,7 +233,7 @@ static ssize_t set_servo##value (struct device *dev, \ | |||
233 | return retval < 0 ? retval : count; \ | 233 | return retval < 0 ? retval : count; \ |
234 | } \ | 234 | } \ |
235 | \ | 235 | \ |
236 | static ssize_t show_servo##value (struct device *dev, char *buf) \ | 236 | static ssize_t show_servo##value (struct device *dev, struct device_attribute *attr, char *buf) \ |
237 | { \ | 237 | { \ |
238 | struct usb_interface *intf = to_usb_interface (dev); \ | 238 | struct usb_interface *intf = to_usb_interface (dev); \ |
239 | struct phidget_servo *servo = usb_get_intfdata (intf); \ | 239 | struct phidget_servo *servo = usb_get_intfdata (intf); \ |
diff --git a/drivers/usb/misc/usbled.c b/drivers/usb/misc/usbled.c index ee329d5e1c5e..f6ba4c788dbc 100644 --- a/drivers/usb/misc/usbled.c +++ b/drivers/usb/misc/usbled.c | |||
@@ -81,14 +81,14 @@ static void change_color(struct usb_led *led) | |||
81 | } | 81 | } |
82 | 82 | ||
83 | #define show_set(value) \ | 83 | #define show_set(value) \ |
84 | static ssize_t show_##value(struct device *dev, char *buf) \ | 84 | static ssize_t show_##value(struct device *dev, struct device_attribute *attr, char *buf) \ |
85 | { \ | 85 | { \ |
86 | struct usb_interface *intf = to_usb_interface(dev); \ | 86 | struct usb_interface *intf = to_usb_interface(dev); \ |
87 | struct usb_led *led = usb_get_intfdata(intf); \ | 87 | struct usb_led *led = usb_get_intfdata(intf); \ |
88 | \ | 88 | \ |
89 | return sprintf(buf, "%d\n", led->value); \ | 89 | return sprintf(buf, "%d\n", led->value); \ |
90 | } \ | 90 | } \ |
91 | static ssize_t set_##value(struct device *dev, const char *buf, size_t count) \ | 91 | static ssize_t set_##value(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) \ |
92 | { \ | 92 | { \ |
93 | struct usb_interface *intf = to_usb_interface(dev); \ | 93 | struct usb_interface *intf = to_usb_interface(dev); \ |
94 | struct usb_led *led = usb_get_intfdata(intf); \ | 94 | struct usb_led *led = usb_get_intfdata(intf); \ |
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c index a9a7cf4a38eb..fd6ff4cb2c62 100644 --- a/drivers/usb/net/kaweth.c +++ b/drivers/usb/net/kaweth.c | |||
@@ -520,7 +520,7 @@ static void int_callback(struct urb *u, struct pt_regs *regs) | |||
520 | 520 | ||
521 | /* we check the link state to report changes */ | 521 | /* we check the link state to report changes */ |
522 | if (kaweth->linkstate != (act_state = ( kaweth->intbuffer[STATE_OFFSET] | STATE_MASK) >> STATE_SHIFT)) { | 522 | if (kaweth->linkstate != (act_state = ( kaweth->intbuffer[STATE_OFFSET] | STATE_MASK) >> STATE_SHIFT)) { |
523 | if (!act_state) | 523 | if (act_state) |
524 | netif_carrier_on(kaweth->net); | 524 | netif_carrier_on(kaweth->net); |
525 | else | 525 | else |
526 | netif_carrier_off(kaweth->net); | 526 | netif_carrier_off(kaweth->net); |
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index 85476e76b244..4cbb408af727 100644 --- a/drivers/usb/net/usbnet.c +++ b/drivers/usb/net/usbnet.c | |||
@@ -2765,7 +2765,7 @@ static int blan_mdlm_bind (struct usbnet *dev, struct usb_interface *intf) | |||
2765 | } | 2765 | } |
2766 | /* expect bcdVersion 1.0, ignore */ | 2766 | /* expect bcdVersion 1.0, ignore */ |
2767 | if (memcmp(&desc->bGUID, blan_guid, 16) | 2767 | if (memcmp(&desc->bGUID, blan_guid, 16) |
2768 | && memcmp(&desc->bGUID, blan_guid, 16) ) { | 2768 | && memcmp(&desc->bGUID, safe_guid, 16) ) { |
2769 | /* hey, this one might _really_ be MDLM! */ | 2769 | /* hey, this one might _really_ be MDLM! */ |
2770 | dev_dbg (&intf->dev, "MDLM guid\n"); | 2770 | dev_dbg (&intf->dev, "MDLM guid\n"); |
2771 | goto bad_desc; | 2771 | goto bad_desc; |
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index bc798edf0358..9438909e87a5 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -455,6 +455,17 @@ config USB_SERIAL_XIRCOM | |||
455 | To compile this driver as a module, choose M here: the | 455 | To compile this driver as a module, choose M here: the |
456 | module will be called keyspan_pda. | 456 | module will be called keyspan_pda. |
457 | 457 | ||
458 | config USB_SERIAL_OPTION | ||
459 | tristate "USB Option PCMCIA serial driver" | ||
460 | depends on USB_SERIAL && USB_OHCI_HCD && PCCARD | ||
461 | help | ||
462 | Say Y here if you want to use an Option card. This is a | ||
463 | GSM card, controlled by three serial ports which are connected | ||
464 | via an OHCI adapter located on a PC card. | ||
465 | |||
466 | To compile this driver as a module, choose M here: the | ||
467 | module will be called option. | ||
468 | |||
458 | config USB_SERIAL_OMNINET | 469 | config USB_SERIAL_OMNINET |
459 | tristate "USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)" | 470 | tristate "USB ZyXEL omni.net LCD Plus Driver (EXPERIMENTAL)" |
460 | depends on USB_SERIAL && EXPERIMENTAL | 471 | depends on USB_SERIAL && EXPERIMENTAL |
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index d56ff6d86cce..6c7cdcc99a9e 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile | |||
@@ -32,6 +32,7 @@ obj-$(CONFIG_USB_SERIAL_KLSI) += kl5kusb105.o | |||
32 | obj-$(CONFIG_USB_SERIAL_KOBIL_SCT) += kobil_sct.o | 32 | obj-$(CONFIG_USB_SERIAL_KOBIL_SCT) += kobil_sct.o |
33 | obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o | 33 | obj-$(CONFIG_USB_SERIAL_MCT_U232) += mct_u232.o |
34 | obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o | 34 | obj-$(CONFIG_USB_SERIAL_OMNINET) += omninet.o |
35 | obj-$(CONFIG_USB_SERIAL_OPTION) += option.o | ||
35 | obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o | 36 | obj-$(CONFIG_USB_SERIAL_PL2303) += pl2303.o |
36 | obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o | 37 | obj-$(CONFIG_USB_SERIAL_SAFE) += safe_serial.o |
37 | obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o | 38 | obj-$(CONFIG_USB_SERIAL_TI) += ti_usb_3410_5052.o |
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index 7e9bb63eb466..4ace9964fc6b 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c | |||
@@ -7,6 +7,14 @@ | |||
7 | * modify it under the terms of the GNU General Public License version | 7 | * modify it under the terms of the GNU General Public License version |
8 | * 2 as published by the Free Software Foundation. | 8 | * 2 as published by the Free Software Foundation. |
9 | * | 9 | * |
10 | * Support to set flow control line levels using TIOCMGET and TIOCMSET | ||
11 | * thanks to Karl Hiramoto karl@hiramoto.org. RTSCTS hardware flow | ||
12 | * control thanks to Munir Nassar nassarmu@real-time.com | ||
13 | * | ||
14 | * Outstanding Issues: | ||
15 | * Buffers are not flushed when the port is opened. | ||
16 | * Multiple calls to write() may fail with "Resource temporarily unavailable" | ||
17 | * | ||
10 | */ | 18 | */ |
11 | 19 | ||
12 | #include <linux/config.h> | 20 | #include <linux/config.h> |
@@ -24,7 +32,7 @@ | |||
24 | /* | 32 | /* |
25 | * Version Information | 33 | * Version Information |
26 | */ | 34 | */ |
27 | #define DRIVER_VERSION "v0.03" | 35 | #define DRIVER_VERSION "v0.04" |
28 | #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver" | 36 | #define DRIVER_DESC "Silicon Labs CP2101/CP2102 RS232 serial adaptor driver" |
29 | 37 | ||
30 | /* | 38 | /* |
@@ -35,6 +43,9 @@ static void cp2101_cleanup(struct usb_serial_port*); | |||
35 | static void cp2101_close(struct usb_serial_port*, struct file*); | 43 | static void cp2101_close(struct usb_serial_port*, struct file*); |
36 | static void cp2101_get_termios(struct usb_serial_port*); | 44 | static void cp2101_get_termios(struct usb_serial_port*); |
37 | static void cp2101_set_termios(struct usb_serial_port*, struct termios*); | 45 | static void cp2101_set_termios(struct usb_serial_port*, struct termios*); |
46 | static int cp2101_tiocmget (struct usb_serial_port *, struct file *); | ||
47 | static int cp2101_tiocmset (struct usb_serial_port *, struct file *, | ||
48 | unsigned int, unsigned int); | ||
38 | static void cp2101_break_ctl(struct usb_serial_port*, int); | 49 | static void cp2101_break_ctl(struct usb_serial_port*, int); |
39 | static int cp2101_startup (struct usb_serial *); | 50 | static int cp2101_startup (struct usb_serial *); |
40 | static void cp2101_shutdown(struct usb_serial*); | 51 | static void cp2101_shutdown(struct usb_serial*); |
@@ -43,9 +54,10 @@ static void cp2101_shutdown(struct usb_serial*); | |||
43 | static int debug; | 54 | static int debug; |
44 | 55 | ||
45 | static struct usb_device_id id_table [] = { | 56 | static struct usb_device_id id_table [] = { |
46 | {USB_DEVICE(0x10c4, 0xea60) }, /*Silicon labs factory default*/ | 57 | { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ |
47 | {USB_DEVICE(0x10ab, 0x10c5) }, /*Siemens MC60 Cable*/ | 58 | { USB_DEVICE(0x10C4, 0x80CA) }, /* Degree Controls Inc */ |
48 | { } /* Terminating Entry*/ | 59 | { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ |
60 | { } /* Terminating Entry */ | ||
49 | }; | 61 | }; |
50 | 62 | ||
51 | MODULE_DEVICE_TABLE (usb, id_table); | 63 | MODULE_DEVICE_TABLE (usb, id_table); |
@@ -70,32 +82,35 @@ static struct usb_serial_device_type cp2101_device = { | |||
70 | .close = cp2101_close, | 82 | .close = cp2101_close, |
71 | .break_ctl = cp2101_break_ctl, | 83 | .break_ctl = cp2101_break_ctl, |
72 | .set_termios = cp2101_set_termios, | 84 | .set_termios = cp2101_set_termios, |
85 | .tiocmget = cp2101_tiocmget, | ||
86 | .tiocmset = cp2101_tiocmset, | ||
73 | .attach = cp2101_startup, | 87 | .attach = cp2101_startup, |
74 | .shutdown = cp2101_shutdown, | 88 | .shutdown = cp2101_shutdown, |
75 | }; | 89 | }; |
76 | 90 | ||
77 | /*Config request types*/ | 91 | /* Config request types */ |
78 | #define REQTYPE_HOST_TO_DEVICE 0x41 | 92 | #define REQTYPE_HOST_TO_DEVICE 0x41 |
79 | #define REQTYPE_DEVICE_TO_HOST 0xc1 | 93 | #define REQTYPE_DEVICE_TO_HOST 0xc1 |
80 | 94 | ||
81 | /*Config SET requests. To GET, add 1 to the request number*/ | 95 | /* Config SET requests. To GET, add 1 to the request number */ |
82 | #define CP2101_UART 0x00 /*Enable / Disable*/ | 96 | #define CP2101_UART 0x00 /* Enable / Disable */ |
83 | #define CP2101_BAUDRATE 0x01 /*(BAUD_RATE_GEN_FREQ / baudrate)*/ | 97 | #define CP2101_BAUDRATE 0x01 /* (BAUD_RATE_GEN_FREQ / baudrate) */ |
84 | #define CP2101_BITS 0x03 /*0x(0)(data bits)(parity)(stop bits)*/ | 98 | #define CP2101_BITS 0x03 /* 0x(0)(databits)(parity)(stopbits) */ |
85 | #define CP2101_BREAK 0x05 /*On / Off*/ | 99 | #define CP2101_BREAK 0x05 /* On / Off */ |
86 | #define CP2101_DTRRTS 0x07 /*101 / 202 ???*/ | 100 | #define CP2101_CONTROL 0x07 /* Flow control line states */ |
87 | #define CP2101_CONFIG_16 0x13 /*16 bytes of config data ???*/ | 101 | #define CP2101_MODEMCTL 0x13 /* Modem controls */ |
88 | #define CP2101_CONFIG_6 0x19 /*6 bytes of config data ???*/ | 102 | #define CP2101_CONFIG_6 0x19 /* 6 bytes of config data ??? */ |
89 | 103 | ||
90 | /*CP2101_UART*/ | 104 | /* CP2101_UART */ |
91 | #define UART_ENABLE 0x0001 | 105 | #define UART_ENABLE 0x0001 |
92 | #define UART_DISABLE 0x0000 | 106 | #define UART_DISABLE 0x0000 |
93 | 107 | ||
94 | /*CP2101_BAUDRATE*/ | 108 | /* CP2101_BAUDRATE */ |
95 | #define BAUD_RATE_GEN_FREQ 0x384000 | 109 | #define BAUD_RATE_GEN_FREQ 0x384000 |
96 | 110 | ||
97 | /*CP2101_BITS*/ | 111 | /* CP2101_BITS */ |
98 | #define BITS_DATA_MASK 0X0f00 | 112 | #define BITS_DATA_MASK 0X0f00 |
113 | #define BITS_DATA_5 0X0500 | ||
99 | #define BITS_DATA_6 0X0600 | 114 | #define BITS_DATA_6 0X0600 |
100 | #define BITS_DATA_7 0X0700 | 115 | #define BITS_DATA_7 0X0700 |
101 | #define BITS_DATA_8 0X0800 | 116 | #define BITS_DATA_8 0X0800 |
@@ -112,64 +127,137 @@ static struct usb_serial_device_type cp2101_device = { | |||
112 | #define BITS_STOP_1 0x0000 | 127 | #define BITS_STOP_1 0x0000 |
113 | #define BITS_STOP_1_5 0x0001 | 128 | #define BITS_STOP_1_5 0x0001 |
114 | #define BITS_STOP_2 0x0002 | 129 | #define BITS_STOP_2 0x0002 |
130 | |||
131 | /* CP2101_BREAK */ | ||
115 | #define BREAK_ON 0x0000 | 132 | #define BREAK_ON 0x0000 |
116 | #define BREAK_OFF 0x0001 | 133 | #define BREAK_OFF 0x0001 |
117 | 134 | ||
135 | /* CP2101_CONTROL */ | ||
136 | #define CONTROL_DTR 0x0001 | ||
137 | #define CONTROL_RTS 0x0002 | ||
138 | #define CONTROL_CTS 0x0010 | ||
139 | #define CONTROL_DSR 0x0020 | ||
140 | #define CONTROL_RING 0x0040 | ||
141 | #define CONTROL_DCD 0x0080 | ||
142 | #define CONTROL_WRITE_DTR 0x0100 | ||
143 | #define CONTROL_WRITE_RTS 0x0200 | ||
118 | 144 | ||
119 | static int cp2101_get_config(struct usb_serial_port* port, u8 request) | 145 | /* |
146 | * cp2101_get_config | ||
147 | * Reads from the CP2101 configuration registers | ||
148 | * 'size' is specified in bytes. | ||
149 | * 'data' is a pointer to a pre-allocated array of integers large | ||
150 | * enough to hold 'size' bytes (with 4 bytes to each integer) | ||
151 | */ | ||
152 | static int cp2101_get_config(struct usb_serial_port* port, u8 request, | ||
153 | unsigned int *data, int size) | ||
120 | { | 154 | { |
121 | struct usb_serial *serial = port->serial; | 155 | struct usb_serial *serial = port->serial; |
122 | unsigned char buf[4]; | 156 | u32 *buf; |
123 | unsigned int value; | 157 | int result, i, length; |
124 | int result, i; | 158 | |
159 | /* Number of integers required to contain the array */ | ||
160 | length = (((size - 1) | 3) + 1)/4; | ||
161 | |||
162 | buf = kmalloc (length * sizeof(u32), GFP_KERNEL); | ||
163 | memset(buf, 0, length * sizeof(u32)); | ||
164 | |||
165 | if (!buf) { | ||
166 | dev_err(&port->dev, "%s - out of memory.\n", __FUNCTION__); | ||
167 | return -ENOMEM; | ||
168 | } | ||
125 | 169 | ||
126 | /*For get requests, the request number must be incremented*/ | 170 | /* For get requests, the request number must be incremented */ |
127 | request++; | 171 | request++; |
128 | 172 | ||
129 | /*Issue the request, attempting to read 4 bytes*/ | 173 | /* Issue the request, attempting to read 'size' bytes */ |
130 | result = usb_control_msg (serial->dev,usb_rcvctrlpipe (serial->dev, 0), | 174 | result = usb_control_msg (serial->dev,usb_rcvctrlpipe (serial->dev, 0), |
131 | request, REQTYPE_DEVICE_TO_HOST, 0x0000, | 175 | request, REQTYPE_DEVICE_TO_HOST, 0x0000, |
132 | 0, buf, 4, 300); | 176 | 0, buf, size, 300); |
133 | 177 | ||
134 | if (result < 0) { | 178 | /* Convert data into an array of integers */ |
135 | dev_err(&port->dev, "%s - Unable to send config request, " | 179 | for (i=0; i<length; i++) |
136 | "request=0x%x result=%d\n", | 180 | data[i] = le32_to_cpu(buf[i]); |
137 | __FUNCTION__, request, result); | ||
138 | return result; | ||
139 | } | ||
140 | 181 | ||
141 | /*Assemble each byte read into an integer value*/ | 182 | kfree(buf); |
142 | value = 0; | ||
143 | for (i=0; i<4 && i<result; i++) | ||
144 | value |= (buf[i] << (i * 8)); | ||
145 | 183 | ||
146 | dbg( " %s - request=0x%x result=%d value=0x%x", | 184 | if (result != size) { |
147 | __FUNCTION__, request, result, value); | 185 | dev_err(&port->dev, "%s - Unable to send config request, " |
186 | "request=0x%x size=%d result=%d\n", | ||
187 | __FUNCTION__, request, size, result); | ||
188 | return -EPROTO; | ||
189 | } | ||
148 | 190 | ||
149 | return value; | 191 | return 0; |
150 | } | 192 | } |
151 | 193 | ||
152 | static int cp2101_set_config(struct usb_serial_port* port, u8 request, u16 value) | 194 | /* |
195 | * cp2101_set_config | ||
196 | * Writes to the CP2101 configuration registers | ||
197 | * Values less than 16 bits wide are sent directly | ||
198 | * 'size' is specified in bytes. | ||
199 | */ | ||
200 | static int cp2101_set_config(struct usb_serial_port* port, u8 request, | ||
201 | unsigned int *data, int size) | ||
153 | { | 202 | { |
154 | struct usb_serial *serial = port->serial; | 203 | struct usb_serial *serial = port->serial; |
155 | int result; | 204 | u32 *buf; |
156 | result = usb_control_msg (serial->dev, usb_sndctrlpipe(serial->dev, 0), | 205 | int result, i, length; |
157 | request, REQTYPE_HOST_TO_DEVICE, value, | ||
158 | 0, NULL, 0, 300); | ||
159 | 206 | ||
160 | if (result <0) { | 207 | /* Number of integers required to contain the array */ |
161 | dev_err(&port->dev, "%s - Unable to send config request, " | 208 | length = (((size - 1) | 3) + 1)/4; |
162 | "request=0x%x value=0x%x result=%d\n", | 209 | |
163 | __FUNCTION__, request, value, result); | 210 | buf = kmalloc(length * sizeof(u32), GFP_KERNEL); |
164 | return result; | 211 | if (!buf) { |
212 | dev_err(&port->dev, "%s - out of memory.\n", | ||
213 | __FUNCTION__); | ||
214 | return -ENOMEM; | ||
215 | } | ||
216 | |||
217 | /* Array of integers into bytes */ | ||
218 | for (i = 0; i < length; i++) | ||
219 | buf[i] = cpu_to_le32(data[i]); | ||
220 | |||
221 | if (size > 2) { | ||
222 | result = usb_control_msg (serial->dev, | ||
223 | usb_sndctrlpipe(serial->dev, 0), | ||
224 | request, REQTYPE_HOST_TO_DEVICE, 0x0000, | ||
225 | 0, buf, size, 300); | ||
226 | } else { | ||
227 | result = usb_control_msg (serial->dev, | ||
228 | usb_sndctrlpipe(serial->dev, 0), | ||
229 | request, REQTYPE_HOST_TO_DEVICE, data[0], | ||
230 | 0, NULL, 0, 300); | ||
165 | } | 231 | } |
166 | 232 | ||
167 | dbg(" %s - request=0x%x value=0x%x result=%d", | 233 | kfree(buf); |
168 | __FUNCTION__, request, value, result); | 234 | |
235 | if ((size > 2 && result != size) || result < 0) { | ||
236 | dev_err(&port->dev, "%s - Unable to send request, " | ||
237 | "request=0x%x size=%d result=%d\n", | ||
238 | __FUNCTION__, request, size, result); | ||
239 | return -EPROTO; | ||
240 | } | ||
169 | 241 | ||
242 | /* Single data value */ | ||
243 | result = usb_control_msg (serial->dev, | ||
244 | usb_sndctrlpipe(serial->dev, 0), | ||
245 | request, REQTYPE_HOST_TO_DEVICE, data[0], | ||
246 | 0, NULL, 0, 300); | ||
170 | return 0; | 247 | return 0; |
171 | } | 248 | } |
172 | 249 | ||
250 | /* | ||
251 | * cp2101_set_config_single | ||
252 | * Convenience function for calling cp2101_set_config on single data values | ||
253 | * without requiring an integer pointer | ||
254 | */ | ||
255 | static inline int cp2101_set_config_single(struct usb_serial_port* port, | ||
256 | u8 request, unsigned int data) | ||
257 | { | ||
258 | return cp2101_set_config(port, request, &data, 2); | ||
259 | } | ||
260 | |||
173 | static int cp2101_open (struct usb_serial_port *port, struct file *filp) | 261 | static int cp2101_open (struct usb_serial_port *port, struct file *filp) |
174 | { | 262 | { |
175 | struct usb_serial *serial = port->serial; | 263 | struct usb_serial *serial = port->serial; |
@@ -177,7 +265,7 @@ static int cp2101_open (struct usb_serial_port *port, struct file *filp) | |||
177 | 265 | ||
178 | dbg("%s - port %d", __FUNCTION__, port->number); | 266 | dbg("%s - port %d", __FUNCTION__, port->number); |
179 | 267 | ||
180 | if (cp2101_set_config(port, CP2101_UART, UART_ENABLE)) { | 268 | if (cp2101_set_config_single(port, CP2101_UART, UART_ENABLE)) { |
181 | dev_err(&port->dev, "%s - Unable to enable UART\n", | 269 | dev_err(&port->dev, "%s - Unable to enable UART\n", |
182 | __FUNCTION__); | 270 | __FUNCTION__); |
183 | return -EPROTO; | 271 | return -EPROTO; |
@@ -198,9 +286,12 @@ static int cp2101_open (struct usb_serial_port *port, struct file *filp) | |||
198 | return result; | 286 | return result; |
199 | } | 287 | } |
200 | 288 | ||
201 | /*Configure the termios structure*/ | 289 | /* Configure the termios structure */ |
202 | cp2101_get_termios(port); | 290 | cp2101_get_termios(port); |
203 | 291 | ||
292 | /* Set the DTR and RTS pins low */ | ||
293 | cp2101_tiocmset(port, NULL, TIOCM_DTR | TIOCM_RTS, 0); | ||
294 | |||
204 | return 0; | 295 | return 0; |
205 | } | 296 | } |
206 | 297 | ||
@@ -228,16 +319,18 @@ static void cp2101_close (struct usb_serial_port *port, struct file * filp) | |||
228 | usb_kill_urb(port->write_urb); | 319 | usb_kill_urb(port->write_urb); |
229 | usb_kill_urb(port->read_urb); | 320 | usb_kill_urb(port->read_urb); |
230 | 321 | ||
231 | cp2101_set_config(port, CP2101_UART, UART_DISABLE); | 322 | cp2101_set_config_single(port, CP2101_UART, UART_DISABLE); |
232 | } | 323 | } |
233 | 324 | ||
234 | /* cp2101_get_termios*/ | 325 | /* |
235 | /* Reads the baud rate, data bits, parity and stop bits from the device*/ | 326 | * cp2101_get_termios |
236 | /* Corrects any unsupported values*/ | 327 | * Reads the baud rate, data bits, parity, stop bits and flow control mode |
237 | /* Configures the termios structure to reflect the state of the device*/ | 328 | * from the device, corrects any unsupported values, and configures the |
329 | * termios structure to reflect the state of the device | ||
330 | */ | ||
238 | static void cp2101_get_termios (struct usb_serial_port *port) | 331 | static void cp2101_get_termios (struct usb_serial_port *port) |
239 | { | 332 | { |
240 | unsigned int cflag; | 333 | unsigned int cflag, modem_ctl[4]; |
241 | int baud; | 334 | int baud; |
242 | int bits; | 335 | int bits; |
243 | 336 | ||
@@ -249,15 +342,16 @@ static void cp2101_get_termios (struct usb_serial_port *port) | |||
249 | } | 342 | } |
250 | cflag = port->tty->termios->c_cflag; | 343 | cflag = port->tty->termios->c_cflag; |
251 | 344 | ||
252 | baud = cp2101_get_config(port, CP2101_BAUDRATE); | 345 | cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2); |
253 | /*Convert to baudrate*/ | 346 | /* Convert to baudrate */ |
254 | if (baud) | 347 | if (baud) |
255 | baud = BAUD_RATE_GEN_FREQ / baud; | 348 | baud = BAUD_RATE_GEN_FREQ / baud; |
256 | 349 | ||
257 | dbg("%s - baud rate = %d", __FUNCTION__, baud); | 350 | dbg("%s - baud rate = %d", __FUNCTION__, baud); |
258 | cflag &= ~CBAUD; | 351 | cflag &= ~CBAUD; |
259 | switch (baud) { | 352 | switch (baud) { |
260 | /* The baud rates which are commented out below | 353 | /* |
354 | * The baud rates which are commented out below | ||
261 | * appear to be supported by the device | 355 | * appear to be supported by the device |
262 | * but are non-standard | 356 | * but are non-standard |
263 | */ | 357 | */ |
@@ -284,14 +378,18 @@ static void cp2101_get_termios (struct usb_serial_port *port) | |||
284 | dbg("%s - Baud rate is not supported, " | 378 | dbg("%s - Baud rate is not supported, " |
285 | "using 9600 baud", __FUNCTION__); | 379 | "using 9600 baud", __FUNCTION__); |
286 | cflag |= B9600; | 380 | cflag |= B9600; |
287 | cp2101_set_config(port, CP2101_BAUDRATE, | 381 | cp2101_set_config_single(port, CP2101_BAUDRATE, |
288 | (BAUD_RATE_GEN_FREQ/9600)); | 382 | (BAUD_RATE_GEN_FREQ/9600)); |
289 | break; | 383 | break; |
290 | } | 384 | } |
291 | 385 | ||
292 | bits = cp2101_get_config(port, CP2101_BITS); | 386 | cp2101_get_config(port, CP2101_BITS, &bits, 2); |
293 | cflag &= ~CSIZE; | 387 | cflag &= ~CSIZE; |
294 | switch(bits & BITS_DATA_MASK) { | 388 | switch(bits & BITS_DATA_MASK) { |
389 | case BITS_DATA_5: | ||
390 | dbg("%s - data bits = 5", __FUNCTION__); | ||
391 | cflag |= CS5; | ||
392 | break; | ||
295 | case BITS_DATA_6: | 393 | case BITS_DATA_6: |
296 | dbg("%s - data bits = 6", __FUNCTION__); | 394 | dbg("%s - data bits = 6", __FUNCTION__); |
297 | cflag |= CS6; | 395 | cflag |= CS6; |
@@ -310,7 +408,7 @@ static void cp2101_get_termios (struct usb_serial_port *port) | |||
310 | cflag |= CS8; | 408 | cflag |= CS8; |
311 | bits &= ~BITS_DATA_MASK; | 409 | bits &= ~BITS_DATA_MASK; |
312 | bits |= BITS_DATA_8; | 410 | bits |= BITS_DATA_8; |
313 | cp2101_set_config(port, CP2101_BITS, bits); | 411 | cp2101_set_config(port, CP2101_BITS, &bits, 2); |
314 | break; | 412 | break; |
315 | default: | 413 | default: |
316 | dbg("%s - Unknown number of data bits, " | 414 | dbg("%s - Unknown number of data bits, " |
@@ -318,7 +416,7 @@ static void cp2101_get_termios (struct usb_serial_port *port) | |||
318 | cflag |= CS8; | 416 | cflag |= CS8; |
319 | bits &= ~BITS_DATA_MASK; | 417 | bits &= ~BITS_DATA_MASK; |
320 | bits |= BITS_DATA_8; | 418 | bits |= BITS_DATA_8; |
321 | cp2101_set_config(port, CP2101_BITS, bits); | 419 | cp2101_set_config(port, CP2101_BITS, &bits, 2); |
322 | break; | 420 | break; |
323 | } | 421 | } |
324 | 422 | ||
@@ -341,21 +439,21 @@ static void cp2101_get_termios (struct usb_serial_port *port) | |||
341 | "disabling parity)", __FUNCTION__); | 439 | "disabling parity)", __FUNCTION__); |
342 | cflag &= ~PARENB; | 440 | cflag &= ~PARENB; |
343 | bits &= ~BITS_PARITY_MASK; | 441 | bits &= ~BITS_PARITY_MASK; |
344 | cp2101_set_config(port, CP2101_BITS, bits); | 442 | cp2101_set_config(port, CP2101_BITS, &bits, 2); |
345 | break; | 443 | break; |
346 | case BITS_PARITY_SPACE: | 444 | case BITS_PARITY_SPACE: |
347 | dbg("%s - parity = SPACE (not supported, " | 445 | dbg("%s - parity = SPACE (not supported, " |
348 | "disabling parity)", __FUNCTION__); | 446 | "disabling parity)", __FUNCTION__); |
349 | cflag &= ~PARENB; | 447 | cflag &= ~PARENB; |
350 | bits &= ~BITS_PARITY_MASK; | 448 | bits &= ~BITS_PARITY_MASK; |
351 | cp2101_set_config(port, CP2101_BITS, bits); | 449 | cp2101_set_config(port, CP2101_BITS, &bits, 2); |
352 | break; | 450 | break; |
353 | default: | 451 | default: |
354 | dbg("%s - Unknown parity mode, " | 452 | dbg("%s - Unknown parity mode, " |
355 | "disabling parity", __FUNCTION__); | 453 | "disabling parity", __FUNCTION__); |
356 | cflag &= ~PARENB; | 454 | cflag &= ~PARENB; |
357 | bits &= ~BITS_PARITY_MASK; | 455 | bits &= ~BITS_PARITY_MASK; |
358 | cp2101_set_config(port, CP2101_BITS, bits); | 456 | cp2101_set_config(port, CP2101_BITS, &bits, 2); |
359 | break; | 457 | break; |
360 | } | 458 | } |
361 | 459 | ||
@@ -366,9 +464,9 @@ static void cp2101_get_termios (struct usb_serial_port *port) | |||
366 | break; | 464 | break; |
367 | case BITS_STOP_1_5: | 465 | case BITS_STOP_1_5: |
368 | dbg("%s - stop bits = 1.5 (not supported, " | 466 | dbg("%s - stop bits = 1.5 (not supported, " |
369 | "using 1 stop bit", __FUNCTION__); | 467 | "using 1 stop bit)", __FUNCTION__); |
370 | bits &= ~BITS_STOP_MASK; | 468 | bits &= ~BITS_STOP_MASK; |
371 | cp2101_set_config(port, CP2101_BITS, bits); | 469 | cp2101_set_config(port, CP2101_BITS, &bits, 2); |
372 | break; | 470 | break; |
373 | case BITS_STOP_2: | 471 | case BITS_STOP_2: |
374 | dbg("%s - stop bits = 2", __FUNCTION__); | 472 | dbg("%s - stop bits = 2", __FUNCTION__); |
@@ -378,10 +476,19 @@ static void cp2101_get_termios (struct usb_serial_port *port) | |||
378 | dbg("%s - Unknown number of stop bits, " | 476 | dbg("%s - Unknown number of stop bits, " |
379 | "using 1 stop bit", __FUNCTION__); | 477 | "using 1 stop bit", __FUNCTION__); |
380 | bits &= ~BITS_STOP_MASK; | 478 | bits &= ~BITS_STOP_MASK; |
381 | cp2101_set_config(port, CP2101_BITS, bits); | 479 | cp2101_set_config(port, CP2101_BITS, &bits, 2); |
382 | break; | 480 | break; |
383 | } | 481 | } |
384 | 482 | ||
483 | cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16); | ||
484 | if (modem_ctl[0] & 0x0008) { | ||
485 | dbg("%s - flow control = CRTSCTS", __FUNCTION__); | ||
486 | cflag |= CRTSCTS; | ||
487 | } else { | ||
488 | dbg("%s - flow control = NONE", __FUNCTION__); | ||
489 | cflag &= ~CRTSCTS; | ||
490 | } | ||
491 | |||
385 | port->tty->termios->c_cflag = cflag; | 492 | port->tty->termios->c_cflag = cflag; |
386 | } | 493 | } |
387 | 494 | ||
@@ -389,8 +496,8 @@ static void cp2101_set_termios (struct usb_serial_port *port, | |||
389 | struct termios *old_termios) | 496 | struct termios *old_termios) |
390 | { | 497 | { |
391 | unsigned int cflag, old_cflag=0; | 498 | unsigned int cflag, old_cflag=0; |
392 | int baud=0; | 499 | int baud=0, bits; |
393 | int bits; | 500 | unsigned int modem_ctl[4]; |
394 | 501 | ||
395 | dbg("%s - port %d", __FUNCTION__, port->number); | 502 | dbg("%s - port %d", __FUNCTION__, port->number); |
396 | 503 | ||
@@ -400,7 +507,7 @@ static void cp2101_set_termios (struct usb_serial_port *port, | |||
400 | } | 507 | } |
401 | cflag = port->tty->termios->c_cflag; | 508 | cflag = port->tty->termios->c_cflag; |
402 | 509 | ||
403 | /* check that they really want us to change something */ | 510 | /* Check that they really want us to change something */ |
404 | if (old_termios) { | 511 | if (old_termios) { |
405 | if ((cflag == old_termios->c_cflag) && | 512 | if ((cflag == old_termios->c_cflag) && |
406 | (RELEVANT_IFLAG(port->tty->termios->c_iflag) | 513 | (RELEVANT_IFLAG(port->tty->termios->c_iflag) |
@@ -415,7 +522,8 @@ static void cp2101_set_termios (struct usb_serial_port *port, | |||
415 | /* If the baud rate is to be updated*/ | 522 | /* If the baud rate is to be updated*/ |
416 | if ((cflag & CBAUD) != (old_cflag & CBAUD)) { | 523 | if ((cflag & CBAUD) != (old_cflag & CBAUD)) { |
417 | switch (cflag & CBAUD) { | 524 | switch (cflag & CBAUD) { |
418 | /* The baud rates which are commented out below | 525 | /* |
526 | * The baud rates which are commented out below | ||
419 | * appear to be supported by the device | 527 | * appear to be supported by the device |
420 | * but are non-standard | 528 | * but are non-standard |
421 | */ | 529 | */ |
@@ -448,18 +556,22 @@ static void cp2101_set_termios (struct usb_serial_port *port, | |||
448 | if (baud) { | 556 | if (baud) { |
449 | dbg("%s - Setting baud rate to %d baud", __FUNCTION__, | 557 | dbg("%s - Setting baud rate to %d baud", __FUNCTION__, |
450 | baud); | 558 | baud); |
451 | if (cp2101_set_config(port, CP2101_BAUDRATE, | 559 | if (cp2101_set_config_single(port, CP2101_BAUDRATE, |
452 | (BAUD_RATE_GEN_FREQ / baud))) | 560 | (BAUD_RATE_GEN_FREQ / baud))) |
453 | dev_err(&port->dev, "Baud rate requested not " | 561 | dev_err(&port->dev, "Baud rate requested not " |
454 | "supported by device\n"); | 562 | "supported by device\n"); |
455 | } | 563 | } |
456 | } | 564 | } |
457 | 565 | ||
458 | /*If the number of data bits is to be updated*/ | 566 | /* If the number of data bits is to be updated */ |
459 | if ((cflag & CSIZE) != (old_cflag & CSIZE)) { | 567 | if ((cflag & CSIZE) != (old_cflag & CSIZE)) { |
460 | bits = cp2101_get_config(port, CP2101_BITS); | 568 | cp2101_get_config(port, CP2101_BITS, &bits, 2); |
461 | bits &= ~BITS_DATA_MASK; | 569 | bits &= ~BITS_DATA_MASK; |
462 | switch (cflag & CSIZE) { | 570 | switch (cflag & CSIZE) { |
571 | case CS5: | ||
572 | bits |= BITS_DATA_5; | ||
573 | dbg("%s - data bits = 5", __FUNCTION__); | ||
574 | break; | ||
463 | case CS6: | 575 | case CS6: |
464 | bits |= BITS_DATA_6; | 576 | bits |= BITS_DATA_6; |
465 | dbg("%s - data bits = 6", __FUNCTION__); | 577 | dbg("%s - data bits = 6", __FUNCTION__); |
@@ -483,13 +595,13 @@ static void cp2101_set_termios (struct usb_serial_port *port, | |||
483 | bits |= BITS_DATA_8; | 595 | bits |= BITS_DATA_8; |
484 | break; | 596 | break; |
485 | } | 597 | } |
486 | if (cp2101_set_config(port, CP2101_BITS, bits)) | 598 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) |
487 | dev_err(&port->dev, "Number of data bits requested " | 599 | dev_err(&port->dev, "Number of data bits requested " |
488 | "not supported by device\n"); | 600 | "not supported by device\n"); |
489 | } | 601 | } |
490 | 602 | ||
491 | if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) { | 603 | if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))) { |
492 | bits = cp2101_get_config(port, CP2101_BITS); | 604 | cp2101_get_config(port, CP2101_BITS, &bits, 2); |
493 | bits &= ~BITS_PARITY_MASK; | 605 | bits &= ~BITS_PARITY_MASK; |
494 | if (cflag & PARENB) { | 606 | if (cflag & PARENB) { |
495 | if (cflag & PARODD) { | 607 | if (cflag & PARODD) { |
@@ -500,13 +612,13 @@ static void cp2101_set_termios (struct usb_serial_port *port, | |||
500 | dbg("%s - parity = EVEN", __FUNCTION__); | 612 | dbg("%s - parity = EVEN", __FUNCTION__); |
501 | } | 613 | } |
502 | } | 614 | } |
503 | if (cp2101_set_config(port, CP2101_BITS, bits)) | 615 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) |
504 | dev_err(&port->dev, "Parity mode not supported " | 616 | dev_err(&port->dev, "Parity mode not supported " |
505 | "by device\n"); | 617 | "by device\n"); |
506 | } | 618 | } |
507 | 619 | ||
508 | if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { | 620 | if ((cflag & CSTOPB) != (old_cflag & CSTOPB)) { |
509 | bits = cp2101_get_config(port, CP2101_BITS); | 621 | cp2101_get_config(port, CP2101_BITS, &bits, 2); |
510 | bits &= ~BITS_STOP_MASK; | 622 | bits &= ~BITS_STOP_MASK; |
511 | if (cflag & CSTOPB) { | 623 | if (cflag & CSTOPB) { |
512 | bits |= BITS_STOP_2; | 624 | bits |= BITS_STOP_2; |
@@ -515,15 +627,90 @@ static void cp2101_set_termios (struct usb_serial_port *port, | |||
515 | bits |= BITS_STOP_1; | 627 | bits |= BITS_STOP_1; |
516 | dbg("%s - stop bits = 1", __FUNCTION__); | 628 | dbg("%s - stop bits = 1", __FUNCTION__); |
517 | } | 629 | } |
518 | if (cp2101_set_config(port, CP2101_BITS, bits)) | 630 | if (cp2101_set_config(port, CP2101_BITS, &bits, 2)) |
519 | dev_err(&port->dev, "Number of stop bits requested " | 631 | dev_err(&port->dev, "Number of stop bits requested " |
520 | "not supported by device\n"); | 632 | "not supported by device\n"); |
521 | } | 633 | } |
634 | |||
635 | if ((cflag & CRTSCTS) != (old_cflag & CRTSCTS)) { | ||
636 | cp2101_get_config(port, CP2101_MODEMCTL, modem_ctl, 16); | ||
637 | dbg("%s - read modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", | ||
638 | __FUNCTION__, modem_ctl[0], modem_ctl[1], | ||
639 | modem_ctl[2], modem_ctl[3]); | ||
640 | |||
641 | if (cflag & CRTSCTS) { | ||
642 | modem_ctl[0] &= ~0x7B; | ||
643 | modem_ctl[0] |= 0x09; | ||
644 | modem_ctl[1] = 0x80; | ||
645 | dbg("%s - flow control = CRTSCTS", __FUNCTION__); | ||
646 | } else { | ||
647 | modem_ctl[0] &= ~0x7B; | ||
648 | modem_ctl[0] |= 0x01; | ||
649 | modem_ctl[1] |= 0x40; | ||
650 | dbg("%s - flow control = NONE", __FUNCTION__); | ||
651 | } | ||
652 | |||
653 | dbg("%s - write modem controls = 0x%.4x 0x%.4x 0x%.4x 0x%.4x", | ||
654 | __FUNCTION__, modem_ctl[0], modem_ctl[1], | ||
655 | modem_ctl[2], modem_ctl[3]); | ||
656 | cp2101_set_config(port, CP2101_MODEMCTL, modem_ctl, 16); | ||
657 | } | ||
658 | |||
659 | } | ||
660 | |||
661 | static int cp2101_tiocmset (struct usb_serial_port *port, struct file *file, | ||
662 | unsigned int set, unsigned int clear) | ||
663 | { | ||
664 | int control = 0; | ||
665 | |||
666 | dbg("%s - port %d", __FUNCTION__, port->number); | ||
667 | |||
668 | if (set & TIOCM_RTS) { | ||
669 | control |= CONTROL_RTS; | ||
670 | control |= CONTROL_WRITE_RTS; | ||
671 | } | ||
672 | if (set & TIOCM_DTR) { | ||
673 | control |= CONTROL_DTR; | ||
674 | control |= CONTROL_WRITE_DTR; | ||
675 | } | ||
676 | if (clear & TIOCM_RTS) { | ||
677 | control &= ~CONTROL_RTS; | ||
678 | control |= CONTROL_WRITE_RTS; | ||
679 | } | ||
680 | if (clear & TIOCM_DTR) { | ||
681 | control &= ~CONTROL_DTR; | ||
682 | control |= CONTROL_WRITE_DTR; | ||
683 | } | ||
684 | |||
685 | dbg("%s - control = 0x%.4x", __FUNCTION__, control); | ||
686 | |||
687 | return cp2101_set_config(port, CP2101_CONTROL, &control, 2); | ||
688 | |||
689 | } | ||
690 | |||
691 | static int cp2101_tiocmget (struct usb_serial_port *port, struct file *file) | ||
692 | { | ||
693 | int control, result; | ||
694 | |||
695 | dbg("%s - port %d", __FUNCTION__, port->number); | ||
696 | |||
697 | cp2101_get_config(port, CP2101_CONTROL, &control, 1); | ||
698 | |||
699 | result = ((control & CONTROL_DTR) ? TIOCM_DTR : 0) | ||
700 | |((control & CONTROL_RTS) ? TIOCM_RTS : 0) | ||
701 | |((control & CONTROL_CTS) ? TIOCM_CTS : 0) | ||
702 | |((control & CONTROL_DSR) ? TIOCM_DSR : 0) | ||
703 | |((control & CONTROL_RING)? TIOCM_RI : 0) | ||
704 | |((control & CONTROL_DCD) ? TIOCM_CD : 0); | ||
705 | |||
706 | dbg("%s - control = 0x%.2x", __FUNCTION__, control); | ||
707 | |||
708 | return result; | ||
522 | } | 709 | } |
523 | 710 | ||
524 | static void cp2101_break_ctl (struct usb_serial_port *port, int break_state) | 711 | static void cp2101_break_ctl (struct usb_serial_port *port, int break_state) |
525 | { | 712 | { |
526 | u16 state; | 713 | int state; |
527 | 714 | ||
528 | dbg("%s - port %d", __FUNCTION__, port->number); | 715 | dbg("%s - port %d", __FUNCTION__, port->number); |
529 | if (break_state == 0) | 716 | if (break_state == 0) |
@@ -532,12 +719,12 @@ static void cp2101_break_ctl (struct usb_serial_port *port, int break_state) | |||
532 | state = BREAK_ON; | 719 | state = BREAK_ON; |
533 | dbg("%s - turning break %s", __FUNCTION__, | 720 | dbg("%s - turning break %s", __FUNCTION__, |
534 | state==BREAK_OFF ? "off" : "on"); | 721 | state==BREAK_OFF ? "off" : "on"); |
535 | cp2101_set_config(port, CP2101_BREAK, state); | 722 | cp2101_set_config(port, CP2101_BREAK, &state, 2); |
536 | } | 723 | } |
537 | 724 | ||
538 | static int cp2101_startup (struct usb_serial *serial) | 725 | static int cp2101_startup (struct usb_serial *serial) |
539 | { | 726 | { |
540 | /*CP2101 buffers behave strangely unless device is reset*/ | 727 | /* CP2101 buffers behave strangely unless device is reset */ |
541 | usb_reset_device(serial->dev); | 728 | usb_reset_device(serial->dev); |
542 | return 0; | 729 | return 0; |
543 | } | 730 | } |
@@ -548,7 +735,7 @@ static void cp2101_shutdown (struct usb_serial *serial) | |||
548 | 735 | ||
549 | dbg("%s", __FUNCTION__); | 736 | dbg("%s", __FUNCTION__); |
550 | 737 | ||
551 | /* stop reads and writes on all ports */ | 738 | /* Stop reads and writes on all ports */ |
552 | for (i=0; i < serial->num_ports; ++i) { | 739 | for (i=0; i < serial->num_ports; ++i) { |
553 | cp2101_cleanup(serial->port[i]); | 740 | cp2101_cleanup(serial->port[i]); |
554 | } | 741 | } |
@@ -560,16 +747,16 @@ static int __init cp2101_init (void) | |||
560 | 747 | ||
561 | retval = usb_serial_register(&cp2101_device); | 748 | retval = usb_serial_register(&cp2101_device); |
562 | if (retval) | 749 | if (retval) |
563 | return retval; /*Failed to register*/ | 750 | return retval; /* Failed to register */ |
564 | 751 | ||
565 | retval = usb_register(&cp2101_driver); | 752 | retval = usb_register(&cp2101_driver); |
566 | if (retval) { | 753 | if (retval) { |
567 | /*Failed to register*/ | 754 | /* Failed to register */ |
568 | usb_serial_deregister(&cp2101_device); | 755 | usb_serial_deregister(&cp2101_device); |
569 | return retval; | 756 | return retval; |
570 | } | 757 | } |
571 | 758 | ||
572 | /*Success*/ | 759 | /* Success */ |
573 | info(DRIVER_DESC " " DRIVER_VERSION); | 760 | info(DRIVER_DESC " " DRIVER_VERSION); |
574 | return 0; | 761 | return 0; |
575 | } | 762 | } |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 52394f08a947..d882fa3ad19a 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -264,7 +264,7 @@ | |||
264 | /* | 264 | /* |
265 | * Version Information | 265 | * Version Information |
266 | */ | 266 | */ |
267 | #define DRIVER_VERSION "v1.4.1" | 267 | #define DRIVER_VERSION "v1.4.2" |
268 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>" | 268 | #define DRIVER_AUTHOR "Greg Kroah-Hartman <greg@kroah.com>, Bill Ryder <bryder@sgi.com>, Kuba Ober <kuba@mareimbrium.org>" |
269 | #define DRIVER_DESC "USB FTDI Serial Converters Driver" | 269 | #define DRIVER_DESC "USB FTDI Serial Converters Driver" |
270 | 270 | ||
@@ -364,6 +364,7 @@ static struct usb_device_id id_table_8U232AM [] = { | |||
364 | { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0, 0x3ff) }, | 364 | { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0, 0x3ff) }, |
365 | { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0, 0x3ff) }, | 365 | { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0, 0x3ff) }, |
366 | { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0, 0x3ff) }, | 366 | { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0, 0x3ff) }, |
367 | { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UM100_PID, 0, 0x3ff) }, | ||
367 | { USB_DEVICE_VER(FTDI_VID, INSIDE_ACCESSO, 0, 0x3ff) }, | 368 | { USB_DEVICE_VER(FTDI_VID, INSIDE_ACCESSO, 0, 0x3ff) }, |
368 | { USB_DEVICE_VER(INTREPID_VID, INTREPID_VALUECAN_PID, 0, 0x3ff) }, | 369 | { USB_DEVICE_VER(INTREPID_VID, INTREPID_VALUECAN_PID, 0, 0x3ff) }, |
369 | { USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0, 0x3ff) }, | 370 | { USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0, 0x3ff) }, |
@@ -475,6 +476,7 @@ static struct usb_device_id id_table_FT232BM [] = { | |||
475 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, | 476 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, |
476 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, | 477 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, |
477 | { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0x400, 0xffff) }, | 478 | { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UO100_PID, 0x400, 0xffff) }, |
479 | { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UM100_PID, 0x400, 0xffff) }, | ||
478 | { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, | 480 | { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, |
479 | { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, | 481 | { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, |
480 | { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, | 482 | { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, |
@@ -618,6 +620,7 @@ static struct usb_device_id id_table_combined [] = { | |||
618 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, | 620 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, |
619 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, | 621 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, |
620 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) }, | 622 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) }, |
623 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) }, | ||
621 | { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, | 624 | { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, |
622 | { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, | 625 | { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, |
623 | { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, | 626 | { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, |
@@ -684,6 +687,8 @@ struct ftdi_private { | |||
684 | char prev_status, diff_status; /* Used for TIOCMIWAIT */ | 687 | char prev_status, diff_status; /* Used for TIOCMIWAIT */ |
685 | __u8 rx_flags; /* receive state flags (throttling) */ | 688 | __u8 rx_flags; /* receive state flags (throttling) */ |
686 | spinlock_t rx_lock; /* spinlock for receive state */ | 689 | spinlock_t rx_lock; /* spinlock for receive state */ |
690 | struct work_struct rx_work; | ||
691 | int rx_processed; | ||
687 | 692 | ||
688 | __u16 interface; /* FT2232C port interface (0 for FT232/245) */ | 693 | __u16 interface; /* FT2232C port interface (0 for FT232/245) */ |
689 | 694 | ||
@@ -714,7 +719,7 @@ static int ftdi_write_room (struct usb_serial_port *port); | |||
714 | static int ftdi_chars_in_buffer (struct usb_serial_port *port); | 719 | static int ftdi_chars_in_buffer (struct usb_serial_port *port); |
715 | static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs); | 720 | static void ftdi_write_bulk_callback (struct urb *urb, struct pt_regs *regs); |
716 | static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs); | 721 | static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs); |
717 | static void ftdi_process_read (struct usb_serial_port *port); | 722 | static void ftdi_process_read (void *param); |
718 | static void ftdi_set_termios (struct usb_serial_port *port, struct termios * old); | 723 | static void ftdi_set_termios (struct usb_serial_port *port, struct termios * old); |
719 | static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file); | 724 | static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file); |
720 | static int ftdi_tiocmset (struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear); | 725 | static int ftdi_tiocmset (struct usb_serial_port *port, struct file * file, unsigned int set, unsigned int clear); |
@@ -1213,7 +1218,7 @@ check_and_exit: | |||
1213 | * *************************************************************************** | 1218 | * *************************************************************************** |
1214 | */ | 1219 | */ |
1215 | 1220 | ||
1216 | static ssize_t show_latency_timer(struct device *dev, char *buf) | 1221 | static ssize_t show_latency_timer(struct device *dev, struct device_attribute *attr, char *buf) |
1217 | { | 1222 | { |
1218 | struct usb_serial_port *port = to_usb_serial_port(dev); | 1223 | struct usb_serial_port *port = to_usb_serial_port(dev); |
1219 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1224 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
@@ -1240,7 +1245,7 @@ static ssize_t show_latency_timer(struct device *dev, char *buf) | |||
1240 | } | 1245 | } |
1241 | 1246 | ||
1242 | /* Write a new value of the latency timer, in units of milliseconds. */ | 1247 | /* Write a new value of the latency timer, in units of milliseconds. */ |
1243 | static ssize_t store_latency_timer(struct device *dev, const char *valbuf, | 1248 | static ssize_t store_latency_timer(struct device *dev, struct device_attribute *attr, const char *valbuf, |
1244 | size_t count) | 1249 | size_t count) |
1245 | { | 1250 | { |
1246 | struct usb_serial_port *port = to_usb_serial_port(dev); | 1251 | struct usb_serial_port *port = to_usb_serial_port(dev); |
@@ -1271,7 +1276,7 @@ static ssize_t store_latency_timer(struct device *dev, const char *valbuf, | |||
1271 | 1276 | ||
1272 | /* Write an event character directly to the FTDI register. The ASCII | 1277 | /* Write an event character directly to the FTDI register. The ASCII |
1273 | value is in the low 8 bits, with the enable bit in the 9th bit. */ | 1278 | value is in the low 8 bits, with the enable bit in the 9th bit. */ |
1274 | static ssize_t store_event_char(struct device *dev, const char *valbuf, | 1279 | static ssize_t store_event_char(struct device *dev, struct device_attribute *attr, const char *valbuf, |
1275 | size_t count) | 1280 | size_t count) |
1276 | { | 1281 | { |
1277 | struct usb_serial_port *port = to_usb_serial_port(dev); | 1282 | struct usb_serial_port *port = to_usb_serial_port(dev); |
@@ -1384,6 +1389,8 @@ static int ftdi_common_startup (struct usb_serial *serial) | |||
1384 | port->read_urb->transfer_buffer_length = BUFSZ; | 1389 | port->read_urb->transfer_buffer_length = BUFSZ; |
1385 | } | 1390 | } |
1386 | 1391 | ||
1392 | INIT_WORK(&priv->rx_work, ftdi_process_read, port); | ||
1393 | |||
1387 | /* Free port's existing write urb and transfer buffer. */ | 1394 | /* Free port's existing write urb and transfer buffer. */ |
1388 | if (port->write_urb) { | 1395 | if (port->write_urb) { |
1389 | usb_free_urb (port->write_urb); | 1396 | usb_free_urb (port->write_urb); |
@@ -1614,6 +1621,7 @@ static int ftdi_open (struct usb_serial_port *port, struct file *filp) | |||
1614 | spin_unlock_irqrestore(&priv->rx_lock, flags); | 1621 | spin_unlock_irqrestore(&priv->rx_lock, flags); |
1615 | 1622 | ||
1616 | /* Start reading from the device */ | 1623 | /* Start reading from the device */ |
1624 | priv->rx_processed = 0; | ||
1617 | usb_fill_bulk_urb(port->read_urb, dev, | 1625 | usb_fill_bulk_urb(port->read_urb, dev, |
1618 | usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress), | 1626 | usb_rcvbulkpipe(dev, port->bulk_in_endpointAddress), |
1619 | port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, | 1627 | port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length, |
@@ -1664,6 +1672,10 @@ static void ftdi_close (struct usb_serial_port *port, struct file *filp) | |||
1664 | err("Error from RTS LOW urb"); | 1672 | err("Error from RTS LOW urb"); |
1665 | } | 1673 | } |
1666 | } /* Note change no line if hupcl is off */ | 1674 | } /* Note change no line if hupcl is off */ |
1675 | |||
1676 | /* cancel any scheduled reading */ | ||
1677 | cancel_delayed_work(&priv->rx_work); | ||
1678 | flush_scheduled_work(); | ||
1667 | 1679 | ||
1668 | /* shutdown our bulk read */ | 1680 | /* shutdown our bulk read */ |
1669 | if (port->read_urb) | 1681 | if (port->read_urb) |
@@ -1859,23 +1871,14 @@ static void ftdi_read_bulk_callback (struct urb *urb, struct pt_regs *regs) | |||
1859 | return; | 1871 | return; |
1860 | } | 1872 | } |
1861 | 1873 | ||
1862 | /* If throttled, delay receive processing until unthrottled. */ | ||
1863 | spin_lock(&priv->rx_lock); | ||
1864 | if (priv->rx_flags & THROTTLED) { | ||
1865 | dbg("Deferring read urb processing until unthrottled"); | ||
1866 | priv->rx_flags |= ACTUALLY_THROTTLED; | ||
1867 | spin_unlock(&priv->rx_lock); | ||
1868 | return; | ||
1869 | } | ||
1870 | spin_unlock(&priv->rx_lock); | ||
1871 | |||
1872 | ftdi_process_read(port); | 1874 | ftdi_process_read(port); |
1873 | 1875 | ||
1874 | } /* ftdi_read_bulk_callback */ | 1876 | } /* ftdi_read_bulk_callback */ |
1875 | 1877 | ||
1876 | 1878 | ||
1877 | static void ftdi_process_read (struct usb_serial_port *port) | 1879 | static void ftdi_process_read (void *param) |
1878 | { /* ftdi_process_read */ | 1880 | { /* ftdi_process_read */ |
1881 | struct usb_serial_port *port = (struct usb_serial_port*)param; | ||
1879 | struct urb *urb; | 1882 | struct urb *urb; |
1880 | struct tty_struct *tty; | 1883 | struct tty_struct *tty; |
1881 | struct ftdi_private *priv; | 1884 | struct ftdi_private *priv; |
@@ -1886,6 +1889,7 @@ static void ftdi_process_read (struct usb_serial_port *port) | |||
1886 | int result; | 1889 | int result; |
1887 | int need_flip; | 1890 | int need_flip; |
1888 | int packet_offset; | 1891 | int packet_offset; |
1892 | unsigned long flags; | ||
1889 | 1893 | ||
1890 | dbg("%s - port %d", __FUNCTION__, port->number); | 1894 | dbg("%s - port %d", __FUNCTION__, port->number); |
1891 | 1895 | ||
@@ -1912,12 +1916,18 @@ static void ftdi_process_read (struct usb_serial_port *port) | |||
1912 | 1916 | ||
1913 | data = urb->transfer_buffer; | 1917 | data = urb->transfer_buffer; |
1914 | 1918 | ||
1915 | /* The first two bytes of every read packet are status */ | 1919 | if (priv->rx_processed) { |
1916 | if (urb->actual_length > 2) { | 1920 | dbg("%s - already processed: %d bytes, %d remain", __FUNCTION__, |
1917 | usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); | 1921 | priv->rx_processed, |
1922 | urb->actual_length - priv->rx_processed); | ||
1918 | } else { | 1923 | } else { |
1919 | dbg("Status only: %03oo %03oo",data[0],data[1]); | 1924 | /* The first two bytes of every read packet are status */ |
1920 | } | 1925 | if (urb->actual_length > 2) { |
1926 | usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); | ||
1927 | } else { | ||
1928 | dbg("Status only: %03oo %03oo",data[0],data[1]); | ||
1929 | } | ||
1930 | } | ||
1921 | 1931 | ||
1922 | 1932 | ||
1923 | /* TO DO -- check for hung up line and handle appropriately: */ | 1933 | /* TO DO -- check for hung up line and handle appropriately: */ |
@@ -1926,8 +1936,12 @@ static void ftdi_process_read (struct usb_serial_port *port) | |||
1926 | /* if CD is dropped and the line is not CLOCAL then we should hangup */ | 1936 | /* if CD is dropped and the line is not CLOCAL then we should hangup */ |
1927 | 1937 | ||
1928 | need_flip = 0; | 1938 | need_flip = 0; |
1929 | for (packet_offset=0; packet_offset < urb->actual_length; packet_offset += PKTSZ) { | 1939 | for (packet_offset = priv->rx_processed; packet_offset < urb->actual_length; packet_offset += PKTSZ) { |
1940 | int length; | ||
1941 | |||
1930 | /* Compare new line status to the old one, signal if different */ | 1942 | /* Compare new line status to the old one, signal if different */ |
1943 | /* N.B. packet may be processed more than once, but differences | ||
1944 | * are only processed once. */ | ||
1931 | if (priv != NULL) { | 1945 | if (priv != NULL) { |
1932 | char new_status = data[packet_offset+0] & FTDI_STATUS_B0_MASK; | 1946 | char new_status = data[packet_offset+0] & FTDI_STATUS_B0_MASK; |
1933 | if (new_status != priv->prev_status) { | 1947 | if (new_status != priv->prev_status) { |
@@ -1937,6 +1951,35 @@ static void ftdi_process_read (struct usb_serial_port *port) | |||
1937 | } | 1951 | } |
1938 | } | 1952 | } |
1939 | 1953 | ||
1954 | length = min(PKTSZ, urb->actual_length-packet_offset)-2; | ||
1955 | if (length < 0) { | ||
1956 | err("%s - bad packet length: %d", __FUNCTION__, length+2); | ||
1957 | length = 0; | ||
1958 | } | ||
1959 | |||
1960 | /* have to make sure we don't overflow the buffer | ||
1961 | with tty_insert_flip_char's */ | ||
1962 | if (tty->flip.count+length > TTY_FLIPBUF_SIZE) { | ||
1963 | tty_flip_buffer_push(tty); | ||
1964 | need_flip = 0; | ||
1965 | |||
1966 | if (tty->flip.count != 0) { | ||
1967 | /* flip didn't work, this happens when ftdi_process_read() is | ||
1968 | * called from ftdi_unthrottle, because TTY_DONT_FLIP is set */ | ||
1969 | dbg("%s - flip buffer push failed", __FUNCTION__); | ||
1970 | break; | ||
1971 | } | ||
1972 | } | ||
1973 | if (priv->rx_flags & THROTTLED) { | ||
1974 | dbg("%s - throttled", __FUNCTION__); | ||
1975 | break; | ||
1976 | } | ||
1977 | if (tty->ldisc.receive_room(tty)-tty->flip.count < length) { | ||
1978 | /* break out & wait for throttling/unthrottling to happen */ | ||
1979 | dbg("%s - receive room low", __FUNCTION__); | ||
1980 | break; | ||
1981 | } | ||
1982 | |||
1940 | /* Handle errors and break */ | 1983 | /* Handle errors and break */ |
1941 | error_flag = TTY_NORMAL; | 1984 | error_flag = TTY_NORMAL; |
1942 | /* Although the device uses a bitmask and hence can have multiple */ | 1985 | /* Although the device uses a bitmask and hence can have multiple */ |
@@ -1959,13 +2002,8 @@ static void ftdi_process_read (struct usb_serial_port *port) | |||
1959 | error_flag = TTY_FRAME; | 2002 | error_flag = TTY_FRAME; |
1960 | dbg("FRAMING error"); | 2003 | dbg("FRAMING error"); |
1961 | } | 2004 | } |
1962 | if (urb->actual_length > packet_offset + 2) { | 2005 | if (length > 0) { |
1963 | for (i = 2; (i < PKTSZ) && ((i+packet_offset) < urb->actual_length); ++i) { | 2006 | for (i = 2; i < length+2; i++) { |
1964 | /* have to make sure we don't overflow the buffer | ||
1965 | with tty_insert_flip_char's */ | ||
1966 | if(tty->flip.count >= TTY_FLIPBUF_SIZE) { | ||
1967 | tty_flip_buffer_push(tty); | ||
1968 | } | ||
1969 | /* Note that the error flag is duplicated for | 2007 | /* Note that the error flag is duplicated for |
1970 | every character received since we don't know | 2008 | every character received since we don't know |
1971 | which character it applied to */ | 2009 | which character it applied to */ |
@@ -2002,6 +2040,35 @@ static void ftdi_process_read (struct usb_serial_port *port) | |||
2002 | tty_flip_buffer_push(tty); | 2040 | tty_flip_buffer_push(tty); |
2003 | } | 2041 | } |
2004 | 2042 | ||
2043 | if (packet_offset < urb->actual_length) { | ||
2044 | /* not completely processed - record progress */ | ||
2045 | priv->rx_processed = packet_offset; | ||
2046 | dbg("%s - incomplete, %d bytes processed, %d remain", | ||
2047 | __FUNCTION__, packet_offset, | ||
2048 | urb->actual_length - packet_offset); | ||
2049 | /* check if we were throttled while processing */ | ||
2050 | spin_lock_irqsave(&priv->rx_lock, flags); | ||
2051 | if (priv->rx_flags & THROTTLED) { | ||
2052 | priv->rx_flags |= ACTUALLY_THROTTLED; | ||
2053 | spin_unlock_irqrestore(&priv->rx_lock, flags); | ||
2054 | dbg("%s - deferring remainder until unthrottled", | ||
2055 | __FUNCTION__); | ||
2056 | return; | ||
2057 | } | ||
2058 | spin_unlock_irqrestore(&priv->rx_lock, flags); | ||
2059 | /* if the port is closed stop trying to read */ | ||
2060 | if (port->open_count > 0){ | ||
2061 | /* delay processing of remainder */ | ||
2062 | schedule_delayed_work(&priv->rx_work, 1); | ||
2063 | } else { | ||
2064 | dbg("%s - port is closed", __FUNCTION__); | ||
2065 | } | ||
2066 | return; | ||
2067 | } | ||
2068 | |||
2069 | /* urb is completely processed */ | ||
2070 | priv->rx_processed = 0; | ||
2071 | |||
2005 | /* if the port is closed stop trying to read */ | 2072 | /* if the port is closed stop trying to read */ |
2006 | if (port->open_count > 0){ | 2073 | if (port->open_count > 0){ |
2007 | /* Continue trying to always read */ | 2074 | /* Continue trying to always read */ |
@@ -2441,7 +2508,7 @@ static void ftdi_unthrottle (struct usb_serial_port *port) | |||
2441 | spin_unlock_irqrestore(&priv->rx_lock, flags); | 2508 | spin_unlock_irqrestore(&priv->rx_lock, flags); |
2442 | 2509 | ||
2443 | if (actually_throttled) | 2510 | if (actually_throttled) |
2444 | ftdi_process_read(port); | 2511 | schedule_work(&priv->rx_work); |
2445 | } | 2512 | } |
2446 | 2513 | ||
2447 | static int __init ftdi_init (void) | 2514 | static int __init ftdi_init (void) |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index a52bb13a9ce4..8866376823a5 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -144,6 +144,8 @@ | |||
144 | 144 | ||
145 | /* ELV USB Module UO100 (PID sent by Stefan Frings) */ | 145 | /* ELV USB Module UO100 (PID sent by Stefan Frings) */ |
146 | #define FTDI_ELV_UO100_PID 0xFB58 /* Product Id */ | 146 | #define FTDI_ELV_UO100_PID 0xFB58 /* Product Id */ |
147 | /* ELV USB Module UM100 (PID sent by Arnim Laeuger) */ | ||
148 | #define FTDI_ELV_UM100_PID 0xFB5A /* Product Id */ | ||
147 | 149 | ||
148 | /* | 150 | /* |
149 | * Definitions for ID TECH (www.idt-net.com) devices | 151 | * Definitions for ID TECH (www.idt-net.com) devices |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c new file mode 100644 index 000000000000..b722175f108f --- /dev/null +++ b/drivers/usb/serial/option.c | |||
@@ -0,0 +1,729 @@ | |||
1 | /* | ||
2 | Option Card (PCMCIA to) USB to Serial Driver | ||
3 | |||
4 | Copyright (C) 2005 Matthias Urlichs <smurf@smurf.noris.de> | ||
5 | |||
6 | This driver is free software; you can redistribute it and/or modify | ||
7 | it under the terms of Version 2 of the GNU General Public License as | ||
8 | published by the Free Software Foundation. | ||
9 | |||
10 | Portions copied from the Keyspan driver by Hugh Blemings <hugh@blemings.org> | ||
11 | |||
12 | History: | ||
13 | |||
14 | 2005-05-19 v0.1 Initial version, based on incomplete docs | ||
15 | and analysis of misbehavior of the standard driver | ||
16 | 2005-05-20 v0.2 Extended the input buffer to avoid losing | ||
17 | random 64-byte chunks of data | ||
18 | 2005-05-21 v0.3 implemented chars_in_buffer() | ||
19 | turned on low_latency | ||
20 | simplified the code somewhat | ||
21 | */ | ||
22 | #define DRIVER_VERSION "v0.3" | ||
23 | #define DRIVER_AUTHOR "Matthias Urlichs <smurf@smurf.noris.de>" | ||
24 | #define DRIVER_DESC "Option Card (PC-Card to) USB to Serial Driver" | ||
25 | |||
26 | #include <linux/config.h> | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/jiffies.h> | ||
29 | #include <linux/errno.h> | ||
30 | #include <linux/tty.h> | ||
31 | #include <linux/tty_flip.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/usb.h> | ||
34 | #include "usb-serial.h" | ||
35 | |||
36 | /* Function prototypes */ | ||
37 | static int option_open (struct usb_serial_port *port, struct file *filp); | ||
38 | static void option_close (struct usb_serial_port *port, struct file *filp); | ||
39 | static int option_startup (struct usb_serial *serial); | ||
40 | static void option_shutdown (struct usb_serial *serial); | ||
41 | static void option_rx_throttle (struct usb_serial_port *port); | ||
42 | static void option_rx_unthrottle (struct usb_serial_port *port); | ||
43 | static int option_write_room (struct usb_serial_port *port); | ||
44 | |||
45 | static void option_instat_callback(struct urb *urb, struct pt_regs *regs); | ||
46 | |||
47 | |||
48 | static int option_write (struct usb_serial_port *port, | ||
49 | const unsigned char *buf, int count); | ||
50 | |||
51 | static int option_chars_in_buffer (struct usb_serial_port *port); | ||
52 | static int option_ioctl (struct usb_serial_port *port, struct file *file, | ||
53 | unsigned int cmd, unsigned long arg); | ||
54 | static void option_set_termios (struct usb_serial_port *port, | ||
55 | struct termios *old); | ||
56 | static void option_break_ctl (struct usb_serial_port *port, int break_state); | ||
57 | static int option_tiocmget (struct usb_serial_port *port, struct file *file); | ||
58 | static int option_tiocmset (struct usb_serial_port *port, struct file *file, | ||
59 | unsigned int set, unsigned int clear); | ||
60 | static int option_send_setup (struct usb_serial_port *port); | ||
61 | |||
62 | /* Vendor and product IDs */ | ||
63 | #define OPTION_VENDOR_ID 0x0AF0 | ||
64 | |||
65 | #define OPTION_PRODUCT_OLD 0x5000 | ||
66 | #define OPTION_PRODUCT_WLAN 0x6000 | ||
67 | |||
68 | static struct usb_device_id option_ids[] = { | ||
69 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) }, | ||
70 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_WLAN) }, | ||
71 | { } /* Terminating entry */ | ||
72 | }; | ||
73 | |||
74 | MODULE_DEVICE_TABLE(usb, option_ids); | ||
75 | |||
76 | static struct usb_driver option_driver = { | ||
77 | .owner = THIS_MODULE, | ||
78 | .name = "option", | ||
79 | .probe = usb_serial_probe, | ||
80 | .disconnect = usb_serial_disconnect, | ||
81 | .id_table = option_ids, | ||
82 | }; | ||
83 | |||
84 | /* The card has three separate interfaces, wich the serial driver | ||
85 | * recognizes separately, thus num_port=1. | ||
86 | */ | ||
87 | static struct usb_serial_device_type option_3port_device = { | ||
88 | .owner = THIS_MODULE, | ||
89 | .name = "Option 3-port card", | ||
90 | .short_name = "option", | ||
91 | .id_table = option_ids, | ||
92 | .num_interrupt_in = NUM_DONT_CARE, | ||
93 | .num_bulk_in = NUM_DONT_CARE, | ||
94 | .num_bulk_out = NUM_DONT_CARE, | ||
95 | .num_ports = 1, /* 3 */ | ||
96 | .open = option_open, | ||
97 | .close = option_close, | ||
98 | .write = option_write, | ||
99 | .write_room = option_write_room, | ||
100 | .chars_in_buffer = option_chars_in_buffer, | ||
101 | .throttle = option_rx_throttle, | ||
102 | .unthrottle = option_rx_unthrottle, | ||
103 | .ioctl = option_ioctl, | ||
104 | .set_termios = option_set_termios, | ||
105 | .break_ctl = option_break_ctl, | ||
106 | .tiocmget = option_tiocmget, | ||
107 | .tiocmset = option_tiocmset, | ||
108 | .attach = option_startup, | ||
109 | .shutdown = option_shutdown, | ||
110 | .read_int_callback = option_instat_callback, | ||
111 | }; | ||
112 | |||
113 | static int debug; | ||
114 | |||
115 | /* per port private data */ | ||
116 | |||
117 | #define N_IN_URB 4 | ||
118 | #define N_OUT_URB 1 | ||
119 | #define IN_BUFLEN 1024 | ||
120 | #define OUT_BUFLEN 1024 | ||
121 | |||
122 | struct option_port_private { | ||
123 | /* Input endpoints and buffer for this port */ | ||
124 | struct urb *in_urbs[N_IN_URB]; | ||
125 | char in_buffer[N_IN_URB][IN_BUFLEN]; | ||
126 | /* Output endpoints and buffer for this port */ | ||
127 | struct urb *out_urbs[N_OUT_URB]; | ||
128 | char out_buffer[N_OUT_URB][OUT_BUFLEN]; | ||
129 | |||
130 | /* Settings for the port */ | ||
131 | int rts_state; /* Handshaking pins (outputs) */ | ||
132 | int dtr_state; | ||
133 | int cts_state; /* Handshaking pins (inputs) */ | ||
134 | int dsr_state; | ||
135 | int dcd_state; | ||
136 | int ri_state; | ||
137 | // int break_on; | ||
138 | |||
139 | unsigned long tx_start_time[N_OUT_URB]; | ||
140 | }; | ||
141 | |||
142 | |||
143 | /* Functions used by new usb-serial code. */ | ||
144 | static int __init | ||
145 | option_init (void) | ||
146 | { | ||
147 | int retval; | ||
148 | retval = usb_serial_register(&option_3port_device); | ||
149 | if (retval) | ||
150 | goto failed_3port_device_register; | ||
151 | retval = usb_register(&option_driver); | ||
152 | if (retval) | ||
153 | goto failed_driver_register; | ||
154 | |||
155 | info(DRIVER_DESC ": " DRIVER_VERSION); | ||
156 | |||
157 | return 0; | ||
158 | |||
159 | failed_driver_register: | ||
160 | usb_serial_deregister (&option_3port_device); | ||
161 | failed_3port_device_register: | ||
162 | return retval; | ||
163 | } | ||
164 | |||
165 | static void __exit | ||
166 | option_exit (void) | ||
167 | { | ||
168 | usb_deregister (&option_driver); | ||
169 | usb_serial_deregister (&option_3port_device); | ||
170 | } | ||
171 | |||
172 | module_init(option_init); | ||
173 | module_exit(option_exit); | ||
174 | |||
175 | static void | ||
176 | option_rx_throttle (struct usb_serial_port *port) | ||
177 | { | ||
178 | dbg("%s", __FUNCTION__); | ||
179 | } | ||
180 | |||
181 | |||
182 | static void | ||
183 | option_rx_unthrottle (struct usb_serial_port *port) | ||
184 | { | ||
185 | dbg("%s", __FUNCTION__); | ||
186 | } | ||
187 | |||
188 | |||
189 | static void | ||
190 | option_break_ctl (struct usb_serial_port *port, int break_state) | ||
191 | { | ||
192 | /* Unfortunately, I don't know how to send a break */ | ||
193 | dbg("%s", __FUNCTION__); | ||
194 | } | ||
195 | |||
196 | |||
197 | static void | ||
198 | option_set_termios (struct usb_serial_port *port, | ||
199 | struct termios *old_termios) | ||
200 | { | ||
201 | dbg("%s", __FUNCTION__); | ||
202 | |||
203 | option_send_setup(port); | ||
204 | } | ||
205 | |||
206 | static int | ||
207 | option_tiocmget(struct usb_serial_port *port, struct file *file) | ||
208 | { | ||
209 | unsigned int value; | ||
210 | struct option_port_private *portdata; | ||
211 | |||
212 | portdata = usb_get_serial_port_data(port); | ||
213 | |||
214 | value = ((portdata->rts_state) ? TIOCM_RTS : 0) | | ||
215 | ((portdata->dtr_state) ? TIOCM_DTR : 0) | | ||
216 | ((portdata->cts_state) ? TIOCM_CTS : 0) | | ||
217 | ((portdata->dsr_state) ? TIOCM_DSR : 0) | | ||
218 | ((portdata->dcd_state) ? TIOCM_CAR : 0) | | ||
219 | ((portdata->ri_state) ? TIOCM_RNG : 0); | ||
220 | |||
221 | return value; | ||
222 | } | ||
223 | |||
224 | static int | ||
225 | option_tiocmset (struct usb_serial_port *port, struct file *file, | ||
226 | unsigned int set, unsigned int clear) | ||
227 | { | ||
228 | struct option_port_private *portdata; | ||
229 | |||
230 | portdata = usb_get_serial_port_data(port); | ||
231 | |||
232 | if (set & TIOCM_RTS) | ||
233 | portdata->rts_state = 1; | ||
234 | if (set & TIOCM_DTR) | ||
235 | portdata->dtr_state = 1; | ||
236 | |||
237 | if (clear & TIOCM_RTS) | ||
238 | portdata->rts_state = 0; | ||
239 | if (clear & TIOCM_DTR) | ||
240 | portdata->dtr_state = 0; | ||
241 | return option_send_setup(port); | ||
242 | } | ||
243 | |||
244 | static int | ||
245 | option_ioctl (struct usb_serial_port *port, struct file *file, | ||
246 | unsigned int cmd, unsigned long arg) | ||
247 | { | ||
248 | return -ENOIOCTLCMD; | ||
249 | } | ||
250 | |||
251 | /* Write */ | ||
252 | static int | ||
253 | option_write(struct usb_serial_port *port, | ||
254 | const unsigned char *buf, int count) | ||
255 | { | ||
256 | struct option_port_private *portdata; | ||
257 | int i; | ||
258 | int left, todo; | ||
259 | struct urb *this_urb = NULL; /* spurious */ | ||
260 | int err; | ||
261 | |||
262 | portdata = usb_get_serial_port_data(port); | ||
263 | |||
264 | dbg("%s: write (%d chars)", __FUNCTION__, count); | ||
265 | |||
266 | #if 0 | ||
267 | spin_lock(&port->lock); | ||
268 | if (port->write_urb_busy) { | ||
269 | spin_unlock(&port->lock); | ||
270 | dbg("%s: already writing", __FUNCTION__); | ||
271 | return 0; | ||
272 | } | ||
273 | port->write_urb_busy = 1; | ||
274 | spin_unlock(&port->lock); | ||
275 | #endif | ||
276 | |||
277 | i = 0; | ||
278 | left = count; | ||
279 | while (left>0) { | ||
280 | todo = left; | ||
281 | if (todo > OUT_BUFLEN) | ||
282 | todo = OUT_BUFLEN; | ||
283 | |||
284 | for (;i < N_OUT_URB; i++) { | ||
285 | /* Check we have a valid urb/endpoint before we use it... */ | ||
286 | this_urb = portdata->out_urbs[i]; | ||
287 | if (this_urb->status != -EINPROGRESS) | ||
288 | break; | ||
289 | if (this_urb->transfer_flags & URB_ASYNC_UNLINK) | ||
290 | continue; | ||
291 | if (time_before(jiffies, portdata->tx_start_time[i] + 10 * HZ)) | ||
292 | continue; | ||
293 | this_urb->transfer_flags |= URB_ASYNC_UNLINK; | ||
294 | usb_unlink_urb(this_urb); | ||
295 | } | ||
296 | |||
297 | if (i == N_OUT_URB) { | ||
298 | /* no bulk out free! */ | ||
299 | dbg("%s: no output urb -- left %d", __FUNCTION__,count-left); | ||
300 | #if 0 | ||
301 | port->write_urb_busy = 0; | ||
302 | #endif | ||
303 | return count-left; | ||
304 | } | ||
305 | |||
306 | dbg("%s: endpoint %d buf %d", __FUNCTION__, usb_pipeendpoint(this_urb->pipe), i); | ||
307 | |||
308 | memcpy (this_urb->transfer_buffer, buf, todo); | ||
309 | |||
310 | /* send the data out the bulk port */ | ||
311 | this_urb->transfer_buffer_length = todo; | ||
312 | |||
313 | this_urb->transfer_flags &= ~URB_ASYNC_UNLINK; | ||
314 | this_urb->dev = port->serial->dev; | ||
315 | err = usb_submit_urb(this_urb, GFP_ATOMIC); | ||
316 | if (err) { | ||
317 | dbg("usb_submit_urb %p (write bulk) failed (%d,, has %d)", this_urb, err, this_urb->status); | ||
318 | continue; | ||
319 | } | ||
320 | portdata->tx_start_time[i] = jiffies; | ||
321 | buf += todo; | ||
322 | left -= todo; | ||
323 | } | ||
324 | |||
325 | count -= left; | ||
326 | #if 0 | ||
327 | port->write_urb_busy = 0; | ||
328 | #endif | ||
329 | dbg("%s: wrote (did %d)", __FUNCTION__, count); | ||
330 | return count; | ||
331 | } | ||
332 | |||
333 | static void | ||
334 | option_indat_callback (struct urb *urb, struct pt_regs *regs) | ||
335 | { | ||
336 | int i, err; | ||
337 | int endpoint; | ||
338 | struct usb_serial_port *port; | ||
339 | struct tty_struct *tty; | ||
340 | unsigned char *data = urb->transfer_buffer; | ||
341 | |||
342 | dbg("%s: %p", __FUNCTION__, urb); | ||
343 | |||
344 | endpoint = usb_pipeendpoint(urb->pipe); | ||
345 | port = (struct usb_serial_port *) urb->context; | ||
346 | |||
347 | if (urb->status) { | ||
348 | dbg("%s: nonzero status: %d on endpoint %02x.", | ||
349 | __FUNCTION__, urb->status, endpoint); | ||
350 | } else { | ||
351 | tty = port->tty; | ||
352 | if (urb->actual_length) { | ||
353 | for (i = 0; i < urb->actual_length ; ++i) { | ||
354 | if (tty->flip.count >= TTY_FLIPBUF_SIZE) | ||
355 | tty_flip_buffer_push(tty); | ||
356 | tty_insert_flip_char(tty, data[i], 0); | ||
357 | } | ||
358 | tty_flip_buffer_push(tty); | ||
359 | } else { | ||
360 | dbg("%s: empty read urb received", __FUNCTION__); | ||
361 | } | ||
362 | |||
363 | /* Resubmit urb so we continue receiving */ | ||
364 | if (port->open_count && urb->status != -ESHUTDOWN) { | ||
365 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
366 | if (err) | ||
367 | printk(KERN_ERR "%s: resubmit read urb failed. (%d)", __FUNCTION__, err); | ||
368 | } | ||
369 | } | ||
370 | return; | ||
371 | } | ||
372 | |||
373 | static void | ||
374 | option_outdat_callback (struct urb *urb, struct pt_regs *regs) | ||
375 | { | ||
376 | struct usb_serial_port *port; | ||
377 | |||
378 | dbg("%s", __FUNCTION__); | ||
379 | |||
380 | port = (struct usb_serial_port *) urb->context; | ||
381 | |||
382 | if (port->open_count) | ||
383 | schedule_work(&port->work); | ||
384 | } | ||
385 | |||
386 | static void | ||
387 | option_instat_callback (struct urb *urb, struct pt_regs *regs) | ||
388 | { | ||
389 | int err; | ||
390 | struct usb_serial_port *port = (struct usb_serial_port *) urb->context; | ||
391 | struct option_port_private *portdata = usb_get_serial_port_data(port); | ||
392 | struct usb_serial *serial = port->serial; | ||
393 | |||
394 | dbg("%s", __FUNCTION__); | ||
395 | dbg("%s: urb %p port %p has data %p", __FUNCTION__,urb,port,portdata); | ||
396 | |||
397 | if (urb->status == 0) { | ||
398 | struct usb_ctrlrequest *req_pkt = | ||
399 | (struct usb_ctrlrequest *)urb->transfer_buffer; | ||
400 | |||
401 | if (!req_pkt) { | ||
402 | dbg("%s: NULL req_pkt\n", __FUNCTION__); | ||
403 | return; | ||
404 | } | ||
405 | if ((req_pkt->bRequestType == 0xA1) && (req_pkt->bRequest == 0x20)) { | ||
406 | int old_dcd_state; | ||
407 | unsigned char signals = *((unsigned char *) | ||
408 | urb->transfer_buffer + sizeof(struct usb_ctrlrequest)); | ||
409 | |||
410 | dbg("%s: signal x%x", __FUNCTION__, signals); | ||
411 | |||
412 | old_dcd_state = portdata->dcd_state; | ||
413 | portdata->cts_state = 1; | ||
414 | portdata->dcd_state = ((signals & 0x01) ? 1 : 0); | ||
415 | portdata->dsr_state = ((signals & 0x02) ? 1 : 0); | ||
416 | portdata->ri_state = ((signals & 0x08) ? 1 : 0); | ||
417 | |||
418 | if (port->tty && !C_CLOCAL(port->tty) | ||
419 | && old_dcd_state && !portdata->dcd_state) { | ||
420 | tty_hangup(port->tty); | ||
421 | } | ||
422 | } else | ||
423 | dbg("%s: type %x req %x", __FUNCTION__, req_pkt->bRequestType,req_pkt->bRequest); | ||
424 | } else | ||
425 | dbg("%s: error %d", __FUNCTION__, urb->status); | ||
426 | |||
427 | /* Resubmit urb so we continue receiving IRQ data */ | ||
428 | if (urb->status != -ESHUTDOWN) { | ||
429 | urb->dev = serial->dev; | ||
430 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
431 | if (err) | ||
432 | dbg("%s: resubmit intr urb failed. (%d)", __FUNCTION__, err); | ||
433 | } | ||
434 | } | ||
435 | |||
436 | |||
437 | static int | ||
438 | option_write_room (struct usb_serial_port *port) | ||
439 | { | ||
440 | struct option_port_private *portdata; | ||
441 | int i; | ||
442 | int data_len = 0; | ||
443 | struct urb *this_urb; | ||
444 | |||
445 | portdata = usb_get_serial_port_data(port); | ||
446 | |||
447 | for (i=0; i < N_OUT_URB; i++) | ||
448 | this_urb = portdata->out_urbs[i]; | ||
449 | if (this_urb && this_urb->status != -EINPROGRESS) | ||
450 | data_len += OUT_BUFLEN; | ||
451 | |||
452 | dbg("%s: %d", __FUNCTION__, data_len); | ||
453 | return data_len; | ||
454 | } | ||
455 | |||
456 | |||
457 | static int | ||
458 | option_chars_in_buffer (struct usb_serial_port *port) | ||
459 | { | ||
460 | struct option_port_private *portdata; | ||
461 | int i; | ||
462 | int data_len = 0; | ||
463 | struct urb *this_urb; | ||
464 | |||
465 | portdata = usb_get_serial_port_data(port); | ||
466 | |||
467 | for (i=0; i < N_OUT_URB; i++) | ||
468 | this_urb = portdata->out_urbs[i]; | ||
469 | if (this_urb && this_urb->status == -EINPROGRESS) | ||
470 | data_len += this_urb->transfer_buffer_length; | ||
471 | |||
472 | dbg("%s: %d", __FUNCTION__, data_len); | ||
473 | return data_len; | ||
474 | } | ||
475 | |||
476 | |||
477 | static int | ||
478 | option_open (struct usb_serial_port *port, struct file *filp) | ||
479 | { | ||
480 | struct option_port_private *portdata; | ||
481 | struct usb_serial *serial = port->serial; | ||
482 | int i, err; | ||
483 | struct urb *urb; | ||
484 | |||
485 | portdata = usb_get_serial_port_data(port); | ||
486 | |||
487 | dbg("%s", __FUNCTION__); | ||
488 | |||
489 | /* Set some sane defaults */ | ||
490 | portdata->rts_state = 1; | ||
491 | portdata->dtr_state = 1; | ||
492 | |||
493 | /* Reset low level data toggle and start reading from endpoints */ | ||
494 | for (i = 0; i < N_IN_URB; i++) { | ||
495 | urb = portdata->in_urbs[i]; | ||
496 | if (! urb) | ||
497 | continue; | ||
498 | if (urb->dev != serial->dev) { | ||
499 | dbg("%s: dev %p != %p", __FUNCTION__, urb->dev, serial->dev); | ||
500 | continue; | ||
501 | } | ||
502 | |||
503 | /* make sure endpoint data toggle is synchronized with the device */ | ||
504 | |||
505 | usb_clear_halt(urb->dev, urb->pipe); | ||
506 | |||
507 | err = usb_submit_urb(urb, GFP_KERNEL); | ||
508 | if (err) { | ||
509 | dbg("%s: submit urb %d failed (%d) %d", __FUNCTION__, i, err, | ||
510 | urb->transfer_buffer_length); | ||
511 | } | ||
512 | } | ||
513 | |||
514 | /* Reset low level data toggle on out endpoints */ | ||
515 | for (i = 0; i < N_OUT_URB; i++) { | ||
516 | urb = portdata->out_urbs[i]; | ||
517 | if (! urb) | ||
518 | continue; | ||
519 | urb->dev = serial->dev; | ||
520 | /* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 0); */ | ||
521 | } | ||
522 | |||
523 | port->tty->low_latency = 1; | ||
524 | |||
525 | option_send_setup(port); | ||
526 | |||
527 | return (0); | ||
528 | } | ||
529 | |||
530 | static inline void | ||
531 | stop_urb(struct urb *urb) | ||
532 | { | ||
533 | if (urb && urb->status == -EINPROGRESS) { | ||
534 | urb->transfer_flags &= ~URB_ASYNC_UNLINK; | ||
535 | usb_kill_urb(urb); | ||
536 | } | ||
537 | } | ||
538 | |||
539 | static void | ||
540 | option_close(struct usb_serial_port *port, struct file *filp) | ||
541 | { | ||
542 | int i; | ||
543 | struct usb_serial *serial = port->serial; | ||
544 | struct option_port_private *portdata; | ||
545 | |||
546 | dbg("%s", __FUNCTION__); | ||
547 | portdata = usb_get_serial_port_data(port); | ||
548 | |||
549 | portdata->rts_state = 0; | ||
550 | portdata->dtr_state = 0; | ||
551 | |||
552 | if (serial->dev) { | ||
553 | option_send_setup(port); | ||
554 | |||
555 | /* Stop reading/writing urbs */ | ||
556 | for (i = 0; i < N_IN_URB; i++) | ||
557 | stop_urb(portdata->in_urbs[i]); | ||
558 | for (i = 0; i < N_OUT_URB; i++) | ||
559 | stop_urb(portdata->out_urbs[i]); | ||
560 | } | ||
561 | port->tty = NULL; | ||
562 | } | ||
563 | |||
564 | |||
565 | /* Helper functions used by option_setup_urbs */ | ||
566 | static struct urb * | ||
567 | option_setup_urb (struct usb_serial *serial, int endpoint, | ||
568 | int dir, void *ctx, char *buf, int len, | ||
569 | void (*callback)(struct urb *, struct pt_regs *regs)) | ||
570 | { | ||
571 | struct urb *urb; | ||
572 | |||
573 | if (endpoint == -1) | ||
574 | return NULL; /* endpoint not needed */ | ||
575 | |||
576 | urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */ | ||
577 | if (urb == NULL) { | ||
578 | dbg("%s: alloc for endpoint %d failed.", __FUNCTION__, endpoint); | ||
579 | return NULL; | ||
580 | } | ||
581 | |||
582 | /* Fill URB using supplied data. */ | ||
583 | usb_fill_bulk_urb(urb, serial->dev, | ||
584 | usb_sndbulkpipe(serial->dev, endpoint) | dir, | ||
585 | buf, len, callback, ctx); | ||
586 | |||
587 | return urb; | ||
588 | } | ||
589 | |||
590 | /* Setup urbs */ | ||
591 | static void | ||
592 | option_setup_urbs(struct usb_serial *serial) | ||
593 | { | ||
594 | int j; | ||
595 | struct usb_serial_port *port; | ||
596 | struct option_port_private *portdata; | ||
597 | |||
598 | dbg("%s", __FUNCTION__); | ||
599 | |||
600 | port = serial->port[0]; | ||
601 | portdata = usb_get_serial_port_data(port); | ||
602 | |||
603 | /* Do indat endpoints first */ | ||
604 | for (j = 0; j <= N_IN_URB; ++j) { | ||
605 | portdata->in_urbs[j] = option_setup_urb (serial, | ||
606 | port->bulk_in_endpointAddress, USB_DIR_IN, port, | ||
607 | portdata->in_buffer[j], IN_BUFLEN, option_indat_callback); | ||
608 | } | ||
609 | |||
610 | /* outdat endpoints */ | ||
611 | for (j = 0; j <= N_OUT_URB; ++j) { | ||
612 | portdata->out_urbs[j] = option_setup_urb (serial, | ||
613 | port->bulk_out_endpointAddress, USB_DIR_OUT, port, | ||
614 | portdata->out_buffer[j], OUT_BUFLEN, option_outdat_callback); | ||
615 | } | ||
616 | } | ||
617 | |||
618 | |||
619 | static int | ||
620 | option_send_setup(struct usb_serial_port *port) | ||
621 | { | ||
622 | struct usb_serial *serial = port->serial; | ||
623 | struct option_port_private *portdata; | ||
624 | |||
625 | dbg("%s", __FUNCTION__); | ||
626 | |||
627 | portdata = usb_get_serial_port_data(port); | ||
628 | |||
629 | if (port->tty) { | ||
630 | int val = 0; | ||
631 | if (portdata->dtr_state) | ||
632 | val |= 0x01; | ||
633 | if (portdata->rts_state) | ||
634 | val |= 0x02; | ||
635 | |||
636 | return usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), | ||
637 | 0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT); | ||
638 | } | ||
639 | |||
640 | return 0; | ||
641 | } | ||
642 | |||
643 | |||
644 | static int | ||
645 | option_startup (struct usb_serial *serial) | ||
646 | { | ||
647 | int i, err; | ||
648 | struct usb_serial_port *port; | ||
649 | struct option_port_private *portdata; | ||
650 | |||
651 | dbg("%s", __FUNCTION__); | ||
652 | |||
653 | /* Now setup per port private data */ | ||
654 | for (i = 0; i < serial->num_ports; i++) { | ||
655 | port = serial->port[i]; | ||
656 | portdata = kmalloc(sizeof(struct option_port_private), GFP_KERNEL); | ||
657 | if (!portdata) { | ||
658 | dbg("%s: kmalloc for option_port_private (%d) failed!.", __FUNCTION__, i); | ||
659 | return (1); | ||
660 | } | ||
661 | memset(portdata, 0, sizeof(struct option_port_private)); | ||
662 | |||
663 | usb_set_serial_port_data(port, portdata); | ||
664 | |||
665 | if (! port->interrupt_in_urb) | ||
666 | continue; | ||
667 | err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); | ||
668 | if (err) | ||
669 | dbg("%s: submit irq_in urb failed %d", __FUNCTION__, err); | ||
670 | } | ||
671 | |||
672 | option_setup_urbs(serial); | ||
673 | |||
674 | return (0); | ||
675 | } | ||
676 | |||
677 | static void | ||
678 | option_shutdown (struct usb_serial *serial) | ||
679 | { | ||
680 | int i, j; | ||
681 | struct usb_serial_port *port; | ||
682 | struct option_port_private *portdata; | ||
683 | |||
684 | dbg("%s", __FUNCTION__); | ||
685 | |||
686 | /* Stop reading/writing urbs */ | ||
687 | for (i = 0; i < serial->num_ports; ++i) { | ||
688 | port = serial->port[i]; | ||
689 | portdata = usb_get_serial_port_data(port); | ||
690 | for (j = 0; j < N_IN_URB; j++) | ||
691 | stop_urb(portdata->in_urbs[j]); | ||
692 | for (j = 0; j < N_OUT_URB; j++) | ||
693 | stop_urb(portdata->out_urbs[j]); | ||
694 | } | ||
695 | |||
696 | /* Now free them */ | ||
697 | for (i = 0; i < serial->num_ports; ++i) { | ||
698 | port = serial->port[i]; | ||
699 | portdata = usb_get_serial_port_data(port); | ||
700 | |||
701 | for (j = 0; j < N_IN_URB; j++) { | ||
702 | if (portdata->in_urbs[j]) { | ||
703 | usb_free_urb(portdata->in_urbs[j]); | ||
704 | portdata->in_urbs[j] = NULL; | ||
705 | } | ||
706 | } | ||
707 | for (j = 0; j < N_OUT_URB; j++) { | ||
708 | if (portdata->out_urbs[j]) { | ||
709 | usb_free_urb(portdata->out_urbs[j]); | ||
710 | portdata->out_urbs[j] = NULL; | ||
711 | } | ||
712 | } | ||
713 | } | ||
714 | |||
715 | /* Now free per port private data */ | ||
716 | for (i = 0; i < serial->num_ports; i++) { | ||
717 | port = serial->port[i]; | ||
718 | kfree(usb_get_serial_port_data(port)); | ||
719 | } | ||
720 | } | ||
721 | |||
722 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
723 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
724 | MODULE_VERSION(DRIVER_VERSION); | ||
725 | MODULE_LICENSE("GPL"); | ||
726 | |||
727 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
728 | MODULE_PARM_DESC(debug, "Debug messages"); | ||
729 | |||
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 4536f63faaea..5da76dd8fb28 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -1297,13 +1297,6 @@ static int __init usb_serial_init(void) | |||
1297 | goto exit_bus; | 1297 | goto exit_bus; |
1298 | } | 1298 | } |
1299 | 1299 | ||
1300 | /* register the generic driver, if we should */ | ||
1301 | result = usb_serial_generic_register(debug); | ||
1302 | if (result < 0) { | ||
1303 | err("%s - registering generic driver failed", __FUNCTION__); | ||
1304 | goto exit_generic; | ||
1305 | } | ||
1306 | |||
1307 | usb_serial_tty_driver->owner = THIS_MODULE; | 1300 | usb_serial_tty_driver->owner = THIS_MODULE; |
1308 | usb_serial_tty_driver->driver_name = "usbserial"; | 1301 | usb_serial_tty_driver->driver_name = "usbserial"; |
1309 | usb_serial_tty_driver->devfs_name = "usb/tts/"; | 1302 | usb_serial_tty_driver->devfs_name = "usb/tts/"; |
@@ -1329,17 +1322,24 @@ static int __init usb_serial_init(void) | |||
1329 | goto exit_tty; | 1322 | goto exit_tty; |
1330 | } | 1323 | } |
1331 | 1324 | ||
1325 | /* register the generic driver, if we should */ | ||
1326 | result = usb_serial_generic_register(debug); | ||
1327 | if (result < 0) { | ||
1328 | err("%s - registering generic driver failed", __FUNCTION__); | ||
1329 | goto exit_generic; | ||
1330 | } | ||
1331 | |||
1332 | info(DRIVER_DESC " " DRIVER_VERSION); | 1332 | info(DRIVER_DESC " " DRIVER_VERSION); |
1333 | 1333 | ||
1334 | return result; | 1334 | return result; |
1335 | 1335 | ||
1336 | exit_generic: | ||
1337 | usb_deregister(&usb_serial_driver); | ||
1338 | |||
1336 | exit_tty: | 1339 | exit_tty: |
1337 | tty_unregister_driver(usb_serial_tty_driver); | 1340 | tty_unregister_driver(usb_serial_tty_driver); |
1338 | 1341 | ||
1339 | exit_reg_driver: | 1342 | exit_reg_driver: |
1340 | usb_serial_generic_deregister(); | ||
1341 | |||
1342 | exit_generic: | ||
1343 | bus_unregister(&usb_serial_bus_type); | 1343 | bus_unregister(&usb_serial_bus_type); |
1344 | 1344 | ||
1345 | exit_bus: | 1345 | exit_bus: |
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 22e48a2b0bd1..e43eddc3d44b 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c | |||
@@ -233,13 +233,11 @@ static int command_abort(struct scsi_cmnd *srb) | |||
233 | set_bit(US_FLIDX_ABORTING, &us->flags); | 233 | set_bit(US_FLIDX_ABORTING, &us->flags); |
234 | usb_stor_stop_transport(us); | 234 | usb_stor_stop_transport(us); |
235 | } | 235 | } |
236 | scsi_unlock(us_to_host(us)); | ||
237 | 236 | ||
238 | /* Wait for the aborted command to finish */ | 237 | /* Wait for the aborted command to finish */ |
239 | wait_for_completion(&us->notify); | 238 | wait_for_completion(&us->notify); |
240 | 239 | ||
241 | /* Reacquire the lock and allow USB transfers to resume */ | 240 | /* Reacquire the lock and allow USB transfers to resume */ |
242 | scsi_lock(us_to_host(us)); | ||
243 | clear_bit(US_FLIDX_ABORTING, &us->flags); | 241 | clear_bit(US_FLIDX_ABORTING, &us->flags); |
244 | clear_bit(US_FLIDX_TIMED_OUT, &us->flags); | 242 | clear_bit(US_FLIDX_TIMED_OUT, &us->flags); |
245 | return SUCCESS; | 243 | return SUCCESS; |
@@ -255,8 +253,6 @@ static int device_reset(struct scsi_cmnd *srb) | |||
255 | 253 | ||
256 | US_DEBUGP("%s called\n", __FUNCTION__); | 254 | US_DEBUGP("%s called\n", __FUNCTION__); |
257 | 255 | ||
258 | scsi_unlock(us_to_host(us)); | ||
259 | |||
260 | /* lock the device pointers and do the reset */ | 256 | /* lock the device pointers and do the reset */ |
261 | down(&(us->dev_semaphore)); | 257 | down(&(us->dev_semaphore)); |
262 | if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { | 258 | if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { |
@@ -266,8 +262,6 @@ static int device_reset(struct scsi_cmnd *srb) | |||
266 | result = us->transport_reset(us); | 262 | result = us->transport_reset(us); |
267 | up(&(us->dev_semaphore)); | 263 | up(&(us->dev_semaphore)); |
268 | 264 | ||
269 | /* lock the host for the return */ | ||
270 | scsi_lock(us_to_host(us)); | ||
271 | return result; | 265 | return result; |
272 | } | 266 | } |
273 | 267 | ||
@@ -282,8 +276,6 @@ static int bus_reset(struct scsi_cmnd *srb) | |||
282 | 276 | ||
283 | US_DEBUGP("%s called\n", __FUNCTION__); | 277 | US_DEBUGP("%s called\n", __FUNCTION__); |
284 | 278 | ||
285 | scsi_unlock(us_to_host(us)); | ||
286 | |||
287 | /* The USB subsystem doesn't handle synchronisation between | 279 | /* The USB subsystem doesn't handle synchronisation between |
288 | * a device's several drivers. Therefore we reset only devices | 280 | * a device's several drivers. Therefore we reset only devices |
289 | * with just one interface, which we of course own. */ | 281 | * with just one interface, which we of course own. */ |
@@ -310,7 +302,6 @@ static int bus_reset(struct scsi_cmnd *srb) | |||
310 | up(&(us->dev_semaphore)); | 302 | up(&(us->dev_semaphore)); |
311 | 303 | ||
312 | /* lock the host for the return */ | 304 | /* lock the host for the return */ |
313 | scsi_lock(us_to_host(us)); | ||
314 | return result < 0 ? FAILED : SUCCESS; | 305 | return result < 0 ? FAILED : SUCCESS; |
315 | } | 306 | } |
316 | 307 | ||
@@ -407,7 +398,7 @@ US_DO_ALL_FLAGS | |||
407 | ***********************************************************************/ | 398 | ***********************************************************************/ |
408 | 399 | ||
409 | /* Output routine for the sysfs max_sectors file */ | 400 | /* Output routine for the sysfs max_sectors file */ |
410 | static ssize_t show_max_sectors(struct device *dev, char *buf) | 401 | static ssize_t show_max_sectors(struct device *dev, struct device_attribute *attr, char *buf) |
411 | { | 402 | { |
412 | struct scsi_device *sdev = to_scsi_device(dev); | 403 | struct scsi_device *sdev = to_scsi_device(dev); |
413 | 404 | ||
@@ -415,7 +406,7 @@ static ssize_t show_max_sectors(struct device *dev, char *buf) | |||
415 | } | 406 | } |
416 | 407 | ||
417 | /* Input routine for the sysfs max_sectors file */ | 408 | /* Input routine for the sysfs max_sectors file */ |
418 | static ssize_t store_max_sectors(struct device *dev, const char *buf, | 409 | static ssize_t store_max_sectors(struct device *dev, struct device_attribute *attr, const char *buf, |
419 | size_t count) | 410 | size_t count) |
420 | { | 411 | { |
421 | struct scsi_device *sdev = to_scsi_device(dev); | 412 | struct scsi_device *sdev = to_scsi_device(dev); |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index d2891f475793..9fcc7bd1fbe4 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -862,6 +862,15 @@ UNUSUAL_DEV( 0x090a, 0x1001, 0x0100, 0x0100, | |||
862 | US_SC_DEVICE, US_PR_BULK, NULL, | 862 | US_SC_DEVICE, US_PR_BULK, NULL, |
863 | US_FL_NEED_OVERRIDE ), | 863 | US_FL_NEED_OVERRIDE ), |
864 | 864 | ||
865 | /* Reported by Filippo Bardelli <filibard@libero.it> | ||
866 | * The device reports a subclass of RBC, which is wrong. | ||
867 | */ | ||
868 | UNUSUAL_DEV( 0x090a, 0x1050, 0x0100, 0x0100, | ||
869 | "Trumpion Microelectronics, Inc.", | ||
870 | "33520 USB Digital Voice Recorder", | ||
871 | US_SC_UFI, US_PR_DEVICE, NULL, | ||
872 | 0), | ||
873 | |||
865 | /* Trumpion Microelectronics MP3 player (felipe_alfaro@linuxmail.org) */ | 874 | /* Trumpion Microelectronics MP3 player (felipe_alfaro@linuxmail.org) */ |
866 | UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999, | 875 | UNUSUAL_DEV( 0x090a, 0x1200, 0x0000, 0x9999, |
867 | "Trumpion", | 876 | "Trumpion", |