diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-07-13 16:23:51 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-07-13 16:23:51 -0400 |
commit | 327309e899662b482c58cf25f574513d38b5788c (patch) | |
tree | 069de438aa0e92dd9b6ba28e6b207e2cd07151a5 /drivers/usb | |
parent | 0c168775709faa74c1b87f1e61046e0c51ade7f3 (diff) | |
parent | c32511e2718618f0b53479eb36e07439aa363a74 (diff) |
Merge upstream 2.6.13-rc3 into ieee80211 branch of netdev-2.6.
Diffstat (limited to 'drivers/usb')
52 files changed, 2251 insertions, 873 deletions
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index d79cd218a551..df014c2a7c54 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile | |||
@@ -65,12 +65,14 @@ obj-$(CONFIG_USB_EMI26) += misc/ | |||
65 | obj-$(CONFIG_USB_EMI62) += misc/ | 65 | obj-$(CONFIG_USB_EMI62) += misc/ |
66 | obj-$(CONFIG_USB_IDMOUSE) += misc/ | 66 | obj-$(CONFIG_USB_IDMOUSE) += misc/ |
67 | obj-$(CONFIG_USB_LCD) += misc/ | 67 | obj-$(CONFIG_USB_LCD) += misc/ |
68 | obj-$(CONFIG_USB_LD) += misc/ | ||
68 | obj-$(CONFIG_USB_LED) += misc/ | 69 | obj-$(CONFIG_USB_LED) += misc/ |
69 | obj-$(CONFIG_USB_LEGOTOWER) += misc/ | 70 | obj-$(CONFIG_USB_LEGOTOWER) += misc/ |
70 | obj-$(CONFIG_USB_RIO500) += misc/ | 71 | obj-$(CONFIG_USB_RIO500) += misc/ |
71 | obj-$(CONFIG_USB_TEST) += misc/ | 72 | obj-$(CONFIG_USB_TEST) += misc/ |
72 | obj-$(CONFIG_USB_USS720) += misc/ | 73 | obj-$(CONFIG_USB_USS720) += misc/ |
73 | obj-$(CONFIG_USB_PHIDGETSERVO) += misc/ | 74 | obj-$(CONFIG_USB_PHIDGETSERVO) += misc/ |
75 | obj-$(CONFIG_USB_SISUSBVGA) += misc/ | ||
74 | 76 | ||
75 | obj-$(CONFIG_USB_ATM) += atm/ | 77 | obj-$(CONFIG_USB_ATM) += atm/ |
76 | obj-$(CONFIG_USB_SPEEDTOUCH) += atm/ | 78 | obj-$(CONFIG_USB_SPEEDTOUCH) += atm/ |
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index cbd4a7d25d0b..8e184e2641cb 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c | |||
@@ -427,7 +427,7 @@ static void cxacru_poll_status(struct cxacru_data *instance) | |||
427 | atm_dev->link_rate = buf[CXINF_DOWNSTREAM_RATE] * 1000 / 424; | 427 | atm_dev->link_rate = buf[CXINF_DOWNSTREAM_RATE] * 1000 / 424; |
428 | atm_dev->signal = ATM_PHY_SIG_FOUND; | 428 | atm_dev->signal = ATM_PHY_SIG_FOUND; |
429 | 429 | ||
430 | dev_info(dev, "ADSL line: up (%d Kib/s down | %d Kib/s up)\n", | 430 | dev_info(dev, "ADSL line: up (%d kb/s down | %d kb/s up)\n", |
431 | buf[CXINF_DOWNSTREAM_RATE], buf[CXINF_UPSTREAM_RATE]); | 431 | buf[CXINF_DOWNSTREAM_RATE], buf[CXINF_UPSTREAM_RATE]); |
432 | break; | 432 | break; |
433 | 433 | ||
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 6a6eaa2a3b1c..d0cbbb7f0385 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c | |||
@@ -100,6 +100,8 @@ struct speedtch_instance_data { | |||
100 | 100 | ||
101 | struct work_struct status_checker; | 101 | struct work_struct status_checker; |
102 | 102 | ||
103 | unsigned char last_status; | ||
104 | |||
103 | int poll_delay; /* milliseconds */ | 105 | int poll_delay; /* milliseconds */ |
104 | 106 | ||
105 | struct timer_list resubmit_timer; | 107 | struct timer_list resubmit_timer; |
@@ -423,52 +425,48 @@ static void speedtch_check_status(struct speedtch_instance_data *instance) | |||
423 | struct usbatm_data *usbatm = instance->usbatm; | 425 | struct usbatm_data *usbatm = instance->usbatm; |
424 | struct atm_dev *atm_dev = usbatm->atm_dev; | 426 | struct atm_dev *atm_dev = usbatm->atm_dev; |
425 | unsigned char *buf = instance->scratch_buffer; | 427 | unsigned char *buf = instance->scratch_buffer; |
426 | int ret; | 428 | int down_speed, up_speed, ret; |
429 | unsigned char status; | ||
427 | 430 | ||
428 | atm_dbg(usbatm, "%s entered\n", __func__); | 431 | atm_dbg(usbatm, "%s entered\n", __func__); |
429 | 432 | ||
430 | ret = speedtch_read_status(instance); | 433 | ret = speedtch_read_status(instance); |
431 | if (ret < 0) { | 434 | if (ret < 0) { |
432 | atm_warn(usbatm, "error %d fetching device status\n", ret); | 435 | atm_warn(usbatm, "error %d fetching device status\n", ret); |
433 | if (instance->poll_delay < MAX_POLL_DELAY) | 436 | instance->poll_delay = min(2 * instance->poll_delay, MAX_POLL_DELAY); |
434 | instance->poll_delay *= 2; | ||
435 | return; | 437 | return; |
436 | } | 438 | } |
437 | 439 | ||
438 | if (instance->poll_delay > MIN_POLL_DELAY) | 440 | instance->poll_delay = max(instance->poll_delay / 2, MIN_POLL_DELAY); |
439 | instance->poll_delay /= 2; | ||
440 | 441 | ||
441 | atm_dbg(usbatm, "%s: line state %02x\n", __func__, buf[OFFSET_7]); | 442 | status = buf[OFFSET_7]; |
442 | 443 | ||
443 | switch (buf[OFFSET_7]) { | 444 | atm_dbg(usbatm, "%s: line state %02x\n", __func__, status); |
444 | case 0: | 445 | |
445 | if (atm_dev->signal != ATM_PHY_SIG_LOST) { | 446 | if ((status != instance->last_status) || !status) { |
447 | switch (status) { | ||
448 | case 0: | ||
446 | atm_dev->signal = ATM_PHY_SIG_LOST; | 449 | atm_dev->signal = ATM_PHY_SIG_LOST; |
447 | atm_info(usbatm, "ADSL line is down\n"); | 450 | if (instance->last_status) |
448 | /* It'll never resync again unless we ask it to... */ | 451 | atm_info(usbatm, "ADSL line is down\n"); |
452 | /* It may never resync again unless we ask it to... */ | ||
449 | ret = speedtch_start_synchro(instance); | 453 | ret = speedtch_start_synchro(instance); |
450 | } | 454 | break; |
451 | break; | ||
452 | 455 | ||
453 | case 0x08: | 456 | case 0x08: |
454 | if (atm_dev->signal != ATM_PHY_SIG_UNKNOWN) { | ||
455 | atm_dev->signal = ATM_PHY_SIG_UNKNOWN; | 457 | atm_dev->signal = ATM_PHY_SIG_UNKNOWN; |
456 | atm_info(usbatm, "ADSL line is blocked?\n"); | 458 | atm_info(usbatm, "ADSL line is blocked?\n"); |
457 | } | 459 | break; |
458 | break; | ||
459 | 460 | ||
460 | case 0x10: | 461 | case 0x10: |
461 | if (atm_dev->signal != ATM_PHY_SIG_LOST) { | ||
462 | atm_dev->signal = ATM_PHY_SIG_LOST; | 462 | atm_dev->signal = ATM_PHY_SIG_LOST; |
463 | atm_info(usbatm, "ADSL line is synchronising\n"); | 463 | atm_info(usbatm, "ADSL line is synchronising\n"); |
464 | } | 464 | break; |
465 | break; | ||
466 | 465 | ||
467 | case 0x20: | 466 | case 0x20: |
468 | if (atm_dev->signal != ATM_PHY_SIG_FOUND) { | 467 | down_speed = buf[OFFSET_b] | (buf[OFFSET_b + 1] << 8) |
469 | int down_speed = buf[OFFSET_b] | (buf[OFFSET_b + 1] << 8) | ||
470 | | (buf[OFFSET_b + 2] << 16) | (buf[OFFSET_b + 3] << 24); | 468 | | (buf[OFFSET_b + 2] << 16) | (buf[OFFSET_b + 3] << 24); |
471 | int up_speed = buf[OFFSET_b + 4] | (buf[OFFSET_b + 5] << 8) | 469 | up_speed = buf[OFFSET_b + 4] | (buf[OFFSET_b + 5] << 8) |
472 | | (buf[OFFSET_b + 6] << 16) | (buf[OFFSET_b + 7] << 24); | 470 | | (buf[OFFSET_b + 6] << 16) | (buf[OFFSET_b + 7] << 24); |
473 | 471 | ||
474 | if (!(down_speed & 0x0000ffff) && !(up_speed & 0x0000ffff)) { | 472 | if (!(down_speed & 0x0000ffff) && !(up_speed & 0x0000ffff)) { |
@@ -480,17 +478,17 @@ static void speedtch_check_status(struct speedtch_instance_data *instance) | |||
480 | atm_dev->signal = ATM_PHY_SIG_FOUND; | 478 | atm_dev->signal = ATM_PHY_SIG_FOUND; |
481 | 479 | ||
482 | atm_info(usbatm, | 480 | atm_info(usbatm, |
483 | "ADSL line is up (%d Kib/s down | %d Kib/s up)\n", | 481 | "ADSL line is up (%d kb/s down | %d kb/s up)\n", |
484 | down_speed, up_speed); | 482 | down_speed, up_speed); |
485 | } | 483 | break; |
486 | break; | ||
487 | 484 | ||
488 | default: | 485 | default: |
489 | if (atm_dev->signal != ATM_PHY_SIG_UNKNOWN) { | ||
490 | atm_dev->signal = ATM_PHY_SIG_UNKNOWN; | 486 | atm_dev->signal = ATM_PHY_SIG_UNKNOWN; |
491 | atm_info(usbatm, "Unknown line state %02x\n", buf[OFFSET_7]); | 487 | atm_info(usbatm, "Unknown line state %02x\n", status); |
488 | break; | ||
492 | } | 489 | } |
493 | break; | 490 | |
491 | instance->last_status = status; | ||
494 | } | 492 | } |
495 | } | 493 | } |
496 | 494 | ||
@@ -730,6 +728,7 @@ static int speedtch_bind(struct usbatm_data *usbatm, | |||
730 | 728 | ||
731 | instance->status_checker.timer.function = speedtch_status_poll; | 729 | instance->status_checker.timer.function = speedtch_status_poll; |
732 | instance->status_checker.timer.data = (unsigned long)instance; | 730 | instance->status_checker.timer.data = (unsigned long)instance; |
731 | instance->last_status = 0xff; | ||
733 | instance->poll_delay = MIN_POLL_DELAY; | 732 | instance->poll_delay = MIN_POLL_DELAY; |
734 | 733 | ||
735 | init_timer(&instance->resubmit_timer); | 734 | init_timer(&instance->resubmit_timer); |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 69e859e0f51d..adff5a77e31f 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -422,6 +422,17 @@ bail_out: | |||
422 | return -EIO; | 422 | return -EIO; |
423 | } | 423 | } |
424 | 424 | ||
425 | static void acm_tty_unregister(struct acm *acm) | ||
426 | { | ||
427 | tty_unregister_device(acm_tty_driver, acm->minor); | ||
428 | usb_put_intf(acm->control); | ||
429 | acm_table[acm->minor] = NULL; | ||
430 | usb_free_urb(acm->ctrlurb); | ||
431 | usb_free_urb(acm->readurb); | ||
432 | usb_free_urb(acm->writeurb); | ||
433 | kfree(acm); | ||
434 | } | ||
435 | |||
425 | static void acm_tty_close(struct tty_struct *tty, struct file *filp) | 436 | static void acm_tty_close(struct tty_struct *tty, struct file *filp) |
426 | { | 437 | { |
427 | struct acm *acm = tty->driver_data; | 438 | struct acm *acm = tty->driver_data; |
@@ -436,14 +447,8 @@ static void acm_tty_close(struct tty_struct *tty, struct file *filp) | |||
436 | usb_kill_urb(acm->ctrlurb); | 447 | usb_kill_urb(acm->ctrlurb); |
437 | usb_kill_urb(acm->writeurb); | 448 | usb_kill_urb(acm->writeurb); |
438 | usb_kill_urb(acm->readurb); | 449 | usb_kill_urb(acm->readurb); |
439 | } else { | 450 | } else |
440 | tty_unregister_device(acm_tty_driver, acm->minor); | 451 | acm_tty_unregister(acm); |
441 | acm_table[acm->minor] = NULL; | ||
442 | usb_free_urb(acm->ctrlurb); | ||
443 | usb_free_urb(acm->readurb); | ||
444 | usb_free_urb(acm->writeurb); | ||
445 | kfree(acm); | ||
446 | } | ||
447 | } | 452 | } |
448 | up(&open_sem); | 453 | up(&open_sem); |
449 | } | 454 | } |
@@ -905,7 +910,8 @@ skip_normal_probe: | |||
905 | 910 | ||
906 | usb_driver_claim_interface(&acm_driver, data_interface, acm); | 911 | usb_driver_claim_interface(&acm_driver, data_interface, acm); |
907 | 912 | ||
908 | tty_register_device(acm_tty_driver, minor, &intf->dev); | 913 | usb_get_intf(control_interface); |
914 | tty_register_device(acm_tty_driver, minor, &control_interface->dev); | ||
909 | 915 | ||
910 | acm_table[minor] = acm; | 916 | acm_table[minor] = acm; |
911 | usb_set_intfdata (intf, acm); | 917 | usb_set_intfdata (intf, acm); |
@@ -954,12 +960,7 @@ static void acm_disconnect(struct usb_interface *intf) | |||
954 | usb_driver_release_interface(&acm_driver, acm->data); | 960 | usb_driver_release_interface(&acm_driver, acm->data); |
955 | 961 | ||
956 | if (!acm->used) { | 962 | if (!acm->used) { |
957 | tty_unregister_device(acm_tty_driver, acm->minor); | 963 | acm_tty_unregister(acm); |
958 | acm_table[acm->minor] = NULL; | ||
959 | usb_free_urb(acm->ctrlurb); | ||
960 | usb_free_urb(acm->readurb); | ||
961 | usb_free_urb(acm->writeurb); | ||
962 | kfree(acm); | ||
963 | up(&open_sem); | 964 | up(&open_sem); |
964 | return; | 965 | return; |
965 | } | 966 | } |
diff --git a/drivers/usb/core/buffer.c b/drivers/usb/core/buffer.c index b7827df21f48..fc15b4acc8af 100644 --- a/drivers/usb/core/buffer.c +++ b/drivers/usb/core/buffer.c | |||
@@ -106,7 +106,7 @@ void hcd_buffer_destroy (struct usb_hcd *hcd) | |||
106 | void *hcd_buffer_alloc ( | 106 | void *hcd_buffer_alloc ( |
107 | struct usb_bus *bus, | 107 | struct usb_bus *bus, |
108 | size_t size, | 108 | size_t size, |
109 | int mem_flags, | 109 | unsigned mem_flags, |
110 | dma_addr_t *dma | 110 | dma_addr_t *dma |
111 | ) | 111 | ) |
112 | { | 112 | { |
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index 71b4a8d66318..fc056062c960 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c | |||
@@ -380,6 +380,7 @@ int usb_hcd_pci_resume (struct pci_dev *dev) | |||
380 | usb_hc_died (hcd); | 380 | usb_hc_died (hcd); |
381 | } | 381 | } |
382 | 382 | ||
383 | pci_enable_device(dev); | ||
383 | return retval; | 384 | return retval; |
384 | } | 385 | } |
385 | EXPORT_SYMBOL (usb_hcd_pci_resume); | 386 | EXPORT_SYMBOL (usb_hcd_pci_resume); |
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 83e732a0d64a..8616356f55e8 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -1112,7 +1112,7 @@ static void urb_unlink (struct urb *urb) | |||
1112 | * expects usb_submit_urb() to have sanity checked and conditioned all | 1112 | * expects usb_submit_urb() to have sanity checked and conditioned all |
1113 | * inputs in the urb | 1113 | * inputs in the urb |
1114 | */ | 1114 | */ |
1115 | static int hcd_submit_urb (struct urb *urb, int mem_flags) | 1115 | static int hcd_submit_urb (struct urb *urb, unsigned mem_flags) |
1116 | { | 1116 | { |
1117 | int status; | 1117 | int status; |
1118 | struct usb_hcd *hcd = urb->dev->bus->hcpriv; | 1118 | struct usb_hcd *hcd = urb->dev->bus->hcpriv; |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index 8dc13cde2f73..67db4a999b93 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -142,12 +142,12 @@ struct hcd_timeout { /* timeouts we allocate */ | |||
142 | 142 | ||
143 | struct usb_operations { | 143 | struct usb_operations { |
144 | int (*get_frame_number) (struct usb_device *usb_dev); | 144 | int (*get_frame_number) (struct usb_device *usb_dev); |
145 | int (*submit_urb) (struct urb *urb, int mem_flags); | 145 | int (*submit_urb) (struct urb *urb, unsigned mem_flags); |
146 | int (*unlink_urb) (struct urb *urb, int status); | 146 | int (*unlink_urb) (struct urb *urb, int status); |
147 | 147 | ||
148 | /* allocate dma-consistent buffer for URB_DMA_NOMAPPING */ | 148 | /* allocate dma-consistent buffer for URB_DMA_NOMAPPING */ |
149 | void *(*buffer_alloc)(struct usb_bus *bus, size_t size, | 149 | void *(*buffer_alloc)(struct usb_bus *bus, size_t size, |
150 | int mem_flags, | 150 | unsigned mem_flags, |
151 | dma_addr_t *dma); | 151 | dma_addr_t *dma); |
152 | void (*buffer_free)(struct usb_bus *bus, size_t size, | 152 | void (*buffer_free)(struct usb_bus *bus, size_t size, |
153 | void *addr, dma_addr_t dma); | 153 | void *addr, dma_addr_t dma); |
@@ -200,7 +200,7 @@ struct hc_driver { | |||
200 | int (*urb_enqueue) (struct usb_hcd *hcd, | 200 | int (*urb_enqueue) (struct usb_hcd *hcd, |
201 | struct usb_host_endpoint *ep, | 201 | struct usb_host_endpoint *ep, |
202 | struct urb *urb, | 202 | struct urb *urb, |
203 | int mem_flags); | 203 | unsigned mem_flags); |
204 | int (*urb_dequeue) (struct usb_hcd *hcd, struct urb *urb); | 204 | int (*urb_dequeue) (struct usb_hcd *hcd, struct urb *urb); |
205 | 205 | ||
206 | /* hw synch, freeing endpoint resources that urb_dequeue can't */ | 206 | /* hw synch, freeing endpoint resources that urb_dequeue can't */ |
@@ -247,7 +247,7 @@ int hcd_buffer_create (struct usb_hcd *hcd); | |||
247 | void hcd_buffer_destroy (struct usb_hcd *hcd); | 247 | void hcd_buffer_destroy (struct usb_hcd *hcd); |
248 | 248 | ||
249 | void *hcd_buffer_alloc (struct usb_bus *bus, size_t size, | 249 | void *hcd_buffer_alloc (struct usb_bus *bus, size_t size, |
250 | int mem_flags, dma_addr_t *dma); | 250 | unsigned mem_flags, dma_addr_t *dma); |
251 | void hcd_buffer_free (struct usb_bus *bus, size_t size, | 251 | void hcd_buffer_free (struct usb_bus *bus, size_t size, |
252 | void *addr, dma_addr_t dma); | 252 | void *addr, dma_addr_t dma); |
253 | 253 | ||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 32ff32181852..c3e46d24a37e 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/ioctl.h> | 26 | #include <linux/ioctl.h> |
27 | #include <linux/usb.h> | 27 | #include <linux/usb.h> |
28 | #include <linux/usbdevice_fs.h> | 28 | #include <linux/usbdevice_fs.h> |
29 | #include <linux/kthread.h> | ||
29 | 30 | ||
30 | #include <asm/semaphore.h> | 31 | #include <asm/semaphore.h> |
31 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
@@ -47,8 +48,7 @@ static LIST_HEAD(hub_event_list); /* List of hubs needing servicing */ | |||
47 | /* Wakes up khubd */ | 48 | /* Wakes up khubd */ |
48 | static DECLARE_WAIT_QUEUE_HEAD(khubd_wait); | 49 | static DECLARE_WAIT_QUEUE_HEAD(khubd_wait); |
49 | 50 | ||
50 | static pid_t khubd_pid = 0; /* PID of khubd */ | 51 | static struct task_struct *khubd_task; |
51 | static DECLARE_COMPLETION(khubd_exited); | ||
52 | 52 | ||
53 | /* cycle leds on hubs that aren't blinking for attention */ | 53 | /* cycle leds on hubs that aren't blinking for attention */ |
54 | static int blinkenlights = 0; | 54 | static int blinkenlights = 0; |
@@ -2807,23 +2807,16 @@ loop: | |||
2807 | 2807 | ||
2808 | static int hub_thread(void *__unused) | 2808 | static int hub_thread(void *__unused) |
2809 | { | 2809 | { |
2810 | /* | ||
2811 | * This thread doesn't need any user-level access, | ||
2812 | * so get rid of all our resources | ||
2813 | */ | ||
2814 | |||
2815 | daemonize("khubd"); | ||
2816 | allow_signal(SIGKILL); | ||
2817 | |||
2818 | /* Send me a signal to get me die (for debugging) */ | ||
2819 | do { | 2810 | do { |
2820 | hub_events(); | 2811 | hub_events(); |
2821 | wait_event_interruptible(khubd_wait, !list_empty(&hub_event_list)); | 2812 | wait_event_interruptible(khubd_wait, |
2813 | !list_empty(&hub_event_list) || | ||
2814 | kthread_should_stop()); | ||
2822 | try_to_freeze(); | 2815 | try_to_freeze(); |
2823 | } while (!signal_pending(current)); | 2816 | } while (!kthread_should_stop() || !list_empty(&hub_event_list)); |
2824 | 2817 | ||
2825 | pr_debug ("%s: khubd exiting\n", usbcore_name); | 2818 | pr_debug("%s: khubd exiting\n", usbcore_name); |
2826 | complete_and_exit(&khubd_exited, 0); | 2819 | return 0; |
2827 | } | 2820 | } |
2828 | 2821 | ||
2829 | static struct usb_device_id hub_id_table [] = { | 2822 | static struct usb_device_id hub_id_table [] = { |
@@ -2849,20 +2842,15 @@ static struct usb_driver hub_driver = { | |||
2849 | 2842 | ||
2850 | int usb_hub_init(void) | 2843 | int usb_hub_init(void) |
2851 | { | 2844 | { |
2852 | pid_t pid; | ||
2853 | |||
2854 | if (usb_register(&hub_driver) < 0) { | 2845 | if (usb_register(&hub_driver) < 0) { |
2855 | printk(KERN_ERR "%s: can't register hub driver\n", | 2846 | printk(KERN_ERR "%s: can't register hub driver\n", |
2856 | usbcore_name); | 2847 | usbcore_name); |
2857 | return -1; | 2848 | return -1; |
2858 | } | 2849 | } |
2859 | 2850 | ||
2860 | pid = kernel_thread(hub_thread, NULL, CLONE_KERNEL); | 2851 | khubd_task = kthread_run(hub_thread, NULL, "khubd"); |
2861 | if (pid >= 0) { | 2852 | if (!IS_ERR(khubd_task)) |
2862 | khubd_pid = pid; | ||
2863 | |||
2864 | return 0; | 2853 | return 0; |
2865 | } | ||
2866 | 2854 | ||
2867 | /* Fall through if kernel_thread failed */ | 2855 | /* Fall through if kernel_thread failed */ |
2868 | usb_deregister(&hub_driver); | 2856 | usb_deregister(&hub_driver); |
@@ -2873,12 +2861,7 @@ int usb_hub_init(void) | |||
2873 | 2861 | ||
2874 | void usb_hub_cleanup(void) | 2862 | void usb_hub_cleanup(void) |
2875 | { | 2863 | { |
2876 | int ret; | 2864 | kthread_stop(khubd_task); |
2877 | |||
2878 | /* Kill the thread */ | ||
2879 | ret = kill_proc(khubd_pid, SIGKILL, 1); | ||
2880 | |||
2881 | wait_for_completion(&khubd_exited); | ||
2882 | 2865 | ||
2883 | /* | 2866 | /* |
2884 | * Hub resources are freed for us by usb_deregister. It calls | 2867 | * Hub resources are freed for us by usb_deregister. It calls |
@@ -2890,7 +2873,6 @@ void usb_hub_cleanup(void) | |||
2890 | usb_deregister(&hub_driver); | 2873 | usb_deregister(&hub_driver); |
2891 | } /* usb_hub_cleanup() */ | 2874 | } /* usb_hub_cleanup() */ |
2892 | 2875 | ||
2893 | |||
2894 | static int config_descriptors_changed(struct usb_device *udev) | 2876 | static int config_descriptors_changed(struct usb_device *udev) |
2895 | { | 2877 | { |
2896 | unsigned index; | 2878 | unsigned index; |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index f50aaf25c98e..a428ef479bd7 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -320,7 +320,7 @@ int usb_sg_init ( | |||
320 | struct scatterlist *sg, | 320 | struct scatterlist *sg, |
321 | int nents, | 321 | int nents, |
322 | size_t length, | 322 | size_t length, |
323 | int mem_flags | 323 | unsigned mem_flags |
324 | ) | 324 | ) |
325 | { | 325 | { |
326 | int i; | 326 | int i; |
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index 740cb4c668df..00297f113849 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -196,6 +196,7 @@ usb_descriptor_attr (bDeviceClass, "%02x\n") | |||
196 | usb_descriptor_attr (bDeviceSubClass, "%02x\n") | 196 | usb_descriptor_attr (bDeviceSubClass, "%02x\n") |
197 | usb_descriptor_attr (bDeviceProtocol, "%02x\n") | 197 | usb_descriptor_attr (bDeviceProtocol, "%02x\n") |
198 | usb_descriptor_attr (bNumConfigurations, "%d\n") | 198 | usb_descriptor_attr (bNumConfigurations, "%d\n") |
199 | usb_descriptor_attr (bMaxPacketSize0, "%d\n") | ||
199 | 200 | ||
200 | static struct attribute *dev_attrs[] = { | 201 | static struct attribute *dev_attrs[] = { |
201 | /* current configuration's attributes */ | 202 | /* current configuration's attributes */ |
@@ -211,6 +212,7 @@ static struct attribute *dev_attrs[] = { | |||
211 | &dev_attr_bDeviceSubClass.attr, | 212 | &dev_attr_bDeviceSubClass.attr, |
212 | &dev_attr_bDeviceProtocol.attr, | 213 | &dev_attr_bDeviceProtocol.attr, |
213 | &dev_attr_bNumConfigurations.attr, | 214 | &dev_attr_bNumConfigurations.attr, |
215 | &dev_attr_bMaxPacketSize0.attr, | ||
214 | &dev_attr_speed.attr, | 216 | &dev_attr_speed.attr, |
215 | &dev_attr_devnum.attr, | 217 | &dev_attr_devnum.attr, |
216 | &dev_attr_version.attr, | 218 | &dev_attr_version.attr, |
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 0faf18d511de..c0feee25ff0a 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c | |||
@@ -60,7 +60,7 @@ void usb_init_urb(struct urb *urb) | |||
60 | * | 60 | * |
61 | * The driver must call usb_free_urb() when it is finished with the urb. | 61 | * The driver must call usb_free_urb() when it is finished with the urb. |
62 | */ | 62 | */ |
63 | struct urb *usb_alloc_urb(int iso_packets, int mem_flags) | 63 | struct urb *usb_alloc_urb(int iso_packets, unsigned mem_flags) |
64 | { | 64 | { |
65 | struct urb *urb; | 65 | struct urb *urb; |
66 | 66 | ||
@@ -224,7 +224,7 @@ struct urb * usb_get_urb(struct urb *urb) | |||
224 | * GFP_NOIO, unless b) or c) apply | 224 | * GFP_NOIO, unless b) or c) apply |
225 | * | 225 | * |
226 | */ | 226 | */ |
227 | int usb_submit_urb(struct urb *urb, int mem_flags) | 227 | int usb_submit_urb(struct urb *urb, unsigned mem_flags) |
228 | { | 228 | { |
229 | int pipe, temp, max; | 229 | int pipe, temp, max; |
230 | struct usb_device *dev; | 230 | struct usb_device *dev; |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index a3c42203213a..99c85d2f92da 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -1129,7 +1129,7 @@ int __usb_get_extra_descriptor(char *buffer, unsigned size, | |||
1129 | void *usb_buffer_alloc ( | 1129 | void *usb_buffer_alloc ( |
1130 | struct usb_device *dev, | 1130 | struct usb_device *dev, |
1131 | size_t size, | 1131 | size_t size, |
1132 | int mem_flags, | 1132 | unsigned mem_flags, |
1133 | dma_addr_t *dma | 1133 | dma_addr_t *dma |
1134 | ) | 1134 | ) |
1135 | { | 1135 | { |
@@ -1532,6 +1532,9 @@ EXPORT_SYMBOL(usb_register); | |||
1532 | EXPORT_SYMBOL(usb_deregister); | 1532 | EXPORT_SYMBOL(usb_deregister); |
1533 | EXPORT_SYMBOL(usb_disabled); | 1533 | EXPORT_SYMBOL(usb_disabled); |
1534 | 1534 | ||
1535 | EXPORT_SYMBOL_GPL(usb_get_intf); | ||
1536 | EXPORT_SYMBOL_GPL(usb_put_intf); | ||
1537 | |||
1535 | EXPORT_SYMBOL(usb_alloc_dev); | 1538 | EXPORT_SYMBOL(usb_alloc_dev); |
1536 | EXPORT_SYMBOL(usb_put_dev); | 1539 | EXPORT_SYMBOL(usb_put_dev); |
1537 | EXPORT_SYMBOL(usb_get_dev); | 1540 | EXPORT_SYMBOL(usb_get_dev); |
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index 4d692670f288..583db7c38cf1 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -470,7 +470,7 @@ static int dummy_disable (struct usb_ep *_ep) | |||
470 | } | 470 | } |
471 | 471 | ||
472 | static struct usb_request * | 472 | static struct usb_request * |
473 | dummy_alloc_request (struct usb_ep *_ep, int mem_flags) | 473 | dummy_alloc_request (struct usb_ep *_ep, unsigned mem_flags) |
474 | { | 474 | { |
475 | struct dummy_ep *ep; | 475 | struct dummy_ep *ep; |
476 | struct dummy_request *req; | 476 | struct dummy_request *req; |
@@ -507,7 +507,7 @@ dummy_alloc_buffer ( | |||
507 | struct usb_ep *_ep, | 507 | struct usb_ep *_ep, |
508 | unsigned bytes, | 508 | unsigned bytes, |
509 | dma_addr_t *dma, | 509 | dma_addr_t *dma, |
510 | int mem_flags | 510 | unsigned mem_flags |
511 | ) { | 511 | ) { |
512 | char *retval; | 512 | char *retval; |
513 | struct dummy_ep *ep; | 513 | struct dummy_ep *ep; |
@@ -540,7 +540,8 @@ fifo_complete (struct usb_ep *ep, struct usb_request *req) | |||
540 | } | 540 | } |
541 | 541 | ||
542 | static int | 542 | static int |
543 | dummy_queue (struct usb_ep *_ep, struct usb_request *_req, int mem_flags) | 543 | dummy_queue (struct usb_ep *_ep, struct usb_request *_req, |
544 | unsigned mem_flags) | ||
544 | { | 545 | { |
545 | struct dummy_ep *ep; | 546 | struct dummy_ep *ep; |
546 | struct dummy_request *req; | 547 | struct dummy_request *req; |
@@ -998,7 +999,7 @@ static int dummy_urb_enqueue ( | |||
998 | struct usb_hcd *hcd, | 999 | struct usb_hcd *hcd, |
999 | struct usb_host_endpoint *ep, | 1000 | struct usb_host_endpoint *ep, |
1000 | struct urb *urb, | 1001 | struct urb *urb, |
1001 | int mem_flags | 1002 | unsigned mem_flags |
1002 | ) { | 1003 | ) { |
1003 | struct dummy *dum; | 1004 | struct dummy *dum; |
1004 | struct urbp *urbp; | 1005 | struct urbp *urbp; |
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index 5bb53ae88969..8509e955007d 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c | |||
@@ -945,15 +945,16 @@ config_buf (enum usb_device_speed speed, | |||
945 | 945 | ||
946 | /*-------------------------------------------------------------------------*/ | 946 | /*-------------------------------------------------------------------------*/ |
947 | 947 | ||
948 | static void eth_start (struct eth_dev *dev, int gfp_flags); | 948 | static void eth_start (struct eth_dev *dev, unsigned gfp_flags); |
949 | static int alloc_requests (struct eth_dev *dev, unsigned n, int gfp_flags); | 949 | static int alloc_requests (struct eth_dev *dev, unsigned n, unsigned gfp_flags); |
950 | 950 | ||
951 | static int | 951 | static int |
952 | set_ether_config (struct eth_dev *dev, int gfp_flags) | 952 | set_ether_config (struct eth_dev *dev, unsigned gfp_flags) |
953 | { | 953 | { |
954 | int result = 0; | 954 | int result = 0; |
955 | struct usb_gadget *gadget = dev->gadget; | 955 | struct usb_gadget *gadget = dev->gadget; |
956 | 956 | ||
957 | #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) | ||
957 | /* status endpoint used for RNDIS and (optionally) CDC */ | 958 | /* status endpoint used for RNDIS and (optionally) CDC */ |
958 | if (!subset_active(dev) && dev->status_ep) { | 959 | if (!subset_active(dev) && dev->status_ep) { |
959 | dev->status = ep_desc (gadget, &hs_status_desc, | 960 | dev->status = ep_desc (gadget, &hs_status_desc, |
@@ -967,6 +968,7 @@ set_ether_config (struct eth_dev *dev, int gfp_flags) | |||
967 | goto done; | 968 | goto done; |
968 | } | 969 | } |
969 | } | 970 | } |
971 | #endif | ||
970 | 972 | ||
971 | dev->in = ep_desc (dev->gadget, &hs_source_desc, &fs_source_desc); | 973 | dev->in = ep_desc (dev->gadget, &hs_source_desc, &fs_source_desc); |
972 | dev->in_ep->driver_data = dev; | 974 | dev->in_ep->driver_data = dev; |
@@ -1079,7 +1081,7 @@ static void eth_reset_config (struct eth_dev *dev) | |||
1079 | * that returns config descriptors, and altsetting code. | 1081 | * that returns config descriptors, and altsetting code. |
1080 | */ | 1082 | */ |
1081 | static int | 1083 | static int |
1082 | eth_set_config (struct eth_dev *dev, unsigned number, int gfp_flags) | 1084 | eth_set_config (struct eth_dev *dev, unsigned number, unsigned gfp_flags) |
1083 | { | 1085 | { |
1084 | int result = 0; | 1086 | int result = 0; |
1085 | struct usb_gadget *gadget = dev->gadget; | 1087 | struct usb_gadget *gadget = dev->gadget; |
@@ -1596,7 +1598,7 @@ static void defer_kevent (struct eth_dev *dev, int flag) | |||
1596 | static void rx_complete (struct usb_ep *ep, struct usb_request *req); | 1598 | static void rx_complete (struct usb_ep *ep, struct usb_request *req); |
1597 | 1599 | ||
1598 | static int | 1600 | static int |
1599 | rx_submit (struct eth_dev *dev, struct usb_request *req, int gfp_flags) | 1601 | rx_submit (struct eth_dev *dev, struct usb_request *req, unsigned gfp_flags) |
1600 | { | 1602 | { |
1601 | struct sk_buff *skb; | 1603 | struct sk_buff *skb; |
1602 | int retval = -ENOMEM; | 1604 | int retval = -ENOMEM; |
@@ -1722,7 +1724,7 @@ clean: | |||
1722 | } | 1724 | } |
1723 | 1725 | ||
1724 | static int prealloc (struct list_head *list, struct usb_ep *ep, | 1726 | static int prealloc (struct list_head *list, struct usb_ep *ep, |
1725 | unsigned n, int gfp_flags) | 1727 | unsigned n, unsigned gfp_flags) |
1726 | { | 1728 | { |
1727 | unsigned i; | 1729 | unsigned i; |
1728 | struct usb_request *req; | 1730 | struct usb_request *req; |
@@ -1761,7 +1763,7 @@ extra: | |||
1761 | return 0; | 1763 | return 0; |
1762 | } | 1764 | } |
1763 | 1765 | ||
1764 | static int alloc_requests (struct eth_dev *dev, unsigned n, int gfp_flags) | 1766 | static int alloc_requests (struct eth_dev *dev, unsigned n, unsigned gfp_flags) |
1765 | { | 1767 | { |
1766 | int status; | 1768 | int status; |
1767 | 1769 | ||
@@ -1777,7 +1779,7 @@ fail: | |||
1777 | return status; | 1779 | return status; |
1778 | } | 1780 | } |
1779 | 1781 | ||
1780 | static void rx_fill (struct eth_dev *dev, int gfp_flags) | 1782 | static void rx_fill (struct eth_dev *dev, unsigned gfp_flags) |
1781 | { | 1783 | { |
1782 | struct usb_request *req; | 1784 | struct usb_request *req; |
1783 | unsigned long flags; | 1785 | unsigned long flags; |
@@ -2022,7 +2024,7 @@ static int rndis_control_ack (struct net_device *net) | |||
2022 | 2024 | ||
2023 | #endif /* RNDIS */ | 2025 | #endif /* RNDIS */ |
2024 | 2026 | ||
2025 | static void eth_start (struct eth_dev *dev, int gfp_flags) | 2027 | static void eth_start (struct eth_dev *dev, unsigned gfp_flags) |
2026 | { | 2028 | { |
2027 | DEBUG (dev, "%s\n", __FUNCTION__); | 2029 | DEBUG (dev, "%s\n", __FUNCTION__); |
2028 | 2030 | ||
@@ -2428,7 +2430,7 @@ autoconf_fail: | |||
2428 | dev->req->complete = eth_setup_complete; | 2430 | dev->req->complete = eth_setup_complete; |
2429 | 2431 | ||
2430 | /* ... and maybe likewise for status transfer */ | 2432 | /* ... and maybe likewise for status transfer */ |
2431 | #ifdef DEV_CONFIG_CDC | 2433 | #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) |
2432 | if (dev->status_ep) { | 2434 | if (dev->status_ep) { |
2433 | dev->stat_req = eth_req_alloc (dev->status_ep, | 2435 | dev->stat_req = eth_req_alloc (dev->status_ep, |
2434 | STATUS_BYTECOUNT, GFP_KERNEL); | 2436 | STATUS_BYTECOUNT, GFP_KERNEL); |
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index ed773a9111de..eaab26f4ed37 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -269,7 +269,7 @@ static int goku_ep_disable(struct usb_ep *_ep) | |||
269 | /*-------------------------------------------------------------------------*/ | 269 | /*-------------------------------------------------------------------------*/ |
270 | 270 | ||
271 | static struct usb_request * | 271 | static struct usb_request * |
272 | goku_alloc_request(struct usb_ep *_ep, int gfp_flags) | 272 | goku_alloc_request(struct usb_ep *_ep, unsigned gfp_flags) |
273 | { | 273 | { |
274 | struct goku_request *req; | 274 | struct goku_request *req; |
275 | 275 | ||
@@ -327,7 +327,7 @@ goku_free_request(struct usb_ep *_ep, struct usb_request *_req) | |||
327 | */ | 327 | */ |
328 | static void * | 328 | static void * |
329 | goku_alloc_buffer(struct usb_ep *_ep, unsigned bytes, | 329 | goku_alloc_buffer(struct usb_ep *_ep, unsigned bytes, |
330 | dma_addr_t *dma, int gfp_flags) | 330 | dma_addr_t *dma, unsigned gfp_flags) |
331 | { | 331 | { |
332 | void *retval; | 332 | void *retval; |
333 | struct goku_ep *ep; | 333 | struct goku_ep *ep; |
@@ -789,7 +789,7 @@ finished: | |||
789 | /*-------------------------------------------------------------------------*/ | 789 | /*-------------------------------------------------------------------------*/ |
790 | 790 | ||
791 | static int | 791 | static int |
792 | goku_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags) | 792 | goku_queue(struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags) |
793 | { | 793 | { |
794 | struct goku_request *req; | 794 | struct goku_request *req; |
795 | struct goku_ep *ep; | 795 | struct goku_ep *ep; |
diff --git a/drivers/usb/gadget/lh7a40x_udc.c b/drivers/usb/gadget/lh7a40x_udc.c index df75ab65a5ec..4842577789c9 100644 --- a/drivers/usb/gadget/lh7a40x_udc.c +++ b/drivers/usb/gadget/lh7a40x_udc.c | |||
@@ -1106,7 +1106,7 @@ static int lh7a40x_ep_disable(struct usb_ep *_ep) | |||
1106 | } | 1106 | } |
1107 | 1107 | ||
1108 | static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep, | 1108 | static struct usb_request *lh7a40x_alloc_request(struct usb_ep *ep, |
1109 | int gfp_flags) | 1109 | unsigned gfp_flags) |
1110 | { | 1110 | { |
1111 | struct lh7a40x_request *req; | 1111 | struct lh7a40x_request *req; |
1112 | 1112 | ||
@@ -1134,7 +1134,7 @@ static void lh7a40x_free_request(struct usb_ep *ep, struct usb_request *_req) | |||
1134 | } | 1134 | } |
1135 | 1135 | ||
1136 | static void *lh7a40x_alloc_buffer(struct usb_ep *ep, unsigned bytes, | 1136 | static void *lh7a40x_alloc_buffer(struct usb_ep *ep, unsigned bytes, |
1137 | dma_addr_t * dma, int gfp_flags) | 1137 | dma_addr_t * dma, unsigned gfp_flags) |
1138 | { | 1138 | { |
1139 | char *retval; | 1139 | char *retval; |
1140 | 1140 | ||
@@ -1158,7 +1158,7 @@ static void lh7a40x_free_buffer(struct usb_ep *ep, void *buf, dma_addr_t dma, | |||
1158 | * NOTE: Sets INDEX register | 1158 | * NOTE: Sets INDEX register |
1159 | */ | 1159 | */ |
1160 | static int lh7a40x_queue(struct usb_ep *_ep, struct usb_request *_req, | 1160 | static int lh7a40x_queue(struct usb_ep *_ep, struct usb_request *_req, |
1161 | int gfp_flags) | 1161 | unsigned gfp_flags) |
1162 | { | 1162 | { |
1163 | struct lh7a40x_request *req; | 1163 | struct lh7a40x_request *req; |
1164 | struct lh7a40x_ep *ep; | 1164 | struct lh7a40x_ep *ep; |
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 13a3dbc9949b..477fab2e74d1 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -376,7 +376,7 @@ static int net2280_disable (struct usb_ep *_ep) | |||
376 | /*-------------------------------------------------------------------------*/ | 376 | /*-------------------------------------------------------------------------*/ |
377 | 377 | ||
378 | static struct usb_request * | 378 | static struct usb_request * |
379 | net2280_alloc_request (struct usb_ep *_ep, int gfp_flags) | 379 | net2280_alloc_request (struct usb_ep *_ep, unsigned gfp_flags) |
380 | { | 380 | { |
381 | struct net2280_ep *ep; | 381 | struct net2280_ep *ep; |
382 | struct net2280_request *req; | 382 | struct net2280_request *req; |
@@ -463,7 +463,7 @@ net2280_alloc_buffer ( | |||
463 | struct usb_ep *_ep, | 463 | struct usb_ep *_ep, |
464 | unsigned bytes, | 464 | unsigned bytes, |
465 | dma_addr_t *dma, | 465 | dma_addr_t *dma, |
466 | int gfp_flags | 466 | unsigned gfp_flags |
467 | ) | 467 | ) |
468 | { | 468 | { |
469 | void *retval; | 469 | void *retval; |
@@ -897,7 +897,7 @@ done (struct net2280_ep *ep, struct net2280_request *req, int status) | |||
897 | /*-------------------------------------------------------------------------*/ | 897 | /*-------------------------------------------------------------------------*/ |
898 | 898 | ||
899 | static int | 899 | static int |
900 | net2280_queue (struct usb_ep *_ep, struct usb_request *_req, int gfp_flags) | 900 | net2280_queue (struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags) |
901 | { | 901 | { |
902 | struct net2280_request *req; | 902 | struct net2280_request *req; |
903 | struct net2280_ep *ep; | 903 | struct net2280_ep *ep; |
@@ -1490,7 +1490,7 @@ show_registers (struct device *_dev, struct device_attribute *attr, char *buf) | |||
1490 | unsigned long flags; | 1490 | unsigned long flags; |
1491 | int i; | 1491 | int i; |
1492 | u32 t1, t2; | 1492 | u32 t1, t2; |
1493 | char *s; | 1493 | const char *s; |
1494 | 1494 | ||
1495 | dev = dev_get_drvdata (_dev); | 1495 | dev = dev_get_drvdata (_dev); |
1496 | next = buf; | 1496 | next = buf; |
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index a2b812af6e66..ff5533e69560 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c | |||
@@ -269,7 +269,7 @@ static int omap_ep_disable(struct usb_ep *_ep) | |||
269 | /*-------------------------------------------------------------------------*/ | 269 | /*-------------------------------------------------------------------------*/ |
270 | 270 | ||
271 | static struct usb_request * | 271 | static struct usb_request * |
272 | omap_alloc_request(struct usb_ep *ep, int gfp_flags) | 272 | omap_alloc_request(struct usb_ep *ep, unsigned gfp_flags) |
273 | { | 273 | { |
274 | struct omap_req *req; | 274 | struct omap_req *req; |
275 | 275 | ||
@@ -298,7 +298,7 @@ omap_alloc_buffer( | |||
298 | struct usb_ep *_ep, | 298 | struct usb_ep *_ep, |
299 | unsigned bytes, | 299 | unsigned bytes, |
300 | dma_addr_t *dma, | 300 | dma_addr_t *dma, |
301 | int gfp_flags | 301 | unsigned gfp_flags |
302 | ) | 302 | ) |
303 | { | 303 | { |
304 | void *retval; | 304 | void *retval; |
@@ -937,7 +937,7 @@ static void dma_channel_release(struct omap_ep *ep) | |||
937 | /*-------------------------------------------------------------------------*/ | 937 | /*-------------------------------------------------------------------------*/ |
938 | 938 | ||
939 | static int | 939 | static int |
940 | omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags) | 940 | omap_ep_queue(struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags) |
941 | { | 941 | { |
942 | struct omap_ep *ep = container_of(_ep, struct omap_ep, ep); | 942 | struct omap_ep *ep = container_of(_ep, struct omap_ep, ep); |
943 | struct omap_req *req = container_of(_req, struct omap_req, req); | 943 | struct omap_req *req = container_of(_req, struct omap_req, req); |
@@ -2908,6 +2908,7 @@ static int __exit omap_udc_remove(struct device *dev) | |||
2908 | * make host resumes and VBUS detection trigger OMAP wakeup events; that | 2908 | * make host resumes and VBUS detection trigger OMAP wakeup events; that |
2909 | * may involve talking to an external transceiver (e.g. isp1301). | 2909 | * may involve talking to an external transceiver (e.g. isp1301). |
2910 | */ | 2910 | */ |
2911 | |||
2911 | static int omap_udc_suspend(struct device *dev, pm_message_t message, u32 level) | 2912 | static int omap_udc_suspend(struct device *dev, pm_message_t message, u32 level) |
2912 | { | 2913 | { |
2913 | u32 devstat; | 2914 | u32 devstat; |
@@ -2936,8 +2937,6 @@ static int omap_udc_resume(struct device *dev, u32 level) | |||
2936 | return 0; | 2937 | return 0; |
2937 | 2938 | ||
2938 | DBG("resume + wakeup/SRP\n"); | 2939 | DBG("resume + wakeup/SRP\n"); |
2939 | udc->gadget.dev.parent->power.power_state = PMSG_ON; | ||
2940 | udc->gadget.dev.power.power_state = PMSG_ON; | ||
2941 | omap_pullup(&udc->gadget, 1); | 2940 | omap_pullup(&udc->gadget, 1); |
2942 | 2941 | ||
2943 | /* maybe the host would enumerate us if we nudged it */ | 2942 | /* maybe the host would enumerate us if we nudged it */ |
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 6a0b957af335..1507738337c4 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c | |||
@@ -332,7 +332,7 @@ static int pxa2xx_ep_disable (struct usb_ep *_ep) | |||
332 | * pxa2xx_ep_alloc_request - allocate a request data structure | 332 | * pxa2xx_ep_alloc_request - allocate a request data structure |
333 | */ | 333 | */ |
334 | static struct usb_request * | 334 | static struct usb_request * |
335 | pxa2xx_ep_alloc_request (struct usb_ep *_ep, int gfp_flags) | 335 | pxa2xx_ep_alloc_request (struct usb_ep *_ep, unsigned gfp_flags) |
336 | { | 336 | { |
337 | struct pxa2xx_request *req; | 337 | struct pxa2xx_request *req; |
338 | 338 | ||
@@ -367,7 +367,7 @@ pxa2xx_ep_free_request (struct usb_ep *_ep, struct usb_request *_req) | |||
367 | */ | 367 | */ |
368 | static void * | 368 | static void * |
369 | pxa2xx_ep_alloc_buffer(struct usb_ep *_ep, unsigned bytes, | 369 | pxa2xx_ep_alloc_buffer(struct usb_ep *_ep, unsigned bytes, |
370 | dma_addr_t *dma, int gfp_flags) | 370 | dma_addr_t *dma, unsigned gfp_flags) |
371 | { | 371 | { |
372 | char *retval; | 372 | char *retval; |
373 | 373 | ||
@@ -874,7 +874,7 @@ done: | |||
874 | /*-------------------------------------------------------------------------*/ | 874 | /*-------------------------------------------------------------------------*/ |
875 | 875 | ||
876 | static int | 876 | static int |
877 | pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, int gfp_flags) | 877 | pxa2xx_ep_queue(struct usb_ep *_ep, struct usb_request *_req, unsigned gfp_flags) |
878 | { | 878 | { |
879 | struct pxa2xx_request *req; | 879 | struct pxa2xx_request *req; |
880 | struct pxa2xx_ep *ep; | 880 | struct pxa2xx_ep *ep; |
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index a6e035e24479..bb9b2d94eed5 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c | |||
@@ -612,7 +612,7 @@ static void source_sink_complete (struct usb_ep *ep, struct usb_request *req) | |||
612 | } | 612 | } |
613 | 613 | ||
614 | static struct usb_request * | 614 | static struct usb_request * |
615 | source_sink_start_ep (struct usb_ep *ep, int gfp_flags) | 615 | source_sink_start_ep (struct usb_ep *ep, unsigned gfp_flags) |
616 | { | 616 | { |
617 | struct usb_request *req; | 617 | struct usb_request *req; |
618 | int status; | 618 | int status; |
@@ -640,7 +640,7 @@ source_sink_start_ep (struct usb_ep *ep, int gfp_flags) | |||
640 | } | 640 | } |
641 | 641 | ||
642 | static int | 642 | static int |
643 | set_source_sink_config (struct zero_dev *dev, int gfp_flags) | 643 | set_source_sink_config (struct zero_dev *dev, unsigned gfp_flags) |
644 | { | 644 | { |
645 | int result = 0; | 645 | int result = 0; |
646 | struct usb_ep *ep; | 646 | struct usb_ep *ep; |
@@ -744,7 +744,7 @@ static void loopback_complete (struct usb_ep *ep, struct usb_request *req) | |||
744 | } | 744 | } |
745 | 745 | ||
746 | static int | 746 | static int |
747 | set_loopback_config (struct zero_dev *dev, int gfp_flags) | 747 | set_loopback_config (struct zero_dev *dev, unsigned gfp_flags) |
748 | { | 748 | { |
749 | int result = 0; | 749 | int result = 0; |
750 | struct usb_ep *ep; | 750 | struct usb_ep *ep; |
@@ -845,7 +845,7 @@ static void zero_reset_config (struct zero_dev *dev) | |||
845 | * by limiting configuration choices (like the pxa2xx). | 845 | * by limiting configuration choices (like the pxa2xx). |
846 | */ | 846 | */ |
847 | static int | 847 | static int |
848 | zero_set_config (struct zero_dev *dev, unsigned number, int gfp_flags) | 848 | zero_set_config (struct zero_dev *dev, unsigned number, unsigned gfp_flags) |
849 | { | 849 | { |
850 | int result = 0; | 850 | int result = 0; |
851 | struct usb_gadget *gadget = dev->gadget; | 851 | struct usb_gadget *gadget = dev->gadget; |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 35248a37b717..149b13fc0a71 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -960,7 +960,7 @@ static int ehci_urb_enqueue ( | |||
960 | struct usb_hcd *hcd, | 960 | struct usb_hcd *hcd, |
961 | struct usb_host_endpoint *ep, | 961 | struct usb_host_endpoint *ep, |
962 | struct urb *urb, | 962 | struct urb *urb, |
963 | int mem_flags | 963 | unsigned mem_flags |
964 | ) { | 964 | ) { |
965 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 965 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
966 | struct list_head qtd_list; | 966 | struct list_head qtd_list; |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 45d89a7083b1..d74b2d68a50e 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -898,7 +898,7 @@ submit_async ( | |||
898 | struct usb_host_endpoint *ep, | 898 | struct usb_host_endpoint *ep, |
899 | struct urb *urb, | 899 | struct urb *urb, |
900 | struct list_head *qtd_list, | 900 | struct list_head *qtd_list, |
901 | int mem_flags | 901 | unsigned mem_flags |
902 | ) { | 902 | ) { |
903 | struct ehci_qtd *qtd; | 903 | struct ehci_qtd *qtd; |
904 | int epnum; | 904 | int epnum; |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index c2104cad4033..9af4f64532a9 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -588,7 +588,7 @@ static int intr_submit ( | |||
588 | struct usb_host_endpoint *ep, | 588 | struct usb_host_endpoint *ep, |
589 | struct urb *urb, | 589 | struct urb *urb, |
590 | struct list_head *qtd_list, | 590 | struct list_head *qtd_list, |
591 | int mem_flags | 591 | unsigned mem_flags |
592 | ) { | 592 | ) { |
593 | unsigned epnum; | 593 | unsigned epnum; |
594 | unsigned long flags; | 594 | unsigned long flags; |
@@ -633,7 +633,7 @@ done: | |||
633 | /* ehci_iso_stream ops work with both ITD and SITD */ | 633 | /* ehci_iso_stream ops work with both ITD and SITD */ |
634 | 634 | ||
635 | static struct ehci_iso_stream * | 635 | static struct ehci_iso_stream * |
636 | iso_stream_alloc (int mem_flags) | 636 | iso_stream_alloc (unsigned mem_flags) |
637 | { | 637 | { |
638 | struct ehci_iso_stream *stream; | 638 | struct ehci_iso_stream *stream; |
639 | 639 | ||
@@ -846,7 +846,7 @@ iso_stream_find (struct ehci_hcd *ehci, struct urb *urb) | |||
846 | /* ehci_iso_sched ops can be ITD-only or SITD-only */ | 846 | /* ehci_iso_sched ops can be ITD-only or SITD-only */ |
847 | 847 | ||
848 | static struct ehci_iso_sched * | 848 | static struct ehci_iso_sched * |
849 | iso_sched_alloc (unsigned packets, int mem_flags) | 849 | iso_sched_alloc (unsigned packets, unsigned mem_flags) |
850 | { | 850 | { |
851 | struct ehci_iso_sched *iso_sched; | 851 | struct ehci_iso_sched *iso_sched; |
852 | int size = sizeof *iso_sched; | 852 | int size = sizeof *iso_sched; |
@@ -919,7 +919,7 @@ itd_urb_transaction ( | |||
919 | struct ehci_iso_stream *stream, | 919 | struct ehci_iso_stream *stream, |
920 | struct ehci_hcd *ehci, | 920 | struct ehci_hcd *ehci, |
921 | struct urb *urb, | 921 | struct urb *urb, |
922 | int mem_flags | 922 | unsigned mem_flags |
923 | ) | 923 | ) |
924 | { | 924 | { |
925 | struct ehci_itd *itd; | 925 | struct ehci_itd *itd; |
@@ -1412,7 +1412,8 @@ itd_complete ( | |||
1412 | 1412 | ||
1413 | /*-------------------------------------------------------------------------*/ | 1413 | /*-------------------------------------------------------------------------*/ |
1414 | 1414 | ||
1415 | static int itd_submit (struct ehci_hcd *ehci, struct urb *urb, int mem_flags) | 1415 | static int itd_submit (struct ehci_hcd *ehci, struct urb *urb, |
1416 | unsigned mem_flags) | ||
1416 | { | 1417 | { |
1417 | int status = -EINVAL; | 1418 | int status = -EINVAL; |
1418 | unsigned long flags; | 1419 | unsigned long flags; |
@@ -1523,7 +1524,7 @@ sitd_urb_transaction ( | |||
1523 | struct ehci_iso_stream *stream, | 1524 | struct ehci_iso_stream *stream, |
1524 | struct ehci_hcd *ehci, | 1525 | struct ehci_hcd *ehci, |
1525 | struct urb *urb, | 1526 | struct urb *urb, |
1526 | int mem_flags | 1527 | unsigned mem_flags |
1527 | ) | 1528 | ) |
1528 | { | 1529 | { |
1529 | struct ehci_sitd *sitd; | 1530 | struct ehci_sitd *sitd; |
@@ -1772,7 +1773,8 @@ sitd_complete ( | |||
1772 | } | 1773 | } |
1773 | 1774 | ||
1774 | 1775 | ||
1775 | static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb, int mem_flags) | 1776 | static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb, |
1777 | unsigned mem_flags) | ||
1776 | { | 1778 | { |
1777 | int status = -EINVAL; | 1779 | int status = -EINVAL; |
1778 | unsigned long flags; | 1780 | unsigned long flags; |
@@ -1822,7 +1824,8 @@ done: | |||
1822 | #else | 1824 | #else |
1823 | 1825 | ||
1824 | static inline int | 1826 | static inline int |
1825 | sitd_submit (struct ehci_hcd *ehci, struct urb *urb, int mem_flags) | 1827 | sitd_submit (struct ehci_hcd *ehci, struct urb *urb, |
1828 | unsigned mem_flags) | ||
1826 | { | 1829 | { |
1827 | ehci_dbg (ehci, "split iso support is disabled\n"); | 1830 | ehci_dbg (ehci, "split iso support is disabled\n"); |
1828 | return -ENOSYS; | 1831 | return -ENOSYS; |
diff --git a/drivers/usb/host/hc_crisv10.c b/drivers/usb/host/hc_crisv10.c index d9883d774d3a..81f8f6b7fdce 100644 --- a/drivers/usb/host/hc_crisv10.c +++ b/drivers/usb/host/hc_crisv10.c | |||
@@ -463,7 +463,8 @@ static void etrax_usb_free_epid(int epid); | |||
463 | 463 | ||
464 | static int etrax_remove_from_sb_list(struct urb *urb); | 464 | static int etrax_remove_from_sb_list(struct urb *urb); |
465 | 465 | ||
466 | static void* etrax_usb_buffer_alloc(struct usb_bus* bus, size_t size, int mem_flags, dma_addr_t *dma); | 466 | static void* etrax_usb_buffer_alloc(struct usb_bus* bus, size_t size, |
467 | unsigned mem_flags, dma_addr_t *dma); | ||
467 | static void etrax_usb_buffer_free(struct usb_bus *bus, size_t size, void *addr, dma_addr_t dma); | 468 | static void etrax_usb_buffer_free(struct usb_bus *bus, size_t size, void *addr, dma_addr_t dma); |
468 | 469 | ||
469 | static void etrax_usb_add_to_bulk_sb_list(struct urb *urb, int epid); | 470 | static void etrax_usb_add_to_bulk_sb_list(struct urb *urb, int epid); |
@@ -476,7 +477,7 @@ static int etrax_usb_submit_ctrl_urb(struct urb *urb); | |||
476 | static int etrax_usb_submit_intr_urb(struct urb *urb); | 477 | static int etrax_usb_submit_intr_urb(struct urb *urb); |
477 | static int etrax_usb_submit_isoc_urb(struct urb *urb); | 478 | static int etrax_usb_submit_isoc_urb(struct urb *urb); |
478 | 479 | ||
479 | static int etrax_usb_submit_urb(struct urb *urb, int mem_flags); | 480 | static int etrax_usb_submit_urb(struct urb *urb, unsigned mem_flags); |
480 | static int etrax_usb_unlink_urb(struct urb *urb, int status); | 481 | static int etrax_usb_unlink_urb(struct urb *urb, int status); |
481 | static int etrax_usb_get_frame_number(struct usb_device *usb_dev); | 482 | static int etrax_usb_get_frame_number(struct usb_device *usb_dev); |
482 | 483 | ||
@@ -1262,7 +1263,7 @@ static int etrax_usb_allocate_epid(void) | |||
1262 | return -1; | 1263 | return -1; |
1263 | } | 1264 | } |
1264 | 1265 | ||
1265 | static int etrax_usb_submit_urb(struct urb *urb, int mem_flags) | 1266 | static int etrax_usb_submit_urb(struct urb *urb, unsigned mem_flags) |
1266 | { | 1267 | { |
1267 | etrax_hc_t *hc; | 1268 | etrax_hc_t *hc; |
1268 | int ret = -EINVAL; | 1269 | int ret = -EINVAL; |
@@ -4277,7 +4278,8 @@ etrax_usb_bulk_eot_timer_func(unsigned long dummy) | |||
4277 | } | 4278 | } |
4278 | 4279 | ||
4279 | static void* | 4280 | static void* |
4280 | etrax_usb_buffer_alloc(struct usb_bus* bus, size_t size, int mem_flags, dma_addr_t *dma) | 4281 | etrax_usb_buffer_alloc(struct usb_bus* bus, size_t size, |
4282 | unsigned mem_flags, dma_addr_t *dma) | ||
4281 | { | 4283 | { |
4282 | return kmalloc(size, mem_flags); | 4284 | return kmalloc(size, mem_flags); |
4283 | } | 4285 | } |
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index ff0a168e8eed..50b1970fe6b6 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c | |||
@@ -17,7 +17,7 @@ | |||
17 | * The driver basically works. A number of people have used it with a range | 17 | * The driver basically works. A number of people have used it with a range |
18 | * of devices. | 18 | * of devices. |
19 | * | 19 | * |
20 | *The driver passes all usbtests 1-14. | 20 | * The driver passes all usbtests 1-14. |
21 | * | 21 | * |
22 | * Suspending/resuming of root hub via sysfs works. Remote wakeup works too. | 22 | * Suspending/resuming of root hub via sysfs works. Remote wakeup works too. |
23 | * And suspending/resuming of platform device works too. Suspend/resume | 23 | * And suspending/resuming of platform device works too. Suspend/resume |
@@ -229,7 +229,7 @@ static void preproc_atl_queue(struct isp116x *isp116x) | |||
229 | struct isp116x_ep *ep; | 229 | struct isp116x_ep *ep; |
230 | struct urb *urb; | 230 | struct urb *urb; |
231 | struct ptd *ptd; | 231 | struct ptd *ptd; |
232 | u16 toggle, dir, len; | 232 | u16 toggle = 0, dir = PTD_DIR_SETUP, len; |
233 | 233 | ||
234 | for (ep = isp116x->atl_active; ep; ep = ep->active) { | 234 | for (ep = isp116x->atl_active; ep; ep = ep->active) { |
235 | BUG_ON(list_empty(&ep->hep->urb_list)); | 235 | BUG_ON(list_empty(&ep->hep->urb_list)); |
@@ -251,8 +251,6 @@ static void preproc_atl_queue(struct isp116x *isp116x) | |||
251 | dir = PTD_DIR_OUT; | 251 | dir = PTD_DIR_OUT; |
252 | break; | 252 | break; |
253 | case USB_PID_SETUP: | 253 | case USB_PID_SETUP: |
254 | toggle = 0; | ||
255 | dir = PTD_DIR_SETUP; | ||
256 | len = sizeof(struct usb_ctrlrequest); | 254 | len = sizeof(struct usb_ctrlrequest); |
257 | ep->data = urb->setup_packet; | 255 | ep->data = urb->setup_packet; |
258 | break; | 256 | break; |
@@ -264,11 +262,9 @@ static void preproc_atl_queue(struct isp116x *isp116x) | |||
264 | ? PTD_DIR_OUT : PTD_DIR_IN; | 262 | ? PTD_DIR_OUT : PTD_DIR_IN; |
265 | break; | 263 | break; |
266 | default: | 264 | default: |
267 | /* To please gcc */ | ||
268 | toggle = dir = 0; | ||
269 | ERR("%s %d: ep->nextpid %d\n", __func__, __LINE__, | 265 | ERR("%s %d: ep->nextpid %d\n", __func__, __LINE__, |
270 | ep->nextpid); | 266 | ep->nextpid); |
271 | BUG_ON(1); | 267 | BUG(); |
272 | } | 268 | } |
273 | 269 | ||
274 | ptd->count = PTD_CC_MSK | PTD_ACTIVE_MSK | PTD_TOGGLE(toggle); | 270 | ptd->count = PTD_CC_MSK | PTD_ACTIVE_MSK | PTD_TOGGLE(toggle); |
@@ -697,7 +693,7 @@ static int balance(struct isp116x *isp116x, u16 period, u16 load) | |||
697 | 693 | ||
698 | static int isp116x_urb_enqueue(struct usb_hcd *hcd, | 694 | static int isp116x_urb_enqueue(struct usb_hcd *hcd, |
699 | struct usb_host_endpoint *hep, struct urb *urb, | 695 | struct usb_host_endpoint *hep, struct urb *urb, |
700 | int mem_flags) | 696 | unsigned mem_flags) |
701 | { | 697 | { |
702 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | 698 | struct isp116x *isp116x = hcd_to_isp116x(hcd); |
703 | struct usb_device *udev = urb->dev; | 699 | struct usb_device *udev = urb->dev; |
@@ -719,7 +715,7 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd, | |||
719 | } | 715 | } |
720 | /* avoid all allocations within spinlocks: request or endpoint */ | 716 | /* avoid all allocations within spinlocks: request or endpoint */ |
721 | if (!hep->hcpriv) { | 717 | if (!hep->hcpriv) { |
722 | ep = kcalloc(1, sizeof *ep, (__force unsigned)mem_flags); | 718 | ep = kcalloc(1, sizeof *ep, mem_flags); |
723 | if (!ep) | 719 | if (!ep) |
724 | return -ENOMEM; | 720 | return -ENOMEM; |
725 | } | 721 | } |
@@ -1054,7 +1050,7 @@ static int isp116x_hub_control(struct usb_hcd *hcd, | |||
1054 | break; | 1050 | break; |
1055 | case GetHubStatus: | 1051 | case GetHubStatus: |
1056 | DBG("GetHubStatus\n"); | 1052 | DBG("GetHubStatus\n"); |
1057 | *(__le32 *) buf = cpu_to_le32(0); | 1053 | *(__le32 *) buf = 0; |
1058 | break; | 1054 | break; |
1059 | case GetPortStatus: | 1055 | case GetPortStatus: |
1060 | DBG("GetPortStatus\n"); | 1056 | DBG("GetPortStatus\n"); |
@@ -1810,9 +1806,9 @@ static int isp116x_suspend(struct device *dev, pm_message_t state, u32 phase) | |||
1810 | ret = usb_suspend_device(hcd->self.root_hub, state); | 1806 | ret = usb_suspend_device(hcd->self.root_hub, state); |
1811 | if (!ret) { | 1807 | if (!ret) { |
1812 | dev->power.power_state = state; | 1808 | dev->power.power_state = state; |
1813 | INFO("%s suspended\n", (char *)hcd_name); | 1809 | INFO("%s suspended\n", hcd_name); |
1814 | } else | 1810 | } else |
1815 | ERR("%s suspend failed\n", (char *)hcd_name); | 1811 | ERR("%s suspend failed\n", hcd_name); |
1816 | 1812 | ||
1817 | return ret; | 1813 | return ret; |
1818 | } | 1814 | } |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 13cd2177b557..68decab280dd 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -180,7 +180,7 @@ static int ohci_urb_enqueue ( | |||
180 | struct usb_hcd *hcd, | 180 | struct usb_hcd *hcd, |
181 | struct usb_host_endpoint *ep, | 181 | struct usb_host_endpoint *ep, |
182 | struct urb *urb, | 182 | struct urb *urb, |
183 | int mem_flags | 183 | unsigned mem_flags |
184 | ) { | 184 | ) { |
185 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 185 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
186 | struct ed *ed; | 186 | struct ed *ed; |
@@ -673,8 +673,10 @@ retry: | |||
673 | 673 | ||
674 | ohci_dump (ohci, 1); | 674 | ohci_dump (ohci, 1); |
675 | 675 | ||
676 | if (ohci_to_hcd(ohci)->self.root_hub == NULL) | 676 | if (ohci_to_hcd(ohci)->self.root_hub == NULL) { |
677 | register_reboot_notifier (&ohci->reboot_notifier); | ||
677 | create_debug_files (ohci); | 678 | create_debug_files (ohci); |
679 | } | ||
678 | 680 | ||
679 | return 0; | 681 | return 0; |
680 | } | 682 | } |
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index e2fc4129dfc6..83ca4549a50e 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c | |||
@@ -419,10 +419,11 @@ ohci_hub_descriptor ( | |||
419 | 419 | ||
420 | /* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */ | 420 | /* two bitmaps: ports removable, and usb 1.0 legacy PortPwrCtrlMask */ |
421 | rh = roothub_b (ohci); | 421 | rh = roothub_b (ohci); |
422 | memset(desc->bitmap, 0xff, sizeof(desc->bitmap)); | ||
422 | desc->bitmap [0] = rh & RH_B_DR; | 423 | desc->bitmap [0] = rh & RH_B_DR; |
423 | if (ports > 7) { | 424 | if (ports > 7) { |
424 | desc->bitmap [1] = (rh & RH_B_DR) >> 8; | 425 | desc->bitmap [1] = (rh & RH_B_DR) >> 8; |
425 | desc->bitmap [2] = desc->bitmap [3] = 0xff; | 426 | desc->bitmap [2] = 0xff; |
426 | } else | 427 | } else |
427 | desc->bitmap [1] = 0xff; | 428 | desc->bitmap [1] = 0xff; |
428 | } | 429 | } |
diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c index 23735a36af00..fd3c4d3714bd 100644 --- a/drivers/usb/host/ohci-mem.c +++ b/drivers/usb/host/ohci-mem.c | |||
@@ -84,7 +84,7 @@ dma_to_td (struct ohci_hcd *hc, dma_addr_t td_dma) | |||
84 | 84 | ||
85 | /* TDs ... */ | 85 | /* TDs ... */ |
86 | static struct td * | 86 | static struct td * |
87 | td_alloc (struct ohci_hcd *hc, int mem_flags) | 87 | td_alloc (struct ohci_hcd *hc, unsigned mem_flags) |
88 | { | 88 | { |
89 | dma_addr_t dma; | 89 | dma_addr_t dma; |
90 | struct td *td; | 90 | struct td *td; |
@@ -118,7 +118,7 @@ td_free (struct ohci_hcd *hc, struct td *td) | |||
118 | 118 | ||
119 | /* EDs ... */ | 119 | /* EDs ... */ |
120 | static struct ed * | 120 | static struct ed * |
121 | ed_alloc (struct ohci_hcd *hc, int mem_flags) | 121 | ed_alloc (struct ohci_hcd *hc, unsigned mem_flags) |
122 | { | 122 | { |
123 | dma_addr_t dma; | 123 | dma_addr_t dma; |
124 | struct ed *ed; | 124 | struct ed *ed; |
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index b62d69937694..5cde76faab93 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c | |||
@@ -456,34 +456,22 @@ static int ohci_hcd_omap_drv_remove(struct device *dev) | |||
456 | 456 | ||
457 | #ifdef CONFIG_PM | 457 | #ifdef CONFIG_PM |
458 | 458 | ||
459 | /* states match PCI usage, always suspending the root hub except that | 459 | static int ohci_omap_suspend(struct device *dev, pm_message_t message, u32 level) |
460 | * 4 ~= D3cold (ACPI D3) with clock off (resume sees reset). | ||
461 | * | ||
462 | * FIXME: above comment is not right, and code is wrong, too :-(. | ||
463 | */ | ||
464 | |||
465 | static int ohci_omap_suspend(struct device *dev, pm_message_t state, u32 level) | ||
466 | { | 460 | { |
467 | struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); | 461 | struct ohci_hcd *ohci = hcd_to_ohci(dev_get_drvdata(dev)); |
468 | int status = -EINVAL; | 462 | int status = -EINVAL; |
469 | 463 | ||
470 | if (level != SUSPEND_POWER_DOWN) | 464 | if (level != SUSPEND_POWER_DOWN) |
471 | return 0; | 465 | return 0; |
472 | if (state <= dev->power.power_state) | ||
473 | return 0; | ||
474 | 466 | ||
475 | dev_dbg(dev, "suspend to %d\n", state); | ||
476 | down(&ohci_to_hcd(ohci)->self.root_hub->serialize); | 467 | down(&ohci_to_hcd(ohci)->self.root_hub->serialize); |
477 | status = ohci_hub_suspend(ohci_to_hcd(ohci)); | 468 | status = ohci_hub_suspend(ohci_to_hcd(ohci)); |
478 | if (status == 0) { | 469 | if (status == 0) { |
479 | if (state >= 4) { | 470 | omap_ohci_clock_power(0); |
480 | omap_ohci_clock_power(0); | 471 | ohci_to_hcd(ohci)->self.root_hub->state = |
481 | ohci_to_hcd(ohci)->self.root_hub->state = | 472 | USB_STATE_SUSPENDED; |
482 | USB_STATE_SUSPENDED; | ||
483 | state = 4; | ||
484 | } | ||
485 | ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; | 473 | ohci_to_hcd(ohci)->state = HC_STATE_SUSPENDED; |
486 | dev->power.power_state = state; | 474 | dev->power.power_state = PMSG_SUSPEND; |
487 | } | 475 | } |
488 | up(&ohci_to_hcd(ohci)->self.root_hub->serialize); | 476 | up(&ohci_to_hcd(ohci)->self.root_hub->serialize); |
489 | return status; | 477 | return status; |
@@ -497,29 +485,20 @@ static int ohci_omap_resume(struct device *dev, u32 level) | |||
497 | if (level != RESUME_POWER_ON) | 485 | if (level != RESUME_POWER_ON) |
498 | return 0; | 486 | return 0; |
499 | 487 | ||
500 | switch (dev->power.power_state) { | 488 | if (time_before(jiffies, ohci->next_statechange)) |
501 | case 0: | 489 | msleep(5); |
502 | break; | 490 | ohci->next_statechange = jiffies; |
503 | case 4: | 491 | omap_ohci_clock_power(1); |
504 | if (time_before(jiffies, ohci->next_statechange)) | ||
505 | msleep(5); | ||
506 | ohci->next_statechange = jiffies; | ||
507 | omap_ohci_clock_power(1); | ||
508 | /* FALLTHROUGH */ | ||
509 | default: | ||
510 | dev_dbg(dev, "resume from %d\n", dev->power.power_state); | ||
511 | #ifdef CONFIG_USB_SUSPEND | 492 | #ifdef CONFIG_USB_SUSPEND |
512 | /* get extra cleanup even if remote wakeup isn't in use */ | 493 | /* get extra cleanup even if remote wakeup isn't in use */ |
513 | status = usb_resume_device(ohci_to_hcd(ohci)->self.root_hub); | 494 | status = usb_resume_device(ohci_to_hcd(ohci)->self.root_hub); |
514 | #else | 495 | #else |
515 | down(&ohci_to_hcd(ohci)->self.root_hub->serialize); | 496 | down(&ohci_to_hcd(ohci)->self.root_hub->serialize); |
516 | status = ohci_hub_resume(ohci_to_hcd(ohci)); | 497 | status = ohci_hub_resume(ohci_to_hcd(ohci)); |
517 | up(&ohci_to_hcd(ohci)->self.root_hub->serialize); | 498 | up(&ohci_to_hcd(ohci)->self.root_hub->serialize); |
518 | #endif | 499 | #endif |
519 | if (status == 0) | 500 | if (status == 0) |
520 | dev->power.power_state = 0; | 501 | dev->power.power_state = PMSG_ON; |
521 | break; | ||
522 | } | ||
523 | return status; | 502 | return status; |
524 | } | 503 | } |
525 | 504 | ||
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 6c3f910bc307..7a890a65f55d 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
@@ -815,7 +815,7 @@ static int sl811h_urb_enqueue( | |||
815 | struct usb_hcd *hcd, | 815 | struct usb_hcd *hcd, |
816 | struct usb_host_endpoint *hep, | 816 | struct usb_host_endpoint *hep, |
817 | struct urb *urb, | 817 | struct urb *urb, |
818 | int mem_flags | 818 | unsigned mem_flags |
819 | ) { | 819 | ) { |
820 | struct sl811 *sl811 = hcd_to_sl811(hcd); | 820 | struct sl811 *sl811 = hcd_to_sl811(hcd); |
821 | struct usb_device *udev = urb->dev; | 821 | struct usb_device *udev = urb->dev; |
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index 269d8ef01459..38aebe361ca1 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c | |||
@@ -20,7 +20,6 @@ | |||
20 | #include <linux/timer.h> | 20 | #include <linux/timer.h> |
21 | #include <linux/ioport.h> | 21 | #include <linux/ioport.h> |
22 | 22 | ||
23 | #include <pcmcia/version.h> | ||
24 | #include <pcmcia/cs_types.h> | 23 | #include <pcmcia/cs_types.h> |
25 | #include <pcmcia/cs.h> | 24 | #include <pcmcia/cs.h> |
26 | #include <pcmcia/cistpl.h> | 25 | #include <pcmcia/cistpl.h> |
@@ -389,11 +388,6 @@ static dev_link_t *sl811_cs_attach(void) | |||
389 | dev_list = link; | 388 | dev_list = link; |
390 | client_reg.dev_info = (dev_info_t *) &driver_name; | 389 | client_reg.dev_info = (dev_info_t *) &driver_name; |
391 | client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; | 390 | client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE; |
392 | client_reg.EventMask = | ||
393 | CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL | | ||
394 | CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET | | ||
395 | CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME; | ||
396 | client_reg.event_handler = &sl811_cs_event; | ||
397 | client_reg.Version = 0x0210; | 391 | client_reg.Version = 0x0210; |
398 | client_reg.event_callback_args.client_data = link; | 392 | client_reg.event_callback_args.client_data = link; |
399 | ret = pcmcia_register_client(&link->handle, &client_reg); | 393 | ret = pcmcia_register_client(&link->handle, &client_reg); |
@@ -418,6 +412,7 @@ static struct pcmcia_driver sl811_cs_driver = { | |||
418 | .name = (char *)driver_name, | 412 | .name = (char *)driver_name, |
419 | }, | 413 | }, |
420 | .attach = sl811_cs_attach, | 414 | .attach = sl811_cs_attach, |
415 | .event = sl811_cs_event, | ||
421 | .detach = sl811_cs_detach, | 416 | .detach = sl811_cs_detach, |
422 | .id_table = sl811_ids, | 417 | .id_table = sl811_ids, |
423 | }; | 418 | }; |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 5f18084a116d..bbb36cd6ed61 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
@@ -1164,7 +1164,7 @@ static struct urb *uhci_find_urb_ep(struct uhci_hcd *uhci, struct urb *urb) | |||
1164 | 1164 | ||
1165 | static int uhci_urb_enqueue(struct usb_hcd *hcd, | 1165 | static int uhci_urb_enqueue(struct usb_hcd *hcd, |
1166 | struct usb_host_endpoint *ep, | 1166 | struct usb_host_endpoint *ep, |
1167 | struct urb *urb, int mem_flags) | 1167 | struct urb *urb, unsigned mem_flags) |
1168 | { | 1168 | { |
1169 | int ret; | 1169 | int ret; |
1170 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); | 1170 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
diff --git a/drivers/usb/input/Kconfig b/drivers/usb/input/Kconfig index fd59f6bdd67f..298e4a25e3d3 100644 --- a/drivers/usb/input/Kconfig +++ b/drivers/usb/input/Kconfig | |||
@@ -259,3 +259,16 @@ config USB_ATI_REMOTE | |||
259 | To compile this driver as a module, choose M here: the module will be | 259 | To compile this driver as a module, choose M here: the module will be |
260 | called ati_remote. | 260 | called ati_remote. |
261 | 261 | ||
262 | config USB_KEYSPAN_REMOTE | ||
263 | tristate "Keyspan DMR USB remote control (EXPERIMENTAL)" | ||
264 | depends on USB && INPUT && EXPERIMENTAL | ||
265 | ---help--- | ||
266 | Say Y here if you want to use a Keyspan DMR USB remote control. | ||
267 | Currently only the UIA-11 type of receiver has been tested. The tag | ||
268 | on the receiver that connects to the USB port should have a P/N that | ||
269 | will tell you what type of DMR you have. The UIA-10 type is not | ||
270 | supported at this time. This driver maps all buttons to keypress | ||
271 | events. | ||
272 | |||
273 | To compile this driver as a module, choose M here: the module will | ||
274 | be called keyspan_remote. | ||
diff --git a/drivers/usb/input/Makefile b/drivers/usb/input/Makefile index 831b2b0f1f05..f1547be632d4 100644 --- a/drivers/usb/input/Makefile +++ b/drivers/usb/input/Makefile | |||
@@ -31,6 +31,7 @@ obj-$(CONFIG_USB_ATI_REMOTE) += ati_remote.o | |||
31 | obj-$(CONFIG_USB_HID) += usbhid.o | 31 | obj-$(CONFIG_USB_HID) += usbhid.o |
32 | obj-$(CONFIG_USB_KBD) += usbkbd.o | 32 | obj-$(CONFIG_USB_KBD) += usbkbd.o |
33 | obj-$(CONFIG_USB_KBTAB) += kbtab.o | 33 | obj-$(CONFIG_USB_KBTAB) += kbtab.o |
34 | obj-$(CONFIG_USB_KEYSPAN_REMOTE) += keyspan_remote.o | ||
34 | obj-$(CONFIG_USB_MOUSE) += usbmouse.o | 35 | obj-$(CONFIG_USB_MOUSE) += usbmouse.o |
35 | obj-$(CONFIG_USB_MTOUCH) += mtouchusb.o | 36 | obj-$(CONFIG_USB_MTOUCH) += mtouchusb.o |
36 | obj-$(CONFIG_USB_ITMTOUCH) += itmtouch.o | 37 | obj-$(CONFIG_USB_ITMTOUCH) += itmtouch.o |
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index 100b49bd1d3e..2350e7a5ad70 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c | |||
@@ -1428,6 +1428,19 @@ void hid_init_reports(struct hid_device *hid) | |||
1428 | #define USB_DEVICE_ID_VERNIER_SKIP 0x0003 | 1428 | #define USB_DEVICE_ID_VERNIER_SKIP 0x0003 |
1429 | #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 | 1429 | #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 |
1430 | 1430 | ||
1431 | #define USB_VENDOR_ID_LD 0x0f11 | ||
1432 | #define USB_DEVICE_ID_CASSY 0x1000 | ||
1433 | #define USB_DEVICE_ID_POCKETCASSY 0x1010 | ||
1434 | #define USB_DEVICE_ID_MOBILECASSY 0x1020 | ||
1435 | #define USB_DEVICE_ID_JWM 0x1080 | ||
1436 | #define USB_DEVICE_ID_DMMP 0x1081 | ||
1437 | #define USB_DEVICE_ID_UMIP 0x1090 | ||
1438 | #define USB_DEVICE_ID_VIDEOCOM 0x1200 | ||
1439 | #define USB_DEVICE_ID_COM3LAB 0x2000 | ||
1440 | #define USB_DEVICE_ID_TELEPORT 0x2010 | ||
1441 | #define USB_DEVICE_ID_NETWORKANALYSER 0x2020 | ||
1442 | #define USB_DEVICE_ID_POWERCONTROL 0x2030 | ||
1443 | |||
1431 | 1444 | ||
1432 | /* | 1445 | /* |
1433 | * Alphabetically sorted blacklist by quirk type. | 1446 | * Alphabetically sorted blacklist by quirk type. |
@@ -1463,6 +1476,17 @@ static struct hid_blacklist { | |||
1463 | { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE }, | 1476 | { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_POWERMATE, HID_QUIRK_IGNORE }, |
1464 | { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE }, | 1477 | { USB_VENDOR_ID_GRIFFIN, USB_DEVICE_ID_SOUNDKNOB, HID_QUIRK_IGNORE }, |
1465 | { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE }, | 1478 | { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE }, |
1479 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_CASSY, HID_QUIRK_IGNORE }, | ||
1480 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_POCKETCASSY, HID_QUIRK_IGNORE }, | ||
1481 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_MOBILECASSY, HID_QUIRK_IGNORE }, | ||
1482 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_JWM, HID_QUIRK_IGNORE }, | ||
1483 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_DMMP, HID_QUIRK_IGNORE }, | ||
1484 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_UMIP, HID_QUIRK_IGNORE }, | ||
1485 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_VIDEOCOM, HID_QUIRK_IGNORE }, | ||
1486 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_COM3LAB, HID_QUIRK_IGNORE }, | ||
1487 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_TELEPORT, HID_QUIRK_IGNORE }, | ||
1488 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_NETWORKANALYSER, HID_QUIRK_IGNORE }, | ||
1489 | { USB_VENDOR_ID_LD, USB_DEVICE_ID_POWERCONTROL, HID_QUIRK_IGNORE }, | ||
1466 | { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS, HID_QUIRK_IGNORE }, | 1490 | { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1024LS, HID_QUIRK_IGNORE }, |
1467 | { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS, HID_QUIRK_IGNORE }, | 1491 | { USB_VENDOR_ID_MCC, USB_DEVICE_ID_MCC_PMD1208LS, HID_QUIRK_IGNORE }, |
1468 | { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE }, | 1492 | { USB_VENDOR_ID_MGE, USB_DEVICE_ID_MGE_UPS, HID_QUIRK_IGNORE }, |
diff --git a/drivers/usb/input/keyspan_remote.c b/drivers/usb/input/keyspan_remote.c new file mode 100644 index 000000000000..67dc93685203 --- /dev/null +++ b/drivers/usb/input/keyspan_remote.c | |||
@@ -0,0 +1,633 @@ | |||
1 | /* | ||
2 | * keyspan_remote: USB driver for the Keyspan DMR | ||
3 | * | ||
4 | * Copyright (C) 2005 Zymeta Corporation - Michael Downey (downey@zymeta.com) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2. | ||
9 | * | ||
10 | * This driver has been put together with the support of Innosys, Inc. | ||
11 | * and Keyspan, Inc the manufacturers of the Keyspan USB DMR product. | ||
12 | */ | ||
13 | |||
14 | #include <linux/config.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/errno.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/moduleparam.h> | ||
21 | #include <linux/input.h> | ||
22 | #include <linux/usb.h> | ||
23 | |||
24 | #define DRIVER_VERSION "v0.1" | ||
25 | #define DRIVER_AUTHOR "Michael Downey <downey@zymeta.com>" | ||
26 | #define DRIVER_DESC "Driver for the USB Keyspan remote control." | ||
27 | #define DRIVER_LICENSE "GPL" | ||
28 | |||
29 | /* Parameters that can be passed to the driver. */ | ||
30 | static int debug; | ||
31 | module_param(debug, int, 0444); | ||
32 | MODULE_PARM_DESC(debug, "Enable extra debug messages and information"); | ||
33 | |||
34 | /* Vendor and product ids */ | ||
35 | #define USB_KEYSPAN_VENDOR_ID 0x06CD | ||
36 | #define USB_KEYSPAN_PRODUCT_UIA11 0x0202 | ||
37 | |||
38 | /* Defines for converting the data from the remote. */ | ||
39 | #define ZERO 0x18 | ||
40 | #define ZERO_MASK 0x1F /* 5 bits for a 0 */ | ||
41 | #define ONE 0x3C | ||
42 | #define ONE_MASK 0x3F /* 6 bits for a 1 */ | ||
43 | #define SYNC 0x3F80 | ||
44 | #define SYNC_MASK 0x3FFF /* 14 bits for a SYNC sequence */ | ||
45 | #define STOP 0x00 | ||
46 | #define STOP_MASK 0x1F /* 5 bits for the STOP sequence */ | ||
47 | #define GAP 0xFF | ||
48 | |||
49 | #define RECV_SIZE 8 /* The UIA-11 type have a 8 byte limit. */ | ||
50 | |||
51 | /* table of devices that work with this driver */ | ||
52 | static struct usb_device_id keyspan_table[] = { | ||
53 | { USB_DEVICE(USB_KEYSPAN_VENDOR_ID, USB_KEYSPAN_PRODUCT_UIA11) }, | ||
54 | { } /* Terminating entry */ | ||
55 | }; | ||
56 | |||
57 | /* Structure to store all the real stuff that a remote sends to us. */ | ||
58 | struct keyspan_message { | ||
59 | u16 system; | ||
60 | u8 button; | ||
61 | u8 toggle; | ||
62 | }; | ||
63 | |||
64 | /* Structure used for all the bit testing magic needed to be done. */ | ||
65 | struct bit_tester { | ||
66 | u32 tester; | ||
67 | int len; | ||
68 | int pos; | ||
69 | int bits_left; | ||
70 | u8 buffer[32]; | ||
71 | }; | ||
72 | |||
73 | /* Structure to hold all of our driver specific stuff */ | ||
74 | struct usb_keyspan { | ||
75 | char name[128]; | ||
76 | char phys[64]; | ||
77 | struct usb_device* udev; | ||
78 | struct input_dev input; | ||
79 | struct usb_interface* interface; | ||
80 | struct usb_endpoint_descriptor* in_endpoint; | ||
81 | struct urb* irq_urb; | ||
82 | int open; | ||
83 | dma_addr_t in_dma; | ||
84 | unsigned char* in_buffer; | ||
85 | |||
86 | /* variables used to parse messages from remote. */ | ||
87 | struct bit_tester data; | ||
88 | int stage; | ||
89 | int toggle; | ||
90 | }; | ||
91 | |||
92 | /* | ||
93 | * Table that maps the 31 possible keycodes to input keys. | ||
94 | * Currently there are 15 and 17 button models so RESERVED codes | ||
95 | * are blank areas in the mapping. | ||
96 | */ | ||
97 | static int keyspan_key_table[] = { | ||
98 | KEY_RESERVED, /* 0 is just a place holder. */ | ||
99 | KEY_RESERVED, | ||
100 | KEY_STOP, | ||
101 | KEY_PLAYCD, | ||
102 | KEY_RESERVED, | ||
103 | KEY_PREVIOUSSONG, | ||
104 | KEY_REWIND, | ||
105 | KEY_FORWARD, | ||
106 | KEY_NEXTSONG, | ||
107 | KEY_RESERVED, | ||
108 | KEY_RESERVED, | ||
109 | KEY_RESERVED, | ||
110 | KEY_PAUSE, | ||
111 | KEY_VOLUMEUP, | ||
112 | KEY_RESERVED, | ||
113 | KEY_RESERVED, | ||
114 | KEY_RESERVED, | ||
115 | KEY_VOLUMEDOWN, | ||
116 | KEY_RESERVED, | ||
117 | KEY_UP, | ||
118 | KEY_RESERVED, | ||
119 | KEY_MUTE, | ||
120 | KEY_LEFT, | ||
121 | KEY_ENTER, | ||
122 | KEY_RIGHT, | ||
123 | KEY_RESERVED, | ||
124 | KEY_RESERVED, | ||
125 | KEY_DOWN, | ||
126 | KEY_RESERVED, | ||
127 | KEY_KPASTERISK, | ||
128 | KEY_RESERVED, | ||
129 | KEY_MENU | ||
130 | }; | ||
131 | |||
132 | static struct usb_driver keyspan_driver; | ||
133 | |||
134 | /* | ||
135 | * Debug routine that prints out what we've received from the remote. | ||
136 | */ | ||
137 | static void keyspan_print(struct usb_keyspan* dev) /*unsigned char* data)*/ | ||
138 | { | ||
139 | char codes[4*RECV_SIZE]; | ||
140 | int i; | ||
141 | |||
142 | for (i = 0; i < RECV_SIZE; i++) { | ||
143 | snprintf(codes+i*3, 4, "%02x ", dev->in_buffer[i]); | ||
144 | } | ||
145 | |||
146 | dev_info(&dev->udev->dev, "%s\n", codes); | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * Routine that manages the bit_tester structure. It makes sure that there are | ||
151 | * at least bits_needed bits loaded into the tester. | ||
152 | */ | ||
153 | static int keyspan_load_tester(struct usb_keyspan* dev, int bits_needed) | ||
154 | { | ||
155 | if (dev->data.bits_left >= bits_needed) | ||
156 | return(0); | ||
157 | |||
158 | /* | ||
159 | * Somehow we've missed the last message. The message will be repeated | ||
160 | * though so it's not too big a deal | ||
161 | */ | ||
162 | if (dev->data.pos >= dev->data.len) { | ||
163 | dev_dbg(&dev->udev, "%s - Error ran out of data. pos: %d, len: %d\n", | ||
164 | __FUNCTION__, dev->data.pos, dev->data.len); | ||
165 | return(-1); | ||
166 | } | ||
167 | |||
168 | /* Load as much as we can into the tester. */ | ||
169 | while ((dev->data.bits_left + 7 < (sizeof(dev->data.tester) * 8)) && | ||
170 | (dev->data.pos < dev->data.len)) { | ||
171 | dev->data.tester += (dev->data.buffer[dev->data.pos++] << dev->data.bits_left); | ||
172 | dev->data.bits_left += 8; | ||
173 | } | ||
174 | |||
175 | return(0); | ||
176 | } | ||
177 | |||
178 | /* | ||
179 | * Routine that handles all the logic needed to parse out the message from the remote. | ||
180 | */ | ||
181 | static void keyspan_check_data(struct usb_keyspan *remote, struct pt_regs *regs) | ||
182 | { | ||
183 | int i; | ||
184 | int found = 0; | ||
185 | struct keyspan_message message; | ||
186 | |||
187 | switch(remote->stage) { | ||
188 | case 0: | ||
189 | /* | ||
190 | * In stage 0 we want to find the start of a message. The remote sends a 0xFF as filler. | ||
191 | * So the first byte that isn't a FF should be the start of a new message. | ||
192 | */ | ||
193 | for (i = 0; i < RECV_SIZE && remote->in_buffer[i] == GAP; ++i); | ||
194 | |||
195 | if (i < RECV_SIZE) { | ||
196 | memcpy(remote->data.buffer, remote->in_buffer, RECV_SIZE); | ||
197 | remote->data.len = RECV_SIZE; | ||
198 | remote->data.pos = 0; | ||
199 | remote->data.tester = 0; | ||
200 | remote->data.bits_left = 0; | ||
201 | remote->stage = 1; | ||
202 | } | ||
203 | break; | ||
204 | |||
205 | case 1: | ||
206 | /* | ||
207 | * Stage 1 we should have 16 bytes and should be able to detect a | ||
208 | * SYNC. The SYNC is 14 bits, 7 0's and then 7 1's. | ||
209 | */ | ||
210 | memcpy(remote->data.buffer + remote->data.len, remote->in_buffer, RECV_SIZE); | ||
211 | remote->data.len += RECV_SIZE; | ||
212 | |||
213 | found = 0; | ||
214 | while ((remote->data.bits_left >= 14 || remote->data.pos < remote->data.len) && !found) { | ||
215 | for (i = 0; i < 8; ++i) { | ||
216 | if (keyspan_load_tester(remote, 14) != 0) { | ||
217 | remote->stage = 0; | ||
218 | return; | ||
219 | } | ||
220 | |||
221 | if ((remote->data.tester & SYNC_MASK) == SYNC) { | ||
222 | remote->data.tester = remote->data.tester >> 14; | ||
223 | remote->data.bits_left -= 14; | ||
224 | found = 1; | ||
225 | break; | ||
226 | } else { | ||
227 | remote->data.tester = remote->data.tester >> 1; | ||
228 | --remote->data.bits_left; | ||
229 | } | ||
230 | } | ||
231 | } | ||
232 | |||
233 | if (!found) { | ||
234 | remote->stage = 0; | ||
235 | remote->data.len = 0; | ||
236 | } else { | ||
237 | remote->stage = 2; | ||
238 | } | ||
239 | break; | ||
240 | |||
241 | case 2: | ||
242 | /* | ||
243 | * Stage 2 we should have 24 bytes which will be enough for a full | ||
244 | * message. We need to parse out the system code, button code, | ||
245 | * toggle code, and stop. | ||
246 | */ | ||
247 | memcpy(remote->data.buffer + remote->data.len, remote->in_buffer, RECV_SIZE); | ||
248 | remote->data.len += RECV_SIZE; | ||
249 | |||
250 | message.system = 0; | ||
251 | for (i = 0; i < 9; i++) { | ||
252 | keyspan_load_tester(remote, 6); | ||
253 | |||
254 | if ((remote->data.tester & ZERO_MASK) == ZERO) { | ||
255 | message.system = message.system << 1; | ||
256 | remote->data.tester = remote->data.tester >> 5; | ||
257 | remote->data.bits_left -= 5; | ||
258 | } else if ((remote->data.tester & ONE_MASK) == ONE) { | ||
259 | message.system = (message.system << 1) + 1; | ||
260 | remote->data.tester = remote->data.tester >> 6; | ||
261 | remote->data.bits_left -= 6; | ||
262 | } else { | ||
263 | err("%s - Unknown sequence found in system data.\n", __FUNCTION__); | ||
264 | remote->stage = 0; | ||
265 | return; | ||
266 | } | ||
267 | } | ||
268 | |||
269 | message.button = 0; | ||
270 | for (i = 0; i < 5; i++) { | ||
271 | keyspan_load_tester(remote, 6); | ||
272 | |||
273 | if ((remote->data.tester & ZERO_MASK) == ZERO) { | ||
274 | message.button = message.button << 1; | ||
275 | remote->data.tester = remote->data.tester >> 5; | ||
276 | remote->data.bits_left -= 5; | ||
277 | } else if ((remote->data.tester & ONE_MASK) == ONE) { | ||
278 | message.button = (message.button << 1) + 1; | ||
279 | remote->data.tester = remote->data.tester >> 6; | ||
280 | remote->data.bits_left -= 6; | ||
281 | } else { | ||
282 | err("%s - Unknown sequence found in button data.\n", __FUNCTION__); | ||
283 | remote->stage = 0; | ||
284 | return; | ||
285 | } | ||
286 | } | ||
287 | |||
288 | keyspan_load_tester(remote, 6); | ||
289 | if ((remote->data.tester & ZERO_MASK) == ZERO) { | ||
290 | message.toggle = 0; | ||
291 | remote->data.tester = remote->data.tester >> 5; | ||
292 | remote->data.bits_left -= 5; | ||
293 | } else if ((remote->data.tester & ONE_MASK) == ONE) { | ||
294 | message.toggle = 1; | ||
295 | remote->data.tester = remote->data.tester >> 6; | ||
296 | remote->data.bits_left -= 6; | ||
297 | } else { | ||
298 | err("%s - Error in message, invalid toggle.\n", __FUNCTION__); | ||
299 | } | ||
300 | |||
301 | keyspan_load_tester(remote, 5); | ||
302 | if ((remote->data.tester & STOP_MASK) == STOP) { | ||
303 | remote->data.tester = remote->data.tester >> 5; | ||
304 | remote->data.bits_left -= 5; | ||
305 | } else { | ||
306 | err("Bad message recieved, no stop bit found.\n"); | ||
307 | } | ||
308 | |||
309 | dev_dbg(&remote->udev, | ||
310 | "%s found valid message: system: %d, button: %d, toggle: %d\n", | ||
311 | __FUNCTION__, message.system, message.button, message.toggle); | ||
312 | |||
313 | if (message.toggle != remote->toggle) { | ||
314 | input_regs(&remote->input, regs); | ||
315 | input_report_key(&remote->input, keyspan_key_table[message.button], 1); | ||
316 | input_report_key(&remote->input, keyspan_key_table[message.button], 0); | ||
317 | input_sync(&remote->input); | ||
318 | remote->toggle = message.toggle; | ||
319 | } | ||
320 | |||
321 | remote->stage = 0; | ||
322 | break; | ||
323 | } | ||
324 | } | ||
325 | |||
326 | /* | ||
327 | * Routine for sending all the initialization messages to the remote. | ||
328 | */ | ||
329 | static int keyspan_setup(struct usb_device* dev) | ||
330 | { | ||
331 | int retval = 0; | ||
332 | |||
333 | retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
334 | 0x11, 0x40, 0x5601, 0x0, NULL, 0, 0); | ||
335 | if (retval) { | ||
336 | dev_dbg(&dev->dev, "%s - failed to set bit rate due to error: %d\n", | ||
337 | __FUNCTION__, retval); | ||
338 | return(retval); | ||
339 | } | ||
340 | |||
341 | retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
342 | 0x44, 0x40, 0x0, 0x0, NULL, 0, 0); | ||
343 | if (retval) { | ||
344 | dev_dbg(&dev->dev, "%s - failed to set resume sensitivity due to error: %d\n", | ||
345 | __FUNCTION__, retval); | ||
346 | return(retval); | ||
347 | } | ||
348 | |||
349 | retval = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), | ||
350 | 0x22, 0x40, 0x0, 0x0, NULL, 0, 0); | ||
351 | if (retval) { | ||
352 | dev_dbg(&dev->dev, "%s - failed to turn receive on due to error: %d\n", | ||
353 | __FUNCTION__, retval); | ||
354 | return(retval); | ||
355 | } | ||
356 | |||
357 | dev_dbg(&dev->dev, "%s - Setup complete.\n", __FUNCTION__); | ||
358 | return(retval); | ||
359 | } | ||
360 | |||
361 | /* | ||
362 | * Routine used to handle a new message that has come in. | ||
363 | */ | ||
364 | static void keyspan_irq_recv(struct urb *urb, struct pt_regs *regs) | ||
365 | { | ||
366 | struct usb_keyspan *dev = urb->context; | ||
367 | int retval; | ||
368 | |||
369 | /* Check our status in case we need to bail out early. */ | ||
370 | switch (urb->status) { | ||
371 | case 0: | ||
372 | break; | ||
373 | |||
374 | /* Device went away so don't keep trying to read from it. */ | ||
375 | case -ECONNRESET: | ||
376 | case -ENOENT: | ||
377 | case -ESHUTDOWN: | ||
378 | return; | ||
379 | |||
380 | default: | ||
381 | goto resubmit; | ||
382 | break; | ||
383 | } | ||
384 | |||
385 | if (debug) | ||
386 | keyspan_print(dev); | ||
387 | |||
388 | keyspan_check_data(dev, regs); | ||
389 | |||
390 | resubmit: | ||
391 | retval = usb_submit_urb(urb, GFP_ATOMIC); | ||
392 | if (retval) | ||
393 | err ("%s - usb_submit_urb failed with result: %d", __FUNCTION__, retval); | ||
394 | } | ||
395 | |||
396 | static int keyspan_open(struct input_dev *dev) | ||
397 | { | ||
398 | struct usb_keyspan *remote = dev->private; | ||
399 | |||
400 | if (remote->open++) | ||
401 | return 0; | ||
402 | |||
403 | remote->irq_urb->dev = remote->udev; | ||
404 | if (usb_submit_urb(remote->irq_urb, GFP_KERNEL)) { | ||
405 | remote->open--; | ||
406 | return -EIO; | ||
407 | } | ||
408 | |||
409 | return 0; | ||
410 | } | ||
411 | |||
412 | static void keyspan_close(struct input_dev *dev) | ||
413 | { | ||
414 | struct usb_keyspan *remote = dev->private; | ||
415 | |||
416 | if (!--remote->open) | ||
417 | usb_kill_urb(remote->irq_urb); | ||
418 | } | ||
419 | |||
420 | /* | ||
421 | * Routine that sets up the driver to handle a specific USB device detected on the bus. | ||
422 | */ | ||
423 | static int keyspan_probe(struct usb_interface *interface, const struct usb_device_id *id) | ||
424 | { | ||
425 | int i; | ||
426 | int retval = -ENOMEM; | ||
427 | char path[64]; | ||
428 | char *buf; | ||
429 | struct usb_keyspan *remote = NULL; | ||
430 | struct usb_host_interface *iface_desc; | ||
431 | struct usb_endpoint_descriptor *endpoint; | ||
432 | struct usb_device *udev = usb_get_dev(interface_to_usbdev(interface)); | ||
433 | |||
434 | /* See if the offered device matches what we can accept */ | ||
435 | if ((udev->descriptor.idVendor != USB_KEYSPAN_VENDOR_ID) || | ||
436 | (udev->descriptor.idProduct != USB_KEYSPAN_PRODUCT_UIA11) ) | ||
437 | return -ENODEV; | ||
438 | |||
439 | /* allocate memory for our device state and initialize it */ | ||
440 | remote = kmalloc(sizeof(*remote), GFP_KERNEL); | ||
441 | if (remote == NULL) { | ||
442 | err("Out of memory\n"); | ||
443 | goto error; | ||
444 | } | ||
445 | memset(remote, 0x00, sizeof(*remote)); | ||
446 | |||
447 | remote->udev = udev; | ||
448 | remote->interface = interface; | ||
449 | remote->toggle = -1; /* Set to -1 so we will always not match the toggle from the first remote message. */ | ||
450 | |||
451 | /* set up the endpoint information */ | ||
452 | /* use only the first in interrupt endpoint */ | ||
453 | iface_desc = interface->cur_altsetting; | ||
454 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { | ||
455 | endpoint = &iface_desc->endpoint[i].desc; | ||
456 | |||
457 | if (!remote->in_endpoint && | ||
458 | (endpoint->bEndpointAddress & USB_DIR_IN) && | ||
459 | ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) { | ||
460 | /* we found our interrupt in endpoint */ | ||
461 | remote->in_endpoint = endpoint; | ||
462 | |||
463 | remote->in_buffer = usb_buffer_alloc(remote->udev, RECV_SIZE, SLAB_ATOMIC, &remote->in_dma); | ||
464 | if (!remote->in_buffer) { | ||
465 | retval = -ENOMEM; | ||
466 | goto error; | ||
467 | } | ||
468 | } | ||
469 | } | ||
470 | |||
471 | if (!remote->in_endpoint) { | ||
472 | err("Could not find interrupt input endpoint.\n"); | ||
473 | retval = -ENODEV; | ||
474 | goto error; | ||
475 | } | ||
476 | |||
477 | remote->irq_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
478 | if (!remote->irq_urb) { | ||
479 | err("Failed to allocate urb.\n"); | ||
480 | retval = -ENOMEM; | ||
481 | goto error; | ||
482 | } | ||
483 | |||
484 | retval = keyspan_setup(remote->udev); | ||
485 | if (retval) { | ||
486 | err("Failed to setup device.\n"); | ||
487 | retval = -ENODEV; | ||
488 | goto error; | ||
489 | } | ||
490 | |||
491 | /* | ||
492 | * Setup the input system with the bits we are going to be reporting | ||
493 | */ | ||
494 | remote->input.evbit[0] = BIT(EV_KEY); /* We will only report KEY events. */ | ||
495 | for (i = 0; i < 32; ++i) { | ||
496 | if (keyspan_key_table[i] != KEY_RESERVED) { | ||
497 | set_bit(keyspan_key_table[i], remote->input.keybit); | ||
498 | } | ||
499 | } | ||
500 | |||
501 | remote->input.private = remote; | ||
502 | remote->input.open = keyspan_open; | ||
503 | remote->input.close = keyspan_close; | ||
504 | |||
505 | usb_make_path(remote->udev, path, 64); | ||
506 | sprintf(remote->phys, "%s/input0", path); | ||
507 | |||
508 | remote->input.name = remote->name; | ||
509 | remote->input.phys = remote->phys; | ||
510 | remote->input.id.bustype = BUS_USB; | ||
511 | remote->input.id.vendor = le16_to_cpu(remote->udev->descriptor.idVendor); | ||
512 | remote->input.id.product = le16_to_cpu(remote->udev->descriptor.idProduct); | ||
513 | remote->input.id.version = le16_to_cpu(remote->udev->descriptor.bcdDevice); | ||
514 | |||
515 | if (!(buf = kmalloc(63, GFP_KERNEL))) { | ||
516 | usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma); | ||
517 | kfree(remote); | ||
518 | return -ENOMEM; | ||
519 | } | ||
520 | |||
521 | if (remote->udev->descriptor.iManufacturer && | ||
522 | usb_string(remote->udev, remote->udev->descriptor.iManufacturer, buf, 63) > 0) | ||
523 | strcat(remote->name, buf); | ||
524 | |||
525 | if (remote->udev->descriptor.iProduct && | ||
526 | usb_string(remote->udev, remote->udev->descriptor.iProduct, buf, 63) > 0) | ||
527 | sprintf(remote->name, "%s %s", remote->name, buf); | ||
528 | |||
529 | if (!strlen(remote->name)) | ||
530 | sprintf(remote->name, "USB Keyspan Remote %04x:%04x", | ||
531 | remote->input.id.vendor, remote->input.id.product); | ||
532 | |||
533 | kfree(buf); | ||
534 | |||
535 | /* | ||
536 | * Initialize the URB to access the device. The urb gets sent to the device in keyspan_open() | ||
537 | */ | ||
538 | usb_fill_int_urb(remote->irq_urb, | ||
539 | remote->udev, usb_rcvintpipe(remote->udev, remote->in_endpoint->bEndpointAddress), | ||
540 | remote->in_buffer, RECV_SIZE, keyspan_irq_recv, remote, | ||
541 | remote->in_endpoint->bInterval); | ||
542 | remote->irq_urb->transfer_dma = remote->in_dma; | ||
543 | remote->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; | ||
544 | |||
545 | /* we can register the device now, as it is ready */ | ||
546 | input_register_device(&remote->input); | ||
547 | |||
548 | /* save our data pointer in this interface device */ | ||
549 | usb_set_intfdata(interface, remote); | ||
550 | |||
551 | /* let the user know what node this device is now attached to */ | ||
552 | info("connected: %s on %s", remote->name, path); | ||
553 | return 0; | ||
554 | |||
555 | error: | ||
556 | /* | ||
557 | * In case of error we need to clean up any allocated buffers | ||
558 | */ | ||
559 | if (remote->irq_urb) | ||
560 | usb_free_urb(remote->irq_urb); | ||
561 | |||
562 | if (remote->in_buffer) | ||
563 | usb_buffer_free(remote->udev, RECV_SIZE, remote->in_buffer, remote->in_dma); | ||
564 | |||
565 | if (remote) | ||
566 | kfree(remote); | ||
567 | |||
568 | return retval; | ||
569 | } | ||
570 | |||
571 | /* | ||
572 | * Routine called when a device is disconnected from the USB. | ||
573 | */ | ||
574 | static void keyspan_disconnect(struct usb_interface *interface) | ||
575 | { | ||
576 | struct usb_keyspan *remote; | ||
577 | |||
578 | /* prevent keyspan_open() from racing keyspan_disconnect() */ | ||
579 | lock_kernel(); | ||
580 | |||
581 | remote = usb_get_intfdata(interface); | ||
582 | usb_set_intfdata(interface, NULL); | ||
583 | |||
584 | if (remote) { /* We have a valid driver structure so clean up everything we allocated. */ | ||
585 | input_unregister_device(&remote->input); | ||
586 | usb_kill_urb(remote->irq_urb); | ||
587 | usb_free_urb(remote->irq_urb); | ||
588 | usb_buffer_free(interface_to_usbdev(interface), RECV_SIZE, remote->in_buffer, remote->in_dma); | ||
589 | kfree(remote); | ||
590 | } | ||
591 | |||
592 | unlock_kernel(); | ||
593 | |||
594 | info("USB Keyspan now disconnected"); | ||
595 | } | ||
596 | |||
597 | /* | ||
598 | * Standard driver set up sections | ||
599 | */ | ||
600 | static struct usb_driver keyspan_driver = | ||
601 | { | ||
602 | .owner = THIS_MODULE, | ||
603 | .name = "keyspan_remote", | ||
604 | .probe = keyspan_probe, | ||
605 | .disconnect = keyspan_disconnect, | ||
606 | .id_table = keyspan_table | ||
607 | }; | ||
608 | |||
609 | static int __init usb_keyspan_init(void) | ||
610 | { | ||
611 | int result; | ||
612 | |||
613 | /* register this driver with the USB subsystem */ | ||
614 | result = usb_register(&keyspan_driver); | ||
615 | if (result) | ||
616 | err("usb_register failed. Error number %d\n", result); | ||
617 | |||
618 | return result; | ||
619 | } | ||
620 | |||
621 | static void __exit usb_keyspan_exit(void) | ||
622 | { | ||
623 | /* deregister this driver with the USB subsystem */ | ||
624 | usb_deregister(&keyspan_driver); | ||
625 | } | ||
626 | |||
627 | module_init(usb_keyspan_init); | ||
628 | module_exit(usb_keyspan_exit); | ||
629 | |||
630 | MODULE_DEVICE_TABLE(usb, keyspan_table); | ||
631 | MODULE_AUTHOR(DRIVER_AUTHOR); | ||
632 | MODULE_DESCRIPTION(DRIVER_DESC); | ||
633 | MODULE_LICENSE(DRIVER_LICENSE); | ||
diff --git a/drivers/usb/media/Makefile b/drivers/usb/media/Makefile index 2b76df7005fe..d83adffa925f 100644 --- a/drivers/usb/media/Makefile +++ b/drivers/usb/media/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for USB Media drivers | 2 | # Makefile for USB Media drivers |
3 | # | 3 | # |
4 | 4 | ||
5 | sn9c102-objs := sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o sn9c102_pas106b.o sn9c102_pas202bcb.o sn9c102_tas5110c1b.o sn9c102_tas5130d1b.o | 5 | sn9c102-objs := sn9c102_core.o sn9c102_hv7131d.o sn9c102_mi0343.o sn9c102_ov7630.o sn9c102_pas106b.o sn9c102_pas202bcb.o sn9c102_tas5110c1b.o sn9c102_tas5130d1b.o |
6 | 6 | ||
7 | obj-$(CONFIG_USB_DABUSB) += dabusb.o | 7 | obj-$(CONFIG_USB_DABUSB) += dabusb.o |
8 | obj-$(CONFIG_USB_DSBR) += dsbr100.o | 8 | obj-$(CONFIG_USB_DSBR) += dsbr100.o |
diff --git a/drivers/usb/media/sn9c102.h b/drivers/usb/media/sn9c102.h index 8b8a4c8743f8..e5cea0e2eb57 100644 --- a/drivers/usb/media/sn9c102.h +++ b/drivers/usb/media/sn9c102.h | |||
@@ -56,7 +56,7 @@ | |||
56 | #define SN9C102_MODULE_AUTHOR "(C) 2004-2005 Luca Risolia" | 56 | #define SN9C102_MODULE_AUTHOR "(C) 2004-2005 Luca Risolia" |
57 | #define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" | 57 | #define SN9C102_AUTHOR_EMAIL "<luca.risolia@studio.unibo.it>" |
58 | #define SN9C102_MODULE_LICENSE "GPL" | 58 | #define SN9C102_MODULE_LICENSE "GPL" |
59 | #define SN9C102_MODULE_VERSION "1:1.24" | 59 | #define SN9C102_MODULE_VERSION "1:1.24a" |
60 | #define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 24) | 60 | #define SN9C102_MODULE_VERSION_CODE KERNEL_VERSION(1, 0, 24) |
61 | 61 | ||
62 | enum sn9c102_bridge { | 62 | enum sn9c102_bridge { |
diff --git a/drivers/usb/media/sn9c102_core.c b/drivers/usb/media/sn9c102_core.c index 31d57400d5be..cf8cfbabefde 100644 --- a/drivers/usb/media/sn9c102_core.c +++ b/drivers/usb/media/sn9c102_core.c | |||
@@ -429,7 +429,7 @@ sn9c102_i2c_try_read(struct sn9c102_device* cam, | |||
429 | } | 429 | } |
430 | 430 | ||
431 | 431 | ||
432 | static int | 432 | int |
433 | sn9c102_i2c_try_write(struct sn9c102_device* cam, | 433 | sn9c102_i2c_try_write(struct sn9c102_device* cam, |
434 | struct sn9c102_sensor* sensor, u8 address, u8 value) | 434 | struct sn9c102_sensor* sensor, u8 address, u8 value) |
435 | { | 435 | { |
diff --git a/drivers/usb/media/sn9c102_ov7630.c b/drivers/usb/media/sn9c102_ov7630.c new file mode 100644 index 000000000000..d27c5aedeaf8 --- /dev/null +++ b/drivers/usb/media/sn9c102_ov7630.c | |||
@@ -0,0 +1,394 @@ | |||
1 | /*************************************************************************** | ||
2 | * Plug-in for OV7630 image sensor connected to the SN9C10x PC Camera * | ||
3 | * Controllers * | ||
4 | * * | ||
5 | * Copyright (C) 2005 by Luca Risolia <luca.risolia@studio.unibo.it> * | ||
6 | * * | ||
7 | * This program is free software; you can redistribute it and/or modify * | ||
8 | * it under the terms of the GNU General Public License as published by * | ||
9 | * the Free Software Foundation; either version 2 of the License, or * | ||
10 | * (at your option) any later version. * | ||
11 | * * | ||
12 | * This program is distributed in the hope that it will be useful, * | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | ||
15 | * GNU General Public License for more details. * | ||
16 | * * | ||
17 | * You should have received a copy of the GNU General Public License * | ||
18 | * along with this program; if not, write to the Free Software * | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * | ||
20 | ***************************************************************************/ | ||
21 | |||
22 | #include "sn9c102_sensor.h" | ||
23 | |||
24 | |||
25 | static struct sn9c102_sensor ov7630; | ||
26 | |||
27 | |||
28 | static int ov7630_init(struct sn9c102_device* cam) | ||
29 | { | ||
30 | int err = 0; | ||
31 | |||
32 | err += sn9c102_write_reg(cam, 0x00, 0x14); | ||
33 | err += sn9c102_write_reg(cam, 0x60, 0x17); | ||
34 | err += sn9c102_write_reg(cam, 0x0f, 0x18); | ||
35 | err += sn9c102_write_reg(cam, 0x50, 0x19); | ||
36 | |||
37 | err += sn9c102_i2c_write(cam, 0x12, 0x8d); | ||
38 | err += sn9c102_i2c_write(cam, 0x11, 0x00); | ||
39 | err += sn9c102_i2c_write(cam, 0x15, 0x34); | ||
40 | err += sn9c102_i2c_write(cam, 0x16, 0x03); | ||
41 | err += sn9c102_i2c_write(cam, 0x17, 0x1c); | ||
42 | err += sn9c102_i2c_write(cam, 0x18, 0xbd); | ||
43 | err += sn9c102_i2c_write(cam, 0x19, 0x06); | ||
44 | err += sn9c102_i2c_write(cam, 0x1a, 0xf6); | ||
45 | err += sn9c102_i2c_write(cam, 0x1b, 0x04); | ||
46 | err += sn9c102_i2c_write(cam, 0x20, 0x44); | ||
47 | err += sn9c102_i2c_write(cam, 0x23, 0xee); | ||
48 | err += sn9c102_i2c_write(cam, 0x26, 0xa0); | ||
49 | err += sn9c102_i2c_write(cam, 0x27, 0x9a); | ||
50 | err += sn9c102_i2c_write(cam, 0x28, 0x20); | ||
51 | err += sn9c102_i2c_write(cam, 0x29, 0x30); | ||
52 | err += sn9c102_i2c_write(cam, 0x2f, 0x3d); | ||
53 | err += sn9c102_i2c_write(cam, 0x30, 0x24); | ||
54 | err += sn9c102_i2c_write(cam, 0x32, 0x86); | ||
55 | err += sn9c102_i2c_write(cam, 0x60, 0xa9); | ||
56 | err += sn9c102_i2c_write(cam, 0x61, 0x42); | ||
57 | err += sn9c102_i2c_write(cam, 0x65, 0x00); | ||
58 | err += sn9c102_i2c_write(cam, 0x69, 0x38); | ||
59 | err += sn9c102_i2c_write(cam, 0x6f, 0x88); | ||
60 | err += sn9c102_i2c_write(cam, 0x70, 0x0b); | ||
61 | err += sn9c102_i2c_write(cam, 0x71, 0x00); | ||
62 | err += sn9c102_i2c_write(cam, 0x74, 0x21); | ||
63 | err += sn9c102_i2c_write(cam, 0x7d, 0xf7); | ||
64 | |||
65 | return err; | ||
66 | } | ||
67 | |||
68 | |||
69 | static int ov7630_set_ctrl(struct sn9c102_device* cam, | ||
70 | const struct v4l2_control* ctrl) | ||
71 | { | ||
72 | int err = 0; | ||
73 | |||
74 | switch (ctrl->id) { | ||
75 | case V4L2_CID_EXPOSURE: | ||
76 | err += sn9c102_i2c_write(cam, 0x10, ctrl->value >> 2); | ||
77 | err += sn9c102_i2c_write(cam, 0x76, ctrl->value & 0x03); | ||
78 | break; | ||
79 | case V4L2_CID_RED_BALANCE: | ||
80 | err += sn9c102_i2c_write(cam, 0x02, ctrl->value); | ||
81 | break; | ||
82 | case V4L2_CID_BLUE_BALANCE: | ||
83 | err += sn9c102_i2c_write(cam, 0x03, ctrl->value); | ||
84 | break; | ||
85 | case V4L2_CID_GAIN: | ||
86 | err += sn9c102_i2c_write(cam, 0x00, ctrl->value); | ||
87 | break; | ||
88 | case V4L2_CID_CONTRAST: | ||
89 | err += ctrl->value ? sn9c102_i2c_write(cam, 0x05, | ||
90 | (ctrl->value-1) | 0x20) | ||
91 | : sn9c102_i2c_write(cam, 0x05, 0x00); | ||
92 | break; | ||
93 | case V4L2_CID_BRIGHTNESS: | ||
94 | err += sn9c102_i2c_write(cam, 0x06, ctrl->value); | ||
95 | break; | ||
96 | case V4L2_CID_SATURATION: | ||
97 | err += sn9c102_i2c_write(cam, 0x03, ctrl->value << 4); | ||
98 | break; | ||
99 | case V4L2_CID_HUE: | ||
100 | err += ctrl->value ? sn9c102_i2c_write(cam, 0x04, | ||
101 | (ctrl->value-1) | 0x20) | ||
102 | : sn9c102_i2c_write(cam, 0x04, 0x00); | ||
103 | break; | ||
104 | case V4L2_CID_DO_WHITE_BALANCE: | ||
105 | err += sn9c102_i2c_write(cam, 0x0c, ctrl->value); | ||
106 | break; | ||
107 | case V4L2_CID_WHITENESS: | ||
108 | err += sn9c102_i2c_write(cam, 0x0d, ctrl->value); | ||
109 | break; | ||
110 | case V4L2_CID_AUTO_WHITE_BALANCE: | ||
111 | err += sn9c102_i2c_write(cam, 0x12, (ctrl->value << 2) | 0x09); | ||
112 | break; | ||
113 | case V4L2_CID_AUTOGAIN: | ||
114 | err += sn9c102_i2c_write(cam, 0x13, ctrl->value); | ||
115 | break; | ||
116 | case V4L2_CID_VFLIP: | ||
117 | err += sn9c102_i2c_write(cam, 0x75, 0x0e | (ctrl->value << 7)); | ||
118 | break; | ||
119 | case V4L2_CID_BLACK_LEVEL: | ||
120 | err += sn9c102_i2c_write(cam, 0x25, ctrl->value); | ||
121 | break; | ||
122 | case SN9C102_V4L2_CID_BRIGHT_LEVEL: | ||
123 | err += sn9c102_i2c_write(cam, 0x24, ctrl->value); | ||
124 | break; | ||
125 | case SN9C102_V4L2_CID_GAMMA: | ||
126 | err += sn9c102_i2c_write(cam, 0x14, (ctrl->value << 2) | 0x80); | ||
127 | break; | ||
128 | case SN9C102_V4L2_CID_BAND_FILTER: | ||
129 | err += sn9c102_i2c_write(cam, 0x2d, ctrl->value << 2); | ||
130 | break; | ||
131 | default: | ||
132 | return -EINVAL; | ||
133 | } | ||
134 | |||
135 | return err ? -EIO : 0; | ||
136 | } | ||
137 | |||
138 | |||
139 | static int ov7630_set_crop(struct sn9c102_device* cam, | ||
140 | const struct v4l2_rect* rect) | ||
141 | { | ||
142 | struct sn9c102_sensor* s = &ov7630; | ||
143 | int err = 0; | ||
144 | u8 v_start = (u8)(rect->top - s->cropcap.bounds.top) + 1; | ||
145 | |||
146 | err += sn9c102_write_reg(cam, v_start, 0x13); | ||
147 | |||
148 | return err; | ||
149 | } | ||
150 | |||
151 | |||
152 | static int ov7630_set_pix_format(struct sn9c102_device* cam, | ||
153 | const struct v4l2_pix_format* pix) | ||
154 | { | ||
155 | int err = 0; | ||
156 | |||
157 | if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) | ||
158 | err += sn9c102_write_reg(cam, 0x20, 0x19); | ||
159 | else | ||
160 | err += sn9c102_write_reg(cam, 0x50, 0x19); | ||
161 | |||
162 | return err; | ||
163 | } | ||
164 | |||
165 | |||
166 | static struct sn9c102_sensor ov7630 = { | ||
167 | .name = "OV7630", | ||
168 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", | ||
169 | .sysfs_ops = SN9C102_I2C_WRITE, | ||
170 | .frequency = SN9C102_I2C_100KHZ, | ||
171 | .interface = SN9C102_I2C_2WIRES, | ||
172 | .i2c_slave_id = 0x21, | ||
173 | .init = &ov7630_init, | ||
174 | .qctrl = { | ||
175 | { | ||
176 | .id = V4L2_CID_GAIN, | ||
177 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
178 | .name = "global gain", | ||
179 | .minimum = 0x00, | ||
180 | .maximum = 0x3f, | ||
181 | .step = 0x01, | ||
182 | .default_value = 0x14, | ||
183 | .flags = 0, | ||
184 | }, | ||
185 | { | ||
186 | .id = V4L2_CID_HUE, | ||
187 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
188 | .name = "hue", | ||
189 | .minimum = 0x00, | ||
190 | .maximum = 0x1f+1, | ||
191 | .step = 0x01, | ||
192 | .default_value = 0x00, | ||
193 | .flags = 0, | ||
194 | }, | ||
195 | { | ||
196 | .id = V4L2_CID_SATURATION, | ||
197 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
198 | .name = "saturation", | ||
199 | .minimum = 0x00, | ||
200 | .maximum = 0x0f, | ||
201 | .step = 0x01, | ||
202 | .default_value = 0x08, | ||
203 | .flags = 0, | ||
204 | }, | ||
205 | { | ||
206 | .id = V4L2_CID_CONTRAST, | ||
207 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
208 | .name = "contrast", | ||
209 | .minimum = 0x00, | ||
210 | .maximum = 0x1f+1, | ||
211 | .step = 0x01, | ||
212 | .default_value = 0x00, | ||
213 | .flags = 0, | ||
214 | }, | ||
215 | { | ||
216 | .id = V4L2_CID_EXPOSURE, | ||
217 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
218 | .name = "exposure", | ||
219 | .minimum = 0x000, | ||
220 | .maximum = 0x3ff, | ||
221 | .step = 0x001, | ||
222 | .default_value = 0x83<<2, | ||
223 | .flags = 0, | ||
224 | }, | ||
225 | { | ||
226 | .id = V4L2_CID_RED_BALANCE, | ||
227 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
228 | .name = "red balance", | ||
229 | .minimum = 0x00, | ||
230 | .maximum = 0xff, | ||
231 | .step = 0x01, | ||
232 | .default_value = 0x3a, | ||
233 | .flags = 0, | ||
234 | }, | ||
235 | { | ||
236 | .id = V4L2_CID_BLUE_BALANCE, | ||
237 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
238 | .name = "blue balance", | ||
239 | .minimum = 0x00, | ||
240 | .maximum = 0xff, | ||
241 | .step = 0x01, | ||
242 | .default_value = 0x77, | ||
243 | .flags = 0, | ||
244 | }, | ||
245 | { | ||
246 | .id = V4L2_CID_BRIGHTNESS, | ||
247 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
248 | .name = "brightness", | ||
249 | .minimum = 0x00, | ||
250 | .maximum = 0xff, | ||
251 | .step = 0x01, | ||
252 | .default_value = 0xa0, | ||
253 | .flags = 0, | ||
254 | }, | ||
255 | { | ||
256 | .id = V4L2_CID_DO_WHITE_BALANCE, | ||
257 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
258 | .name = "white balance background: blue", | ||
259 | .minimum = 0x00, | ||
260 | .maximum = 0x3f, | ||
261 | .step = 0x01, | ||
262 | .default_value = 0x20, | ||
263 | .flags = 0, | ||
264 | }, | ||
265 | { | ||
266 | .id = V4L2_CID_WHITENESS, | ||
267 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
268 | .name = "white balance background: red", | ||
269 | .minimum = 0x00, | ||
270 | .maximum = 0x3f, | ||
271 | .step = 0x01, | ||
272 | .default_value = 0x20, | ||
273 | .flags = 0, | ||
274 | }, | ||
275 | { | ||
276 | .id = V4L2_CID_AUTO_WHITE_BALANCE, | ||
277 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
278 | .name = "auto white balance", | ||
279 | .minimum = 0x00, | ||
280 | .maximum = 0x01, | ||
281 | .step = 0x01, | ||
282 | .default_value = 0x01, | ||
283 | .flags = 0, | ||
284 | }, | ||
285 | { | ||
286 | .id = V4L2_CID_AUTOGAIN, | ||
287 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
288 | .name = "gain & exposure mode", | ||
289 | .minimum = 0x00, | ||
290 | .maximum = 0x03, | ||
291 | .step = 0x01, | ||
292 | .default_value = 0x00, | ||
293 | .flags = 0, | ||
294 | }, | ||
295 | { | ||
296 | .id = V4L2_CID_VFLIP, | ||
297 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
298 | .name = "vertical flip", | ||
299 | .minimum = 0x00, | ||
300 | .maximum = 0x01, | ||
301 | .step = 0x01, | ||
302 | .default_value = 0x01, | ||
303 | .flags = 0, | ||
304 | }, | ||
305 | { | ||
306 | .id = V4L2_CID_BLACK_LEVEL, | ||
307 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
308 | .name = "black pixel ratio", | ||
309 | .minimum = 0x01, | ||
310 | .maximum = 0x9a, | ||
311 | .step = 0x01, | ||
312 | .default_value = 0x8a, | ||
313 | .flags = 0, | ||
314 | }, | ||
315 | { | ||
316 | .id = SN9C102_V4L2_CID_BRIGHT_LEVEL, | ||
317 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
318 | .name = "bright pixel ratio", | ||
319 | .minimum = 0x01, | ||
320 | .maximum = 0x9a, | ||
321 | .step = 0x01, | ||
322 | .default_value = 0x10, | ||
323 | .flags = 0, | ||
324 | }, | ||
325 | { | ||
326 | .id = SN9C102_V4L2_CID_BAND_FILTER, | ||
327 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
328 | .name = "band filter", | ||
329 | .minimum = 0x00, | ||
330 | .maximum = 0x01, | ||
331 | .step = 0x01, | ||
332 | .default_value = 0x00, | ||
333 | .flags = 0, | ||
334 | }, | ||
335 | { | ||
336 | .id = SN9C102_V4L2_CID_GAMMA, | ||
337 | .type = V4L2_CTRL_TYPE_BOOLEAN, | ||
338 | .name = "rgb gamma", | ||
339 | .minimum = 0x00, | ||
340 | .maximum = 0x01, | ||
341 | .step = 0x01, | ||
342 | .default_value = 0x00, | ||
343 | .flags = 0, | ||
344 | }, | ||
345 | }, | ||
346 | .set_ctrl = &ov7630_set_ctrl, | ||
347 | .cropcap = { | ||
348 | .bounds = { | ||
349 | .left = 0, | ||
350 | .top = 0, | ||
351 | .width = 640, | ||
352 | .height = 480, | ||
353 | }, | ||
354 | .defrect = { | ||
355 | .left = 0, | ||
356 | .top = 0, | ||
357 | .width = 640, | ||
358 | .height = 480, | ||
359 | }, | ||
360 | }, | ||
361 | .set_crop = &ov7630_set_crop, | ||
362 | .pix_format = { | ||
363 | .width = 640, | ||
364 | .height = 480, | ||
365 | .pixelformat = V4L2_PIX_FMT_SBGGR8, | ||
366 | .priv = 8, | ||
367 | }, | ||
368 | .set_pix_format = &ov7630_set_pix_format | ||
369 | }; | ||
370 | |||
371 | |||
372 | int sn9c102_probe_ov7630(struct sn9c102_device* cam) | ||
373 | { | ||
374 | int err = 0; | ||
375 | |||
376 | sn9c102_attach_sensor(cam, &ov7630); | ||
377 | |||
378 | if (le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x608f && | ||
379 | le16_to_cpu(ov7630.usbdev->descriptor.idProduct) != 0x602c) | ||
380 | return -ENODEV; | ||
381 | |||
382 | err += sn9c102_write_reg(cam, 0x01, 0x01); | ||
383 | err += sn9c102_write_reg(cam, 0x00, 0x01); | ||
384 | err += sn9c102_write_reg(cam, 0x28, 0x17); | ||
385 | |||
386 | if (err) | ||
387 | return -EIO; | ||
388 | |||
389 | err += sn9c102_i2c_write(cam, 0x0b, 0); | ||
390 | if (err) | ||
391 | return -ENODEV; | ||
392 | |||
393 | return 0; | ||
394 | } | ||
diff --git a/drivers/usb/media/sn9c102_sensor.h b/drivers/usb/media/sn9c102_sensor.h index 6a7adebcb4bf..a45166c3488c 100644 --- a/drivers/usb/media/sn9c102_sensor.h +++ b/drivers/usb/media/sn9c102_sensor.h | |||
@@ -64,6 +64,7 @@ struct sn9c102_sensor; | |||
64 | */ | 64 | */ |
65 | extern int sn9c102_probe_hv7131d(struct sn9c102_device* cam); | 65 | extern int sn9c102_probe_hv7131d(struct sn9c102_device* cam); |
66 | extern int sn9c102_probe_mi0343(struct sn9c102_device* cam); | 66 | extern int sn9c102_probe_mi0343(struct sn9c102_device* cam); |
67 | extern int sn9c102_probe_ov7630(struct sn9c102_device* cam); | ||
67 | extern int sn9c102_probe_pas106b(struct sn9c102_device* cam); | 68 | extern int sn9c102_probe_pas106b(struct sn9c102_device* cam); |
68 | extern int sn9c102_probe_pas202bcb(struct sn9c102_device* cam); | 69 | extern int sn9c102_probe_pas202bcb(struct sn9c102_device* cam); |
69 | extern int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam); | 70 | extern int sn9c102_probe_tas5110c1b(struct sn9c102_device* cam); |
@@ -80,6 +81,7 @@ static int (*sn9c102_sensor_table[])(struct sn9c102_device*) = { \ | |||
80 | &sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */ \ | 81 | &sn9c102_probe_pas106b, /* strong detection based on SENSOR ids */ \ |
81 | &sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */ \ | 82 | &sn9c102_probe_pas202bcb, /* strong detection based on SENSOR ids */ \ |
82 | &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */ \ | 83 | &sn9c102_probe_hv7131d, /* strong detection based on SENSOR ids */ \ |
84 | &sn9c102_probe_ov7630, /* detection mostly based on USB pid/vid */ \ | ||
83 | &sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */ \ | 85 | &sn9c102_probe_tas5110c1b, /* detection based on USB pid/vid */ \ |
84 | &sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */ \ | 86 | &sn9c102_probe_tas5130d1b, /* detection based on USB pid/vid */ \ |
85 | NULL, \ | 87 | NULL, \ |
@@ -103,7 +105,8 @@ static const struct usb_device_id sn9c102_id_table[] = { \ | |||
103 | { USB_DEVICE(0x0c45, 0x6029), }, /* PAS106B */ \ | 105 | { USB_DEVICE(0x0c45, 0x6029), }, /* PAS106B */ \ |
104 | { USB_DEVICE(0x0c45, 0x602a), }, /* HV7131D */ \ | 106 | { USB_DEVICE(0x0c45, 0x602a), }, /* HV7131D */ \ |
105 | { USB_DEVICE(0x0c45, 0x602b), }, /* MI-0343 */ \ | 107 | { USB_DEVICE(0x0c45, 0x602b), }, /* MI-0343 */ \ |
106 | { USB_DEVICE(0x0c45, 0x602c), }, /* OV7620 */ \ | 108 | { USB_DEVICE(0x0c45, 0x602c), }, /* OV7630 */ \ |
109 | { USB_DEVICE(0x0c45, 0x602d), }, \ | ||
107 | { USB_DEVICE(0x0c45, 0x6030), }, /* MI03x */ \ | 110 | { USB_DEVICE(0x0c45, 0x6030), }, /* MI03x */ \ |
108 | { USB_DEVICE(0x0c45, 0x6080), }, \ | 111 | { USB_DEVICE(0x0c45, 0x6080), }, \ |
109 | { USB_DEVICE(0x0c45, 0x6082), }, /* MI0343 and MI0360 */ \ | 112 | { USB_DEVICE(0x0c45, 0x6082), }, /* MI0343 and MI0360 */ \ |
@@ -145,6 +148,8 @@ static const struct usb_device_id sn9c102_id_table[] = { \ | |||
145 | */ | 148 | */ |
146 | 149 | ||
147 | /* The "try" I2C I/O versions are used when probing the sensor */ | 150 | /* The "try" I2C I/O versions are used when probing the sensor */ |
151 | extern int sn9c102_i2c_try_write(struct sn9c102_device*,struct sn9c102_sensor*, | ||
152 | u8 address, u8 value); | ||
148 | extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*, | 153 | extern int sn9c102_i2c_try_read(struct sn9c102_device*,struct sn9c102_sensor*, |
149 | u8 address); | 154 | u8 address); |
150 | 155 | ||
@@ -201,6 +206,8 @@ enum sn9c102_i2c_interface { | |||
201 | SN9C102_I2C_3WIRES, | 206 | SN9C102_I2C_3WIRES, |
202 | }; | 207 | }; |
203 | 208 | ||
209 | #define SN9C102_MAX_CTRLS V4L2_CID_LASTP1-V4L2_CID_BASE+10 | ||
210 | |||
204 | struct sn9c102_sensor { | 211 | struct sn9c102_sensor { |
205 | char name[32], /* sensor name */ | 212 | char name[32], /* sensor name */ |
206 | maintainer[64]; /* name of the mantainer <email> */ | 213 | maintainer[64]; /* name of the mantainer <email> */ |
@@ -243,7 +250,7 @@ struct sn9c102_sensor { | |||
243 | sensor according to the default configuration structures below. | 250 | sensor according to the default configuration structures below. |
244 | */ | 251 | */ |
245 | 252 | ||
246 | struct v4l2_queryctrl qctrl[V4L2_CID_LASTP1-V4L2_CID_BASE]; | 253 | struct v4l2_queryctrl qctrl[SN9C102_MAX_CTRLS]; |
247 | /* | 254 | /* |
248 | Optional list of default controls, defined as indicated in the | 255 | Optional list of default controls, defined as indicated in the |
249 | V4L2 API. Menu type controls are not handled by this interface. | 256 | V4L2 API. Menu type controls are not handled by this interface. |
@@ -356,7 +363,7 @@ struct sn9c102_sensor { | |||
356 | core module to store successfully updated values of the above | 363 | core module to store successfully updated values of the above |
357 | settings, for rollbacks..etc..in case of errors during atomic I/O | 364 | settings, for rollbacks..etc..in case of errors during atomic I/O |
358 | */ | 365 | */ |
359 | struct v4l2_queryctrl _qctrl[V4L2_CID_LASTP1-V4L2_CID_BASE]; | 366 | struct v4l2_queryctrl _qctrl[SN9C102_MAX_CTRLS]; |
360 | struct v4l2_rect _rect; | 367 | struct v4l2_rect _rect; |
361 | }; | 368 | }; |
362 | 369 | ||
@@ -367,5 +374,8 @@ struct sn9c102_sensor { | |||
367 | #define SN9C102_V4L2_CID_GREEN_BALANCE V4L2_CID_PRIVATE_BASE + 1 | 374 | #define SN9C102_V4L2_CID_GREEN_BALANCE V4L2_CID_PRIVATE_BASE + 1 |
368 | #define SN9C102_V4L2_CID_RESET_LEVEL V4L2_CID_PRIVATE_BASE + 2 | 375 | #define SN9C102_V4L2_CID_RESET_LEVEL V4L2_CID_PRIVATE_BASE + 2 |
369 | #define SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE V4L2_CID_PRIVATE_BASE + 3 | 376 | #define SN9C102_V4L2_CID_PIXEL_BIAS_VOLTAGE V4L2_CID_PRIVATE_BASE + 3 |
377 | #define SN9C102_V4L2_CID_GAMMA V4L2_CID_PRIVATE_BASE + 4 | ||
378 | #define SN9C102_V4L2_CID_BAND_FILTER V4L2_CID_PRIVATE_BASE + 5 | ||
379 | #define SN9C102_V4L2_CID_BRIGHT_LEVEL V4L2_CID_PRIVATE_BASE + 6 | ||
370 | 380 | ||
371 | #endif /* _SN9C102_SENSOR_H_ */ | 381 | #endif /* _SN9C102_SENSOR_H_ */ |
diff --git a/drivers/usb/media/sn9c102_tas5110c1b.c b/drivers/usb/media/sn9c102_tas5110c1b.c index 690d62192273..8775999b5aff 100644 --- a/drivers/usb/media/sn9c102_tas5110c1b.c +++ b/drivers/usb/media/sn9c102_tas5110c1b.c | |||
@@ -24,8 +24,6 @@ | |||
24 | 24 | ||
25 | static struct sn9c102_sensor tas5110c1b; | 25 | static struct sn9c102_sensor tas5110c1b; |
26 | 26 | ||
27 | static struct v4l2_control tas5110c1b_gain; | ||
28 | |||
29 | 27 | ||
30 | static int tas5110c1b_init(struct sn9c102_device* cam) | 28 | static int tas5110c1b_init(struct sn9c102_device* cam) |
31 | { | 29 | { |
@@ -46,21 +44,6 @@ static int tas5110c1b_init(struct sn9c102_device* cam) | |||
46 | } | 44 | } |
47 | 45 | ||
48 | 46 | ||
49 | static int tas5110c1b_get_ctrl(struct sn9c102_device* cam, | ||
50 | struct v4l2_control* ctrl) | ||
51 | { | ||
52 | switch (ctrl->id) { | ||
53 | case V4L2_CID_GAIN: | ||
54 | ctrl->value = tas5110c1b_gain.value; | ||
55 | break; | ||
56 | default: | ||
57 | return -EINVAL; | ||
58 | } | ||
59 | |||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | |||
64 | static int tas5110c1b_set_ctrl(struct sn9c102_device* cam, | 47 | static int tas5110c1b_set_ctrl(struct sn9c102_device* cam, |
65 | const struct v4l2_control* ctrl) | 48 | const struct v4l2_control* ctrl) |
66 | { | 49 | { |
@@ -68,8 +51,7 @@ static int tas5110c1b_set_ctrl(struct sn9c102_device* cam, | |||
68 | 51 | ||
69 | switch (ctrl->id) { | 52 | switch (ctrl->id) { |
70 | case V4L2_CID_GAIN: | 53 | case V4L2_CID_GAIN: |
71 | if (!(err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value))) | 54 | err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value); |
72 | tas5110c1b_gain.value = ctrl->value; | ||
73 | break; | 55 | break; |
74 | default: | 56 | default: |
75 | return -EINVAL; | 57 | return -EINVAL; |
@@ -147,7 +129,6 @@ static struct sn9c102_sensor tas5110c1b = { | |||
147 | .height = 288, | 129 | .height = 288, |
148 | }, | 130 | }, |
149 | }, | 131 | }, |
150 | .get_ctrl = &tas5110c1b_get_ctrl, | ||
151 | .set_crop = &tas5110c1b_set_crop, | 132 | .set_crop = &tas5110c1b_set_crop, |
152 | .pix_format = { | 133 | .pix_format = { |
153 | .width = 352, | 134 | .width = 352, |
diff --git a/drivers/usb/media/sn9c102_tas5130d1b.c b/drivers/usb/media/sn9c102_tas5130d1b.c index b378e941bbe8..927eafdd8c73 100644 --- a/drivers/usb/media/sn9c102_tas5130d1b.c +++ b/drivers/usb/media/sn9c102_tas5130d1b.c | |||
@@ -24,8 +24,6 @@ | |||
24 | 24 | ||
25 | static struct sn9c102_sensor tas5130d1b; | 25 | static struct sn9c102_sensor tas5130d1b; |
26 | 26 | ||
27 | static struct v4l2_control tas5130d1b_gain, tas5130d1b_exposure; | ||
28 | |||
29 | 27 | ||
30 | static int tas5130d1b_init(struct sn9c102_device* cam) | 28 | static int tas5130d1b_init(struct sn9c102_device* cam) |
31 | { | 29 | { |
@@ -44,24 +42,6 @@ static int tas5130d1b_init(struct sn9c102_device* cam) | |||
44 | } | 42 | } |
45 | 43 | ||
46 | 44 | ||
47 | static int tas5130d1b_get_ctrl(struct sn9c102_device* cam, | ||
48 | struct v4l2_control* ctrl) | ||
49 | { | ||
50 | switch (ctrl->id) { | ||
51 | case V4L2_CID_GAIN: | ||
52 | ctrl->value = tas5130d1b_gain.value; | ||
53 | break; | ||
54 | case V4L2_CID_EXPOSURE: | ||
55 | ctrl->value = tas5130d1b_exposure.value; | ||
56 | break; | ||
57 | default: | ||
58 | return -EINVAL; | ||
59 | } | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | |||
65 | static int tas5130d1b_set_ctrl(struct sn9c102_device* cam, | 45 | static int tas5130d1b_set_ctrl(struct sn9c102_device* cam, |
66 | const struct v4l2_control* ctrl) | 46 | const struct v4l2_control* ctrl) |
67 | { | 47 | { |
@@ -69,12 +49,10 @@ static int tas5130d1b_set_ctrl(struct sn9c102_device* cam, | |||
69 | 49 | ||
70 | switch (ctrl->id) { | 50 | switch (ctrl->id) { |
71 | case V4L2_CID_GAIN: | 51 | case V4L2_CID_GAIN: |
72 | if (!(err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value))) | 52 | err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value); |
73 | tas5130d1b_gain.value = ctrl->value; | ||
74 | break; | 53 | break; |
75 | case V4L2_CID_EXPOSURE: | 54 | case V4L2_CID_EXPOSURE: |
76 | if (!(err += sn9c102_i2c_write(cam, 0x40, 0x47 - ctrl->value))) | 55 | err += sn9c102_i2c_write(cam, 0x40, 0x47 - ctrl->value); |
77 | tas5130d1b_exposure.value = ctrl->value; | ||
78 | break; | 56 | break; |
79 | default: | 57 | default: |
80 | return -EINVAL; | 58 | return -EINVAL; |
@@ -147,7 +125,6 @@ static struct sn9c102_sensor tas5130d1b = { | |||
147 | .flags = 0, | 125 | .flags = 0, |
148 | }, | 126 | }, |
149 | }, | 127 | }, |
150 | .get_ctrl = &tas5130d1b_get_ctrl, | ||
151 | .set_ctrl = &tas5130d1b_set_ctrl, | 128 | .set_ctrl = &tas5130d1b_set_ctrl, |
152 | .cropcap = { | 129 | .cropcap = { |
153 | .bounds = { | 130 | .bounds = { |
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig index 3a896954b3a9..6649531fa824 100644 --- a/drivers/usb/misc/Kconfig +++ b/drivers/usb/misc/Kconfig | |||
@@ -139,6 +139,16 @@ config USB_IDMOUSE | |||
139 | 139 | ||
140 | source "drivers/usb/misc/sisusbvga/Kconfig" | 140 | source "drivers/usb/misc/sisusbvga/Kconfig" |
141 | 141 | ||
142 | config USB_LD | ||
143 | tristate "USB LD driver" | ||
144 | depends on USB && EXPERIMENTAL | ||
145 | help | ||
146 | This driver is for generic USB devices that use interrupt transfers, | ||
147 | like LD Didactic's USB devices. | ||
148 | |||
149 | To compile this driver as a module, choose M here: the | ||
150 | module will be called ldusb. | ||
151 | |||
142 | config USB_TEST | 152 | config USB_TEST |
143 | tristate "USB testing driver (DEVELOPMENT)" | 153 | tristate "USB testing driver (DEVELOPMENT)" |
144 | depends on USB && USB_DEVICEFS && EXPERIMENTAL | 154 | depends on USB && USB_DEVICEFS && EXPERIMENTAL |
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile index 4a3814cbd48d..862e40a83689 100644 --- a/drivers/usb/misc/Makefile +++ b/drivers/usb/misc/Makefile | |||
@@ -9,6 +9,7 @@ obj-$(CONFIG_USB_EMI26) += emi26.o | |||
9 | obj-$(CONFIG_USB_EMI62) += emi62.o | 9 | obj-$(CONFIG_USB_EMI62) += emi62.o |
10 | obj-$(CONFIG_USB_IDMOUSE) += idmouse.o | 10 | obj-$(CONFIG_USB_IDMOUSE) += idmouse.o |
11 | obj-$(CONFIG_USB_LCD) += usblcd.o | 11 | obj-$(CONFIG_USB_LCD) += usblcd.o |
12 | obj-$(CONFIG_USB_LD) += ldusb.o | ||
12 | obj-$(CONFIG_USB_LED) += usbled.o | 13 | obj-$(CONFIG_USB_LED) += usbled.o |
13 | obj-$(CONFIG_USB_LEGOTOWER) += legousbtower.o | 14 | obj-$(CONFIG_USB_LEGOTOWER) += legousbtower.o |
14 | obj-$(CONFIG_USB_PHIDGETKIT) += phidgetkit.o | 15 | obj-$(CONFIG_USB_PHIDGETKIT) += phidgetkit.o |
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c new file mode 100644 index 000000000000..66ec88354b93 --- /dev/null +++ b/drivers/usb/misc/ldusb.c | |||
@@ -0,0 +1,794 @@ | |||
1 | /** | ||
2 | * Generic USB driver for report based interrupt in/out devices | ||
3 | * like LD Didactic's USB devices. LD Didactic's USB devices are | ||
4 | * HID devices which do not use HID report definitons (they use | ||
5 | * raw interrupt in and our reports only for communication). | ||
6 | * | ||
7 | * This driver uses a ring buffer for time critical reading of | ||
8 | * interrupt in reports and provides read and write methods for | ||
9 | * raw interrupt reports (similar to the Windows HID driver). | ||
10 | * Devices based on the book USB COMPLETE by Jan Axelson may need | ||
11 | * such a compatibility to the Windows HID driver. | ||
12 | * | ||
13 | * Copyright (C) 2005 Michael Hund <mhund@ld-didactic.de> | ||
14 | * | ||
15 | * This program is free software; you can redistribute it and/or | ||
16 | * modify it under the terms of the GNU General Public License as | ||
17 | * published by the Free Software Foundation; either version 2 of | ||
18 | * the License, or (at your option) any later version. | ||
19 | * | ||
20 | * Derived from Lego USB Tower driver | ||
21 | * Copyright (C) 2003 David Glance <advidgsf@sourceforge.net> | ||
22 | * 2001-2004 Juergen Stuber <starblue@users.sourceforge.net> | ||
23 | * | ||
24 | * V0.1 (mh) Initial version | ||
25 | * V0.11 (mh) Added raw support for HID 1.0 devices (no interrupt out endpoint) | ||
26 | */ | ||
27 | |||
28 | #include <linux/config.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/errno.h> | ||
31 | #include <linux/init.h> | ||
32 | #include <linux/slab.h> | ||
33 | #include <linux/module.h> | ||
34 | |||
35 | #include <asm/uaccess.h> | ||
36 | #include <linux/input.h> | ||
37 | #include <linux/usb.h> | ||
38 | #include <linux/poll.h> | ||
39 | |||
40 | /* Define these values to match your devices */ | ||
41 | #define USB_VENDOR_ID_LD 0x0f11 /* USB Vendor ID of LD Didactic GmbH */ | ||
42 | #define USB_DEVICE_ID_CASSY 0x1000 /* USB Product ID for all CASSY-S modules */ | ||
43 | #define USB_DEVICE_ID_POCKETCASSY 0x1010 /* USB Product ID for Pocket-CASSY */ | ||
44 | #define USB_DEVICE_ID_MOBILECASSY 0x1020 /* USB Product ID for Mobile-CASSY */ | ||
45 | #define USB_DEVICE_ID_JWM 0x1080 /* USB Product ID for Joule and Wattmeter */ | ||
46 | #define USB_DEVICE_ID_DMMP 0x1081 /* USB Product ID for Digital Multimeter P (reserved) */ | ||
47 | #define USB_DEVICE_ID_UMIP 0x1090 /* USB Product ID for UMI P */ | ||
48 | #define USB_DEVICE_ID_VIDEOCOM 0x1200 /* USB Product ID for VideoCom */ | ||
49 | #define USB_DEVICE_ID_COM3LAB 0x2000 /* USB Product ID for COM3LAB */ | ||
50 | #define USB_DEVICE_ID_TELEPORT 0x2010 /* USB Product ID for Terminal Adapter */ | ||
51 | #define USB_DEVICE_ID_NETWORKANALYSER 0x2020 /* USB Product ID for Network Analyser */ | ||
52 | #define USB_DEVICE_ID_POWERCONTROL 0x2030 /* USB Product ID for Controlling device for Power Electronics */ | ||
53 | |||
54 | #define USB_VENDOR_ID_VERNIER 0x08f7 | ||
55 | #define USB_DEVICE_ID_VERNIER_LABPRO 0x0001 | ||
56 | #define USB_DEVICE_ID_VERNIER_GOTEMP 0x0002 | ||
57 | #define USB_DEVICE_ID_VERNIER_SKIP 0x0003 | ||
58 | #define USB_DEVICE_ID_VERNIER_CYCLOPS 0x0004 | ||
59 | |||
60 | |||
61 | #ifdef CONFIG_USB_DYNAMIC_MINORS | ||
62 | #define USB_LD_MINOR_BASE 0 | ||
63 | #else | ||
64 | #define USB_LD_MINOR_BASE 176 | ||
65 | #endif | ||
66 | |||
67 | /* table of devices that work with this driver */ | ||
68 | static struct usb_device_id ld_usb_table [] = { | ||
69 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_CASSY) }, | ||
70 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_POCKETCASSY) }, | ||
71 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_MOBILECASSY) }, | ||
72 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_JWM) }, | ||
73 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_DMMP) }, | ||
74 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_UMIP) }, | ||
75 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_VIDEOCOM) }, | ||
76 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_COM3LAB) }, | ||
77 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_TELEPORT) }, | ||
78 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_NETWORKANALYSER) }, | ||
79 | { USB_DEVICE(USB_VENDOR_ID_LD, USB_DEVICE_ID_POWERCONTROL) }, | ||
80 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_LABPRO) }, | ||
81 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_GOTEMP) }, | ||
82 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_SKIP) }, | ||
83 | { USB_DEVICE(USB_VENDOR_ID_VERNIER, USB_DEVICE_ID_VERNIER_CYCLOPS) }, | ||
84 | { } /* Terminating entry */ | ||
85 | }; | ||
86 | MODULE_DEVICE_TABLE(usb, ld_usb_table); | ||
87 | MODULE_VERSION("V0.11"); | ||
88 | MODULE_AUTHOR("Michael Hund <mhund@ld-didactic.de>"); | ||
89 | MODULE_DESCRIPTION("LD USB Driver"); | ||
90 | MODULE_LICENSE("GPL"); | ||
91 | MODULE_SUPPORTED_DEVICE("LD USB Devices"); | ||
92 | |||
93 | #ifdef CONFIG_USB_DEBUG | ||
94 | static int debug = 1; | ||
95 | #else | ||
96 | static int debug = 0; | ||
97 | #endif | ||
98 | |||
99 | /* Use our own dbg macro */ | ||
100 | #define dbg_info(dev, format, arg...) do { if (debug) dev_info(dev , format , ## arg); } while (0) | ||
101 | |||
102 | /* Module parameters */ | ||
103 | module_param(debug, int, S_IRUGO | S_IWUSR); | ||
104 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | ||
105 | |||
106 | /* All interrupt in transfers are collected in a ring buffer to | ||
107 | * avoid racing conditions and get better performance of the driver. | ||
108 | */ | ||
109 | static int ring_buffer_size = 128; | ||
110 | module_param(ring_buffer_size, int, 0); | ||
111 | MODULE_PARM_DESC(ring_buffer_size, "Read ring buffer size in reports"); | ||
112 | |||
113 | /* The write_buffer can contain more than one interrupt out transfer. | ||
114 | */ | ||
115 | static int write_buffer_size = 10; | ||
116 | module_param(write_buffer_size, int, 0); | ||
117 | MODULE_PARM_DESC(write_buffer_size, "Write buffer size in reports"); | ||
118 | |||
119 | /* As of kernel version 2.6.4 ehci-hcd uses an | ||
120 | * "only one interrupt transfer per frame" shortcut | ||
121 | * to simplify the scheduling of periodic transfers. | ||
122 | * This conflicts with our standard 1ms intervals for in and out URBs. | ||
123 | * We use default intervals of 2ms for in and 2ms for out transfers, | ||
124 | * which should be fast enough. | ||
125 | * Increase the interval to allow more devices that do interrupt transfers, | ||
126 | * or set to 1 to use the standard interval from the endpoint descriptors. | ||
127 | */ | ||
128 | static int min_interrupt_in_interval = 2; | ||
129 | module_param(min_interrupt_in_interval, int, 0); | ||
130 | MODULE_PARM_DESC(min_interrupt_in_interval, "Minimum interrupt in interval in ms"); | ||
131 | |||
132 | static int min_interrupt_out_interval = 2; | ||
133 | module_param(min_interrupt_out_interval, int, 0); | ||
134 | MODULE_PARM_DESC(min_interrupt_out_interval, "Minimum interrupt out interval in ms"); | ||
135 | |||
136 | /* Structure to hold all of our device specific stuff */ | ||
137 | struct ld_usb { | ||
138 | struct semaphore sem; /* locks this structure */ | ||
139 | struct usb_interface* intf; /* save off the usb interface pointer */ | ||
140 | |||
141 | int open_count; /* number of times this port has been opened */ | ||
142 | |||
143 | char* ring_buffer; | ||
144 | unsigned int ring_head; | ||
145 | unsigned int ring_tail; | ||
146 | |||
147 | wait_queue_head_t read_wait; | ||
148 | wait_queue_head_t write_wait; | ||
149 | |||
150 | char* interrupt_in_buffer; | ||
151 | struct usb_endpoint_descriptor* interrupt_in_endpoint; | ||
152 | struct urb* interrupt_in_urb; | ||
153 | int interrupt_in_interval; | ||
154 | size_t interrupt_in_endpoint_size; | ||
155 | int interrupt_in_running; | ||
156 | int interrupt_in_done; | ||
157 | |||
158 | char* interrupt_out_buffer; | ||
159 | struct usb_endpoint_descriptor* interrupt_out_endpoint; | ||
160 | struct urb* interrupt_out_urb; | ||
161 | int interrupt_out_interval; | ||
162 | size_t interrupt_out_endpoint_size; | ||
163 | int interrupt_out_busy; | ||
164 | }; | ||
165 | |||
166 | /* prevent races between open() and disconnect() */ | ||
167 | static DECLARE_MUTEX(disconnect_sem); | ||
168 | |||
169 | static struct usb_driver ld_usb_driver; | ||
170 | |||
171 | /** | ||
172 | * ld_usb_abort_transfers | ||
173 | * aborts transfers and frees associated data structures | ||
174 | */ | ||
175 | static void ld_usb_abort_transfers(struct ld_usb *dev) | ||
176 | { | ||
177 | /* shutdown transfer */ | ||
178 | if (dev->interrupt_in_running) { | ||
179 | dev->interrupt_in_running = 0; | ||
180 | if (dev->intf) | ||
181 | usb_kill_urb(dev->interrupt_in_urb); | ||
182 | } | ||
183 | if (dev->interrupt_out_busy) | ||
184 | if (dev->intf) | ||
185 | usb_kill_urb(dev->interrupt_out_urb); | ||
186 | } | ||
187 | |||
188 | /** | ||
189 | * ld_usb_delete | ||
190 | */ | ||
191 | static void ld_usb_delete(struct ld_usb *dev) | ||
192 | { | ||
193 | ld_usb_abort_transfers(dev); | ||
194 | |||
195 | /* free data structures */ | ||
196 | usb_free_urb(dev->interrupt_in_urb); | ||
197 | usb_free_urb(dev->interrupt_out_urb); | ||
198 | kfree(dev->ring_buffer); | ||
199 | kfree(dev->interrupt_in_buffer); | ||
200 | kfree(dev->interrupt_out_buffer); | ||
201 | kfree(dev); | ||
202 | } | ||
203 | |||
204 | /** | ||
205 | * ld_usb_interrupt_in_callback | ||
206 | */ | ||
207 | static void ld_usb_interrupt_in_callback(struct urb *urb, struct pt_regs *regs) | ||
208 | { | ||
209 | struct ld_usb *dev = urb->context; | ||
210 | size_t *actual_buffer; | ||
211 | unsigned int next_ring_head; | ||
212 | int retval; | ||
213 | |||
214 | if (urb->status) { | ||
215 | if (urb->status == -ENOENT || | ||
216 | urb->status == -ECONNRESET || | ||
217 | urb->status == -ESHUTDOWN) { | ||
218 | goto exit; | ||
219 | } else { | ||
220 | dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n", | ||
221 | __FUNCTION__, urb->status); | ||
222 | goto resubmit; /* maybe we can recover */ | ||
223 | } | ||
224 | } | ||
225 | |||
226 | if (urb->actual_length > 0) { | ||
227 | next_ring_head = (dev->ring_head+1) % ring_buffer_size; | ||
228 | if (next_ring_head != dev->ring_tail) { | ||
229 | actual_buffer = (size_t*)(dev->ring_buffer + dev->ring_head*(sizeof(size_t)+dev->interrupt_in_endpoint_size)); | ||
230 | /* actual_buffer gets urb->actual_length + interrupt_in_buffer */ | ||
231 | *actual_buffer = urb->actual_length; | ||
232 | memcpy(actual_buffer+1, dev->interrupt_in_buffer, urb->actual_length); | ||
233 | dev->ring_head = next_ring_head; | ||
234 | dbg_info(&dev->intf->dev, "%s: received %d bytes\n", | ||
235 | __FUNCTION__, urb->actual_length); | ||
236 | } else | ||
237 | dev_warn(&dev->intf->dev, | ||
238 | "Ring buffer overflow, %d bytes dropped\n", | ||
239 | urb->actual_length); | ||
240 | } | ||
241 | |||
242 | resubmit: | ||
243 | /* resubmit if we're still running */ | ||
244 | if (dev->interrupt_in_running && dev->intf) { | ||
245 | retval = usb_submit_urb(dev->interrupt_in_urb, GFP_ATOMIC); | ||
246 | if (retval) | ||
247 | dev_err(&dev->intf->dev, | ||
248 | "usb_submit_urb failed (%d)\n", retval); | ||
249 | } | ||
250 | |||
251 | exit: | ||
252 | dev->interrupt_in_done = 1; | ||
253 | wake_up_interruptible(&dev->read_wait); | ||
254 | } | ||
255 | |||
256 | /** | ||
257 | * ld_usb_interrupt_out_callback | ||
258 | */ | ||
259 | static void ld_usb_interrupt_out_callback(struct urb *urb, struct pt_regs *regs) | ||
260 | { | ||
261 | struct ld_usb *dev = urb->context; | ||
262 | |||
263 | /* sync/async unlink faults aren't errors */ | ||
264 | if (urb->status && !(urb->status == -ENOENT || | ||
265 | urb->status == -ECONNRESET || | ||
266 | urb->status == -ESHUTDOWN)) | ||
267 | dbg_info(&dev->intf->dev, | ||
268 | "%s - nonzero write interrupt status received: %d\n", | ||
269 | __FUNCTION__, urb->status); | ||
270 | |||
271 | dev->interrupt_out_busy = 0; | ||
272 | wake_up_interruptible(&dev->write_wait); | ||
273 | } | ||
274 | |||
275 | /** | ||
276 | * ld_usb_open | ||
277 | */ | ||
278 | static int ld_usb_open(struct inode *inode, struct file *file) | ||
279 | { | ||
280 | struct ld_usb *dev; | ||
281 | int subminor; | ||
282 | int retval = 0; | ||
283 | struct usb_interface *interface; | ||
284 | |||
285 | nonseekable_open(inode, file); | ||
286 | subminor = iminor(inode); | ||
287 | |||
288 | down(&disconnect_sem); | ||
289 | |||
290 | interface = usb_find_interface(&ld_usb_driver, subminor); | ||
291 | |||
292 | if (!interface) { | ||
293 | err("%s - error, can't find device for minor %d\n", | ||
294 | __FUNCTION__, subminor); | ||
295 | retval = -ENODEV; | ||
296 | goto unlock_disconnect_exit; | ||
297 | } | ||
298 | |||
299 | dev = usb_get_intfdata(interface); | ||
300 | |||
301 | if (!dev) { | ||
302 | retval = -ENODEV; | ||
303 | goto unlock_disconnect_exit; | ||
304 | } | ||
305 | |||
306 | /* lock this device */ | ||
307 | if (down_interruptible(&dev->sem)) { | ||
308 | retval = -ERESTARTSYS; | ||
309 | goto unlock_disconnect_exit; | ||
310 | } | ||
311 | |||
312 | /* allow opening only once */ | ||
313 | if (dev->open_count) { | ||
314 | retval = -EBUSY; | ||
315 | goto unlock_exit; | ||
316 | } | ||
317 | dev->open_count = 1; | ||
318 | |||
319 | /* initialize in direction */ | ||
320 | dev->ring_head = 0; | ||
321 | dev->ring_tail = 0; | ||
322 | usb_fill_int_urb(dev->interrupt_in_urb, | ||
323 | interface_to_usbdev(interface), | ||
324 | usb_rcvintpipe(interface_to_usbdev(interface), | ||
325 | dev->interrupt_in_endpoint->bEndpointAddress), | ||
326 | dev->interrupt_in_buffer, | ||
327 | dev->interrupt_in_endpoint_size, | ||
328 | ld_usb_interrupt_in_callback, | ||
329 | dev, | ||
330 | dev->interrupt_in_interval); | ||
331 | |||
332 | dev->interrupt_in_running = 1; | ||
333 | dev->interrupt_in_done = 0; | ||
334 | |||
335 | retval = usb_submit_urb(dev->interrupt_in_urb, GFP_KERNEL); | ||
336 | if (retval) { | ||
337 | dev_err(&interface->dev, "Couldn't submit interrupt_in_urb %d\n", retval); | ||
338 | dev->interrupt_in_running = 0; | ||
339 | dev->open_count = 0; | ||
340 | goto unlock_exit; | ||
341 | } | ||
342 | |||
343 | /* save device in the file's private structure */ | ||
344 | file->private_data = dev; | ||
345 | |||
346 | unlock_exit: | ||
347 | up(&dev->sem); | ||
348 | |||
349 | unlock_disconnect_exit: | ||
350 | up(&disconnect_sem); | ||
351 | |||
352 | return retval; | ||
353 | } | ||
354 | |||
355 | /** | ||
356 | * ld_usb_release | ||
357 | */ | ||
358 | static int ld_usb_release(struct inode *inode, struct file *file) | ||
359 | { | ||
360 | struct ld_usb *dev; | ||
361 | int retval = 0; | ||
362 | |||
363 | dev = file->private_data; | ||
364 | |||
365 | if (dev == NULL) { | ||
366 | retval = -ENODEV; | ||
367 | goto exit; | ||
368 | } | ||
369 | |||
370 | if (down_interruptible(&dev->sem)) { | ||
371 | retval = -ERESTARTSYS; | ||
372 | goto exit; | ||
373 | } | ||
374 | |||
375 | if (dev->open_count != 1) { | ||
376 | retval = -ENODEV; | ||
377 | goto unlock_exit; | ||
378 | } | ||
379 | if (dev->intf == NULL) { | ||
380 | /* the device was unplugged before the file was released */ | ||
381 | up(&dev->sem); | ||
382 | /* unlock here as ld_usb_delete frees dev */ | ||
383 | ld_usb_delete(dev); | ||
384 | goto exit; | ||
385 | } | ||
386 | |||
387 | /* wait until write transfer is finished */ | ||
388 | if (dev->interrupt_out_busy) | ||
389 | wait_event_interruptible_timeout(dev->write_wait, !dev->interrupt_out_busy, 2 * HZ); | ||
390 | ld_usb_abort_transfers(dev); | ||
391 | dev->open_count = 0; | ||
392 | |||
393 | unlock_exit: | ||
394 | up(&dev->sem); | ||
395 | |||
396 | exit: | ||
397 | return retval; | ||
398 | } | ||
399 | |||
400 | /** | ||
401 | * ld_usb_poll | ||
402 | */ | ||
403 | static unsigned int ld_usb_poll(struct file *file, poll_table *wait) | ||
404 | { | ||
405 | struct ld_usb *dev; | ||
406 | unsigned int mask = 0; | ||
407 | |||
408 | dev = file->private_data; | ||
409 | |||
410 | poll_wait(file, &dev->read_wait, wait); | ||
411 | poll_wait(file, &dev->write_wait, wait); | ||
412 | |||
413 | if (dev->ring_head != dev->ring_tail) | ||
414 | mask |= POLLIN | POLLRDNORM; | ||
415 | if (!dev->interrupt_out_busy) | ||
416 | mask |= POLLOUT | POLLWRNORM; | ||
417 | |||
418 | return mask; | ||
419 | } | ||
420 | |||
421 | /** | ||
422 | * ld_usb_read | ||
423 | */ | ||
424 | static ssize_t ld_usb_read(struct file *file, char __user *buffer, size_t count, | ||
425 | loff_t *ppos) | ||
426 | { | ||
427 | struct ld_usb *dev; | ||
428 | size_t *actual_buffer; | ||
429 | size_t bytes_to_read; | ||
430 | int retval = 0; | ||
431 | |||
432 | dev = file->private_data; | ||
433 | |||
434 | /* verify that we actually have some data to read */ | ||
435 | if (count == 0) | ||
436 | goto exit; | ||
437 | |||
438 | /* lock this object */ | ||
439 | if (down_interruptible(&dev->sem)) { | ||
440 | retval = -ERESTARTSYS; | ||
441 | goto exit; | ||
442 | } | ||
443 | |||
444 | /* verify that the device wasn't unplugged */ | ||
445 | if (dev->intf == NULL) { | ||
446 | retval = -ENODEV; | ||
447 | err("No device or device unplugged %d\n", retval); | ||
448 | goto unlock_exit; | ||
449 | } | ||
450 | |||
451 | /* wait for data */ | ||
452 | if (dev->ring_head == dev->ring_tail) { | ||
453 | if (file->f_flags & O_NONBLOCK) { | ||
454 | retval = -EAGAIN; | ||
455 | goto unlock_exit; | ||
456 | } | ||
457 | retval = wait_event_interruptible(dev->read_wait, dev->interrupt_in_done); | ||
458 | if (retval < 0) | ||
459 | goto unlock_exit; | ||
460 | } | ||
461 | |||
462 | /* actual_buffer contains actual_length + interrupt_in_buffer */ | ||
463 | actual_buffer = (size_t*)(dev->ring_buffer + dev->ring_tail*(sizeof(size_t)+dev->interrupt_in_endpoint_size)); | ||
464 | bytes_to_read = min(count, *actual_buffer); | ||
465 | if (bytes_to_read < *actual_buffer) | ||
466 | dev_warn(&dev->intf->dev, "Read buffer overflow, %d bytes dropped\n", | ||
467 | *actual_buffer-bytes_to_read); | ||
468 | |||
469 | /* copy one interrupt_in_buffer from ring_buffer into userspace */ | ||
470 | if (copy_to_user(buffer, actual_buffer+1, bytes_to_read)) { | ||
471 | retval = -EFAULT; | ||
472 | goto unlock_exit; | ||
473 | } | ||
474 | dev->ring_tail = (dev->ring_tail+1) % ring_buffer_size; | ||
475 | |||
476 | retval = bytes_to_read; | ||
477 | |||
478 | unlock_exit: | ||
479 | /* unlock the device */ | ||
480 | up(&dev->sem); | ||
481 | |||
482 | exit: | ||
483 | return retval; | ||
484 | } | ||
485 | |||
486 | /** | ||
487 | * ld_usb_write | ||
488 | */ | ||
489 | static ssize_t ld_usb_write(struct file *file, const char __user *buffer, | ||
490 | size_t count, loff_t *ppos) | ||
491 | { | ||
492 | struct ld_usb *dev; | ||
493 | size_t bytes_to_write; | ||
494 | int retval = 0; | ||
495 | |||
496 | dev = file->private_data; | ||
497 | |||
498 | /* verify that we actually have some data to write */ | ||
499 | if (count == 0) | ||
500 | goto exit; | ||
501 | |||
502 | /* lock this object */ | ||
503 | if (down_interruptible(&dev->sem)) { | ||
504 | retval = -ERESTARTSYS; | ||
505 | goto exit; | ||
506 | } | ||
507 | |||
508 | /* verify that the device wasn't unplugged */ | ||
509 | if (dev->intf == NULL) { | ||
510 | retval = -ENODEV; | ||
511 | err("No device or device unplugged %d\n", retval); | ||
512 | goto unlock_exit; | ||
513 | } | ||
514 | |||
515 | /* wait until previous transfer is finished */ | ||
516 | if (dev->interrupt_out_busy) { | ||
517 | if (file->f_flags & O_NONBLOCK) { | ||
518 | retval = -EAGAIN; | ||
519 | goto unlock_exit; | ||
520 | } | ||
521 | retval = wait_event_interruptible(dev->write_wait, !dev->interrupt_out_busy); | ||
522 | if (retval < 0) { | ||
523 | goto unlock_exit; | ||
524 | } | ||
525 | } | ||
526 | |||
527 | /* write the data into interrupt_out_buffer from userspace */ | ||
528 | bytes_to_write = min(count, write_buffer_size*dev->interrupt_out_endpoint_size); | ||
529 | if (bytes_to_write < count) | ||
530 | dev_warn(&dev->intf->dev, "Write buffer overflow, %d bytes dropped\n",count-bytes_to_write); | ||
531 | dbg_info(&dev->intf->dev, "%s: count = %d, bytes_to_write = %d\n", __FUNCTION__, count, bytes_to_write); | ||
532 | |||
533 | if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write)) { | ||
534 | retval = -EFAULT; | ||
535 | goto unlock_exit; | ||
536 | } | ||
537 | |||
538 | if (dev->interrupt_out_endpoint == NULL) { | ||
539 | /* try HID_REQ_SET_REPORT=9 on control_endpoint instead of interrupt_out_endpoint */ | ||
540 | retval = usb_control_msg(interface_to_usbdev(dev->intf), | ||
541 | usb_sndctrlpipe(interface_to_usbdev(dev->intf), 0), | ||
542 | 9, | ||
543 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_OUT, | ||
544 | 1 << 8, 0, | ||
545 | dev->interrupt_out_buffer, | ||
546 | bytes_to_write, | ||
547 | USB_CTRL_SET_TIMEOUT * HZ); | ||
548 | if (retval < 0) | ||
549 | err("Couldn't submit HID_REQ_SET_REPORT %d\n", retval); | ||
550 | goto unlock_exit; | ||
551 | } | ||
552 | |||
553 | /* send off the urb */ | ||
554 | usb_fill_int_urb(dev->interrupt_out_urb, | ||
555 | interface_to_usbdev(dev->intf), | ||
556 | usb_sndintpipe(interface_to_usbdev(dev->intf), | ||
557 | dev->interrupt_out_endpoint->bEndpointAddress), | ||
558 | dev->interrupt_out_buffer, | ||
559 | bytes_to_write, | ||
560 | ld_usb_interrupt_out_callback, | ||
561 | dev, | ||
562 | dev->interrupt_out_interval); | ||
563 | |||
564 | dev->interrupt_out_busy = 1; | ||
565 | wmb(); | ||
566 | |||
567 | retval = usb_submit_urb(dev->interrupt_out_urb, GFP_KERNEL); | ||
568 | if (retval) { | ||
569 | dev->interrupt_out_busy = 0; | ||
570 | err("Couldn't submit interrupt_out_urb %d\n", retval); | ||
571 | goto unlock_exit; | ||
572 | } | ||
573 | retval = bytes_to_write; | ||
574 | |||
575 | unlock_exit: | ||
576 | /* unlock the device */ | ||
577 | up(&dev->sem); | ||
578 | |||
579 | exit: | ||
580 | return retval; | ||
581 | } | ||
582 | |||
583 | /* file operations needed when we register this driver */ | ||
584 | static struct file_operations ld_usb_fops = { | ||
585 | .owner = THIS_MODULE, | ||
586 | .read = ld_usb_read, | ||
587 | .write = ld_usb_write, | ||
588 | .open = ld_usb_open, | ||
589 | .release = ld_usb_release, | ||
590 | .poll = ld_usb_poll, | ||
591 | }; | ||
592 | |||
593 | /* | ||
594 | * usb class driver info in order to get a minor number from the usb core, | ||
595 | * and to have the device registered with devfs and the driver core | ||
596 | */ | ||
597 | static struct usb_class_driver ld_usb_class = { | ||
598 | .name = "ldusb%d", | ||
599 | .fops = &ld_usb_fops, | ||
600 | .minor_base = USB_LD_MINOR_BASE, | ||
601 | }; | ||
602 | |||
603 | /** | ||
604 | * ld_usb_probe | ||
605 | * | ||
606 | * Called by the usb core when a new device is connected that it thinks | ||
607 | * this driver might be interested in. | ||
608 | */ | ||
609 | static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) | ||
610 | { | ||
611 | struct usb_device *udev = interface_to_usbdev(intf); | ||
612 | struct ld_usb *dev = NULL; | ||
613 | struct usb_host_interface *iface_desc; | ||
614 | struct usb_endpoint_descriptor *endpoint; | ||
615 | char *buffer; | ||
616 | int i; | ||
617 | int retval = -ENOMEM; | ||
618 | |||
619 | /* allocate memory for our device state and intialize it */ | ||
620 | |||
621 | dev = kmalloc(sizeof(*dev), GFP_KERNEL); | ||
622 | if (dev == NULL) { | ||
623 | dev_err(&intf->dev, "Out of memory\n"); | ||
624 | goto exit; | ||
625 | } | ||
626 | memset(dev, 0x00, sizeof(*dev)); | ||
627 | init_MUTEX(&dev->sem); | ||
628 | dev->intf = intf; | ||
629 | init_waitqueue_head(&dev->read_wait); | ||
630 | init_waitqueue_head(&dev->write_wait); | ||
631 | |||
632 | /* workaround for early firmware versions on fast computers */ | ||
633 | if ((le16_to_cpu(udev->descriptor.idVendor) == USB_VENDOR_ID_LD) && | ||
634 | ((le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_CASSY) || | ||
635 | (le16_to_cpu(udev->descriptor.idProduct) == USB_DEVICE_ID_COM3LAB)) && | ||
636 | (le16_to_cpu(udev->descriptor.bcdDevice) <= 0x103)) { | ||
637 | buffer = kmalloc(256, GFP_KERNEL); | ||
638 | /* usb_string makes SETUP+STALL to leave always ControlReadLoop */ | ||
639 | usb_string(udev, 255, buffer, 256); | ||
640 | kfree(buffer); | ||
641 | } | ||
642 | |||
643 | iface_desc = intf->cur_altsetting; | ||
644 | |||
645 | /* set up the endpoint information */ | ||
646 | for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { | ||
647 | endpoint = &iface_desc->endpoint[i].desc; | ||
648 | |||
649 | if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) && | ||
650 | ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) { | ||
651 | dev->interrupt_in_endpoint = endpoint; | ||
652 | } | ||
653 | |||
654 | if (((endpoint->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) && | ||
655 | ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT)) { | ||
656 | dev->interrupt_out_endpoint = endpoint; | ||
657 | } | ||
658 | } | ||
659 | if (dev->interrupt_in_endpoint == NULL) { | ||
660 | dev_err(&intf->dev, "Interrupt in endpoint not found\n"); | ||
661 | goto error; | ||
662 | } | ||
663 | if (dev->interrupt_out_endpoint == NULL) | ||
664 | dev_warn(&intf->dev, "Interrupt out endpoint not found (using control endpoint instead)\n"); | ||
665 | |||
666 | dev->interrupt_in_endpoint_size = le16_to_cpu(dev->interrupt_in_endpoint->wMaxPacketSize); | ||
667 | dev->ring_buffer = kmalloc(ring_buffer_size*(sizeof(size_t)+dev->interrupt_in_endpoint_size), GFP_KERNEL); | ||
668 | if (!dev->ring_buffer) { | ||
669 | dev_err(&intf->dev, "Couldn't allocate ring_buffer\n"); | ||
670 | goto error; | ||
671 | } | ||
672 | dev->interrupt_in_buffer = kmalloc(dev->interrupt_in_endpoint_size, GFP_KERNEL); | ||
673 | if (!dev->interrupt_in_buffer) { | ||
674 | dev_err(&intf->dev, "Couldn't allocate interrupt_in_buffer\n"); | ||
675 | goto error; | ||
676 | } | ||
677 | dev->interrupt_in_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
678 | if (!dev->interrupt_in_urb) { | ||
679 | dev_err(&intf->dev, "Couldn't allocate interrupt_in_urb\n"); | ||
680 | goto error; | ||
681 | } | ||
682 | dev->interrupt_out_endpoint_size = dev->interrupt_out_endpoint ? le16_to_cpu(dev->interrupt_out_endpoint->wMaxPacketSize) : | ||
683 | udev->descriptor.bMaxPacketSize0; | ||
684 | dev->interrupt_out_buffer = kmalloc(write_buffer_size*dev->interrupt_out_endpoint_size, GFP_KERNEL); | ||
685 | if (!dev->interrupt_out_buffer) { | ||
686 | dev_err(&intf->dev, "Couldn't allocate interrupt_out_buffer\n"); | ||
687 | goto error; | ||
688 | } | ||
689 | dev->interrupt_out_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
690 | if (!dev->interrupt_out_urb) { | ||
691 | dev_err(&intf->dev, "Couldn't allocate interrupt_out_urb\n"); | ||
692 | goto error; | ||
693 | } | ||
694 | dev->interrupt_in_interval = min_interrupt_in_interval > dev->interrupt_in_endpoint->bInterval ? min_interrupt_in_interval : dev->interrupt_in_endpoint->bInterval; | ||
695 | if (dev->interrupt_out_endpoint) | ||
696 | dev->interrupt_out_interval = min_interrupt_out_interval > dev->interrupt_out_endpoint->bInterval ? min_interrupt_out_interval : dev->interrupt_out_endpoint->bInterval; | ||
697 | |||
698 | /* we can register the device now, as it is ready */ | ||
699 | usb_set_intfdata(intf, dev); | ||
700 | |||
701 | retval = usb_register_dev(intf, &ld_usb_class); | ||
702 | if (retval) { | ||
703 | /* something prevented us from registering this driver */ | ||
704 | dev_err(&intf->dev, "Not able to get a minor for this device.\n"); | ||
705 | usb_set_intfdata(intf, NULL); | ||
706 | goto error; | ||
707 | } | ||
708 | |||
709 | /* let the user know what node this device is now attached to */ | ||
710 | dev_info(&intf->dev, "LD USB Device #%d now attached to major %d minor %d\n", | ||
711 | (intf->minor - USB_LD_MINOR_BASE), USB_MAJOR, intf->minor); | ||
712 | |||
713 | exit: | ||
714 | return retval; | ||
715 | |||
716 | error: | ||
717 | ld_usb_delete(dev); | ||
718 | |||
719 | return retval; | ||
720 | } | ||
721 | |||
722 | /** | ||
723 | * ld_usb_disconnect | ||
724 | * | ||
725 | * Called by the usb core when the device is removed from the system. | ||
726 | */ | ||
727 | static void ld_usb_disconnect(struct usb_interface *intf) | ||
728 | { | ||
729 | struct ld_usb *dev; | ||
730 | int minor; | ||
731 | |||
732 | down(&disconnect_sem); | ||
733 | |||
734 | dev = usb_get_intfdata(intf); | ||
735 | usb_set_intfdata(intf, NULL); | ||
736 | |||
737 | down(&dev->sem); | ||
738 | |||
739 | minor = intf->minor; | ||
740 | |||
741 | /* give back our minor */ | ||
742 | usb_deregister_dev(intf, &ld_usb_class); | ||
743 | |||
744 | /* if the device is not opened, then we clean up right now */ | ||
745 | if (!dev->open_count) { | ||
746 | up(&dev->sem); | ||
747 | ld_usb_delete(dev); | ||
748 | } else { | ||
749 | dev->intf = NULL; | ||
750 | up(&dev->sem); | ||
751 | } | ||
752 | |||
753 | up(&disconnect_sem); | ||
754 | |||
755 | dev_info(&intf->dev, "LD USB Device #%d now disconnected\n", | ||
756 | (minor - USB_LD_MINOR_BASE)); | ||
757 | } | ||
758 | |||
759 | /* usb specific object needed to register this driver with the usb subsystem */ | ||
760 | static struct usb_driver ld_usb_driver = { | ||
761 | .owner = THIS_MODULE, | ||
762 | .name = "ldusb", | ||
763 | .probe = ld_usb_probe, | ||
764 | .disconnect = ld_usb_disconnect, | ||
765 | .id_table = ld_usb_table, | ||
766 | }; | ||
767 | |||
768 | /** | ||
769 | * ld_usb_init | ||
770 | */ | ||
771 | static int __init ld_usb_init(void) | ||
772 | { | ||
773 | int retval; | ||
774 | |||
775 | /* register this driver with the USB subsystem */ | ||
776 | retval = usb_register(&ld_usb_driver); | ||
777 | if (retval) | ||
778 | err("usb_register failed for the "__FILE__" driver. Error number %d\n", retval); | ||
779 | |||
780 | return retval; | ||
781 | } | ||
782 | |||
783 | /** | ||
784 | * ld_usb_exit | ||
785 | */ | ||
786 | static void __exit ld_usb_exit(void) | ||
787 | { | ||
788 | /* deregister this driver with the USB subsystem */ | ||
789 | usb_deregister(&ld_usb_driver); | ||
790 | } | ||
791 | |||
792 | module_init(ld_usb_init); | ||
793 | module_exit(ld_usb_exit); | ||
794 | |||
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index 755a4570477f..26266b30028e 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c | |||
@@ -19,11 +19,16 @@ | |||
19 | #define DATA_MAX 32 | 19 | #define DATA_MAX 32 |
20 | 20 | ||
21 | /* | 21 | /* |
22 | * Defined by USB 2.0 clause 9.3, table 9.2. | ||
23 | */ | ||
24 | #define SETUP_MAX 8 | ||
25 | |||
26 | /* | ||
22 | * This limit exists to prevent OOMs when the user process stops reading. | 27 | * This limit exists to prevent OOMs when the user process stops reading. |
23 | */ | 28 | */ |
24 | #define EVENT_MAX 25 | 29 | #define EVENT_MAX 25 |
25 | 30 | ||
26 | #define PRINTF_DFL 120 | 31 | #define PRINTF_DFL 130 |
27 | 32 | ||
28 | struct mon_event_text { | 33 | struct mon_event_text { |
29 | struct list_head e_link; | 34 | struct list_head e_link; |
@@ -33,7 +38,9 @@ struct mon_event_text { | |||
33 | unsigned int tstamp; | 38 | unsigned int tstamp; |
34 | int length; /* Depends on type: xfer length or act length */ | 39 | int length; /* Depends on type: xfer length or act length */ |
35 | int status; | 40 | int status; |
41 | char setup_flag; | ||
36 | char data_flag; | 42 | char data_flag; |
43 | unsigned char setup[SETUP_MAX]; | ||
37 | unsigned char data[DATA_MAX]; | 44 | unsigned char data[DATA_MAX]; |
38 | }; | 45 | }; |
39 | 46 | ||
@@ -64,6 +71,22 @@ static void mon_text_dtor(void *, kmem_cache_t *, unsigned long); | |||
64 | * This is called with the whole mon_bus locked, so no additional lock. | 71 | * This is called with the whole mon_bus locked, so no additional lock. |
65 | */ | 72 | */ |
66 | 73 | ||
74 | static inline char mon_text_get_setup(struct mon_event_text *ep, | ||
75 | struct urb *urb, char ev_type) | ||
76 | { | ||
77 | |||
78 | if (!usb_pipecontrol(urb->pipe) || ev_type != 'S') | ||
79 | return '-'; | ||
80 | |||
81 | if (urb->transfer_flags & URB_NO_SETUP_DMA_MAP) | ||
82 | return 'D'; | ||
83 | if (urb->setup_packet == NULL) | ||
84 | return 'Z'; /* '0' would be not as pretty. */ | ||
85 | |||
86 | memcpy(ep->setup, urb->setup_packet, SETUP_MAX); | ||
87 | return 0; | ||
88 | } | ||
89 | |||
67 | static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb, | 90 | static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb, |
68 | int len, char ev_type) | 91 | int len, char ev_type) |
69 | { | 92 | { |
@@ -90,7 +113,6 @@ static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb, | |||
90 | 113 | ||
91 | /* | 114 | /* |
92 | * Bulk is easy to shortcut reliably. | 115 | * Bulk is easy to shortcut reliably. |
93 | * XXX Control needs setup packet taken. | ||
94 | * XXX Other pipe types need consideration. Currently, we overdo it | 116 | * XXX Other pipe types need consideration. Currently, we overdo it |
95 | * and collect garbage for them: better more than less. | 117 | * and collect garbage for them: better more than less. |
96 | */ | 118 | */ |
@@ -144,6 +166,7 @@ static void mon_text_event(struct mon_reader_text *rp, struct urb *urb, | |||
144 | /* Collecting status makes debugging sense for submits, too */ | 166 | /* Collecting status makes debugging sense for submits, too */ |
145 | ep->status = urb->status; | 167 | ep->status = urb->status; |
146 | 168 | ||
169 | ep->setup_flag = mon_text_get_setup(ep, urb, ev_type); | ||
147 | ep->data_flag = mon_text_get_data(ep, urb, ep->length, ev_type); | 170 | ep->data_flag = mon_text_get_data(ep, urb, ep->length, ev_type); |
148 | 171 | ||
149 | rp->nevents++; | 172 | rp->nevents++; |
@@ -299,10 +322,25 @@ static ssize_t mon_text_read(struct file *file, char __user *buf, | |||
299 | default: /* PIPE_BULK */ utype = 'B'; | 322 | default: /* PIPE_BULK */ utype = 'B'; |
300 | } | 323 | } |
301 | cnt += snprintf(pbuf + cnt, limit - cnt, | 324 | cnt += snprintf(pbuf + cnt, limit - cnt, |
302 | "%lx %u %c %c%c:%03u:%02u %d %d", | 325 | "%lx %u %c %c%c:%03u:%02u", |
303 | ep->id, ep->tstamp, ep->type, | 326 | ep->id, ep->tstamp, ep->type, |
304 | utype, udir, usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe), | 327 | utype, udir, usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe)); |
305 | ep->status, ep->length); | 328 | |
329 | if (ep->setup_flag == 0) { /* Setup packet is present and captured */ | ||
330 | cnt += snprintf(pbuf + cnt, limit - cnt, | ||
331 | " s %02x %02x %04x %04x %04x", | ||
332 | ep->setup[0], | ||
333 | ep->setup[1], | ||
334 | (ep->setup[3] << 8) | ep->setup[2], | ||
335 | (ep->setup[5] << 8) | ep->setup[4], | ||
336 | (ep->setup[7] << 8) | ep->setup[6]); | ||
337 | } else if (ep->setup_flag != '-') { /* Unable to capture setup packet */ | ||
338 | cnt += snprintf(pbuf + cnt, limit - cnt, | ||
339 | " %c __ __ ____ ____ ____", ep->setup_flag); | ||
340 | } else { /* No setup for this kind of URB */ | ||
341 | cnt += snprintf(pbuf + cnt, limit - cnt, " %d", ep->status); | ||
342 | } | ||
343 | cnt += snprintf(pbuf + cnt, limit - cnt, " %d", ep->length); | ||
306 | 344 | ||
307 | if ((data_len = ep->length) > 0) { | 345 | if ((data_len = ep->length) > 0) { |
308 | if (ep->data_flag == 0) { | 346 | if (ep->data_flag == 0) { |
diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c index fd6ff4cb2c62..7ffa99b9760f 100644 --- a/drivers/usb/net/kaweth.c +++ b/drivers/usb/net/kaweth.c | |||
@@ -477,7 +477,7 @@ static int kaweth_reset(struct kaweth_device *kaweth) | |||
477 | } | 477 | } |
478 | 478 | ||
479 | static void kaweth_usb_receive(struct urb *, struct pt_regs *regs); | 479 | static void kaweth_usb_receive(struct urb *, struct pt_regs *regs); |
480 | static int kaweth_resubmit_rx_urb(struct kaweth_device *, int); | 480 | static int kaweth_resubmit_rx_urb(struct kaweth_device *, unsigned); |
481 | 481 | ||
482 | /**************************************************************** | 482 | /**************************************************************** |
483 | int_callback | 483 | int_callback |
@@ -550,7 +550,7 @@ static void kaweth_resubmit_tl(void *d) | |||
550 | * kaweth_resubmit_rx_urb | 550 | * kaweth_resubmit_rx_urb |
551 | ****************************************************************/ | 551 | ****************************************************************/ |
552 | static int kaweth_resubmit_rx_urb(struct kaweth_device *kaweth, | 552 | static int kaweth_resubmit_rx_urb(struct kaweth_device *kaweth, |
553 | int mem_flags) | 553 | unsigned mem_flags) |
554 | { | 554 | { |
555 | int result; | 555 | int result; |
556 | 556 | ||
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index 8a945f4f3693..576f3b852fce 100644 --- a/drivers/usb/net/usbnet.c +++ b/drivers/usb/net/usbnet.c | |||
@@ -3227,9 +3227,9 @@ static int usbnet_stop (struct net_device *net) | |||
3227 | temp = unlink_urbs (dev, &dev->txq) + unlink_urbs (dev, &dev->rxq); | 3227 | temp = unlink_urbs (dev, &dev->txq) + unlink_urbs (dev, &dev->rxq); |
3228 | 3228 | ||
3229 | // maybe wait for deletions to finish. | 3229 | // maybe wait for deletions to finish. |
3230 | while (skb_queue_len (&dev->rxq) | 3230 | while (!skb_queue_empty(&dev->rxq) && |
3231 | && skb_queue_len (&dev->txq) | 3231 | !skb_queue_empty(&dev->txq) && |
3232 | && skb_queue_len (&dev->done)) { | 3232 | !skb_queue_empty(&dev->done)) { |
3233 | msleep(UNLINK_TIMEOUT_MS); | 3233 | msleep(UNLINK_TIMEOUT_MS); |
3234 | if (netif_msg_ifdown (dev)) | 3234 | if (netif_msg_ifdown (dev)) |
3235 | devdbg (dev, "waited for %d urb completions", temp); | 3235 | devdbg (dev, "waited for %d urb completions", temp); |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index d882fa3ad19a..0b03ddab53d9 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -264,16 +264,26 @@ | |||
264 | /* | 264 | /* |
265 | * Version Information | 265 | * Version Information |
266 | */ | 266 | */ |
267 | #define DRIVER_VERSION "v1.4.2" | 267 | #define DRIVER_VERSION "v1.4.3" |
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 | ||
271 | static int debug; | 271 | static int debug; |
272 | 272 | ||
273 | static struct usb_device_id id_table_sio [] = { | 273 | /* struct ftdi_sio_quirk is used by devices requiring special attention. */ |
274 | { USB_DEVICE(FTDI_VID, FTDI_SIO_PID) }, | 274 | struct ftdi_sio_quirk { |
275 | { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, | 275 | void (*setup)(struct usb_serial *); /* Special settings during startup. */ |
276 | { } /* Terminating entry */ | 276 | }; |
277 | |||
278 | static void ftdi_USB_UIRT_setup (struct usb_serial *serial); | ||
279 | static void ftdi_HE_TIRA1_setup (struct usb_serial *serial); | ||
280 | |||
281 | static struct ftdi_sio_quirk ftdi_USB_UIRT_quirk = { | ||
282 | .setup = ftdi_USB_UIRT_setup, | ||
283 | }; | ||
284 | |||
285 | static struct ftdi_sio_quirk ftdi_HE_TIRA1_quirk = { | ||
286 | .setup = ftdi_HE_TIRA1_setup, | ||
277 | }; | 287 | }; |
278 | 288 | ||
279 | /* | 289 | /* |
@@ -288,237 +298,11 @@ static struct usb_device_id id_table_sio [] = { | |||
288 | * the bcdDevice value is used to differentiate FT232BM and FT245BM from | 298 | * the bcdDevice value is used to differentiate FT232BM and FT245BM from |
289 | * the earlier FT8U232AM and FT8U232BM. For now, include all known VID/PID | 299 | * the earlier FT8U232AM and FT8U232BM. For now, include all known VID/PID |
290 | * combinations in both tables. | 300 | * combinations in both tables. |
291 | * FIXME: perhaps bcdDevice can also identify 12MHz devices, but I don't know | 301 | * FIXME: perhaps bcdDevice can also identify 12MHz FT8U232AM devices, |
292 | * if those ever went into mass production. [Ian Abbott] | 302 | * but I don't know if those ever went into mass production. [Ian Abbott] |
293 | */ | 303 | */ |
294 | 304 | ||
295 | 305 | ||
296 | static struct usb_device_id id_table_8U232AM [] = { | ||
297 | { USB_DEVICE_VER(FTDI_VID, FTDI_IRTRANS_PID, 0, 0x3ff) }, | ||
298 | { USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_PID, 0, 0x3ff) }, | ||
299 | { USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_ALT_PID, 0, 0x3ff) }, | ||
300 | { USB_DEVICE_VER(FTDI_VID, FTDI_RELAIS_PID, 0, 0x3ff) }, | ||
301 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_IOBOARD_PID) }, | ||
302 | { USB_DEVICE(INTERBIOMETRICS_VID, INTERBIOMETRICS_MINI_IOBOARD_PID) }, | ||
303 | { USB_DEVICE_VER(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID, 0, 0x3ff) }, | ||
304 | { USB_DEVICE_VER(FTDI_VID, FTDI_XF_632_PID, 0, 0x3ff) }, | ||
305 | { USB_DEVICE_VER(FTDI_VID, FTDI_XF_634_PID, 0, 0x3ff) }, | ||
306 | { USB_DEVICE_VER(FTDI_VID, FTDI_XF_547_PID, 0, 0x3ff) }, | ||
307 | { USB_DEVICE_VER(FTDI_VID, FTDI_XF_633_PID, 0, 0x3ff) }, | ||
308 | { USB_DEVICE_VER(FTDI_VID, FTDI_XF_631_PID, 0, 0x3ff) }, | ||
309 | { USB_DEVICE_VER(FTDI_VID, FTDI_XF_635_PID, 0, 0x3ff) }, | ||
310 | { USB_DEVICE_VER(FTDI_VID, FTDI_XF_640_PID, 0, 0x3ff) }, | ||
311 | { USB_DEVICE_VER(FTDI_VID, FTDI_XF_642_PID, 0, 0x3ff) }, | ||
312 | { USB_DEVICE_VER(FTDI_VID, FTDI_VNHCPCUSB_D_PID, 0, 0x3ff) }, | ||
313 | { USB_DEVICE_VER(FTDI_VID, FTDI_DSS20_PID, 0, 0x3ff) }, | ||
314 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2101_PID, 0, 0x3ff) }, | ||
315 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2102_PID, 0, 0x3ff) }, | ||
316 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2103_PID, 0, 0x3ff) }, | ||
317 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2104_PID, 0, 0x3ff) }, | ||
318 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2201_1_PID, 0, 0x3ff) }, | ||
319 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2201_2_PID, 0, 0x3ff) }, | ||
320 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2202_1_PID, 0, 0x3ff) }, | ||
321 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2202_2_PID, 0, 0x3ff) }, | ||
322 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2203_1_PID, 0, 0x3ff) }, | ||
323 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2203_2_PID, 0, 0x3ff) }, | ||
324 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_1_PID, 0, 0x3ff) }, | ||
325 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_2_PID, 0, 0x3ff) }, | ||
326 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_3_PID, 0, 0x3ff) }, | ||
327 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_4_PID, 0, 0x3ff) }, | ||
328 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_1_PID, 0, 0x3ff) }, | ||
329 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_2_PID, 0, 0x3ff) }, | ||
330 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_3_PID, 0, 0x3ff) }, | ||
331 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_4_PID, 0, 0x3ff) }, | ||
332 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_1_PID, 0, 0x3ff) }, | ||
333 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_2_PID, 0, 0x3ff) }, | ||
334 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_3_PID, 0, 0x3ff) }, | ||
335 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_4_PID, 0, 0x3ff) }, | ||
336 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_1_PID, 0, 0x3ff) }, | ||
337 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_2_PID, 0, 0x3ff) }, | ||
338 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_3_PID, 0, 0x3ff) }, | ||
339 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_4_PID, 0, 0x3ff) }, | ||
340 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_5_PID, 0, 0x3ff) }, | ||
341 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_6_PID, 0, 0x3ff) }, | ||
342 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_7_PID, 0, 0x3ff) }, | ||
343 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_8_PID, 0, 0x3ff) }, | ||
344 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_1_PID, 0, 0x3ff) }, | ||
345 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_2_PID, 0, 0x3ff) }, | ||
346 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_3_PID, 0, 0x3ff) }, | ||
347 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_4_PID, 0, 0x3ff) }, | ||
348 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_5_PID, 0, 0x3ff) }, | ||
349 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_6_PID, 0, 0x3ff) }, | ||
350 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_7_PID, 0, 0x3ff) }, | ||
351 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_8_PID, 0, 0x3ff) }, | ||
352 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_1_PID, 0, 0x3ff) }, | ||
353 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_2_PID, 0, 0x3ff) }, | ||
354 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_3_PID, 0, 0x3ff) }, | ||
355 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_4_PID, 0, 0x3ff) }, | ||
356 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_5_PID, 0, 0x3ff) }, | ||
357 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_6_PID, 0, 0x3ff) }, | ||
358 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_7_PID, 0, 0x3ff) }, | ||
359 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_8_PID, 0, 0x3ff) }, | ||
360 | { USB_DEVICE_VER(IDTECH_VID, IDTECH_IDT1221U_PID, 0, 0x3ff) }, | ||
361 | { USB_DEVICE_VER(OCT_VID, OCT_US101_PID, 0, 0x3ff) }, | ||
362 | { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_1, 0, 0x3ff) }, | ||
363 | { USB_DEVICE_VER(FTDI_VID, PROTEGO_R2X0, 0, 0x3ff) }, | ||
364 | { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 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) }, | ||
367 | { USB_DEVICE_VER(FTDI_VID, FTDI_ELV_UM100_PID, 0, 0x3ff) }, | ||
368 | { USB_DEVICE_VER(FTDI_VID, INSIDE_ACCESSO, 0, 0x3ff) }, | ||
369 | { USB_DEVICE_VER(INTREPID_VID, INTREPID_VALUECAN_PID, 0, 0x3ff) }, | ||
370 | { USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0, 0x3ff) }, | ||
371 | { USB_DEVICE_VER(FALCOM_VID, FALCOM_TWIST_PID, 0, 0x3ff) }, | ||
372 | { USB_DEVICE_VER(FTDI_VID, FTDI_SUUNTO_SPORTS_PID, 0, 0x3ff) }, | ||
373 | { USB_DEVICE_VER(FTDI_VID, FTDI_RM_CANVIEW_PID, 0, 0x3ff) }, | ||
374 | { USB_DEVICE_VER(BANDB_VID, BANDB_USOTL4_PID, 0, 0x3ff) }, | ||
375 | { USB_DEVICE_VER(BANDB_VID, BANDB_USTL4_PID, 0, 0x3ff) }, | ||
376 | { USB_DEVICE_VER(BANDB_VID, BANDB_USO9ML2_PID, 0, 0x3ff) }, | ||
377 | { USB_DEVICE_VER(FTDI_VID, EVER_ECO_PRO_CDS, 0, 0x3ff) }, | ||
378 | { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_0_PID, 0, 0x3ff) }, | ||
379 | { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID, 0, 0x3ff) }, | ||
380 | { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID, 0, 0x3ff) }, | ||
381 | { } /* Terminating entry */ | ||
382 | }; | ||
383 | |||
384 | |||
385 | static struct usb_device_id id_table_FT232BM [] = { | ||
386 | { USB_DEVICE_VER(FTDI_VID, FTDI_IRTRANS_PID, 0x400, 0xffff) }, | ||
387 | { USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_PID, 0x400, 0xffff) }, | ||
388 | { USB_DEVICE_VER(FTDI_VID, FTDI_8U232AM_ALT_PID, 0x400, 0xffff) }, | ||
389 | { USB_DEVICE_VER(FTDI_VID, FTDI_RELAIS_PID, 0x400, 0xffff) }, | ||
390 | { USB_DEVICE_VER(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID, 0x400, 0xffff) }, | ||
391 | { USB_DEVICE_VER(FTDI_VID, FTDI_XF_632_PID, 0x400, 0xffff) }, | ||
392 | { USB_DEVICE_VER(FTDI_VID, FTDI_XF_634_PID, 0x400, 0xffff) }, | ||
393 | { USB_DEVICE_VER(FTDI_VID, FTDI_XF_547_PID, 0x400, 0xffff) }, | ||
394 | { USB_DEVICE_VER(FTDI_VID, FTDI_XF_633_PID, 0x400, 0xffff) }, | ||
395 | { USB_DEVICE_VER(FTDI_VID, FTDI_XF_631_PID, 0x400, 0xffff) }, | ||
396 | { USB_DEVICE_VER(FTDI_VID, FTDI_XF_635_PID, 0x400, 0xffff) }, | ||
397 | { USB_DEVICE_VER(FTDI_VID, FTDI_XF_640_PID, 0x400, 0xffff) }, | ||
398 | { USB_DEVICE_VER(FTDI_VID, FTDI_XF_642_PID, 0x400, 0xffff) }, | ||
399 | { USB_DEVICE_VER(FTDI_VID, FTDI_VNHCPCUSB_D_PID, 0x400, 0xffff) }, | ||
400 | { USB_DEVICE_VER(FTDI_VID, FTDI_DSS20_PID, 0x400, 0xffff) }, | ||
401 | { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_0_PID, 0x400, 0xffff) }, | ||
402 | { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_1_PID, 0x400, 0xffff) }, | ||
403 | { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_2_PID, 0x400, 0xffff) }, | ||
404 | { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_3_PID, 0x400, 0xffff) }, | ||
405 | { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_4_PID, 0x400, 0xffff) }, | ||
406 | { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_5_PID, 0x400, 0xffff) }, | ||
407 | { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_6_PID, 0x400, 0xffff) }, | ||
408 | { USB_DEVICE_VER(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID, 0x400, 0xffff) }, | ||
409 | { USB_DEVICE_VER(FTDI_VID, FTDI_PIEGROUP_PID, 0x400, 0xffff) }, | ||
410 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2101_PID, 0x400, 0xffff) }, | ||
411 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2102_PID, 0x400, 0xffff) }, | ||
412 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2103_PID, 0x400, 0xffff) }, | ||
413 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2104_PID, 0x400, 0xffff) }, | ||
414 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2201_1_PID, 0x400, 0xffff) }, | ||
415 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2201_2_PID, 0x400, 0xffff) }, | ||
416 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2202_1_PID, 0x400, 0xffff) }, | ||
417 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2202_2_PID, 0x400, 0xffff) }, | ||
418 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2203_1_PID, 0x400, 0xffff) }, | ||
419 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2203_2_PID, 0x400, 0xffff) }, | ||
420 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_1_PID, 0x400, 0xffff) }, | ||
421 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_2_PID, 0x400, 0xffff) }, | ||
422 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_3_PID, 0x400, 0xffff) }, | ||
423 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2401_4_PID, 0x400, 0xffff) }, | ||
424 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_1_PID, 0x400, 0xffff) }, | ||
425 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_2_PID, 0x400, 0xffff) }, | ||
426 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_3_PID, 0x400, 0xffff) }, | ||
427 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2402_4_PID, 0x400, 0xffff) }, | ||
428 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_1_PID, 0x400, 0xffff) }, | ||
429 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_2_PID, 0x400, 0xffff) }, | ||
430 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_3_PID, 0x400, 0xffff) }, | ||
431 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2403_4_PID, 0x400, 0xffff) }, | ||
432 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_1_PID, 0x400, 0xffff) }, | ||
433 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_2_PID, 0x400, 0xffff) }, | ||
434 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_3_PID, 0x400, 0xffff) }, | ||
435 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_4_PID, 0x400, 0xffff) }, | ||
436 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_5_PID, 0x400, 0xffff) }, | ||
437 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_6_PID, 0x400, 0xffff) }, | ||
438 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_7_PID, 0x400, 0xffff) }, | ||
439 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2801_8_PID, 0x400, 0xffff) }, | ||
440 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_1_PID, 0x400, 0xffff) }, | ||
441 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_2_PID, 0x400, 0xffff) }, | ||
442 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_3_PID, 0x400, 0xffff) }, | ||
443 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_4_PID, 0x400, 0xffff) }, | ||
444 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_5_PID, 0x400, 0xffff) }, | ||
445 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_6_PID, 0x400, 0xffff) }, | ||
446 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_7_PID, 0x400, 0xffff) }, | ||
447 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2802_8_PID, 0x400, 0xffff) }, | ||
448 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_1_PID, 0x400, 0xffff) }, | ||
449 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_2_PID, 0x400, 0xffff) }, | ||
450 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_3_PID, 0x400, 0xffff) }, | ||
451 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_4_PID, 0x400, 0xffff) }, | ||
452 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_5_PID, 0x400, 0xffff) }, | ||
453 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_6_PID, 0x400, 0xffff) }, | ||
454 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_7_PID, 0x400, 0xffff) }, | ||
455 | { USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_8_PID, 0x400, 0xffff) }, | ||
456 | { USB_DEVICE_VER(IDTECH_VID, IDTECH_IDT1221U_PID, 0x400, 0xffff) }, | ||
457 | { USB_DEVICE_VER(OCT_VID, OCT_US101_PID, 0x400, 0xffff) }, | ||
458 | { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_1, 0x400, 0xffff) }, | ||
459 | { USB_DEVICE_VER(FTDI_VID, PROTEGO_R2X0, 0x400, 0xffff) }, | ||
460 | { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_3, 0x400, 0xffff) }, | ||
461 | { USB_DEVICE_VER(FTDI_VID, PROTEGO_SPECIAL_4, 0x400, 0xffff) }, | ||
462 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E808_PID, 0x400, 0xffff) }, | ||
463 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E809_PID, 0x400, 0xffff) }, | ||
464 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80A_PID, 0x400, 0xffff) }, | ||
465 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80B_PID, 0x400, 0xffff) }, | ||
466 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80C_PID, 0x400, 0xffff) }, | ||
467 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80D_PID, 0x400, 0xffff) }, | ||
468 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80E_PID, 0x400, 0xffff) }, | ||
469 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80F_PID, 0x400, 0xffff) }, | ||
470 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E888_PID, 0x400, 0xffff) }, | ||
471 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E889_PID, 0x400, 0xffff) }, | ||
472 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88A_PID, 0x400, 0xffff) }, | ||
473 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88B_PID, 0x400, 0xffff) }, | ||
474 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88C_PID, 0x400, 0xffff) }, | ||
475 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88D_PID, 0x400, 0xffff) }, | ||
476 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, | ||
477 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_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) }, | ||
480 | { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, | ||
481 | { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, | ||
482 | { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, | ||
483 | { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_1_PID, 0x400, 0xffff) }, | ||
484 | { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_2_PID, 0x400, 0xffff) }, | ||
485 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) }, | ||
486 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) }, | ||
487 | { USB_DEVICE_VER(FTDI_VID, INSIDE_ACCESSO, 0x400, 0xffff) }, | ||
488 | { USB_DEVICE_VER(INTREPID_VID, INTREPID_VALUECAN_PID, 0x400, 0xffff) }, | ||
489 | { USB_DEVICE_VER(INTREPID_VID, INTREPID_NEOVI_PID, 0x400, 0xffff) }, | ||
490 | { USB_DEVICE_VER(FALCOM_VID, FALCOM_TWIST_PID, 0x400, 0xffff) }, | ||
491 | { USB_DEVICE_VER(FTDI_VID, FTDI_SUUNTO_SPORTS_PID, 0x400, 0xffff) }, | ||
492 | { USB_DEVICE_VER(FTDI_VID, FTDI_RM_CANVIEW_PID, 0x400, 0xffff) }, | ||
493 | { USB_DEVICE_VER(BANDB_VID, BANDB_USOTL4_PID, 0x400, 0xffff) }, | ||
494 | { USB_DEVICE_VER(BANDB_VID, BANDB_USTL4_PID, 0x400, 0xffff) }, | ||
495 | { USB_DEVICE_VER(BANDB_VID, BANDB_USO9ML2_PID, 0x400, 0xffff) }, | ||
496 | { USB_DEVICE_VER(FTDI_VID, EVER_ECO_PRO_CDS, 0x400, 0xffff) }, | ||
497 | { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_0_PID, 0x400, 0xffff) }, | ||
498 | { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID, 0x400, 0xffff) }, | ||
499 | { USB_DEVICE_VER(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID, 0x400, 0xffff) }, | ||
500 | { USB_DEVICE_VER(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID, 0x400, 0xffff) }, | ||
501 | { } /* Terminating entry */ | ||
502 | }; | ||
503 | |||
504 | |||
505 | static struct usb_device_id id_table_USB_UIRT [] = { | ||
506 | { USB_DEVICE(FTDI_VID, FTDI_USB_UIRT_PID) }, | ||
507 | { } /* Terminating entry */ | ||
508 | }; | ||
509 | |||
510 | |||
511 | static struct usb_device_id id_table_HE_TIRA1 [] = { | ||
512 | { USB_DEVICE_VER(FTDI_VID, FTDI_HE_TIRA1_PID, 0x400, 0xffff) }, | ||
513 | { } /* Terminating entry */ | ||
514 | }; | ||
515 | |||
516 | |||
517 | static struct usb_device_id id_table_FT2232C[] = { | ||
518 | { USB_DEVICE(FTDI_VID, FTDI_8U2232C_PID) }, | ||
519 | { } /* Terminating entry */ | ||
520 | }; | ||
521 | |||
522 | 306 | ||
523 | static struct usb_device_id id_table_combined [] = { | 307 | static struct usb_device_id id_table_combined [] = { |
524 | { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, | 308 | { USB_DEVICE(FTDI_VID, FTDI_IRTRANS_PID) }, |
@@ -540,14 +324,14 @@ static struct usb_device_id id_table_combined [] = { | |||
540 | { USB_DEVICE(FTDI_VID, FTDI_DSS20_PID) }, | 324 | { USB_DEVICE(FTDI_VID, FTDI_DSS20_PID) }, |
541 | { USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) }, | 325 | { USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) }, |
542 | { USB_DEVICE(FTDI_VID, FTDI_VNHCPCUSB_D_PID) }, | 326 | { USB_DEVICE(FTDI_VID, FTDI_VNHCPCUSB_D_PID) }, |
543 | { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_0_PID, 0x400, 0xffff) }, | 327 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_0_PID) }, |
544 | { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_1_PID, 0x400, 0xffff) }, | 328 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_1_PID) }, |
545 | { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_2_PID, 0x400, 0xffff) }, | 329 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_2_PID) }, |
546 | { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_3_PID, 0x400, 0xffff) }, | 330 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_3_PID) }, |
547 | { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_4_PID, 0x400, 0xffff) }, | 331 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_4_PID) }, |
548 | { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_5_PID, 0x400, 0xffff) }, | 332 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_5_PID) }, |
549 | { USB_DEVICE_VER(FTDI_VID, FTDI_MTXORB_6_PID, 0x400, 0xffff) }, | 333 | { USB_DEVICE(FTDI_VID, FTDI_MTXORB_6_PID) }, |
550 | { USB_DEVICE_VER(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID, 0x400, 0xffff) }, | 334 | { USB_DEVICE(FTDI_VID, FTDI_PERLE_ULTRAPORT_PID) }, |
551 | { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) }, | 335 | { USB_DEVICE(FTDI_VID, FTDI_PIEGROUP_PID) }, |
552 | { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2101_PID) }, | 336 | { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2101_PID) }, |
553 | { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2102_PID) }, | 337 | { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2102_PID) }, |
@@ -597,35 +381,37 @@ static struct usb_device_id id_table_combined [] = { | |||
597 | { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_8_PID) }, | 381 | { USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_8_PID) }, |
598 | { USB_DEVICE(IDTECH_VID, IDTECH_IDT1221U_PID) }, | 382 | { USB_DEVICE(IDTECH_VID, IDTECH_IDT1221U_PID) }, |
599 | { USB_DEVICE(OCT_VID, OCT_US101_PID) }, | 383 | { USB_DEVICE(OCT_VID, OCT_US101_PID) }, |
600 | { USB_DEVICE_VER(FTDI_VID, FTDI_HE_TIRA1_PID, 0x400, 0xffff) }, | 384 | { USB_DEVICE(FTDI_VID, FTDI_HE_TIRA1_PID), |
601 | { USB_DEVICE(FTDI_VID, FTDI_USB_UIRT_PID) }, | 385 | .driver_info = (kernel_ulong_t)&ftdi_HE_TIRA1_quirk }, |
386 | { USB_DEVICE(FTDI_VID, FTDI_USB_UIRT_PID), | ||
387 | .driver_info = (kernel_ulong_t)&ftdi_USB_UIRT_quirk }, | ||
602 | { USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_1) }, | 388 | { USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_1) }, |
603 | { USB_DEVICE(FTDI_VID, PROTEGO_R2X0) }, | 389 | { USB_DEVICE(FTDI_VID, PROTEGO_R2X0) }, |
604 | { USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_3) }, | 390 | { USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_3) }, |
605 | { USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_4) }, | 391 | { USB_DEVICE(FTDI_VID, PROTEGO_SPECIAL_4) }, |
606 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E808_PID, 0x400, 0xffff) }, | 392 | { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E808_PID) }, |
607 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E809_PID, 0x400, 0xffff) }, | 393 | { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E809_PID) }, |
608 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80A_PID, 0x400, 0xffff) }, | 394 | { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80A_PID) }, |
609 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80B_PID, 0x400, 0xffff) }, | 395 | { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80B_PID) }, |
610 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80C_PID, 0x400, 0xffff) }, | 396 | { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80C_PID) }, |
611 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80D_PID, 0x400, 0xffff) }, | 397 | { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80D_PID) }, |
612 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80E_PID, 0x400, 0xffff) }, | 398 | { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80E_PID) }, |
613 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E80F_PID, 0x400, 0xffff) }, | 399 | { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E80F_PID) }, |
614 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E888_PID, 0x400, 0xffff) }, | 400 | { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E888_PID) }, |
615 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E889_PID, 0x400, 0xffff) }, | 401 | { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E889_PID) }, |
616 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88A_PID, 0x400, 0xffff) }, | 402 | { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88A_PID) }, |
617 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88B_PID, 0x400, 0xffff) }, | 403 | { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88B_PID) }, |
618 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88C_PID, 0x400, 0xffff) }, | 404 | { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88C_PID) }, |
619 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88D_PID, 0x400, 0xffff) }, | 405 | { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88D_PID) }, |
620 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88E_PID, 0x400, 0xffff) }, | 406 | { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88E_PID) }, |
621 | { USB_DEVICE_VER(FTDI_VID, FTDI_GUDEADS_E88F_PID, 0x400, 0xffff) }, | 407 | { USB_DEVICE(FTDI_VID, FTDI_GUDEADS_E88F_PID) }, |
622 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) }, | 408 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UO100_PID) }, |
623 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) }, | 409 | { USB_DEVICE(FTDI_VID, FTDI_ELV_UM100_PID) }, |
624 | { USB_DEVICE_VER(FTDI_VID, LINX_SDMUSBQSS_PID, 0x400, 0xffff) }, | 410 | { USB_DEVICE(FTDI_VID, LINX_SDMUSBQSS_PID) }, |
625 | { USB_DEVICE_VER(FTDI_VID, LINX_MASTERDEVEL2_PID, 0x400, 0xffff) }, | 411 | { USB_DEVICE(FTDI_VID, LINX_MASTERDEVEL2_PID) }, |
626 | { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_0_PID, 0x400, 0xffff) }, | 412 | { USB_DEVICE(FTDI_VID, LINX_FUTURE_0_PID) }, |
627 | { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_1_PID, 0x400, 0xffff) }, | 413 | { USB_DEVICE(FTDI_VID, LINX_FUTURE_1_PID) }, |
628 | { USB_DEVICE_VER(FTDI_VID, LINX_FUTURE_2_PID, 0x400, 0xffff) }, | 414 | { USB_DEVICE(FTDI_VID, LINX_FUTURE_2_PID) }, |
629 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) }, | 415 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU20_0_PID) }, |
630 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) }, | 416 | { USB_DEVICE(FTDI_VID, FTDI_CCSICDU40_1_PID) }, |
631 | { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) }, | 417 | { USB_DEVICE(FTDI_VID, INSIDE_ACCESSO) }, |
@@ -642,7 +428,7 @@ static struct usb_device_id id_table_combined [] = { | |||
642 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) }, | 428 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_1_PID) }, |
643 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) }, | 429 | { USB_DEVICE(FTDI_VID, FTDI_4N_GALAXY_DE_2_PID) }, |
644 | { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, | 430 | { USB_DEVICE(MOBILITY_VID, MOBILITY_USB_SERIAL_PID) }, |
645 | { USB_DEVICE_VER(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID, 0x400, 0xffff) }, | 431 | { USB_DEVICE(FTDI_VID, FTDI_ACTIVE_ROBOTS_PID) }, |
646 | { } /* Terminating entry */ | 432 | { } /* Terminating entry */ |
647 | }; | 433 | }; |
648 | 434 | ||
@@ -705,12 +491,8 @@ struct ftdi_private { | |||
705 | ASYNC_SPD_CUST | ASYNC_SPD_SHI | ASYNC_SPD_WARP ) | 491 | ASYNC_SPD_CUST | ASYNC_SPD_SHI | ASYNC_SPD_WARP ) |
706 | 492 | ||
707 | /* function prototypes for a FTDI serial converter */ | 493 | /* function prototypes for a FTDI serial converter */ |
708 | static int ftdi_SIO_startup (struct usb_serial *serial); | 494 | static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id); |
709 | static int ftdi_8U232AM_startup (struct usb_serial *serial); | 495 | static int ftdi_sio_attach (struct usb_serial *serial); |
710 | static int ftdi_FT232BM_startup (struct usb_serial *serial); | ||
711 | static int ftdi_FT2232C_startup (struct usb_serial *serial); | ||
712 | static int ftdi_USB_UIRT_startup (struct usb_serial *serial); | ||
713 | static int ftdi_HE_TIRA1_startup (struct usb_serial *serial); | ||
714 | static void ftdi_shutdown (struct usb_serial *serial); | 496 | static void ftdi_shutdown (struct usb_serial *serial); |
715 | static int ftdi_open (struct usb_serial_port *port, struct file *filp); | 497 | static int ftdi_open (struct usb_serial_port *port, struct file *filp); |
716 | static void ftdi_close (struct usb_serial_port *port, struct file *filp); | 498 | static void ftdi_close (struct usb_serial_port *port, struct file *filp); |
@@ -733,14 +515,16 @@ static unsigned short int ftdi_232am_baud_to_divisor (int baud); | |||
733 | static __u32 ftdi_232bm_baud_base_to_divisor (int baud, int base); | 515 | static __u32 ftdi_232bm_baud_base_to_divisor (int baud, int base); |
734 | static __u32 ftdi_232bm_baud_to_divisor (int baud); | 516 | static __u32 ftdi_232bm_baud_to_divisor (int baud); |
735 | 517 | ||
736 | static struct usb_serial_device_type ftdi_SIO_device = { | 518 | static struct usb_serial_device_type ftdi_sio_device = { |
737 | .owner = THIS_MODULE, | 519 | .owner = THIS_MODULE, |
738 | .name = "FTDI SIO", | 520 | .name = "FTDI USB Serial Device", |
739 | .id_table = id_table_sio, | 521 | .short_name = "ftdi_sio", |
522 | .id_table = id_table_combined, | ||
740 | .num_interrupt_in = 0, | 523 | .num_interrupt_in = 0, |
741 | .num_bulk_in = 1, | 524 | .num_bulk_in = 1, |
742 | .num_bulk_out = 1, | 525 | .num_bulk_out = 1, |
743 | .num_ports = 1, | 526 | .num_ports = 1, |
527 | .probe = ftdi_sio_probe, | ||
744 | .open = ftdi_open, | 528 | .open = ftdi_open, |
745 | .close = ftdi_close, | 529 | .close = ftdi_close, |
746 | .throttle = ftdi_throttle, | 530 | .throttle = ftdi_throttle, |
@@ -755,143 +539,10 @@ static struct usb_serial_device_type ftdi_SIO_device = { | |||
755 | .ioctl = ftdi_ioctl, | 539 | .ioctl = ftdi_ioctl, |
756 | .set_termios = ftdi_set_termios, | 540 | .set_termios = ftdi_set_termios, |
757 | .break_ctl = ftdi_break_ctl, | 541 | .break_ctl = ftdi_break_ctl, |
758 | .attach = ftdi_SIO_startup, | 542 | .attach = ftdi_sio_attach, |
759 | .shutdown = ftdi_shutdown, | 543 | .shutdown = ftdi_shutdown, |
760 | }; | 544 | }; |
761 | 545 | ||
762 | static struct usb_serial_device_type ftdi_8U232AM_device = { | ||
763 | .owner = THIS_MODULE, | ||
764 | .name = "FTDI 8U232AM Compatible", | ||
765 | .id_table = id_table_8U232AM, | ||
766 | .num_interrupt_in = 0, | ||
767 | .num_bulk_in = 1, | ||
768 | .num_bulk_out = 1, | ||
769 | .num_ports = 1, | ||
770 | .open = ftdi_open, | ||
771 | .close = ftdi_close, | ||
772 | .throttle = ftdi_throttle, | ||
773 | .unthrottle = ftdi_unthrottle, | ||
774 | .write = ftdi_write, | ||
775 | .write_room = ftdi_write_room, | ||
776 | .chars_in_buffer = ftdi_chars_in_buffer, | ||
777 | .read_bulk_callback = ftdi_read_bulk_callback, | ||
778 | .write_bulk_callback = ftdi_write_bulk_callback, | ||
779 | .tiocmget = ftdi_tiocmget, | ||
780 | .tiocmset = ftdi_tiocmset, | ||
781 | .ioctl = ftdi_ioctl, | ||
782 | .set_termios = ftdi_set_termios, | ||
783 | .break_ctl = ftdi_break_ctl, | ||
784 | .attach = ftdi_8U232AM_startup, | ||
785 | .shutdown = ftdi_shutdown, | ||
786 | }; | ||
787 | |||
788 | static struct usb_serial_device_type ftdi_FT232BM_device = { | ||
789 | .owner = THIS_MODULE, | ||
790 | .name = "FTDI FT232BM Compatible", | ||
791 | .id_table = id_table_FT232BM, | ||
792 | .num_interrupt_in = 0, | ||
793 | .num_bulk_in = 1, | ||
794 | .num_bulk_out = 1, | ||
795 | .num_ports = 1, | ||
796 | .open = ftdi_open, | ||
797 | .close = ftdi_close, | ||
798 | .throttle = ftdi_throttle, | ||
799 | .unthrottle = ftdi_unthrottle, | ||
800 | .write = ftdi_write, | ||
801 | .write_room = ftdi_write_room, | ||
802 | .chars_in_buffer = ftdi_chars_in_buffer, | ||
803 | .read_bulk_callback = ftdi_read_bulk_callback, | ||
804 | .write_bulk_callback = ftdi_write_bulk_callback, | ||
805 | .tiocmget = ftdi_tiocmget, | ||
806 | .tiocmset = ftdi_tiocmset, | ||
807 | .ioctl = ftdi_ioctl, | ||
808 | .set_termios = ftdi_set_termios, | ||
809 | .break_ctl = ftdi_break_ctl, | ||
810 | .attach = ftdi_FT232BM_startup, | ||
811 | .shutdown = ftdi_shutdown, | ||
812 | }; | ||
813 | |||
814 | static struct usb_serial_device_type ftdi_FT2232C_device = { | ||
815 | .owner = THIS_MODULE, | ||
816 | .name = "FTDI FT2232C Compatible", | ||
817 | .id_table = id_table_FT2232C, | ||
818 | .num_interrupt_in = 0, | ||
819 | .num_bulk_in = 1, | ||
820 | .num_bulk_out = 1, | ||
821 | .num_ports = 1, | ||
822 | .open = ftdi_open, | ||
823 | .close = ftdi_close, | ||
824 | .throttle = ftdi_throttle, | ||
825 | .unthrottle = ftdi_unthrottle, | ||
826 | .write = ftdi_write, | ||
827 | .write_room = ftdi_write_room, | ||
828 | .chars_in_buffer = ftdi_chars_in_buffer, | ||
829 | .read_bulk_callback = ftdi_read_bulk_callback, | ||
830 | .write_bulk_callback = ftdi_write_bulk_callback, | ||
831 | .tiocmget = ftdi_tiocmget, | ||
832 | .tiocmset = ftdi_tiocmset, | ||
833 | .ioctl = ftdi_ioctl, | ||
834 | .set_termios = ftdi_set_termios, | ||
835 | .break_ctl = ftdi_break_ctl, | ||
836 | .attach = ftdi_FT2232C_startup, | ||
837 | .shutdown = ftdi_shutdown, | ||
838 | }; | ||
839 | |||
840 | static struct usb_serial_device_type ftdi_USB_UIRT_device = { | ||
841 | .owner = THIS_MODULE, | ||
842 | .name = "USB-UIRT Infrared Tranceiver", | ||
843 | .id_table = id_table_USB_UIRT, | ||
844 | .num_interrupt_in = 0, | ||
845 | .num_bulk_in = 1, | ||
846 | .num_bulk_out = 1, | ||
847 | .num_ports = 1, | ||
848 | .open = ftdi_open, | ||
849 | .close = ftdi_close, | ||
850 | .throttle = ftdi_throttle, | ||
851 | .unthrottle = ftdi_unthrottle, | ||
852 | .write = ftdi_write, | ||
853 | .write_room = ftdi_write_room, | ||
854 | .chars_in_buffer = ftdi_chars_in_buffer, | ||
855 | .read_bulk_callback = ftdi_read_bulk_callback, | ||
856 | .write_bulk_callback = ftdi_write_bulk_callback, | ||
857 | .tiocmget = ftdi_tiocmget, | ||
858 | .tiocmset = ftdi_tiocmset, | ||
859 | .ioctl = ftdi_ioctl, | ||
860 | .set_termios = ftdi_set_termios, | ||
861 | .break_ctl = ftdi_break_ctl, | ||
862 | .attach = ftdi_USB_UIRT_startup, | ||
863 | .shutdown = ftdi_shutdown, | ||
864 | }; | ||
865 | |||
866 | /* The TIRA1 is based on a FT232BM which requires a fixed baud rate of 100000 | ||
867 | * and which requires RTS-CTS to be enabled. */ | ||
868 | static struct usb_serial_device_type ftdi_HE_TIRA1_device = { | ||
869 | .owner = THIS_MODULE, | ||
870 | .name = "Home-Electronics TIRA-1 IR Transceiver", | ||
871 | .id_table = id_table_HE_TIRA1, | ||
872 | .num_interrupt_in = 0, | ||
873 | .num_bulk_in = 1, | ||
874 | .num_bulk_out = 1, | ||
875 | .num_ports = 1, | ||
876 | .open = ftdi_open, | ||
877 | .close = ftdi_close, | ||
878 | .throttle = ftdi_throttle, | ||
879 | .unthrottle = ftdi_unthrottle, | ||
880 | .write = ftdi_write, | ||
881 | .write_room = ftdi_write_room, | ||
882 | .chars_in_buffer = ftdi_chars_in_buffer, | ||
883 | .read_bulk_callback = ftdi_read_bulk_callback, | ||
884 | .write_bulk_callback = ftdi_write_bulk_callback, | ||
885 | .tiocmget = ftdi_tiocmget, | ||
886 | .tiocmset = ftdi_tiocmset, | ||
887 | .ioctl = ftdi_ioctl, | ||
888 | .set_termios = ftdi_set_termios, | ||
889 | .break_ctl = ftdi_break_ctl, | ||
890 | .attach = ftdi_HE_TIRA1_startup, | ||
891 | .shutdown = ftdi_shutdown, | ||
892 | }; | ||
893 | |||
894 | |||
895 | 546 | ||
896 | #define WDR_TIMEOUT 5000 /* default urb timeout */ | 547 | #define WDR_TIMEOUT 5000 /* default urb timeout */ |
897 | 548 | ||
@@ -1212,6 +863,59 @@ check_and_exit: | |||
1212 | } /* set_serial_info */ | 863 | } /* set_serial_info */ |
1213 | 864 | ||
1214 | 865 | ||
866 | /* Determine type of FTDI chip based on USB config and descriptor. */ | ||
867 | static void ftdi_determine_type(struct usb_serial_port *port) | ||
868 | { | ||
869 | struct ftdi_private *priv = usb_get_serial_port_data(port); | ||
870 | struct usb_serial *serial = port->serial; | ||
871 | struct usb_device *udev = serial->dev; | ||
872 | unsigned version; | ||
873 | unsigned interfaces; | ||
874 | |||
875 | /* Assume it is not the original SIO device for now. */ | ||
876 | priv->baud_base = 48000000 / 16; | ||
877 | priv->write_offset = 0; | ||
878 | |||
879 | version = le16_to_cpu(udev->descriptor.bcdDevice); | ||
880 | interfaces = udev->actconfig->desc.bNumInterfaces; | ||
881 | dbg("%s: bcdDevice = 0x%x, bNumInterfaces = %u", __FUNCTION__, | ||
882 | version, interfaces); | ||
883 | if (interfaces > 1) { | ||
884 | int inter; | ||
885 | |||
886 | /* Multiple interfaces. Assume FT2232C. */ | ||
887 | priv->chip_type = FT2232C; | ||
888 | /* Determine interface code. */ | ||
889 | inter = serial->interface->altsetting->desc.bInterfaceNumber; | ||
890 | if (inter == 0) { | ||
891 | priv->interface = PIT_SIOA; | ||
892 | } else { | ||
893 | priv->interface = PIT_SIOB; | ||
894 | } | ||
895 | /* BM-type devices have a bug where bcdDevice gets set | ||
896 | * to 0x200 when iSerialNumber is 0. */ | ||
897 | if (version < 0x500) { | ||
898 | dbg("%s: something fishy - bcdDevice too low for multi-interface device", | ||
899 | __FUNCTION__); | ||
900 | } | ||
901 | } else if (version < 0x200) { | ||
902 | /* Old device. Assume its the original SIO. */ | ||
903 | priv->chip_type = SIO; | ||
904 | priv->baud_base = 12000000 / 16; | ||
905 | priv->write_offset = 1; | ||
906 | } else if (version < 0x400) { | ||
907 | /* Assume its an FT8U232AM (or FT8U245AM) */ | ||
908 | /* (It might be a BM because of the iSerialNumber bug, | ||
909 | * but it will still work as an AM device.) */ | ||
910 | priv->chip_type = FT8U232AM; | ||
911 | } else { | ||
912 | /* Assume its an FT232BM (or FT245BM) */ | ||
913 | priv->chip_type = FT232BM; | ||
914 | } | ||
915 | info("Detected %s", ftdi_chip_name[priv->chip_type]); | ||
916 | } | ||
917 | |||
918 | |||
1215 | /* | 919 | /* |
1216 | * *************************************************************************** | 920 | * *************************************************************************** |
1217 | * Sysfs Attribute | 921 | * Sysfs Attribute |
@@ -1355,12 +1059,20 @@ static void remove_sysfs_attrs(struct usb_serial *serial) | |||
1355 | * *************************************************************************** | 1059 | * *************************************************************************** |
1356 | */ | 1060 | */ |
1357 | 1061 | ||
1358 | /* Common startup subroutine */ | 1062 | /* Probe function to check for special devices */ |
1359 | /* Called from ftdi_SIO_startup, etc. */ | 1063 | static int ftdi_sio_probe (struct usb_serial *serial, const struct usb_device_id *id) |
1360 | static int ftdi_common_startup (struct usb_serial *serial) | 1064 | { |
1065 | usb_set_serial_data(serial, (void *)id->driver_info); | ||
1066 | |||
1067 | return (0); | ||
1068 | } | ||
1069 | |||
1070 | /* attach subroutine */ | ||
1071 | static int ftdi_sio_attach (struct usb_serial *serial) | ||
1361 | { | 1072 | { |
1362 | struct usb_serial_port *port = serial->port[0]; | 1073 | struct usb_serial_port *port = serial->port[0]; |
1363 | struct ftdi_private *priv; | 1074 | struct ftdi_private *priv; |
1075 | struct ftdi_sio_quirk *quirk; | ||
1364 | 1076 | ||
1365 | dbg("%s",__FUNCTION__); | 1077 | dbg("%s",__FUNCTION__); |
1366 | 1078 | ||
@@ -1400,150 +1112,49 @@ static int ftdi_common_startup (struct usb_serial *serial) | |||
1400 | port->bulk_out_buffer = NULL; | 1112 | port->bulk_out_buffer = NULL; |
1401 | 1113 | ||
1402 | usb_set_serial_port_data(serial->port[0], priv); | 1114 | usb_set_serial_port_data(serial->port[0], priv); |
1403 | |||
1404 | return (0); | ||
1405 | } | ||
1406 | |||
1407 | |||
1408 | /* Startup for the SIO chip */ | ||
1409 | /* Called from usbserial:serial_probe */ | ||
1410 | static int ftdi_SIO_startup (struct usb_serial *serial) | ||
1411 | { | ||
1412 | struct ftdi_private *priv; | ||
1413 | int err; | ||
1414 | |||
1415 | dbg("%s",__FUNCTION__); | ||
1416 | |||
1417 | err = ftdi_common_startup(serial); | ||
1418 | if (err){ | ||
1419 | return (err); | ||
1420 | } | ||
1421 | |||
1422 | priv = usb_get_serial_port_data(serial->port[0]); | ||
1423 | priv->chip_type = SIO; | ||
1424 | priv->baud_base = 12000000 / 16; | ||
1425 | priv->write_offset = 1; | ||
1426 | |||
1427 | return (0); | ||
1428 | } | ||
1429 | |||
1430 | /* Startup for the 8U232AM chip */ | ||
1431 | /* Called from usbserial:serial_probe */ | ||
1432 | static int ftdi_8U232AM_startup (struct usb_serial *serial) | ||
1433 | { /* ftdi_8U232AM_startup */ | ||
1434 | struct ftdi_private *priv; | ||
1435 | int err; | ||
1436 | |||
1437 | dbg("%s",__FUNCTION__); | ||
1438 | err = ftdi_common_startup(serial); | ||
1439 | if (err){ | ||
1440 | return (err); | ||
1441 | } | ||
1442 | 1115 | ||
1443 | priv = usb_get_serial_port_data(serial->port[0]); | 1116 | ftdi_determine_type (serial->port[0]); |
1444 | priv->chip_type = FT8U232AM; | ||
1445 | priv->baud_base = 48000000 / 2; /* Would be / 16, but FTDI supports 0.125, 0.25 and 0.5 divisor fractions! */ | ||
1446 | |||
1447 | create_sysfs_attrs(serial); | 1117 | create_sysfs_attrs(serial); |
1448 | |||
1449 | return (0); | ||
1450 | } /* ftdi_8U232AM_startup */ | ||
1451 | 1118 | ||
1452 | /* Startup for the FT232BM chip */ | 1119 | /* Check for device requiring special set up. */ |
1453 | /* Called from usbserial:serial_probe */ | 1120 | quirk = (struct ftdi_sio_quirk *)usb_get_serial_data(serial); |
1454 | static int ftdi_FT232BM_startup (struct usb_serial *serial) | 1121 | if (quirk && quirk->setup) { |
1455 | { /* ftdi_FT232BM_startup */ | 1122 | quirk->setup(serial); |
1456 | struct ftdi_private *priv; | ||
1457 | int err; | ||
1458 | |||
1459 | dbg("%s",__FUNCTION__); | ||
1460 | err = ftdi_common_startup(serial); | ||
1461 | if (err){ | ||
1462 | return (err); | ||
1463 | } | 1123 | } |
1464 | |||
1465 | priv = usb_get_serial_port_data(serial->port[0]); | ||
1466 | priv->chip_type = FT232BM; | ||
1467 | priv->baud_base = 48000000 / 2; /* Would be / 16, but FT232BM supports multiple of 0.125 divisor fractions! */ | ||
1468 | 1124 | ||
1469 | create_sysfs_attrs(serial); | ||
1470 | |||
1471 | return (0); | 1125 | return (0); |
1472 | } /* ftdi_FT232BM_startup */ | 1126 | } /* ftdi_sio_attach */ |
1473 | |||
1474 | /* Startup for the FT2232C chip */ | ||
1475 | /* Called from usbserial:serial_probe */ | ||
1476 | static int ftdi_FT2232C_startup (struct usb_serial *serial) | ||
1477 | { /* ftdi_FT2232C_startup */ | ||
1478 | struct ftdi_private *priv; | ||
1479 | int err; | ||
1480 | int inter; | ||
1481 | |||
1482 | dbg("%s",__FUNCTION__); | ||
1483 | err = ftdi_common_startup(serial); | ||
1484 | if (err){ | ||
1485 | return (err); | ||
1486 | } | ||
1487 | 1127 | ||
1488 | priv = usb_get_serial_port_data(serial->port[0]); | ||
1489 | priv->chip_type = FT2232C; | ||
1490 | inter = serial->interface->altsetting->desc.bInterfaceNumber; | ||
1491 | 1128 | ||
1492 | if (inter) { | 1129 | /* Setup for the USB-UIRT device, which requires hardwired |
1493 | priv->interface = PIT_SIOB; | 1130 | * baudrate (38400 gets mapped to 312500) */ |
1494 | } | ||
1495 | else { | ||
1496 | priv->interface = PIT_SIOA; | ||
1497 | } | ||
1498 | priv->baud_base = 48000000 / 2; /* Would be / 16, but FT2232C supports multiple of 0.125 divisor fractions! */ | ||
1499 | |||
1500 | create_sysfs_attrs(serial); | ||
1501 | |||
1502 | return (0); | ||
1503 | } /* ftdi_FT2232C_startup */ | ||
1504 | |||
1505 | /* Startup for the USB-UIRT device, which requires hardwired baudrate (38400 gets mapped to 312500) */ | ||
1506 | /* Called from usbserial:serial_probe */ | 1131 | /* Called from usbserial:serial_probe */ |
1507 | static int ftdi_USB_UIRT_startup (struct usb_serial *serial) | 1132 | static void ftdi_USB_UIRT_setup (struct usb_serial *serial) |
1508 | { /* ftdi_USB_UIRT_startup */ | 1133 | { |
1509 | struct ftdi_private *priv; | 1134 | struct ftdi_private *priv; |
1510 | int err; | ||
1511 | 1135 | ||
1512 | dbg("%s",__FUNCTION__); | 1136 | dbg("%s",__FUNCTION__); |
1513 | err = ftdi_8U232AM_startup(serial); | ||
1514 | if (err){ | ||
1515 | return (err); | ||
1516 | } | ||
1517 | 1137 | ||
1518 | priv = usb_get_serial_port_data(serial->port[0]); | 1138 | priv = usb_get_serial_port_data(serial->port[0]); |
1519 | priv->flags |= ASYNC_SPD_CUST; | 1139 | priv->flags |= ASYNC_SPD_CUST; |
1520 | priv->custom_divisor = 77; | 1140 | priv->custom_divisor = 77; |
1521 | priv->force_baud = B38400; | 1141 | priv->force_baud = B38400; |
1522 | 1142 | } /* ftdi_USB_UIRT_setup */ | |
1523 | return (0); | ||
1524 | } /* ftdi_USB_UIRT_startup */ | ||
1525 | 1143 | ||
1526 | /* Startup for the HE-TIRA1 device, which requires hardwired | 1144 | /* Setup for the HE-TIRA1 device, which requires hardwired |
1527 | * baudrate (38400 gets mapped to 100000) */ | 1145 | * baudrate (38400 gets mapped to 100000) and RTS-CTS enabled. */ |
1528 | static int ftdi_HE_TIRA1_startup (struct usb_serial *serial) | 1146 | static void ftdi_HE_TIRA1_setup (struct usb_serial *serial) |
1529 | { /* ftdi_HE_TIRA1_startup */ | 1147 | { |
1530 | struct ftdi_private *priv; | 1148 | struct ftdi_private *priv; |
1531 | int err; | ||
1532 | 1149 | ||
1533 | dbg("%s",__FUNCTION__); | 1150 | dbg("%s",__FUNCTION__); |
1534 | err = ftdi_FT232BM_startup(serial); | ||
1535 | if (err){ | ||
1536 | return (err); | ||
1537 | } | ||
1538 | 1151 | ||
1539 | priv = usb_get_serial_port_data(serial->port[0]); | 1152 | priv = usb_get_serial_port_data(serial->port[0]); |
1540 | priv->flags |= ASYNC_SPD_CUST; | 1153 | priv->flags |= ASYNC_SPD_CUST; |
1541 | priv->custom_divisor = 240; | 1154 | priv->custom_divisor = 240; |
1542 | priv->force_baud = B38400; | 1155 | priv->force_baud = B38400; |
1543 | priv->force_rtscts = 1; | 1156 | priv->force_rtscts = 1; |
1544 | 1157 | } /* ftdi_HE_TIRA1_setup */ | |
1545 | return (0); | ||
1546 | } /* ftdi_HE_TIRA1_startup */ | ||
1547 | 1158 | ||
1548 | 1159 | ||
1549 | /* ftdi_shutdown is called from usbserial:usb_serial_disconnect | 1160 | /* ftdi_shutdown is called from usbserial:usb_serial_disconnect |
@@ -2367,60 +1978,11 @@ static int ftdi_ioctl (struct usb_serial_port *port, struct file * file, unsigne | |||
2367 | { | 1978 | { |
2368 | struct ftdi_private *priv = usb_get_serial_port_data(port); | 1979 | struct ftdi_private *priv = usb_get_serial_port_data(port); |
2369 | 1980 | ||
2370 | int ret, mask; | ||
2371 | |||
2372 | dbg("%s cmd 0x%04x", __FUNCTION__, cmd); | 1981 | dbg("%s cmd 0x%04x", __FUNCTION__, cmd); |
2373 | 1982 | ||
2374 | /* Based on code from acm.c and others */ | 1983 | /* Based on code from acm.c and others */ |
2375 | switch (cmd) { | 1984 | switch (cmd) { |
2376 | 1985 | ||
2377 | case TIOCMBIS: /* turns on (Sets) the lines as specified by the mask */ | ||
2378 | dbg("%s TIOCMBIS", __FUNCTION__); | ||
2379 | if (get_user(mask, (unsigned long __user *) arg)) | ||
2380 | return -EFAULT; | ||
2381 | if (mask & TIOCM_DTR){ | ||
2382 | if ((ret = set_dtr(port, HIGH)) < 0) { | ||
2383 | err("Urb to set DTR failed"); | ||
2384 | return(ret); | ||
2385 | } | ||
2386 | } | ||
2387 | if (mask & TIOCM_RTS) { | ||
2388 | if ((ret = set_rts(port, HIGH)) < 0){ | ||
2389 | err("Urb to set RTS failed"); | ||
2390 | return(ret); | ||
2391 | } | ||
2392 | } | ||
2393 | return(0); | ||
2394 | break; | ||
2395 | |||
2396 | case TIOCMBIC: /* turns off (Clears) the lines as specified by the mask */ | ||
2397 | dbg("%s TIOCMBIC", __FUNCTION__); | ||
2398 | if (get_user(mask, (unsigned long __user *) arg)) | ||
2399 | return -EFAULT; | ||
2400 | if (mask & TIOCM_DTR){ | ||
2401 | if ((ret = set_dtr(port, LOW)) < 0){ | ||
2402 | err("Urb to unset DTR failed"); | ||
2403 | return(ret); | ||
2404 | } | ||
2405 | } | ||
2406 | if (mask & TIOCM_RTS) { | ||
2407 | if ((ret = set_rts(port, LOW)) < 0){ | ||
2408 | err("Urb to unset RTS failed"); | ||
2409 | return(ret); | ||
2410 | } | ||
2411 | } | ||
2412 | return(0); | ||
2413 | break; | ||
2414 | |||
2415 | /* | ||
2416 | * I had originally implemented TCSET{A,S}{,F,W} and | ||
2417 | * TCGET{A,S} here separately, however when testing I | ||
2418 | * found that the higher layers actually do the termios | ||
2419 | * conversions themselves and pass the call onto | ||
2420 | * ftdi_sio_set_termios. | ||
2421 | * | ||
2422 | */ | ||
2423 | |||
2424 | case TIOCGSERIAL: /* gets serial port data */ | 1986 | case TIOCGSERIAL: /* gets serial port data */ |
2425 | return get_serial_info(port, (struct serial_struct __user *) arg); | 1987 | return get_serial_info(port, (struct serial_struct __user *) arg); |
2426 | 1988 | ||
@@ -2516,24 +2078,9 @@ static int __init ftdi_init (void) | |||
2516 | int retval; | 2078 | int retval; |
2517 | 2079 | ||
2518 | dbg("%s", __FUNCTION__); | 2080 | dbg("%s", __FUNCTION__); |
2519 | retval = usb_serial_register(&ftdi_SIO_device); | 2081 | retval = usb_serial_register(&ftdi_sio_device); |
2520 | if (retval) | ||
2521 | goto failed_SIO_register; | ||
2522 | retval = usb_serial_register(&ftdi_8U232AM_device); | ||
2523 | if (retval) | ||
2524 | goto failed_8U232AM_register; | ||
2525 | retval = usb_serial_register(&ftdi_FT232BM_device); | ||
2526 | if (retval) | ||
2527 | goto failed_FT232BM_register; | ||
2528 | retval = usb_serial_register(&ftdi_FT2232C_device); | ||
2529 | if (retval) | ||
2530 | goto failed_FT2232C_register; | ||
2531 | retval = usb_serial_register(&ftdi_USB_UIRT_device); | ||
2532 | if (retval) | ||
2533 | goto failed_USB_UIRT_register; | ||
2534 | retval = usb_serial_register(&ftdi_HE_TIRA1_device); | ||
2535 | if (retval) | 2082 | if (retval) |
2536 | goto failed_HE_TIRA1_register; | 2083 | goto failed_sio_register; |
2537 | retval = usb_register(&ftdi_driver); | 2084 | retval = usb_register(&ftdi_driver); |
2538 | if (retval) | 2085 | if (retval) |
2539 | goto failed_usb_register; | 2086 | goto failed_usb_register; |
@@ -2541,18 +2088,8 @@ static int __init ftdi_init (void) | |||
2541 | info(DRIVER_VERSION ":" DRIVER_DESC); | 2088 | info(DRIVER_VERSION ":" DRIVER_DESC); |
2542 | return 0; | 2089 | return 0; |
2543 | failed_usb_register: | 2090 | failed_usb_register: |
2544 | usb_serial_deregister(&ftdi_HE_TIRA1_device); | 2091 | usb_serial_deregister(&ftdi_sio_device); |
2545 | failed_HE_TIRA1_register: | 2092 | failed_sio_register: |
2546 | usb_serial_deregister(&ftdi_USB_UIRT_device); | ||
2547 | failed_USB_UIRT_register: | ||
2548 | usb_serial_deregister(&ftdi_FT2232C_device); | ||
2549 | failed_FT2232C_register: | ||
2550 | usb_serial_deregister(&ftdi_FT232BM_device); | ||
2551 | failed_FT232BM_register: | ||
2552 | usb_serial_deregister(&ftdi_8U232AM_device); | ||
2553 | failed_8U232AM_register: | ||
2554 | usb_serial_deregister(&ftdi_SIO_device); | ||
2555 | failed_SIO_register: | ||
2556 | return retval; | 2093 | return retval; |
2557 | } | 2094 | } |
2558 | 2095 | ||
@@ -2563,12 +2100,7 @@ static void __exit ftdi_exit (void) | |||
2563 | dbg("%s", __FUNCTION__); | 2100 | dbg("%s", __FUNCTION__); |
2564 | 2101 | ||
2565 | usb_deregister (&ftdi_driver); | 2102 | usb_deregister (&ftdi_driver); |
2566 | usb_serial_deregister (&ftdi_HE_TIRA1_device); | 2103 | usb_serial_deregister (&ftdi_sio_device); |
2567 | usb_serial_deregister (&ftdi_USB_UIRT_device); | ||
2568 | usb_serial_deregister (&ftdi_FT2232C_device); | ||
2569 | usb_serial_deregister (&ftdi_FT232BM_device); | ||
2570 | usb_serial_deregister (&ftdi_8U232AM_device); | ||
2571 | usb_serial_deregister (&ftdi_SIO_device); | ||
2572 | 2104 | ||
2573 | } | 2105 | } |
2574 | 2106 | ||
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 9fcc7bd1fbe4..bd0ab3039bdd 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -697,7 +697,7 @@ UNUSUAL_DEV( 0x07af, 0x0004, 0x0100, 0x0133, | |||
697 | UNUSUAL_DEV( 0x07af, 0x0005, 0x0100, 0x0100, | 697 | UNUSUAL_DEV( 0x07af, 0x0005, 0x0100, 0x0100, |
698 | "Microtech", | 698 | "Microtech", |
699 | "USB-SCSI-HD50", | 699 | "USB-SCSI-HD50", |
700 | US_SC_SCSI, US_PR_BULK, usb_stor_euscsi_init, | 700 | US_SC_DEVICE, US_PR_DEVICE, usb_stor_euscsi_init, |
701 | US_FL_SCM_MULT_TARG ), | 701 | US_FL_SCM_MULT_TARG ), |
702 | 702 | ||
703 | #ifdef CONFIG_USB_STORAGE_DPCM | 703 | #ifdef CONFIG_USB_STORAGE_DPCM |