diff options
Diffstat (limited to 'drivers/usb')
144 files changed, 13936 insertions, 5896 deletions
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index 7dd73546bf4..7580aa5da0f 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
@@ -6,6 +6,9 @@ menuconfig USB_SUPPORT | |||
6 | bool "USB support" | 6 | bool "USB support" |
7 | depends on HAS_IOMEM | 7 | depends on HAS_IOMEM |
8 | default y | 8 | default y |
9 | ---help--- | ||
10 | This option adds core support for Universal Serial Bus (USB). | ||
11 | You will also need drivers from the following menu to make use of it. | ||
9 | 12 | ||
10 | if USB_SUPPORT | 13 | if USB_SUPPORT |
11 | 14 | ||
@@ -18,6 +21,7 @@ config USB_ARCH_HAS_HCD | |||
18 | default y if USB_ARCH_HAS_EHCI | 21 | default y if USB_ARCH_HAS_EHCI |
19 | default y if PCMCIA && !M32R # sl811_cs | 22 | default y if PCMCIA && !M32R # sl811_cs |
20 | default y if ARM # SL-811 | 23 | default y if ARM # SL-811 |
24 | default y if SUPERH # r8a66597-hcd | ||
21 | default PCI | 25 | default PCI |
22 | 26 | ||
23 | # many non-PCI SOC chips embed OHCI | 27 | # many non-PCI SOC chips embed OHCI |
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile index befff5f9d58..516a6400db4 100644 --- a/drivers/usb/Makefile +++ b/drivers/usb/Makefile | |||
@@ -28,26 +28,7 @@ obj-$(CONFIG_USB_MICROTEK) += image/ | |||
28 | 28 | ||
29 | obj-$(CONFIG_USB_SERIAL) += serial/ | 29 | obj-$(CONFIG_USB_SERIAL) += serial/ |
30 | 30 | ||
31 | obj-$(CONFIG_USB_ADUTUX) += misc/ | 31 | obj-$(CONFIG_USB) += misc/ |
32 | obj-$(CONFIG_USB_APPLEDISPLAY) += misc/ | ||
33 | obj-$(CONFIG_USB_AUERSWALD) += misc/ | ||
34 | obj-$(CONFIG_USB_BERRY_CHARGE) += misc/ | ||
35 | obj-$(CONFIG_USB_CYPRESS_CY7C63)+= misc/ | ||
36 | obj-$(CONFIG_USB_CYTHERM) += misc/ | ||
37 | obj-$(CONFIG_USB_EMI26) += misc/ | ||
38 | obj-$(CONFIG_USB_EMI62) += misc/ | ||
39 | obj-$(CONFIG_USB_FTDI_ELAN) += misc/ | ||
40 | obj-$(CONFIG_USB_IDMOUSE) += misc/ | ||
41 | obj-$(CONFIG_USB_LCD) += misc/ | ||
42 | obj-$(CONFIG_USB_LD) += misc/ | ||
43 | obj-$(CONFIG_USB_LED) += misc/ | ||
44 | obj-$(CONFIG_USB_LEGOTOWER) += misc/ | ||
45 | obj-$(CONFIG_USB_PHIDGETSERVO) += misc/ | ||
46 | obj-$(CONFIG_USB_RIO500) += misc/ | ||
47 | obj-$(CONFIG_USB_SISUSBVGA) += misc/ | ||
48 | obj-$(CONFIG_USB_TEST) += misc/ | ||
49 | obj-$(CONFIG_USB_TRANCEVIBRATOR)+= misc/ | ||
50 | obj-$(CONFIG_USB_USS720) += misc/ | ||
51 | 32 | ||
52 | obj-$(CONFIG_USB_ATM) += atm/ | 33 | obj-$(CONFIG_USB_ATM) += atm/ |
53 | obj-$(CONFIG_USB_SPEEDTOUCH) += atm/ | 34 | obj-$(CONFIG_USB_SPEEDTOUCH) += atm/ |
diff --git a/drivers/usb/atm/cxacru.c b/drivers/usb/atm/cxacru.c index 1bc884051e0..a51eeedc18d 100644 --- a/drivers/usb/atm/cxacru.c +++ b/drivers/usb/atm/cxacru.c | |||
@@ -456,7 +456,6 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done, | |||
456 | int* actual_length) | 456 | int* actual_length) |
457 | { | 457 | { |
458 | struct timer_list timer; | 458 | struct timer_list timer; |
459 | int status; | ||
460 | 459 | ||
461 | init_timer(&timer); | 460 | init_timer(&timer); |
462 | timer.expires = jiffies + msecs_to_jiffies(CMD_TIMEOUT); | 461 | timer.expires = jiffies + msecs_to_jiffies(CMD_TIMEOUT); |
@@ -464,12 +463,11 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done, | |||
464 | timer.function = cxacru_timeout_kill; | 463 | timer.function = cxacru_timeout_kill; |
465 | add_timer(&timer); | 464 | add_timer(&timer); |
466 | wait_for_completion(done); | 465 | wait_for_completion(done); |
467 | status = urb->status; | ||
468 | del_timer_sync(&timer); | 466 | del_timer_sync(&timer); |
469 | 467 | ||
470 | if (actual_length) | 468 | if (actual_length) |
471 | *actual_length = urb->actual_length; | 469 | *actual_length = urb->actual_length; |
472 | return status; | 470 | return urb->status; /* must read status after completion */ |
473 | } | 471 | } |
474 | 472 | ||
475 | static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, | 473 | static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, |
@@ -484,7 +482,9 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, | |||
484 | int rbuflen = ((rsize - 1) / stride + 1) * CMD_PACKET_SIZE; | 482 | int rbuflen = ((rsize - 1) / stride + 1) * CMD_PACKET_SIZE; |
485 | 483 | ||
486 | if (wbuflen > PAGE_SIZE || rbuflen > PAGE_SIZE) { | 484 | if (wbuflen > PAGE_SIZE || rbuflen > PAGE_SIZE) { |
487 | dbg("too big transfer requested"); | 485 | if (printk_ratelimit()) |
486 | usb_err(instance->usbatm, "requested transfer size too large (%d, %d)\n", | ||
487 | wbuflen, rbuflen); | ||
488 | ret = -ENOMEM; | 488 | ret = -ENOMEM; |
489 | goto fail; | 489 | goto fail; |
490 | } | 490 | } |
@@ -495,8 +495,9 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, | |||
495 | init_completion(&instance->rcv_done); | 495 | init_completion(&instance->rcv_done); |
496 | ret = usb_submit_urb(instance->rcv_urb, GFP_KERNEL); | 496 | ret = usb_submit_urb(instance->rcv_urb, GFP_KERNEL); |
497 | if (ret < 0) { | 497 | if (ret < 0) { |
498 | dbg("submitting read urb for cm %#x failed", cm); | 498 | if (printk_ratelimit()) |
499 | ret = ret; | 499 | usb_err(instance->usbatm, "submit of read urb for cm %#x failed (%d)\n", |
500 | cm, ret); | ||
500 | goto fail; | 501 | goto fail; |
501 | } | 502 | } |
502 | 503 | ||
@@ -512,27 +513,29 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, | |||
512 | init_completion(&instance->snd_done); | 513 | init_completion(&instance->snd_done); |
513 | ret = usb_submit_urb(instance->snd_urb, GFP_KERNEL); | 514 | ret = usb_submit_urb(instance->snd_urb, GFP_KERNEL); |
514 | if (ret < 0) { | 515 | if (ret < 0) { |
515 | dbg("submitting write urb for cm %#x failed", cm); | 516 | if (printk_ratelimit()) |
516 | ret = ret; | 517 | usb_err(instance->usbatm, "submit of write urb for cm %#x failed (%d)\n", |
518 | cm, ret); | ||
517 | goto fail; | 519 | goto fail; |
518 | } | 520 | } |
519 | 521 | ||
520 | ret = cxacru_start_wait_urb(instance->snd_urb, &instance->snd_done, NULL); | 522 | ret = cxacru_start_wait_urb(instance->snd_urb, &instance->snd_done, NULL); |
521 | if (ret < 0) { | 523 | if (ret < 0) { |
522 | dbg("sending cm %#x failed", cm); | 524 | if (printk_ratelimit()) |
523 | ret = ret; | 525 | usb_err(instance->usbatm, "send of cm %#x failed (%d)\n", cm, ret); |
524 | goto fail; | 526 | goto fail; |
525 | } | 527 | } |
526 | 528 | ||
527 | ret = cxacru_start_wait_urb(instance->rcv_urb, &instance->rcv_done, &actlen); | 529 | ret = cxacru_start_wait_urb(instance->rcv_urb, &instance->rcv_done, &actlen); |
528 | if (ret < 0) { | 530 | if (ret < 0) { |
529 | dbg("receiving cm %#x failed", cm); | 531 | if (printk_ratelimit()) |
530 | ret = ret; | 532 | usb_err(instance->usbatm, "receive of cm %#x failed (%d)\n", cm, ret); |
531 | goto fail; | 533 | goto fail; |
532 | } | 534 | } |
533 | if (actlen % CMD_PACKET_SIZE || !actlen) { | 535 | if (actlen % CMD_PACKET_SIZE || !actlen) { |
534 | dbg("response is not a positive multiple of %d: %#x", | 536 | if (printk_ratelimit()) |
535 | CMD_PACKET_SIZE, actlen); | 537 | usb_err(instance->usbatm, "invalid response length to cm %#x: %d\n", |
538 | cm, actlen); | ||
536 | ret = -EIO; | 539 | ret = -EIO; |
537 | goto fail; | 540 | goto fail; |
538 | } | 541 | } |
@@ -540,12 +543,16 @@ static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm, | |||
540 | /* check the return status and copy the data to the output buffer, if needed */ | 543 | /* check the return status and copy the data to the output buffer, if needed */ |
541 | for (offb = offd = 0; offd < rsize && offb < actlen; offb += CMD_PACKET_SIZE) { | 544 | for (offb = offd = 0; offd < rsize && offb < actlen; offb += CMD_PACKET_SIZE) { |
542 | if (rbuf[offb] != cm) { | 545 | if (rbuf[offb] != cm) { |
543 | dbg("wrong cm %#x in response", rbuf[offb]); | 546 | if (printk_ratelimit()) |
547 | usb_err(instance->usbatm, "wrong cm %#x in response to cm %#x\n", | ||
548 | rbuf[offb], cm); | ||
544 | ret = -EIO; | 549 | ret = -EIO; |
545 | goto fail; | 550 | goto fail; |
546 | } | 551 | } |
547 | if (rbuf[offb + 1] != CM_STATUS_SUCCESS) { | 552 | if (rbuf[offb + 1] != CM_STATUS_SUCCESS) { |
548 | dbg("response failed: %#x", rbuf[offb + 1]); | 553 | if (printk_ratelimit()) |
554 | usb_err(instance->usbatm, "response to cm %#x failed: %#x\n", | ||
555 | cm, rbuf[offb + 1]); | ||
549 | ret = -EIO; | 556 | ret = -EIO; |
550 | goto fail; | 557 | goto fail; |
551 | } | 558 | } |
@@ -584,14 +591,18 @@ static int cxacru_cm_get_array(struct cxacru_data *instance, enum cxacru_cm_requ | |||
584 | for (offb = 0; offb < len; ) { | 591 | for (offb = 0; offb < len; ) { |
585 | int l = le32_to_cpu(buf[offb++]); | 592 | int l = le32_to_cpu(buf[offb++]); |
586 | if (l > stride || l > (len - offb) / 2) { | 593 | if (l > stride || l > (len - offb) / 2) { |
587 | dbg("wrong data length %#x in response", l); | 594 | if (printk_ratelimit()) |
595 | usb_err(instance->usbatm, "invalid data length from cm %#x: %d\n", | ||
596 | cm, l); | ||
588 | ret = -EIO; | 597 | ret = -EIO; |
589 | goto cleanup; | 598 | goto cleanup; |
590 | } | 599 | } |
591 | while (l--) { | 600 | while (l--) { |
592 | offd = le32_to_cpu(buf[offb++]); | 601 | offd = le32_to_cpu(buf[offb++]); |
593 | if (offd >= size) { | 602 | if (offd >= size) { |
594 | dbg("wrong index %#x in response", offd); | 603 | if (printk_ratelimit()) |
604 | usb_err(instance->usbatm, "wrong index #%x in response to cm #%x\n", | ||
605 | offd, cm); | ||
595 | ret = -EIO; | 606 | ret = -EIO; |
596 | goto cleanup; | 607 | goto cleanup; |
597 | } | 608 | } |
diff --git a/drivers/usb/atm/speedtch.c b/drivers/usb/atm/speedtch.c index 638b8009b3b..8b132c4a503 100644 --- a/drivers/usb/atm/speedtch.c +++ b/drivers/usb/atm/speedtch.c | |||
@@ -251,7 +251,6 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance, | |||
251 | { | 251 | { |
252 | unsigned char *buffer; | 252 | unsigned char *buffer; |
253 | struct usbatm_data *usbatm = instance->usbatm; | 253 | struct usbatm_data *usbatm = instance->usbatm; |
254 | struct usb_interface *intf; | ||
255 | struct usb_device *usb_dev = usbatm->usb_dev; | 254 | struct usb_device *usb_dev = usbatm->usb_dev; |
256 | int actual_length; | 255 | int actual_length; |
257 | int ret = 0; | 256 | int ret = 0; |
@@ -265,7 +264,7 @@ static int speedtch_upload_firmware(struct speedtch_instance_data *instance, | |||
265 | goto out; | 264 | goto out; |
266 | } | 265 | } |
267 | 266 | ||
268 | if (!(intf = usb_ifnum_to_if(usb_dev, 2))) { | 267 | if (!usb_ifnum_to_if(usb_dev, 2)) { |
269 | ret = -ENODEV; | 268 | ret = -ENODEV; |
270 | usb_dbg(usbatm, "%s: interface not found!\n", __func__); | 269 | usb_dbg(usbatm, "%s: interface not found!\n", __func__); |
271 | goto out_free; | 270 | goto out_free; |
@@ -612,7 +611,8 @@ static void speedtch_handle_int(struct urb *int_urb) | |||
612 | struct speedtch_instance_data *instance = int_urb->context; | 611 | struct speedtch_instance_data *instance = int_urb->context; |
613 | struct usbatm_data *usbatm = instance->usbatm; | 612 | struct usbatm_data *usbatm = instance->usbatm; |
614 | unsigned int count = int_urb->actual_length; | 613 | unsigned int count = int_urb->actual_length; |
615 | int ret = int_urb->status; | 614 | int status = int_urb->status; |
615 | int ret; | ||
616 | 616 | ||
617 | /* The magic interrupt for "up state" */ | 617 | /* The magic interrupt for "up state" */ |
618 | static const unsigned char up_int[6] = { 0xa1, 0x00, 0x01, 0x00, 0x00, 0x00 }; | 618 | static const unsigned char up_int[6] = { 0xa1, 0x00, 0x01, 0x00, 0x00, 0x00 }; |
@@ -621,8 +621,8 @@ static void speedtch_handle_int(struct urb *int_urb) | |||
621 | 621 | ||
622 | atm_dbg(usbatm, "%s entered\n", __func__); | 622 | atm_dbg(usbatm, "%s entered\n", __func__); |
623 | 623 | ||
624 | if (ret < 0) { | 624 | if (status < 0) { |
625 | atm_dbg(usbatm, "%s: nonzero urb status %d!\n", __func__, ret); | 625 | atm_dbg(usbatm, "%s: nonzero urb status %d!\n", __func__, status); |
626 | goto fail; | 626 | goto fail; |
627 | } | 627 | } |
628 | 628 | ||
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index 8f046659b4e..389c5b164eb 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c | |||
@@ -2,7 +2,8 @@ | |||
2 | * Copyright (c) 2003, 2004 | 2 | * Copyright (c) 2003, 2004 |
3 | * Damien Bergamini <damien.bergamini@free.fr>. All rights reserved. | 3 | * Damien Bergamini <damien.bergamini@free.fr>. All rights reserved. |
4 | * | 4 | * |
5 | * Copyright (c) 2005 Matthieu Castet <castet.matthieu@free.fr> | 5 | * Copyright (c) 2005-2007 Matthieu Castet <castet.matthieu@free.fr> |
6 | * Copyright (c) 2005-2007 Stanislaw Gruszka <stf_xl@wp.pl> | ||
6 | * | 7 | * |
7 | * This software is available to you under a choice of one of two | 8 | * This software is available to you under a choice of one of two |
8 | * licenses. You may choose to be licensed under the terms of the GNU | 9 | * licenses. You may choose to be licensed under the terms of the GNU |
@@ -107,18 +108,51 @@ | |||
107 | #define uea_info(usb_dev, format,args...) \ | 108 | #define uea_info(usb_dev, format,args...) \ |
108 | dev_info(&(usb_dev)->dev ,"[ueagle-atm] " format, ##args) | 109 | dev_info(&(usb_dev)->dev ,"[ueagle-atm] " format, ##args) |
109 | 110 | ||
110 | struct uea_cmvs { | 111 | struct intr_pkt; |
112 | |||
113 | /* cmv's from firmware */ | ||
114 | struct uea_cmvs_v1 { | ||
111 | u32 address; | 115 | u32 address; |
112 | u16 offset; | 116 | u16 offset; |
113 | u32 data; | 117 | u32 data; |
114 | } __attribute__ ((packed)); | 118 | } __attribute__ ((packed)); |
115 | 119 | ||
120 | struct uea_cmvs_v2 { | ||
121 | u32 group; | ||
122 | u32 address; | ||
123 | u32 offset; | ||
124 | u32 data; | ||
125 | } __attribute__ ((packed)); | ||
126 | |||
127 | /* information about currently processed cmv */ | ||
128 | struct cmv_dsc_e1 { | ||
129 | u8 function; | ||
130 | u16 idx; | ||
131 | u32 address; | ||
132 | u16 offset; | ||
133 | }; | ||
134 | |||
135 | struct cmv_dsc_e4 { | ||
136 | u16 function; | ||
137 | u16 offset; | ||
138 | u16 address; | ||
139 | u16 group; | ||
140 | }; | ||
141 | |||
142 | union cmv_dsc { | ||
143 | struct cmv_dsc_e1 e1; | ||
144 | struct cmv_dsc_e4 e4; | ||
145 | }; | ||
146 | |||
116 | struct uea_softc { | 147 | struct uea_softc { |
117 | struct usb_device *usb_dev; | 148 | struct usb_device *usb_dev; |
118 | struct usbatm_data *usbatm; | 149 | struct usbatm_data *usbatm; |
119 | 150 | ||
120 | int modem_index; | 151 | int modem_index; |
121 | unsigned int driver_info; | 152 | unsigned int driver_info; |
153 | int annex; | ||
154 | #define ANNEXA 0 | ||
155 | #define ANNEXB 1 | ||
122 | 156 | ||
123 | int booting; | 157 | int booting; |
124 | int reset; | 158 | int reset; |
@@ -127,20 +161,23 @@ struct uea_softc { | |||
127 | 161 | ||
128 | struct task_struct *kthread; | 162 | struct task_struct *kthread; |
129 | u32 data; | 163 | u32 data; |
130 | wait_queue_head_t cmv_ack_wait; | 164 | u32 data1; |
165 | |||
131 | int cmv_ack; | 166 | int cmv_ack; |
167 | union cmv_dsc cmv_dsc; | ||
132 | 168 | ||
133 | struct work_struct task; | 169 | struct work_struct task; |
170 | struct workqueue_struct *work_q; | ||
134 | u16 pageno; | 171 | u16 pageno; |
135 | u16 ovl; | 172 | u16 ovl; |
136 | 173 | ||
137 | const struct firmware *dsp_firm; | 174 | const struct firmware *dsp_firm; |
138 | struct urb *urb_int; | 175 | struct urb *urb_int; |
139 | 176 | ||
140 | u8 cmv_function; | 177 | void (*dispatch_cmv) (struct uea_softc *, struct intr_pkt *); |
141 | u16 cmv_idx; | 178 | void (*schedule_load_page) (struct uea_softc *, struct intr_pkt *); |
142 | u32 cmv_address; | 179 | int (*stat) (struct uea_softc *); |
143 | u16 cmv_offset; | 180 | int (*send_cmvs) (struct uea_softc *); |
144 | 181 | ||
145 | /* keep in sync with eaglectl */ | 182 | /* keep in sync with eaglectl */ |
146 | struct uea_stats { | 183 | struct uea_stats { |
@@ -174,10 +211,34 @@ struct uea_softc { | |||
174 | #define ELSA_PID_PSTFIRM 0x3350 | 211 | #define ELSA_PID_PSTFIRM 0x3350 |
175 | #define ELSA_PID_PREFIRM 0x3351 | 212 | #define ELSA_PID_PREFIRM 0x3351 |
176 | 213 | ||
214 | #define ELSA_PID_A_PREFIRM 0x3352 | ||
215 | #define ELSA_PID_A_PSTFIRM 0x3353 | ||
216 | #define ELSA_PID_B_PREFIRM 0x3362 | ||
217 | #define ELSA_PID_B_PSTFIRM 0x3363 | ||
218 | |||
177 | /* | 219 | /* |
178 | * Sagem USB IDs | 220 | * Devolo IDs : pots if (pid & 0x10) |
179 | */ | 221 | */ |
180 | #define EAGLE_VID 0x1110 | 222 | #define DEVOLO_VID 0x1039 |
223 | #define DEVOLO_EAGLE_I_A_PID_PSTFIRM 0x2110 | ||
224 | #define DEVOLO_EAGLE_I_A_PID_PREFIRM 0x2111 | ||
225 | |||
226 | #define DEVOLO_EAGLE_I_B_PID_PSTFIRM 0x2100 | ||
227 | #define DEVOLO_EAGLE_I_B_PID_PREFIRM 0x2101 | ||
228 | |||
229 | #define DEVOLO_EAGLE_II_A_PID_PSTFIRM 0x2130 | ||
230 | #define DEVOLO_EAGLE_II_A_PID_PREFIRM 0x2131 | ||
231 | |||
232 | #define DEVOLO_EAGLE_II_B_PID_PSTFIRM 0x2120 | ||
233 | #define DEVOLO_EAGLE_II_B_PID_PREFIRM 0x2121 | ||
234 | |||
235 | /* | ||
236 | * Reference design USB IDs | ||
237 | */ | ||
238 | #define ANALOG_VID 0x1110 | ||
239 | #define ADI930_PID_PREFIRM 0x9001 | ||
240 | #define ADI930_PID_PSTFIRM 0x9000 | ||
241 | |||
181 | #define EAGLE_I_PID_PREFIRM 0x9010 /* Eagle I */ | 242 | #define EAGLE_I_PID_PREFIRM 0x9010 /* Eagle I */ |
182 | #define EAGLE_I_PID_PSTFIRM 0x900F /* Eagle I */ | 243 | #define EAGLE_I_PID_PSTFIRM 0x900F /* Eagle I */ |
183 | 244 | ||
@@ -187,12 +248,12 @@ struct uea_softc { | |||
187 | #define EAGLE_II_PID_PREFIRM 0x9022 /* Eagle II */ | 248 | #define EAGLE_II_PID_PREFIRM 0x9022 /* Eagle II */ |
188 | #define EAGLE_II_PID_PSTFIRM 0x9021 /* Eagle II */ | 249 | #define EAGLE_II_PID_PSTFIRM 0x9021 /* Eagle II */ |
189 | 250 | ||
190 | /* | ||
191 | * Eagle III Pid | ||
192 | */ | ||
193 | #define EAGLE_III_PID_PREFIRM 0x9032 /* Eagle III */ | 251 | #define EAGLE_III_PID_PREFIRM 0x9032 /* Eagle III */ |
194 | #define EAGLE_III_PID_PSTFIRM 0x9031 /* Eagle III */ | 252 | #define EAGLE_III_PID_PSTFIRM 0x9031 /* Eagle III */ |
195 | 253 | ||
254 | #define EAGLE_IV_PID_PREFIRM 0x9042 /* Eagle IV */ | ||
255 | #define EAGLE_IV_PID_PSTFIRM 0x9041 /* Eagle IV */ | ||
256 | |||
196 | /* | 257 | /* |
197 | * USR USB IDs | 258 | * USR USB IDs |
198 | */ | 259 | */ |
@@ -208,11 +269,15 @@ struct uea_softc { | |||
208 | 269 | ||
209 | #define PREFIRM 0 | 270 | #define PREFIRM 0 |
210 | #define PSTFIRM (1<<7) | 271 | #define PSTFIRM (1<<7) |
272 | #define AUTO_ANNEX_A (1<<8) | ||
273 | #define AUTO_ANNEX_B (1<<9) | ||
274 | |||
211 | enum { | 275 | enum { |
212 | ADI930 = 0, | 276 | ADI930 = 0, |
213 | EAGLE_I, | 277 | EAGLE_I, |
214 | EAGLE_II, | 278 | EAGLE_II, |
215 | EAGLE_III | 279 | EAGLE_III, |
280 | EAGLE_IV | ||
216 | }; | 281 | }; |
217 | 282 | ||
218 | /* macros for both struct usb_device_id and struct uea_softc */ | 283 | /* macros for both struct usb_device_id and struct uea_softc */ |
@@ -221,15 +286,18 @@ enum { | |||
221 | #define UEA_CHIP_VERSION(x) \ | 286 | #define UEA_CHIP_VERSION(x) \ |
222 | ((x)->driver_info & 0xf) | 287 | ((x)->driver_info & 0xf) |
223 | 288 | ||
224 | #define IS_ISDN(usb_dev) \ | 289 | #define IS_ISDN(x) \ |
225 | (le16_to_cpu((usb_dev)->descriptor.bcdDevice) & 0x80) | 290 | ((x)->annex & ANNEXB) |
226 | 291 | ||
227 | #define INS_TO_USBDEV(ins) ins->usb_dev | 292 | #define INS_TO_USBDEV(ins) ins->usb_dev |
228 | 293 | ||
229 | #define GET_STATUS(data) \ | 294 | #define GET_STATUS(data) \ |
230 | ((data >> 8) & 0xf) | 295 | ((data >> 8) & 0xf) |
296 | |||
231 | #define IS_OPERATIONAL(sc) \ | 297 | #define IS_OPERATIONAL(sc) \ |
232 | (GET_STATUS(sc->stats.phy.state) == 2) | 298 | ((UEA_CHIP_VERSION(sc) != EAGLE_IV) ? \ |
299 | (GET_STATUS(sc->stats.phy.state) == 2) : \ | ||
300 | (sc->stats.phy.state == 7)) | ||
233 | 301 | ||
234 | /* | 302 | /* |
235 | * Set of macros to handle unaligned data in the firmware blob. | 303 | * Set of macros to handle unaligned data in the firmware blob. |
@@ -259,7 +327,8 @@ enum { | |||
259 | #define UEA_INTR_PIPE 0x04 | 327 | #define UEA_INTR_PIPE 0x04 |
260 | #define UEA_ISO_DATA_PIPE 0x08 | 328 | #define UEA_ISO_DATA_PIPE 0x08 |
261 | 329 | ||
262 | #define UEA_SET_BLOCK 0x0001 | 330 | #define UEA_E1_SET_BLOCK 0x0001 |
331 | #define UEA_E4_SET_BLOCK 0x002c | ||
263 | #define UEA_SET_MODE 0x0003 | 332 | #define UEA_SET_MODE 0x0003 |
264 | #define UEA_SET_2183_DATA 0x0004 | 333 | #define UEA_SET_2183_DATA 0x0004 |
265 | #define UEA_SET_TIMEOUT 0x0011 | 334 | #define UEA_SET_TIMEOUT 0x0011 |
@@ -275,71 +344,179 @@ enum { | |||
275 | #define UEA_MPTX_MAILBOX (0x3fd6 | 0x4000) | 344 | #define UEA_MPTX_MAILBOX (0x3fd6 | 0x4000) |
276 | #define UEA_MPRX_MAILBOX (0x3fdf | 0x4000) | 345 | #define UEA_MPRX_MAILBOX (0x3fdf | 0x4000) |
277 | 346 | ||
278 | /* structure describing a block within a DSP page */ | 347 | /* block information in eagle4 dsp firmware */ |
279 | struct block_info { | 348 | struct block_index { |
349 | __le32 PageOffset; | ||
350 | __le32 NotLastBlock; | ||
351 | __le32 dummy; | ||
352 | __le32 PageSize; | ||
353 | __le32 PageAddress; | ||
354 | __le16 dummy1; | ||
355 | __le16 PageNumber; | ||
356 | } __attribute__ ((packed)); | ||
357 | |||
358 | #define E4_IS_BOOT_PAGE(PageSize) ((le32_to_cpu(PageSize)) & 0x80000000) | ||
359 | #define E4_PAGE_BYTES(PageSize) ((le32_to_cpu(PageSize) & 0x7fffffff) * 4) | ||
360 | |||
361 | #define E4_L1_STRING_HEADER 0x10 | ||
362 | #define E4_MAX_PAGE_NUMBER 0x58 | ||
363 | #define E4_NO_SWAPPAGE_HEADERS 0x31 | ||
364 | |||
365 | /* l1_code is eagle4 dsp firmware format */ | ||
366 | struct l1_code { | ||
367 | u8 string_header[E4_L1_STRING_HEADER]; | ||
368 | u8 page_number_to_block_index[E4_MAX_PAGE_NUMBER]; | ||
369 | struct block_index page_header[E4_NO_SWAPPAGE_HEADERS]; | ||
370 | u8 code [0]; | ||
371 | } __attribute__ ((packed)); | ||
372 | |||
373 | /* structures describing a block within a DSP page */ | ||
374 | struct block_info_e1 { | ||
280 | __le16 wHdr; | 375 | __le16 wHdr; |
281 | #define UEA_BIHDR 0xabcd | ||
282 | __le16 wAddress; | 376 | __le16 wAddress; |
283 | __le16 wSize; | 377 | __le16 wSize; |
284 | __le16 wOvlOffset; | 378 | __le16 wOvlOffset; |
285 | __le16 wOvl; /* overlay */ | 379 | __le16 wOvl; /* overlay */ |
286 | __le16 wLast; | 380 | __le16 wLast; |
287 | } __attribute__ ((packed)); | 381 | } __attribute__ ((packed)); |
288 | #define BLOCK_INFO_SIZE 12 | 382 | #define E1_BLOCK_INFO_SIZE 12 |
383 | |||
384 | struct block_info_e4 { | ||
385 | __be16 wHdr; | ||
386 | __u8 bBootPage; | ||
387 | __u8 bPageNumber; | ||
388 | __be32 dwSize; | ||
389 | __be32 dwAddress; | ||
390 | __be16 wReserved; | ||
391 | } __attribute__ ((packed)); | ||
392 | #define E4_BLOCK_INFO_SIZE 14 | ||
289 | 393 | ||
290 | /* structure representing a CMV (Configuration and Management Variable) */ | 394 | #define UEA_BIHDR 0xabcd |
291 | struct cmv { | 395 | #define UEA_RESERVED 0xffff |
292 | __le16 wPreamble; | 396 | |
293 | #define PREAMBLE 0x535c | 397 | /* constants describing cmv type */ |
294 | __u8 bDirection; | 398 | #define E1_PREAMBLE 0x535c |
295 | #define MODEMTOHOST 0x01 | 399 | #define E1_MODEMTOHOST 0x01 |
296 | #define HOSTTOMODEM 0x10 | 400 | #define E1_HOSTTOMODEM 0x10 |
297 | __u8 bFunction; | 401 | |
298 | #define FUNCTION_TYPE(f) ((f) >> 4) | 402 | #define E1_MEMACCESS 0x1 |
299 | #define MEMACCESS 0x1 | 403 | #define E1_ADSLDIRECTIVE 0x7 |
300 | #define ADSLDIRECTIVE 0x7 | 404 | #define E1_FUNCTION_TYPE(f) ((f) >> 4) |
405 | #define E1_FUNCTION_SUBTYPE(f) ((f) & 0x0f) | ||
406 | |||
407 | #define E4_MEMACCESS 0 | ||
408 | #define E4_ADSLDIRECTIVE 0xf | ||
409 | #define E4_FUNCTION_TYPE(f) ((f) >> 8) | ||
410 | #define E4_FUNCTION_SIZE(f) ((f) & 0x0f) | ||
411 | #define E4_FUNCTION_SUBTYPE(f) (((f) >> 4) & 0x0f) | ||
301 | 412 | ||
302 | #define FUNCTION_SUBTYPE(f) ((f) & 0x0f) | ||
303 | /* for MEMACCESS */ | 413 | /* for MEMACCESS */ |
304 | #define REQUESTREAD 0x0 | 414 | #define E1_REQUESTREAD 0x0 |
305 | #define REQUESTWRITE 0x1 | 415 | #define E1_REQUESTWRITE 0x1 |
306 | #define REPLYREAD 0x2 | 416 | #define E1_REPLYREAD 0x2 |
307 | #define REPLYWRITE 0x3 | 417 | #define E1_REPLYWRITE 0x3 |
418 | |||
419 | #define E4_REQUESTREAD 0x0 | ||
420 | #define E4_REQUESTWRITE 0x4 | ||
421 | #define E4_REPLYREAD (E4_REQUESTREAD | 1) | ||
422 | #define E4_REPLYWRITE (E4_REQUESTWRITE | 1) | ||
423 | |||
308 | /* for ADSLDIRECTIVE */ | 424 | /* for ADSLDIRECTIVE */ |
309 | #define KERNELREADY 0x0 | 425 | #define E1_KERNELREADY 0x0 |
310 | #define MODEMREADY 0x1 | 426 | #define E1_MODEMREADY 0x1 |
311 | 427 | ||
312 | #define MAKEFUNCTION(t, s) (((t) & 0xf) << 4 | ((s) & 0xf)) | 428 | #define E4_KERNELREADY 0x0 |
313 | __le16 wIndex; | 429 | #define E4_MODEMREADY 0x1 |
314 | __le32 dwSymbolicAddress; | 430 | |
315 | #define MAKESA(a, b, c, d) \ | 431 | #define E1_MAKEFUNCTION(t, s) (((t) & 0xf) << 4 | ((s) & 0xf)) |
432 | #define E4_MAKEFUNCTION(t, st, s) (((t) & 0xf) << 8 | ((st) & 0xf) << 4 | ((s) & 0xf)) | ||
433 | |||
434 | #define E1_MAKESA(a, b, c, d) \ | ||
316 | (((c) & 0xff) << 24 | \ | 435 | (((c) & 0xff) << 24 | \ |
317 | ((d) & 0xff) << 16 | \ | 436 | ((d) & 0xff) << 16 | \ |
318 | ((a) & 0xff) << 8 | \ | 437 | ((a) & 0xff) << 8 | \ |
319 | ((b) & 0xff)) | 438 | ((b) & 0xff)) |
320 | #define GETSA1(a) ((a >> 8) & 0xff) | 439 | |
321 | #define GETSA2(a) (a & 0xff) | 440 | #define E1_GETSA1(a) ((a >> 8) & 0xff) |
322 | #define GETSA3(a) ((a >> 24) & 0xff) | 441 | #define E1_GETSA2(a) (a & 0xff) |
323 | #define GETSA4(a) ((a >> 16) & 0xff) | 442 | #define E1_GETSA3(a) ((a >> 24) & 0xff) |
324 | 443 | #define E1_GETSA4(a) ((a >> 16) & 0xff) | |
325 | #define SA_CNTL MAKESA('C', 'N', 'T', 'L') | 444 | |
326 | #define SA_DIAG MAKESA('D', 'I', 'A', 'G') | 445 | #define E1_SA_CNTL E1_MAKESA('C', 'N', 'T', 'L') |
327 | #define SA_INFO MAKESA('I', 'N', 'F', 'O') | 446 | #define E1_SA_DIAG E1_MAKESA('D', 'I', 'A', 'G') |
328 | #define SA_OPTN MAKESA('O', 'P', 'T', 'N') | 447 | #define E1_SA_INFO E1_MAKESA('I', 'N', 'F', 'O') |
329 | #define SA_RATE MAKESA('R', 'A', 'T', 'E') | 448 | #define E1_SA_OPTN E1_MAKESA('O', 'P', 'T', 'N') |
330 | #define SA_STAT MAKESA('S', 'T', 'A', 'T') | 449 | #define E1_SA_RATE E1_MAKESA('R', 'A', 'T', 'E') |
450 | #define E1_SA_STAT E1_MAKESA('S', 'T', 'A', 'T') | ||
451 | |||
452 | #define E4_SA_CNTL 1 | ||
453 | #define E4_SA_STAT 2 | ||
454 | #define E4_SA_INFO 3 | ||
455 | #define E4_SA_TEST 4 | ||
456 | #define E4_SA_OPTN 5 | ||
457 | #define E4_SA_RATE 6 | ||
458 | #define E4_SA_DIAG 7 | ||
459 | #define E4_SA_CNFG 8 | ||
460 | |||
461 | /* structures representing a CMV (Configuration and Management Variable) */ | ||
462 | struct cmv_e1 { | ||
463 | __le16 wPreamble; | ||
464 | __u8 bDirection; | ||
465 | __u8 bFunction; | ||
466 | __le16 wIndex; | ||
467 | __le32 dwSymbolicAddress; | ||
331 | __le16 wOffsetAddress; | 468 | __le16 wOffsetAddress; |
332 | __le32 dwData; | 469 | __le32 dwData; |
333 | } __attribute__ ((packed)); | 470 | } __attribute__ ((packed)); |
334 | #define CMV_SIZE 16 | ||
335 | 471 | ||
336 | /* structure representing swap information */ | 472 | struct cmv_e4 { |
337 | struct swap_info { | 473 | __be16 wGroup; |
474 | __be16 wFunction; | ||
475 | __be16 wOffset; | ||
476 | __be16 wAddress; | ||
477 | __be32 dwData [6]; | ||
478 | } __attribute__ ((packed)); | ||
479 | |||
480 | /* structures representing swap information */ | ||
481 | struct swap_info_e1 { | ||
338 | __u8 bSwapPageNo; | 482 | __u8 bSwapPageNo; |
339 | __u8 bOvl; /* overlay */ | 483 | __u8 bOvl; /* overlay */ |
340 | } __attribute__ ((packed)); | 484 | } __attribute__ ((packed)); |
341 | 485 | ||
342 | /* structure representing interrupt data */ | 486 | struct swap_info_e4 { |
487 | __u8 bSwapPageNo; | ||
488 | } __attribute__ ((packed)); | ||
489 | |||
490 | /* structures representing interrupt data */ | ||
491 | #define e1_bSwapPageNo u.e1.s1.swapinfo.bSwapPageNo | ||
492 | #define e1_bOvl u.e1.s1.swapinfo.bOvl | ||
493 | #define e4_bSwapPageNo u.e4.s1.swapinfo.bSwapPageNo | ||
494 | |||
495 | #define INT_LOADSWAPPAGE 0x0001 | ||
496 | #define INT_INCOMINGCMV 0x0002 | ||
497 | |||
498 | union intr_data_e1 { | ||
499 | struct { | ||
500 | struct swap_info_e1 swapinfo; | ||
501 | __le16 wDataSize; | ||
502 | } __attribute__ ((packed)) s1; | ||
503 | struct { | ||
504 | struct cmv_e1 cmv; | ||
505 | __le16 wDataSize; | ||
506 | } __attribute__ ((packed)) s2; | ||
507 | } __attribute__ ((packed)); | ||
508 | |||
509 | union intr_data_e4 { | ||
510 | struct { | ||
511 | struct swap_info_e4 swapinfo; | ||
512 | __le16 wDataSize; | ||
513 | } __attribute__ ((packed)) s1; | ||
514 | struct { | ||
515 | struct cmv_e4 cmv; | ||
516 | __le16 wDataSize; | ||
517 | } __attribute__ ((packed)) s2; | ||
518 | } __attribute__ ((packed)); | ||
519 | |||
343 | struct intr_pkt { | 520 | struct intr_pkt { |
344 | __u8 bType; | 521 | __u8 bType; |
345 | __u8 bNotification; | 522 | __u8 bNotification; |
@@ -347,43 +524,48 @@ struct intr_pkt { | |||
347 | __le16 wIndex; | 524 | __le16 wIndex; |
348 | __le16 wLength; | 525 | __le16 wLength; |
349 | __le16 wInterrupt; | 526 | __le16 wInterrupt; |
350 | #define INT_LOADSWAPPAGE 0x0001 | ||
351 | #define INT_INCOMINGCMV 0x0002 | ||
352 | union { | 527 | union { |
353 | struct { | 528 | union intr_data_e1 e1; |
354 | struct swap_info swapinfo; | 529 | union intr_data_e4 e4; |
355 | __le16 wDataSize; | 530 | } u; |
356 | } __attribute__ ((packed)) s1; | ||
357 | |||
358 | struct { | ||
359 | struct cmv cmv; | ||
360 | __le16 wDataSize; | ||
361 | } __attribute__ ((packed)) s2; | ||
362 | } __attribute__ ((packed)) u; | ||
363 | #define bSwapPageNo u.s1.swapinfo.bSwapPageNo | ||
364 | #define bOvl u.s1.swapinfo.bOvl | ||
365 | } __attribute__ ((packed)); | 531 | } __attribute__ ((packed)); |
366 | #define INTR_PKT_SIZE 28 | 532 | |
533 | #define E1_INTR_PKT_SIZE 28 | ||
534 | #define E4_INTR_PKT_SIZE 64 | ||
367 | 535 | ||
368 | static struct usb_driver uea_driver; | 536 | static struct usb_driver uea_driver; |
369 | static DEFINE_MUTEX(uea_mutex); | 537 | static DEFINE_MUTEX(uea_mutex); |
370 | static const char *chip_name[] = {"ADI930", "Eagle I", "Eagle II", "Eagle III"}; | 538 | static const char *chip_name[] = {"ADI930", "Eagle I", "Eagle II", "Eagle III", "Eagle IV"}; |
371 | 539 | ||
372 | static int modem_index; | 540 | static int modem_index; |
373 | static unsigned int debug; | 541 | static unsigned int debug; |
374 | static int use_iso[NB_MODEM] = {[0 ... (NB_MODEM - 1)] = 1}; | 542 | static unsigned int altsetting[NB_MODEM] = {[0 ... (NB_MODEM - 1)] = FASTEST_ISO_INTF}; |
375 | static int sync_wait[NB_MODEM]; | 543 | static int sync_wait[NB_MODEM]; |
376 | static char *cmv_file[NB_MODEM]; | 544 | static char *cmv_file[NB_MODEM]; |
545 | static int annex[NB_MODEM]; | ||
377 | 546 | ||
378 | module_param(debug, uint, 0644); | 547 | module_param(debug, uint, 0644); |
379 | MODULE_PARM_DESC(debug, "module debug level (0=off,1=on,2=verbose)"); | 548 | MODULE_PARM_DESC(debug, "module debug level (0=off,1=on,2=verbose)"); |
380 | module_param_array(use_iso, bool, NULL, 0644); | 549 | module_param_array(altsetting, uint, NULL, 0644); |
381 | MODULE_PARM_DESC(use_iso, "use isochronous usb pipe for incoming traffic"); | 550 | MODULE_PARM_DESC(altsetting, "alternate setting for incoming traffic: 0=bulk, " |
551 | "1=isoc slowest, ... , 8=isoc fastest (default)"); | ||
382 | module_param_array(sync_wait, bool, NULL, 0644); | 552 | module_param_array(sync_wait, bool, NULL, 0644); |
383 | MODULE_PARM_DESC(sync_wait, "wait the synchronisation before starting ATM"); | 553 | MODULE_PARM_DESC(sync_wait, "wait the synchronisation before starting ATM"); |
384 | module_param_array(cmv_file, charp, NULL, 0644); | 554 | module_param_array(cmv_file, charp, NULL, 0644); |
385 | MODULE_PARM_DESC(cmv_file, | 555 | MODULE_PARM_DESC(cmv_file, |
386 | "file name with configuration and management variables"); | 556 | "file name with configuration and management variables"); |
557 | module_param_array(annex, uint, NULL, 0644); | ||
558 | MODULE_PARM_DESC(annex, | ||
559 | "manually set annex a/b (0=auto, 1=annex a, 2=annex b)"); | ||
560 | |||
561 | #define uea_wait(sc, cond, timeo) \ | ||
562 | ({ \ | ||
563 | int _r = wait_event_interruptible_timeout(sc->sync_q, \ | ||
564 | (cond) || kthread_should_stop(), timeo); \ | ||
565 | if (kthread_should_stop()) \ | ||
566 | _r = -ENODEV; \ | ||
567 | _r; \ | ||
568 | }) | ||
387 | 569 | ||
388 | #define UPDATE_ATM_STAT(type, val) \ | 570 | #define UPDATE_ATM_STAT(type, val) \ |
389 | do { \ | 571 | do { \ |
@@ -519,6 +701,9 @@ static int uea_load_firmware(struct usb_device *usb, unsigned int ver) | |||
519 | case EAGLE_III: | 701 | case EAGLE_III: |
520 | fw_name = FW_DIR "eagleIII.fw"; | 702 | fw_name = FW_DIR "eagleIII.fw"; |
521 | break; | 703 | break; |
704 | case EAGLE_IV: | ||
705 | fw_name = FW_DIR "eagleIV.fw"; | ||
706 | break; | ||
522 | } | 707 | } |
523 | 708 | ||
524 | ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, usb, uea_upload_pre_firmware); | 709 | ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, usb, uea_upload_pre_firmware); |
@@ -537,7 +722,7 @@ static int uea_load_firmware(struct usb_device *usb, unsigned int ver) | |||
537 | /* | 722 | /* |
538 | * Make sure that the DSP code provided is safe to use. | 723 | * Make sure that the DSP code provided is safe to use. |
539 | */ | 724 | */ |
540 | static int check_dsp(u8 *dsp, unsigned int len) | 725 | static int check_dsp_e1(u8 *dsp, unsigned int len) |
541 | { | 726 | { |
542 | u8 pagecount, blockcount; | 727 | u8 pagecount, blockcount; |
543 | u16 blocksize; | 728 | u16 blocksize; |
@@ -588,6 +773,51 @@ static int check_dsp(u8 *dsp, unsigned int len) | |||
588 | return 0; | 773 | return 0; |
589 | } | 774 | } |
590 | 775 | ||
776 | static int check_dsp_e4(u8 *dsp, int len) | ||
777 | { | ||
778 | int i; | ||
779 | struct l1_code *p = (struct l1_code *) dsp; | ||
780 | unsigned int sum = p->code - dsp; | ||
781 | |||
782 | if (len < sum) | ||
783 | return 1; | ||
784 | |||
785 | if (strcmp("STRATIPHY ANEXA", p->string_header) != 0 && | ||
786 | strcmp("STRATIPHY ANEXB", p->string_header) != 0) | ||
787 | return 1; | ||
788 | |||
789 | for (i = 0; i < E4_MAX_PAGE_NUMBER; i++) { | ||
790 | struct block_index *blockidx; | ||
791 | u8 blockno = p->page_number_to_block_index[i]; | ||
792 | if (blockno >= E4_NO_SWAPPAGE_HEADERS) | ||
793 | continue; | ||
794 | |||
795 | do { | ||
796 | u64 l; | ||
797 | |||
798 | if (blockno >= E4_NO_SWAPPAGE_HEADERS) | ||
799 | return 1; | ||
800 | |||
801 | blockidx = &p->page_header[blockno++]; | ||
802 | if ((u8 *)(blockidx + 1) - dsp >= len) | ||
803 | return 1; | ||
804 | |||
805 | if (le16_to_cpu(blockidx->PageNumber) != i) | ||
806 | return 1; | ||
807 | |||
808 | l = E4_PAGE_BYTES(blockidx->PageSize); | ||
809 | sum += l; | ||
810 | l += le32_to_cpu(blockidx->PageOffset); | ||
811 | if (l > len) | ||
812 | return 1; | ||
813 | |||
814 | /* zero is zero regardless endianes */ | ||
815 | } while (blockidx->NotLastBlock); | ||
816 | } | ||
817 | |||
818 | return (sum == len) ? 0 : 1; | ||
819 | } | ||
820 | |||
591 | /* | 821 | /* |
592 | * send data to the idma pipe | 822 | * send data to the idma pipe |
593 | * */ | 823 | * */ |
@@ -624,13 +854,18 @@ static int request_dsp(struct uea_softc *sc) | |||
624 | int ret; | 854 | int ret; |
625 | char *dsp_name; | 855 | char *dsp_name; |
626 | 856 | ||
627 | if (UEA_CHIP_VERSION(sc) == ADI930) { | 857 | if (UEA_CHIP_VERSION(sc) == EAGLE_IV) { |
628 | if (IS_ISDN(sc->usb_dev)) | 858 | if (IS_ISDN(sc)) |
859 | dsp_name = FW_DIR "DSP4i.bin"; | ||
860 | else | ||
861 | dsp_name = FW_DIR "DSP4p.bin"; | ||
862 | } else if (UEA_CHIP_VERSION(sc) == ADI930) { | ||
863 | if (IS_ISDN(sc)) | ||
629 | dsp_name = FW_DIR "DSP9i.bin"; | 864 | dsp_name = FW_DIR "DSP9i.bin"; |
630 | else | 865 | else |
631 | dsp_name = FW_DIR "DSP9p.bin"; | 866 | dsp_name = FW_DIR "DSP9p.bin"; |
632 | } else { | 867 | } else { |
633 | if (IS_ISDN(sc->usb_dev)) | 868 | if (IS_ISDN(sc)) |
634 | dsp_name = FW_DIR "DSPei.bin"; | 869 | dsp_name = FW_DIR "DSPei.bin"; |
635 | else | 870 | else |
636 | dsp_name = FW_DIR "DSPep.bin"; | 871 | dsp_name = FW_DIR "DSPep.bin"; |
@@ -640,11 +875,16 @@ static int request_dsp(struct uea_softc *sc) | |||
640 | if (ret < 0) { | 875 | if (ret < 0) { |
641 | uea_err(INS_TO_USBDEV(sc), | 876 | uea_err(INS_TO_USBDEV(sc), |
642 | "requesting firmware %s failed with error %d\n", | 877 | "requesting firmware %s failed with error %d\n", |
643 | dsp_name, ret); | 878 | dsp_name, ret); |
644 | return ret; | 879 | return ret; |
645 | } | 880 | } |
646 | 881 | ||
647 | if (check_dsp(sc->dsp_firm->data, sc->dsp_firm->size)) { | 882 | if (UEA_CHIP_VERSION(sc) == EAGLE_IV) |
883 | ret = check_dsp_e4(sc->dsp_firm->data, sc->dsp_firm->size); | ||
884 | else | ||
885 | ret = check_dsp_e1(sc->dsp_firm->data, sc->dsp_firm->size); | ||
886 | |||
887 | if (ret) { | ||
648 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", | 888 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", |
649 | dsp_name); | 889 | dsp_name); |
650 | release_firmware(sc->dsp_firm); | 890 | release_firmware(sc->dsp_firm); |
@@ -658,12 +898,12 @@ static int request_dsp(struct uea_softc *sc) | |||
658 | /* | 898 | /* |
659 | * The uea_load_page() function must be called within a process context | 899 | * The uea_load_page() function must be called within a process context |
660 | */ | 900 | */ |
661 | static void uea_load_page(struct work_struct *work) | 901 | static void uea_load_page_e1(struct work_struct *work) |
662 | { | 902 | { |
663 | struct uea_softc *sc = container_of(work, struct uea_softc, task); | 903 | struct uea_softc *sc = container_of(work, struct uea_softc, task); |
664 | u16 pageno = sc->pageno; | 904 | u16 pageno = sc->pageno; |
665 | u16 ovl = sc->ovl; | 905 | u16 ovl = sc->ovl; |
666 | struct block_info bi; | 906 | struct block_info_e1 bi; |
667 | 907 | ||
668 | u8 *p; | 908 | u8 *p; |
669 | u8 pagecount, blockcount; | 909 | u8 pagecount, blockcount; |
@@ -716,7 +956,7 @@ static void uea_load_page(struct work_struct *work) | |||
716 | bi.wLast = cpu_to_le16((i == blockcount - 1) ? 1 : 0); | 956 | bi.wLast = cpu_to_le16((i == blockcount - 1) ? 1 : 0); |
717 | 957 | ||
718 | /* send block info through the IDMA pipe */ | 958 | /* send block info through the IDMA pipe */ |
719 | if (uea_idma_write(sc, &bi, BLOCK_INFO_SIZE)) | 959 | if (uea_idma_write(sc, &bi, E1_BLOCK_INFO_SIZE)) |
720 | goto bad2; | 960 | goto bad2; |
721 | 961 | ||
722 | /* send block data through the IDMA pipe */ | 962 | /* send block data through the IDMA pipe */ |
@@ -735,17 +975,114 @@ bad1: | |||
735 | uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n", pageno); | 975 | uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n", pageno); |
736 | } | 976 | } |
737 | 977 | ||
978 | static void __uea_load_page_e4(struct uea_softc *sc, u8 pageno, int boot) | ||
979 | { | ||
980 | struct block_info_e4 bi; | ||
981 | struct block_index *blockidx; | ||
982 | struct l1_code *p = (struct l1_code *) sc->dsp_firm->data; | ||
983 | u8 blockno = p->page_number_to_block_index[pageno]; | ||
984 | |||
985 | bi.wHdr = cpu_to_be16(UEA_BIHDR); | ||
986 | bi.bBootPage = boot; | ||
987 | bi.bPageNumber = pageno; | ||
988 | bi.wReserved = cpu_to_be16(UEA_RESERVED); | ||
989 | |||
990 | do { | ||
991 | u8 *blockoffset; | ||
992 | unsigned int blocksize; | ||
993 | |||
994 | blockidx = &p->page_header[blockno]; | ||
995 | blocksize = E4_PAGE_BYTES(blockidx->PageSize); | ||
996 | blockoffset = sc->dsp_firm->data + le32_to_cpu(blockidx->PageOffset); | ||
997 | |||
998 | bi.dwSize = cpu_to_be32(blocksize); | ||
999 | bi.dwAddress = swab32(blockidx->PageAddress); | ||
1000 | |||
1001 | uea_dbg(INS_TO_USBDEV(sc), | ||
1002 | "sending block %u for DSP page %u size %u adress %x\n", | ||
1003 | blockno, pageno, blocksize, le32_to_cpu(blockidx->PageAddress)); | ||
1004 | |||
1005 | /* send block info through the IDMA pipe */ | ||
1006 | if (uea_idma_write(sc, &bi, E4_BLOCK_INFO_SIZE)) | ||
1007 | goto bad; | ||
1008 | |||
1009 | /* send block data through the IDMA pipe */ | ||
1010 | if (uea_idma_write(sc, blockoffset, blocksize)) | ||
1011 | goto bad; | ||
1012 | |||
1013 | blockno++; | ||
1014 | } while (blockidx->NotLastBlock); | ||
1015 | |||
1016 | return; | ||
1017 | |||
1018 | bad: | ||
1019 | uea_err(INS_TO_USBDEV(sc), "sending DSP block %u failed\n", blockno); | ||
1020 | return; | ||
1021 | } | ||
1022 | |||
1023 | static void uea_load_page_e4(struct work_struct *work) | ||
1024 | { | ||
1025 | struct uea_softc *sc = container_of(work, struct uea_softc, task); | ||
1026 | u8 pageno = sc->pageno; | ||
1027 | int i; | ||
1028 | struct block_info_e4 bi; | ||
1029 | struct l1_code *p; | ||
1030 | |||
1031 | uea_dbg(INS_TO_USBDEV(sc), "sending DSP page %u\n", pageno); | ||
1032 | |||
1033 | /* reload firmware when reboot start and it's loaded already */ | ||
1034 | if (pageno == 0 && sc->dsp_firm) { | ||
1035 | release_firmware(sc->dsp_firm); | ||
1036 | sc->dsp_firm = NULL; | ||
1037 | } | ||
1038 | |||
1039 | if (sc->dsp_firm == NULL && request_dsp(sc) < 0) | ||
1040 | return; | ||
1041 | |||
1042 | p = (struct l1_code *) sc->dsp_firm->data; | ||
1043 | if (pageno >= p->page_header[0].PageNumber) { | ||
1044 | uea_err(INS_TO_USBDEV(sc), "invalid DSP page %u requested\n", pageno); | ||
1045 | return; | ||
1046 | } | ||
1047 | |||
1048 | if (pageno != 0) { | ||
1049 | __uea_load_page_e4(sc, pageno, 0); | ||
1050 | return; | ||
1051 | } | ||
1052 | |||
1053 | uea_dbg(INS_TO_USBDEV(sc), | ||
1054 | "sending Main DSP page %u\n", p->page_header[0].PageNumber); | ||
1055 | |||
1056 | for (i = 0; i < le16_to_cpu(p->page_header[0].PageNumber); i++) { | ||
1057 | if (E4_IS_BOOT_PAGE(p->page_header[i].PageSize)) | ||
1058 | __uea_load_page_e4(sc, i, 1); | ||
1059 | } | ||
1060 | |||
1061 | uea_dbg(INS_TO_USBDEV(sc),"sending start bi\n"); | ||
1062 | |||
1063 | bi.wHdr = cpu_to_be16(UEA_BIHDR); | ||
1064 | bi.bBootPage = 0; | ||
1065 | bi.bPageNumber = 0xff; | ||
1066 | bi.wReserved = cpu_to_be16(UEA_RESERVED); | ||
1067 | bi.dwSize = cpu_to_be32(E4_PAGE_BYTES(p->page_header[0].PageSize)); | ||
1068 | bi.dwAddress = swab32(p->page_header[0].PageAddress); | ||
1069 | |||
1070 | /* send block info through the IDMA pipe */ | ||
1071 | if (uea_idma_write(sc, &bi, E4_BLOCK_INFO_SIZE)) | ||
1072 | uea_err(INS_TO_USBDEV(sc), "sending DSP start bi failed\n"); | ||
1073 | } | ||
1074 | |||
738 | static inline void wake_up_cmv_ack(struct uea_softc *sc) | 1075 | static inline void wake_up_cmv_ack(struct uea_softc *sc) |
739 | { | 1076 | { |
740 | BUG_ON(sc->cmv_ack); | 1077 | BUG_ON(sc->cmv_ack); |
741 | sc->cmv_ack = 1; | 1078 | sc->cmv_ack = 1; |
742 | wake_up(&sc->cmv_ack_wait); | 1079 | wake_up(&sc->sync_q); |
743 | } | 1080 | } |
744 | 1081 | ||
745 | static inline int wait_cmv_ack(struct uea_softc *sc) | 1082 | static inline int wait_cmv_ack(struct uea_softc *sc) |
746 | { | 1083 | { |
747 | int ret = wait_event_interruptible_timeout(sc->cmv_ack_wait, | 1084 | int ret = uea_wait(sc, sc->cmv_ack , ACK_TIMEOUT); |
748 | sc->cmv_ack, ACK_TIMEOUT); | 1085 | |
749 | sc->cmv_ack = 0; | 1086 | sc->cmv_ack = 0; |
750 | 1087 | ||
751 | uea_dbg(INS_TO_USBDEV(sc), "wait_event_timeout : %d ms\n", | 1088 | uea_dbg(INS_TO_USBDEV(sc), "wait_event_timeout : %d ms\n", |
@@ -792,33 +1129,34 @@ static int uea_request(struct uea_softc *sc, | |||
792 | return 0; | 1129 | return 0; |
793 | } | 1130 | } |
794 | 1131 | ||
795 | static int uea_cmv(struct uea_softc *sc, | 1132 | static int uea_cmv_e1(struct uea_softc *sc, |
796 | u8 function, u32 address, u16 offset, u32 data) | 1133 | u8 function, u32 address, u16 offset, u32 data) |
797 | { | 1134 | { |
798 | struct cmv cmv; | 1135 | struct cmv_e1 cmv; |
799 | int ret; | 1136 | int ret; |
800 | 1137 | ||
801 | uea_enters(INS_TO_USBDEV(sc)); | 1138 | uea_enters(INS_TO_USBDEV(sc)); |
802 | uea_vdbg(INS_TO_USBDEV(sc), "Function : %d-%d, Address : %c%c%c%c, " | 1139 | uea_vdbg(INS_TO_USBDEV(sc), "Function : %d-%d, Address : %c%c%c%c, " |
803 | "offset : 0x%04x, data : 0x%08x\n", | 1140 | "offset : 0x%04x, data : 0x%08x\n", |
804 | FUNCTION_TYPE(function), FUNCTION_SUBTYPE(function), | 1141 | E1_FUNCTION_TYPE(function), E1_FUNCTION_SUBTYPE(function), |
805 | GETSA1(address), GETSA2(address), GETSA3(address), | 1142 | E1_GETSA1(address), E1_GETSA2(address), E1_GETSA3(address), |
806 | GETSA4(address), offset, data); | 1143 | E1_GETSA4(address), offset, data); |
1144 | |||
807 | /* we send a request, but we expect a reply */ | 1145 | /* we send a request, but we expect a reply */ |
808 | sc->cmv_function = function | 0x2; | 1146 | sc->cmv_dsc.e1.function = function | 0x2; |
809 | sc->cmv_idx++; | 1147 | sc->cmv_dsc.e1.idx++; |
810 | sc->cmv_address = address; | 1148 | sc->cmv_dsc.e1.address = address; |
811 | sc->cmv_offset = offset; | 1149 | sc->cmv_dsc.e1.offset = offset; |
812 | 1150 | ||
813 | cmv.wPreamble = cpu_to_le16(PREAMBLE); | 1151 | cmv.wPreamble = cpu_to_le16(E1_PREAMBLE); |
814 | cmv.bDirection = HOSTTOMODEM; | 1152 | cmv.bDirection = E1_HOSTTOMODEM; |
815 | cmv.bFunction = function; | 1153 | cmv.bFunction = function; |
816 | cmv.wIndex = cpu_to_le16(sc->cmv_idx); | 1154 | cmv.wIndex = cpu_to_le16(sc->cmv_dsc.e1.idx); |
817 | put_unaligned(cpu_to_le32(address), &cmv.dwSymbolicAddress); | 1155 | put_unaligned(cpu_to_le32(address), &cmv.dwSymbolicAddress); |
818 | cmv.wOffsetAddress = cpu_to_le16(offset); | 1156 | cmv.wOffsetAddress = cpu_to_le16(offset); |
819 | put_unaligned(cpu_to_le32(data >> 16 | data << 16), &cmv.dwData); | 1157 | put_unaligned(cpu_to_le32(data >> 16 | data << 16), &cmv.dwData); |
820 | 1158 | ||
821 | ret = uea_request(sc, UEA_SET_BLOCK, UEA_MPTX_START, CMV_SIZE, &cmv); | 1159 | ret = uea_request(sc, UEA_E1_SET_BLOCK, UEA_MPTX_START, sizeof(cmv), &cmv); |
822 | if (ret < 0) | 1160 | if (ret < 0) |
823 | return ret; | 1161 | return ret; |
824 | ret = wait_cmv_ack(sc); | 1162 | ret = wait_cmv_ack(sc); |
@@ -826,10 +1164,44 @@ static int uea_cmv(struct uea_softc *sc, | |||
826 | return ret; | 1164 | return ret; |
827 | } | 1165 | } |
828 | 1166 | ||
829 | static inline int uea_read_cmv(struct uea_softc *sc, | 1167 | static int uea_cmv_e4(struct uea_softc *sc, |
1168 | u16 function, u16 group, u16 address, u16 offset, u32 data) | ||
1169 | { | ||
1170 | struct cmv_e4 cmv; | ||
1171 | int ret; | ||
1172 | |||
1173 | uea_enters(INS_TO_USBDEV(sc)); | ||
1174 | memset(&cmv, 0, sizeof(cmv)); | ||
1175 | |||
1176 | uea_vdbg(INS_TO_USBDEV(sc), "Function : %d-%d, Group : 0x%04x, " | ||
1177 | "Address : 0x%04x, offset : 0x%04x, data : 0x%08x\n", | ||
1178 | E4_FUNCTION_TYPE(function), E4_FUNCTION_SUBTYPE(function), | ||
1179 | group, address, offset, data); | ||
1180 | |||
1181 | /* we send a request, but we expect a reply */ | ||
1182 | sc->cmv_dsc.e4.function = function | (0x1 << 4); | ||
1183 | sc->cmv_dsc.e4.offset = offset; | ||
1184 | sc->cmv_dsc.e4.address = address; | ||
1185 | sc->cmv_dsc.e4.group = group; | ||
1186 | |||
1187 | cmv.wFunction = cpu_to_be16(function); | ||
1188 | cmv.wGroup = cpu_to_be16(group); | ||
1189 | cmv.wAddress = cpu_to_be16(address); | ||
1190 | cmv.wOffset = cpu_to_be16(offset); | ||
1191 | cmv.dwData[0] = cpu_to_be32(data); | ||
1192 | |||
1193 | ret = uea_request(sc, UEA_E4_SET_BLOCK, UEA_MPTX_START, sizeof(cmv), &cmv); | ||
1194 | if (ret < 0) | ||
1195 | return ret; | ||
1196 | ret = wait_cmv_ack(sc); | ||
1197 | uea_leaves(INS_TO_USBDEV(sc)); | ||
1198 | return ret; | ||
1199 | } | ||
1200 | |||
1201 | static inline int uea_read_cmv_e1(struct uea_softc *sc, | ||
830 | u32 address, u16 offset, u32 *data) | 1202 | u32 address, u16 offset, u32 *data) |
831 | { | 1203 | { |
832 | int ret = uea_cmv(sc, MAKEFUNCTION(MEMACCESS, REQUESTREAD), | 1204 | int ret = uea_cmv_e1(sc, E1_MAKEFUNCTION(E1_MEMACCESS, E1_REQUESTREAD), |
833 | address, offset, 0); | 1205 | address, offset, 0); |
834 | if (ret < 0) | 1206 | if (ret < 0) |
835 | uea_err(INS_TO_USBDEV(sc), | 1207 | uea_err(INS_TO_USBDEV(sc), |
@@ -840,10 +1212,27 @@ static inline int uea_read_cmv(struct uea_softc *sc, | |||
840 | return ret; | 1212 | return ret; |
841 | } | 1213 | } |
842 | 1214 | ||
843 | static inline int uea_write_cmv(struct uea_softc *sc, | 1215 | static inline int uea_read_cmv_e4(struct uea_softc *sc, |
1216 | u8 size, u16 group, u16 address, u16 offset, u32 *data) | ||
1217 | { | ||
1218 | int ret = uea_cmv_e4(sc, E4_MAKEFUNCTION(E4_MEMACCESS, E4_REQUESTREAD, size), | ||
1219 | group, address, offset, 0); | ||
1220 | if (ret < 0) | ||
1221 | uea_err(INS_TO_USBDEV(sc), | ||
1222 | "reading cmv failed with error %d\n", ret); | ||
1223 | else { | ||
1224 | *data = sc->data; | ||
1225 | /* size is in 16-bit word quantities */ | ||
1226 | if (size > 2) | ||
1227 | *(data + 1) = sc->data1; | ||
1228 | } | ||
1229 | return ret; | ||
1230 | } | ||
1231 | |||
1232 | static inline int uea_write_cmv_e1(struct uea_softc *sc, | ||
844 | u32 address, u16 offset, u32 data) | 1233 | u32 address, u16 offset, u32 data) |
845 | { | 1234 | { |
846 | int ret = uea_cmv(sc, MAKEFUNCTION(MEMACCESS, REQUESTWRITE), | 1235 | int ret = uea_cmv_e1(sc, E1_MAKEFUNCTION(E1_MEMACCESS, E1_REQUESTWRITE), |
847 | address, offset, data); | 1236 | address, offset, data); |
848 | if (ret < 0) | 1237 | if (ret < 0) |
849 | uea_err(INS_TO_USBDEV(sc), | 1238 | uea_err(INS_TO_USBDEV(sc), |
@@ -852,12 +1241,48 @@ static inline int uea_write_cmv(struct uea_softc *sc, | |||
852 | return ret; | 1241 | return ret; |
853 | } | 1242 | } |
854 | 1243 | ||
1244 | static inline int uea_write_cmv_e4(struct uea_softc *sc, | ||
1245 | u8 size, u16 group, u16 address, u16 offset, u32 data) | ||
1246 | { | ||
1247 | int ret = uea_cmv_e4(sc, E4_MAKEFUNCTION(E4_MEMACCESS, E4_REQUESTWRITE, size), | ||
1248 | group, address, offset, data); | ||
1249 | if (ret < 0) | ||
1250 | uea_err(INS_TO_USBDEV(sc), | ||
1251 | "writing cmv failed with error %d\n", ret); | ||
1252 | |||
1253 | return ret; | ||
1254 | } | ||
1255 | |||
1256 | static void uea_set_bulk_timeout(struct uea_softc *sc, u32 dsrate) | ||
1257 | { | ||
1258 | int ret; | ||
1259 | u16 timeout; | ||
1260 | |||
1261 | /* in bulk mode the modem have problem with high rate | ||
1262 | * changing internal timing could improve things, but the | ||
1263 | * value is misterious. | ||
1264 | * ADI930 don't support it (-EPIPE error). | ||
1265 | */ | ||
1266 | |||
1267 | if (UEA_CHIP_VERSION(sc) == ADI930 || | ||
1268 | altsetting[sc->modem_index] > 0 || | ||
1269 | sc->stats.phy.dsrate == dsrate) | ||
1270 | return; | ||
1271 | |||
1272 | /* Original timming (1Mbit/s) from ADI (used in windows driver) */ | ||
1273 | timeout = (dsrate <= 1024*1024) ? 0 : 1; | ||
1274 | ret = uea_request(sc, UEA_SET_TIMEOUT, timeout, 0, NULL); | ||
1275 | uea_info(INS_TO_USBDEV(sc), "setting new timeout %d%s\n", | ||
1276 | timeout, ret < 0 ? " failed" : ""); | ||
1277 | |||
1278 | } | ||
1279 | |||
855 | /* | 1280 | /* |
856 | * Monitor the modem and update the stat | 1281 | * Monitor the modem and update the stat |
857 | * return 0 if everything is ok | 1282 | * return 0 if everything is ok |
858 | * return < 0 if an error occurs (-EAGAIN reboot needed) | 1283 | * return < 0 if an error occurs (-EAGAIN reboot needed) |
859 | */ | 1284 | */ |
860 | static int uea_stat(struct uea_softc *sc) | 1285 | static int uea_stat_e1(struct uea_softc *sc) |
861 | { | 1286 | { |
862 | u32 data; | 1287 | u32 data; |
863 | int ret; | 1288 | int ret; |
@@ -865,7 +1290,7 @@ static int uea_stat(struct uea_softc *sc) | |||
865 | uea_enters(INS_TO_USBDEV(sc)); | 1290 | uea_enters(INS_TO_USBDEV(sc)); |
866 | data = sc->stats.phy.state; | 1291 | data = sc->stats.phy.state; |
867 | 1292 | ||
868 | ret = uea_read_cmv(sc, SA_STAT, 0, &sc->stats.phy.state); | 1293 | ret = uea_read_cmv_e1(sc, E1_SA_STAT, 0, &sc->stats.phy.state); |
869 | if (ret < 0) | 1294 | if (ret < 0) |
870 | return ret; | 1295 | return ret; |
871 | 1296 | ||
@@ -885,7 +1310,7 @@ static int uea_stat(struct uea_softc *sc) | |||
885 | 1310 | ||
886 | case 3: /* fail ... */ | 1311 | case 3: /* fail ... */ |
887 | uea_info(INS_TO_USBDEV(sc), "modem synchronization failed" | 1312 | uea_info(INS_TO_USBDEV(sc), "modem synchronization failed" |
888 | " (may be try other cmv/dsp)\n"); | 1313 | " (may be try other cmv/dsp)\n"); |
889 | return -EAGAIN; | 1314 | return -EAGAIN; |
890 | 1315 | ||
891 | case 4 ... 6: /* test state */ | 1316 | case 4 ... 6: /* test state */ |
@@ -923,7 +1348,7 @@ static int uea_stat(struct uea_softc *sc) | |||
923 | /* wake up processes waiting for synchronization */ | 1348 | /* wake up processes waiting for synchronization */ |
924 | wake_up(&sc->sync_q); | 1349 | wake_up(&sc->sync_q); |
925 | 1350 | ||
926 | ret = uea_read_cmv(sc, SA_DIAG, 2, &sc->stats.phy.flags); | 1351 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 2, &sc->stats.phy.flags); |
927 | if (ret < 0) | 1352 | if (ret < 0) |
928 | return ret; | 1353 | return ret; |
929 | sc->stats.phy.mflags |= sc->stats.phy.flags; | 1354 | sc->stats.phy.mflags |= sc->stats.phy.flags; |
@@ -937,105 +1362,223 @@ static int uea_stat(struct uea_softc *sc) | |||
937 | return 0; | 1362 | return 0; |
938 | } | 1363 | } |
939 | 1364 | ||
940 | ret = uea_read_cmv(sc, SA_RATE, 0, &data); | 1365 | ret = uea_read_cmv_e1(sc, E1_SA_RATE, 0, &data); |
941 | if (ret < 0) | 1366 | if (ret < 0) |
942 | return ret; | 1367 | return ret; |
943 | 1368 | ||
944 | /* in bulk mode the modem have problem with high rate | 1369 | uea_set_bulk_timeout(sc, (data >> 16) * 32); |
945 | * changing internal timing could improve things, but the | ||
946 | * value is misterious. | ||
947 | * ADI930 don't support it (-EPIPE error). | ||
948 | */ | ||
949 | if (UEA_CHIP_VERSION(sc) != ADI930 | ||
950 | && !use_iso[sc->modem_index] | ||
951 | && sc->stats.phy.dsrate != (data >> 16) * 32) { | ||
952 | /* Original timming from ADI(used in windows driver) | ||
953 | * 0x20ffff>>16 * 32 = 32 * 32 = 1Mbits | ||
954 | */ | ||
955 | u16 timeout = (data <= 0x20ffff) ? 0 : 1; | ||
956 | ret = uea_request(sc, UEA_SET_TIMEOUT, timeout, 0, NULL); | ||
957 | uea_info(INS_TO_USBDEV(sc), | ||
958 | "setting new timeout %d%s\n", timeout, | ||
959 | ret < 0?" failed":""); | ||
960 | } | ||
961 | sc->stats.phy.dsrate = (data >> 16) * 32; | 1370 | sc->stats.phy.dsrate = (data >> 16) * 32; |
962 | sc->stats.phy.usrate = (data & 0xffff) * 32; | 1371 | sc->stats.phy.usrate = (data & 0xffff) * 32; |
963 | UPDATE_ATM_STAT(link_rate, sc->stats.phy.dsrate * 1000 / 424); | 1372 | UPDATE_ATM_STAT(link_rate, sc->stats.phy.dsrate * 1000 / 424); |
964 | 1373 | ||
965 | ret = uea_read_cmv(sc, SA_DIAG, 23, &data); | 1374 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 23, &data); |
966 | if (ret < 0) | 1375 | if (ret < 0) |
967 | return ret; | 1376 | return ret; |
968 | sc->stats.phy.dsattenuation = (data & 0xff) / 2; | 1377 | sc->stats.phy.dsattenuation = (data & 0xff) / 2; |
969 | 1378 | ||
970 | ret = uea_read_cmv(sc, SA_DIAG, 47, &data); | 1379 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 47, &data); |
971 | if (ret < 0) | 1380 | if (ret < 0) |
972 | return ret; | 1381 | return ret; |
973 | sc->stats.phy.usattenuation = (data & 0xff) / 2; | 1382 | sc->stats.phy.usattenuation = (data & 0xff) / 2; |
974 | 1383 | ||
975 | ret = uea_read_cmv(sc, SA_DIAG, 25, &sc->stats.phy.dsmargin); | 1384 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 25, &sc->stats.phy.dsmargin); |
976 | if (ret < 0) | 1385 | if (ret < 0) |
977 | return ret; | 1386 | return ret; |
978 | 1387 | ||
979 | ret = uea_read_cmv(sc, SA_DIAG, 49, &sc->stats.phy.usmargin); | 1388 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 49, &sc->stats.phy.usmargin); |
980 | if (ret < 0) | 1389 | if (ret < 0) |
981 | return ret; | 1390 | return ret; |
982 | 1391 | ||
983 | ret = uea_read_cmv(sc, SA_DIAG, 51, &sc->stats.phy.rxflow); | 1392 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 51, &sc->stats.phy.rxflow); |
984 | if (ret < 0) | 1393 | if (ret < 0) |
985 | return ret; | 1394 | return ret; |
986 | 1395 | ||
987 | ret = uea_read_cmv(sc, SA_DIAG, 52, &sc->stats.phy.txflow); | 1396 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 52, &sc->stats.phy.txflow); |
988 | if (ret < 0) | 1397 | if (ret < 0) |
989 | return ret; | 1398 | return ret; |
990 | 1399 | ||
991 | ret = uea_read_cmv(sc, SA_DIAG, 54, &sc->stats.phy.dsunc); | 1400 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 54, &sc->stats.phy.dsunc); |
992 | if (ret < 0) | 1401 | if (ret < 0) |
993 | return ret; | 1402 | return ret; |
994 | 1403 | ||
995 | /* only for atu-c */ | 1404 | /* only for atu-c */ |
996 | ret = uea_read_cmv(sc, SA_DIAG, 58, &sc->stats.phy.usunc); | 1405 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 58, &sc->stats.phy.usunc); |
997 | if (ret < 0) | 1406 | if (ret < 0) |
998 | return ret; | 1407 | return ret; |
999 | 1408 | ||
1000 | ret = uea_read_cmv(sc, SA_DIAG, 53, &sc->stats.phy.dscorr); | 1409 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 53, &sc->stats.phy.dscorr); |
1001 | if (ret < 0) | 1410 | if (ret < 0) |
1002 | return ret; | 1411 | return ret; |
1003 | 1412 | ||
1004 | /* only for atu-c */ | 1413 | /* only for atu-c */ |
1005 | ret = uea_read_cmv(sc, SA_DIAG, 57, &sc->stats.phy.uscorr); | 1414 | ret = uea_read_cmv_e1(sc, E1_SA_DIAG, 57, &sc->stats.phy.uscorr); |
1006 | if (ret < 0) | 1415 | if (ret < 0) |
1007 | return ret; | 1416 | return ret; |
1008 | 1417 | ||
1009 | ret = uea_read_cmv(sc, SA_INFO, 8, &sc->stats.phy.vidco); | 1418 | ret = uea_read_cmv_e1(sc, E1_SA_INFO, 8, &sc->stats.phy.vidco); |
1010 | if (ret < 0) | 1419 | if (ret < 0) |
1011 | return ret; | 1420 | return ret; |
1012 | 1421 | ||
1013 | ret = uea_read_cmv(sc, SA_INFO, 13, &sc->stats.phy.vidcpe); | 1422 | ret = uea_read_cmv_e1(sc, E1_SA_INFO, 13, &sc->stats.phy.vidcpe); |
1014 | if (ret < 0) | 1423 | if (ret < 0) |
1015 | return ret; | 1424 | return ret; |
1016 | 1425 | ||
1017 | return 0; | 1426 | return 0; |
1018 | } | 1427 | } |
1019 | 1428 | ||
1020 | static int request_cmvs(struct uea_softc *sc, | 1429 | static int uea_stat_e4(struct uea_softc *sc) |
1021 | struct uea_cmvs **cmvs, const struct firmware **fw) | ||
1022 | { | 1430 | { |
1023 | int ret, size; | 1431 | u32 data; |
1024 | u8 *data; | 1432 | u32 tmp_arr[2]; |
1433 | int ret; | ||
1434 | |||
1435 | uea_enters(INS_TO_USBDEV(sc)); | ||
1436 | data = sc->stats.phy.state; | ||
1437 | |||
1438 | /* XXX only need to be done before operationnal... */ | ||
1439 | ret = uea_read_cmv_e4(sc, 1, E4_SA_STAT, 0, 0, &sc->stats.phy.state); | ||
1440 | if (ret < 0) | ||
1441 | return ret; | ||
1442 | |||
1443 | switch (sc->stats.phy.state) { | ||
1444 | case 0x0: /* not yet synchronized */ | ||
1445 | case 0x1: | ||
1446 | case 0x3: | ||
1447 | case 0x4: | ||
1448 | uea_dbg(INS_TO_USBDEV(sc), "modem not yet synchronized\n"); | ||
1449 | return 0; | ||
1450 | case 0x5: /* initialization */ | ||
1451 | case 0x6: | ||
1452 | case 0x9: | ||
1453 | case 0xa: | ||
1454 | uea_dbg(INS_TO_USBDEV(sc), "modem initializing\n"); | ||
1455 | return 0; | ||
1456 | case 0x2: /* fail ... */ | ||
1457 | uea_info(INS_TO_USBDEV(sc), "modem synchronization failed" | ||
1458 | " (may be try other cmv/dsp)\n"); | ||
1459 | return -EAGAIN; | ||
1460 | case 0x7: /* operational */ | ||
1461 | break; | ||
1462 | default: | ||
1463 | uea_warn(INS_TO_USBDEV(sc), "unknown state: %x\n", sc->stats.phy.state); | ||
1464 | return 0; | ||
1465 | } | ||
1466 | |||
1467 | if (data != 7) { | ||
1468 | uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_OFF, 0, NULL); | ||
1469 | uea_info(INS_TO_USBDEV(sc), "modem operational\n"); | ||
1470 | |||
1471 | /* release the dsp firmware as it is not needed until | ||
1472 | * the next failure | ||
1473 | */ | ||
1474 | if (sc->dsp_firm) { | ||
1475 | release_firmware(sc->dsp_firm); | ||
1476 | sc->dsp_firm = NULL; | ||
1477 | } | ||
1478 | } | ||
1479 | |||
1480 | /* always update it as atm layer could not be init when we switch to | ||
1481 | * operational state | ||
1482 | */ | ||
1483 | UPDATE_ATM_STAT(signal, ATM_PHY_SIG_FOUND); | ||
1484 | |||
1485 | /* wake up processes waiting for synchronization */ | ||
1486 | wake_up(&sc->sync_q); | ||
1487 | |||
1488 | /* TODO improve this state machine : | ||
1489 | * we need some CMV info : what they do and their unit | ||
1490 | * we should find the equivalent of eagle3- CMV | ||
1491 | */ | ||
1492 | /* check flags */ | ||
1493 | ret = uea_read_cmv_e4(sc, 1, E4_SA_DIAG, 0, 0, &sc->stats.phy.flags); | ||
1494 | if (ret < 0) | ||
1495 | return ret; | ||
1496 | sc->stats.phy.mflags |= sc->stats.phy.flags; | ||
1497 | |||
1498 | /* in case of a flags ( for example delineation LOSS (& 0x10)), | ||
1499 | * we check the status again in order to detect the failure earlier | ||
1500 | */ | ||
1501 | if (sc->stats.phy.flags) { | ||
1502 | uea_dbg(INS_TO_USBDEV(sc), "Stat flag = 0x%x\n", | ||
1503 | sc->stats.phy.flags); | ||
1504 | if (sc->stats.phy.flags & 1) //delineation LOSS | ||
1505 | return -EAGAIN; | ||
1506 | if (sc->stats.phy.flags & 0x4000) //Reset Flag | ||
1507 | return -EAGAIN; | ||
1508 | return 0; | ||
1509 | } | ||
1510 | |||
1511 | /* rate data may be in upper or lower half of 64 bit word, strange */ | ||
1512 | ret = uea_read_cmv_e4(sc, 4, E4_SA_RATE, 0, 0, tmp_arr); | ||
1513 | if (ret < 0) | ||
1514 | return ret; | ||
1515 | data = (tmp_arr[0]) ? tmp_arr[0] : tmp_arr[1]; | ||
1516 | sc->stats.phy.usrate = data / 1000; | ||
1517 | |||
1518 | ret = uea_read_cmv_e4(sc, 4, E4_SA_RATE, 1, 0, tmp_arr); | ||
1519 | if (ret < 0) | ||
1520 | return ret; | ||
1521 | data = (tmp_arr[0]) ? tmp_arr[0] : tmp_arr[1]; | ||
1522 | uea_set_bulk_timeout(sc, data / 1000); | ||
1523 | sc->stats.phy.dsrate = data / 1000; | ||
1524 | UPDATE_ATM_STAT(link_rate, sc->stats.phy.dsrate * 1000 / 424); | ||
1525 | |||
1526 | ret = uea_read_cmv_e4(sc, 1, E4_SA_INFO, 68, 1, &data); | ||
1527 | if (ret < 0) | ||
1528 | return ret; | ||
1529 | sc->stats.phy.dsattenuation = data / 10; | ||
1530 | |||
1531 | ret = uea_read_cmv_e4(sc, 1, E4_SA_INFO, 69, 1, &data); | ||
1532 | if (ret < 0) | ||
1533 | return ret; | ||
1534 | sc->stats.phy.usattenuation = data / 10; | ||
1535 | |||
1536 | ret = uea_read_cmv_e4(sc, 1, E4_SA_INFO, 68, 3, &data); | ||
1537 | if (ret < 0) | ||
1538 | return ret; | ||
1539 | sc->stats.phy.dsmargin = data / 2; | ||
1540 | |||
1541 | ret = uea_read_cmv_e4(sc, 1, E4_SA_INFO, 69, 3, &data); | ||
1542 | if (ret < 0) | ||
1543 | return ret; | ||
1544 | sc->stats.phy.usmargin = data / 10; | ||
1545 | |||
1546 | return 0; | ||
1547 | } | ||
1548 | |||
1549 | static void cmvs_file_name(struct uea_softc *sc, char *const cmv_name, int ver) | ||
1550 | { | ||
1551 | char file_arr[] = "CMVxy.bin"; | ||
1025 | char *file; | 1552 | char *file; |
1026 | char cmv_name[FIRMWARE_NAME_MAX]; /* 30 bytes stack variable */ | ||
1027 | 1553 | ||
1554 | /* set proper name corresponding modem version and line type */ | ||
1028 | if (cmv_file[sc->modem_index] == NULL) { | 1555 | if (cmv_file[sc->modem_index] == NULL) { |
1029 | if (UEA_CHIP_VERSION(sc) == ADI930) | 1556 | if (UEA_CHIP_VERSION(sc) == ADI930) |
1030 | file = (IS_ISDN(sc->usb_dev)) ? "CMV9i.bin" : "CMV9p.bin"; | 1557 | file_arr[3] = '9'; |
1558 | else if (UEA_CHIP_VERSION(sc) == EAGLE_IV) | ||
1559 | file_arr[3] = '4'; | ||
1031 | else | 1560 | else |
1032 | file = (IS_ISDN(sc->usb_dev)) ? "CMVei.bin" : "CMVep.bin"; | 1561 | file_arr[3] = 'e'; |
1562 | |||
1563 | file_arr[4] = IS_ISDN(sc) ? 'i' : 'p'; | ||
1564 | file = file_arr; | ||
1033 | } else | 1565 | } else |
1034 | file = cmv_file[sc->modem_index]; | 1566 | file = cmv_file[sc->modem_index]; |
1035 | 1567 | ||
1036 | strcpy(cmv_name, FW_DIR); | 1568 | strcpy(cmv_name, FW_DIR); |
1037 | strlcat(cmv_name, file, sizeof(cmv_name)); | 1569 | strlcat(cmv_name, file, FIRMWARE_NAME_MAX); |
1570 | if (ver == 2) | ||
1571 | strlcat(cmv_name, ".v2", FIRMWARE_NAME_MAX); | ||
1572 | } | ||
1573 | |||
1574 | static int request_cmvs_old(struct uea_softc *sc, | ||
1575 | void **cmvs, const struct firmware **fw) | ||
1576 | { | ||
1577 | int ret, size; | ||
1578 | u8 *data; | ||
1579 | char cmv_name[FIRMWARE_NAME_MAX]; /* 30 bytes stack variable */ | ||
1038 | 1580 | ||
1581 | cmvs_file_name(sc, cmv_name, 1); | ||
1039 | ret = request_firmware(fw, cmv_name, &sc->usb_dev->dev); | 1582 | ret = request_firmware(fw, cmv_name, &sc->usb_dev->dev); |
1040 | if (ret < 0) { | 1583 | if (ret < 0) { |
1041 | uea_err(INS_TO_USBDEV(sc), | 1584 | uea_err(INS_TO_USBDEV(sc), |
@@ -1045,16 +1588,197 @@ static int request_cmvs(struct uea_softc *sc, | |||
1045 | } | 1588 | } |
1046 | 1589 | ||
1047 | data = (u8 *) (*fw)->data; | 1590 | data = (u8 *) (*fw)->data; |
1048 | size = *data * sizeof(struct uea_cmvs) + 1; | 1591 | size = (*fw)->size; |
1049 | if (size != (*fw)->size) { | 1592 | if (size < 1) |
1050 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", | 1593 | goto err_fw_corrupted; |
1051 | cmv_name); | 1594 | |
1052 | release_firmware(*fw); | 1595 | if (size != *data * sizeof(struct uea_cmvs_v1) + 1) |
1053 | return -EILSEQ; | 1596 | goto err_fw_corrupted; |
1597 | |||
1598 | *cmvs = (void *)(data + 1); | ||
1599 | return *data; | ||
1600 | |||
1601 | err_fw_corrupted: | ||
1602 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", cmv_name); | ||
1603 | release_firmware(*fw); | ||
1604 | return -EILSEQ; | ||
1605 | } | ||
1606 | |||
1607 | static int request_cmvs(struct uea_softc *sc, | ||
1608 | void **cmvs, const struct firmware **fw, int *ver) | ||
1609 | { | ||
1610 | int ret, size; | ||
1611 | u32 crc; | ||
1612 | u8 *data; | ||
1613 | char cmv_name[FIRMWARE_NAME_MAX]; /* 30 bytes stack variable */ | ||
1614 | |||
1615 | cmvs_file_name(sc, cmv_name, 2); | ||
1616 | ret = request_firmware(fw, cmv_name, &sc->usb_dev->dev); | ||
1617 | if (ret < 0) { | ||
1618 | /* if caller can handle old version, try to provide it */ | ||
1619 | if (*ver == 1) { | ||
1620 | uea_warn(INS_TO_USBDEV(sc), "requesting firmware %s failed, " | ||
1621 | "try to get older cmvs\n", cmv_name); | ||
1622 | return request_cmvs_old(sc, cmvs, fw); | ||
1623 | } | ||
1624 | uea_err(INS_TO_USBDEV(sc), | ||
1625 | "requesting firmware %s failed with error %d\n", | ||
1626 | cmv_name, ret); | ||
1627 | return ret; | ||
1054 | } | 1628 | } |
1055 | 1629 | ||
1056 | *cmvs = (struct uea_cmvs *)(data + 1); | 1630 | size = (*fw)->size; |
1631 | data = (u8 *) (*fw)->data; | ||
1632 | if (size < 4 || strncmp(data, "cmv2", 4) != 0) { | ||
1633 | if (*ver == 1) { | ||
1634 | uea_warn(INS_TO_USBDEV(sc), "firmware %s is corrupted, " | ||
1635 | "try to get older cmvs\n", cmv_name); | ||
1636 | release_firmware(*fw); | ||
1637 | return request_cmvs_old(sc, cmvs, fw); | ||
1638 | } | ||
1639 | goto err_fw_corrupted; | ||
1640 | } | ||
1641 | |||
1642 | *ver = 2; | ||
1643 | |||
1644 | data += 4; | ||
1645 | size -= 4; | ||
1646 | if (size < 5) | ||
1647 | goto err_fw_corrupted; | ||
1648 | |||
1649 | crc = FW_GET_LONG(data); | ||
1650 | data += 4; | ||
1651 | size -= 4; | ||
1652 | if (crc32_be(0, data, size) != crc) | ||
1653 | goto err_fw_corrupted; | ||
1654 | |||
1655 | if (size != *data * sizeof(struct uea_cmvs_v2) + 1) | ||
1656 | goto err_fw_corrupted; | ||
1657 | |||
1658 | *cmvs = (void *) (data + 1); | ||
1057 | return *data; | 1659 | return *data; |
1660 | |||
1661 | err_fw_corrupted: | ||
1662 | uea_err(INS_TO_USBDEV(sc), "firmware %s is corrupted\n", cmv_name); | ||
1663 | release_firmware(*fw); | ||
1664 | return -EILSEQ; | ||
1665 | } | ||
1666 | |||
1667 | static int uea_send_cmvs_e1(struct uea_softc *sc) | ||
1668 | { | ||
1669 | int i, ret, len; | ||
1670 | void *cmvs_ptr; | ||
1671 | const struct firmware *cmvs_fw; | ||
1672 | int ver = 1; // we can handle v1 cmv firmware version; | ||
1673 | |||
1674 | /* Enter in R-IDLE (cmv) until instructed otherwise */ | ||
1675 | ret = uea_write_cmv_e1(sc, E1_SA_CNTL, 0, 1); | ||
1676 | if (ret < 0) | ||
1677 | return ret; | ||
1678 | |||
1679 | /* Dump firmware version */ | ||
1680 | ret = uea_read_cmv_e1(sc, E1_SA_INFO, 10, &sc->stats.phy.firmid); | ||
1681 | if (ret < 0) | ||
1682 | return ret; | ||
1683 | uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n", | ||
1684 | sc->stats.phy.firmid); | ||
1685 | |||
1686 | /* get options */ | ||
1687 | ret = len = request_cmvs(sc, &cmvs_ptr, &cmvs_fw, &ver); | ||
1688 | if (ret < 0) | ||
1689 | return ret; | ||
1690 | |||
1691 | /* send options */ | ||
1692 | if (ver == 1) { | ||
1693 | struct uea_cmvs_v1 *cmvs_v1 = cmvs_ptr; | ||
1694 | |||
1695 | uea_warn(INS_TO_USBDEV(sc), "use deprecated cmvs version, " | ||
1696 | "please update your firmware\n"); | ||
1697 | |||
1698 | for (i = 0; i < len; i++) { | ||
1699 | ret = uea_write_cmv_e1(sc, FW_GET_LONG(&cmvs_v1[i].address), | ||
1700 | FW_GET_WORD(&cmvs_v1[i].offset), | ||
1701 | FW_GET_LONG(&cmvs_v1[i].data)); | ||
1702 | if (ret < 0) | ||
1703 | goto out; | ||
1704 | } | ||
1705 | } else if (ver == 2) { | ||
1706 | struct uea_cmvs_v2 *cmvs_v2 = cmvs_ptr; | ||
1707 | |||
1708 | for (i = 0; i < len; i++) { | ||
1709 | ret = uea_write_cmv_e1(sc, FW_GET_LONG(&cmvs_v2[i].address), | ||
1710 | (u16) FW_GET_LONG(&cmvs_v2[i].offset), | ||
1711 | FW_GET_LONG(&cmvs_v2[i].data)); | ||
1712 | if (ret < 0) | ||
1713 | goto out; | ||
1714 | } | ||
1715 | } else { | ||
1716 | /* This realy should not happen */ | ||
1717 | uea_err(INS_TO_USBDEV(sc), "bad cmvs version %d\n", ver); | ||
1718 | goto out; | ||
1719 | } | ||
1720 | |||
1721 | /* Enter in R-ACT-REQ */ | ||
1722 | ret = uea_write_cmv_e1(sc, E1_SA_CNTL, 0, 2); | ||
1723 | uea_vdbg(INS_TO_USBDEV(sc), "Entering in R-ACT-REQ state\n"); | ||
1724 | uea_info(INS_TO_USBDEV(sc), "modem started, waiting synchronization...\n"); | ||
1725 | out: | ||
1726 | release_firmware(cmvs_fw); | ||
1727 | return ret; | ||
1728 | } | ||
1729 | |||
1730 | static int uea_send_cmvs_e4(struct uea_softc *sc) | ||
1731 | { | ||
1732 | int i, ret, len; | ||
1733 | void *cmvs_ptr; | ||
1734 | const struct firmware *cmvs_fw; | ||
1735 | int ver = 2; // we can only handle v2 cmv firmware version; | ||
1736 | |||
1737 | /* Enter in R-IDLE (cmv) until instructed otherwise */ | ||
1738 | ret = uea_write_cmv_e4(sc, 1, E4_SA_CNTL, 0, 0, 1); | ||
1739 | if (ret < 0) | ||
1740 | return ret; | ||
1741 | |||
1742 | /* Dump firmware version */ | ||
1743 | /* XXX don't read the 3th byte as it is always 6 */ | ||
1744 | ret = uea_read_cmv_e4(sc, 2, E4_SA_INFO, 55, 0, &sc->stats.phy.firmid); | ||
1745 | if (ret < 0) | ||
1746 | return ret; | ||
1747 | uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n", | ||
1748 | sc->stats.phy.firmid); | ||
1749 | |||
1750 | |||
1751 | /* get options */ | ||
1752 | ret = len = request_cmvs(sc, &cmvs_ptr, &cmvs_fw, &ver); | ||
1753 | if (ret < 0) | ||
1754 | return ret; | ||
1755 | |||
1756 | /* send options */ | ||
1757 | if (ver == 2) { | ||
1758 | struct uea_cmvs_v2 *cmvs_v2 = cmvs_ptr; | ||
1759 | |||
1760 | for (i = 0; i < len; i++) { | ||
1761 | ret = uea_write_cmv_e4(sc, 1, | ||
1762 | FW_GET_LONG(&cmvs_v2[i].group), | ||
1763 | FW_GET_LONG(&cmvs_v2[i].address), | ||
1764 | FW_GET_LONG(&cmvs_v2[i].offset), | ||
1765 | FW_GET_LONG(&cmvs_v2[i].data)); | ||
1766 | if (ret < 0) | ||
1767 | goto out; | ||
1768 | } | ||
1769 | } else { | ||
1770 | /* This realy should not happen */ | ||
1771 | uea_err(INS_TO_USBDEV(sc), "bad cmvs version %d\n", ver); | ||
1772 | goto out; | ||
1773 | } | ||
1774 | |||
1775 | /* Enter in R-ACT-REQ */ | ||
1776 | ret = uea_write_cmv_e4(sc, 1, E4_SA_CNTL, 0, 0, 2); | ||
1777 | uea_vdbg(INS_TO_USBDEV(sc), "Entering in R-ACT-REQ state\n"); | ||
1778 | uea_info(INS_TO_USBDEV(sc), "modem started, waiting synchronization...\n"); | ||
1779 | out: | ||
1780 | release_firmware(cmvs_fw); | ||
1781 | return ret; | ||
1058 | } | 1782 | } |
1059 | 1783 | ||
1060 | /* Start boot post firmware modem: | 1784 | /* Start boot post firmware modem: |
@@ -1066,9 +1790,7 @@ static int request_cmvs(struct uea_softc *sc, | |||
1066 | static int uea_start_reset(struct uea_softc *sc) | 1790 | static int uea_start_reset(struct uea_softc *sc) |
1067 | { | 1791 | { |
1068 | u16 zero = 0; /* ;-) */ | 1792 | u16 zero = 0; /* ;-) */ |
1069 | int i, len, ret; | 1793 | int ret; |
1070 | struct uea_cmvs *cmvs; | ||
1071 | const struct firmware *cmvs_fw; | ||
1072 | 1794 | ||
1073 | uea_enters(INS_TO_USBDEV(sc)); | 1795 | uea_enters(INS_TO_USBDEV(sc)); |
1074 | uea_info(INS_TO_USBDEV(sc), "(re)booting started\n"); | 1796 | uea_info(INS_TO_USBDEV(sc), "(re)booting started\n"); |
@@ -1093,25 +1815,36 @@ static int uea_start_reset(struct uea_softc *sc) | |||
1093 | uea_request(sc, UEA_SET_MODE, UEA_START_RESET, 0, NULL); | 1815 | uea_request(sc, UEA_SET_MODE, UEA_START_RESET, 0, NULL); |
1094 | 1816 | ||
1095 | /* original driver use 200ms, but windows driver use 100ms */ | 1817 | /* original driver use 200ms, but windows driver use 100ms */ |
1096 | msleep(100); | 1818 | ret = uea_wait(sc, 0, msecs_to_jiffies(100)); |
1819 | if (ret < 0) | ||
1820 | return ret; | ||
1097 | 1821 | ||
1098 | /* leave reset mode */ | 1822 | /* leave reset mode */ |
1099 | uea_request(sc, UEA_SET_MODE, UEA_END_RESET, 0, NULL); | 1823 | uea_request(sc, UEA_SET_MODE, UEA_END_RESET, 0, NULL); |
1100 | 1824 | ||
1101 | /* clear tx and rx mailboxes */ | 1825 | if (UEA_CHIP_VERSION(sc) != EAGLE_IV) { |
1102 | uea_request(sc, UEA_SET_2183_DATA, UEA_MPTX_MAILBOX, 2, &zero); | 1826 | /* clear tx and rx mailboxes */ |
1103 | uea_request(sc, UEA_SET_2183_DATA, UEA_MPRX_MAILBOX, 2, &zero); | 1827 | uea_request(sc, UEA_SET_2183_DATA, UEA_MPTX_MAILBOX, 2, &zero); |
1104 | uea_request(sc, UEA_SET_2183_DATA, UEA_SWAP_MAILBOX, 2, &zero); | 1828 | uea_request(sc, UEA_SET_2183_DATA, UEA_MPRX_MAILBOX, 2, &zero); |
1829 | uea_request(sc, UEA_SET_2183_DATA, UEA_SWAP_MAILBOX, 2, &zero); | ||
1830 | } | ||
1831 | |||
1832 | ret = uea_wait(sc, 0, msecs_to_jiffies(1000)); | ||
1833 | if (ret < 0) | ||
1834 | return ret; | ||
1835 | |||
1836 | if (UEA_CHIP_VERSION(sc) == EAGLE_IV) | ||
1837 | sc->cmv_dsc.e4.function = E4_MAKEFUNCTION(E4_ADSLDIRECTIVE, E4_MODEMREADY, 1); | ||
1838 | else | ||
1839 | sc->cmv_dsc.e1.function = E1_MAKEFUNCTION(E1_ADSLDIRECTIVE, E1_MODEMREADY); | ||
1105 | 1840 | ||
1106 | msleep(1000); | ||
1107 | sc->cmv_function = MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY); | ||
1108 | /* demask interrupt */ | 1841 | /* demask interrupt */ |
1109 | sc->booting = 0; | 1842 | sc->booting = 0; |
1110 | 1843 | ||
1111 | /* start loading DSP */ | 1844 | /* start loading DSP */ |
1112 | sc->pageno = 0; | 1845 | sc->pageno = 0; |
1113 | sc->ovl = 0; | 1846 | sc->ovl = 0; |
1114 | schedule_work(&sc->task); | 1847 | queue_work(sc->work_q, &sc->task); |
1115 | 1848 | ||
1116 | /* wait for modem ready CMV */ | 1849 | /* wait for modem ready CMV */ |
1117 | ret = wait_cmv_ack(sc); | 1850 | ret = wait_cmv_ack(sc); |
@@ -1120,38 +1853,10 @@ static int uea_start_reset(struct uea_softc *sc) | |||
1120 | 1853 | ||
1121 | uea_vdbg(INS_TO_USBDEV(sc), "Ready CMV received\n"); | 1854 | uea_vdbg(INS_TO_USBDEV(sc), "Ready CMV received\n"); |
1122 | 1855 | ||
1123 | /* Enter in R-IDLE (cmv) until instructed otherwise */ | 1856 | ret = sc->send_cmvs(sc); |
1124 | ret = uea_write_cmv(sc, SA_CNTL, 0, 1); | ||
1125 | if (ret < 0) | 1857 | if (ret < 0) |
1126 | return ret; | 1858 | return ret; |
1127 | 1859 | ||
1128 | /* Dump firmware version */ | ||
1129 | ret = uea_read_cmv(sc, SA_INFO, 10, &sc->stats.phy.firmid); | ||
1130 | if (ret < 0) | ||
1131 | return ret; | ||
1132 | uea_info(INS_TO_USBDEV(sc), "ATU-R firmware version : %x\n", | ||
1133 | sc->stats.phy.firmid); | ||
1134 | |||
1135 | /* get options */ | ||
1136 | ret = len = request_cmvs(sc, &cmvs, &cmvs_fw); | ||
1137 | if (ret < 0) | ||
1138 | return ret; | ||
1139 | |||
1140 | /* send options */ | ||
1141 | for (i = 0; i < len; i++) { | ||
1142 | ret = uea_write_cmv(sc, FW_GET_LONG(&cmvs[i].address), | ||
1143 | FW_GET_WORD(&cmvs[i].offset), | ||
1144 | FW_GET_LONG(&cmvs[i].data)); | ||
1145 | if (ret < 0) | ||
1146 | goto out; | ||
1147 | } | ||
1148 | /* Enter in R-ACT-REQ */ | ||
1149 | ret = uea_write_cmv(sc, SA_CNTL, 0, 2); | ||
1150 | uea_vdbg(INS_TO_USBDEV(sc), "Entering in R-ACT-REQ state\n"); | ||
1151 | uea_info(INS_TO_USBDEV(sc), "Modem started, " | ||
1152 | "waiting synchronization\n"); | ||
1153 | out: | ||
1154 | release_firmware(cmvs_fw); | ||
1155 | sc->reset = 0; | 1860 | sc->reset = 0; |
1156 | uea_leaves(INS_TO_USBDEV(sc)); | 1861 | uea_leaves(INS_TO_USBDEV(sc)); |
1157 | return ret; | 1862 | return ret; |
@@ -1174,12 +1879,10 @@ static int uea_kthread(void *data) | |||
1174 | if (ret < 0 || sc->reset) | 1879 | if (ret < 0 || sc->reset) |
1175 | ret = uea_start_reset(sc); | 1880 | ret = uea_start_reset(sc); |
1176 | if (!ret) | 1881 | if (!ret) |
1177 | ret = uea_stat(sc); | 1882 | ret = sc->stat(sc); |
1178 | if (ret != -EAGAIN) | 1883 | if (ret != -EAGAIN) |
1179 | msleep_interruptible(1000); | 1884 | uea_wait(sc, 0, msecs_to_jiffies(1000)); |
1180 | if (try_to_freeze()) | 1885 | try_to_freeze(); |
1181 | uea_err(INS_TO_USBDEV(sc), "suspend/resume not supported, " | ||
1182 | "please unplug/replug your modem\n"); | ||
1183 | } | 1886 | } |
1184 | uea_leaves(INS_TO_USBDEV(sc)); | 1887 | uea_leaves(INS_TO_USBDEV(sc)); |
1185 | return ret; | 1888 | return ret; |
@@ -1234,7 +1937,6 @@ static int load_XILINX_firmware(struct uea_softc *sc) | |||
1234 | if (ret < 0) | 1937 | if (ret < 0) |
1235 | uea_err(sc->usb_dev, "elsa de-assert failed with error %d\n", ret); | 1938 | uea_err(sc->usb_dev, "elsa de-assert failed with error %d\n", ret); |
1236 | 1939 | ||
1237 | |||
1238 | err1: | 1940 | err1: |
1239 | release_firmware(fw_entry); | 1941 | release_firmware(fw_entry); |
1240 | err0: | 1942 | err0: |
@@ -1243,40 +1945,41 @@ err0: | |||
1243 | } | 1945 | } |
1244 | 1946 | ||
1245 | /* The modem send us an ack. First with check if it right */ | 1947 | /* The modem send us an ack. First with check if it right */ |
1246 | static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv) | 1948 | static void uea_dispatch_cmv_e1(struct uea_softc *sc, struct intr_pkt *intr) |
1247 | { | 1949 | { |
1950 | struct cmv_dsc_e1 *dsc = &sc->cmv_dsc.e1; | ||
1951 | struct cmv_e1 *cmv = &intr->u.e1.s2.cmv; | ||
1952 | |||
1248 | uea_enters(INS_TO_USBDEV(sc)); | 1953 | uea_enters(INS_TO_USBDEV(sc)); |
1249 | if (le16_to_cpu(cmv->wPreamble) != PREAMBLE) | 1954 | if (le16_to_cpu(cmv->wPreamble) != E1_PREAMBLE) |
1250 | goto bad1; | 1955 | goto bad1; |
1251 | 1956 | ||
1252 | if (cmv->bDirection != MODEMTOHOST) | 1957 | if (cmv->bDirection != E1_MODEMTOHOST) |
1253 | goto bad1; | 1958 | goto bad1; |
1254 | 1959 | ||
1255 | /* FIXME : ADI930 reply wrong preambule (func = 2, sub = 2) to | 1960 | /* FIXME : ADI930 reply wrong preambule (func = 2, sub = 2) to |
1256 | * the first MEMACESS cmv. Ignore it... | 1961 | * the first MEMACESS cmv. Ignore it... |
1257 | */ | 1962 | */ |
1258 | if (cmv->bFunction != sc->cmv_function) { | 1963 | if (cmv->bFunction != dsc->function) { |
1259 | if (UEA_CHIP_VERSION(sc) == ADI930 | 1964 | if (UEA_CHIP_VERSION(sc) == ADI930 |
1260 | && cmv->bFunction == MAKEFUNCTION(2, 2)) { | 1965 | && cmv->bFunction == E1_MAKEFUNCTION(2, 2)) { |
1261 | cmv->wIndex = cpu_to_le16(sc->cmv_idx); | 1966 | cmv->wIndex = cpu_to_le16(dsc->idx); |
1262 | put_unaligned(cpu_to_le32(sc->cmv_address), &cmv->dwSymbolicAddress); | 1967 | put_unaligned(cpu_to_le32(dsc->address), &cmv->dwSymbolicAddress); |
1263 | cmv->wOffsetAddress = cpu_to_le16(sc->cmv_offset); | 1968 | cmv->wOffsetAddress = cpu_to_le16(dsc->offset); |
1264 | } | 1969 | } else |
1265 | else | ||
1266 | goto bad2; | 1970 | goto bad2; |
1267 | } | 1971 | } |
1268 | 1972 | ||
1269 | if (cmv->bFunction == MAKEFUNCTION(ADSLDIRECTIVE, MODEMREADY)) { | 1973 | if (cmv->bFunction == E1_MAKEFUNCTION(E1_ADSLDIRECTIVE, E1_MODEMREADY)) { |
1270 | wake_up_cmv_ack(sc); | 1974 | wake_up_cmv_ack(sc); |
1271 | uea_leaves(INS_TO_USBDEV(sc)); | 1975 | uea_leaves(INS_TO_USBDEV(sc)); |
1272 | return; | 1976 | return; |
1273 | } | 1977 | } |
1274 | 1978 | ||
1275 | /* in case of MEMACCESS */ | 1979 | /* in case of MEMACCESS */ |
1276 | if (le16_to_cpu(cmv->wIndex) != sc->cmv_idx || | 1980 | if (le16_to_cpu(cmv->wIndex) != dsc->idx || |
1277 | le32_to_cpu(get_unaligned(&cmv->dwSymbolicAddress)) != | 1981 | le32_to_cpu(get_unaligned(&cmv->dwSymbolicAddress)) != dsc->address || |
1278 | sc->cmv_address | 1982 | le16_to_cpu(cmv->wOffsetAddress) != dsc->offset) |
1279 | || le16_to_cpu(cmv->wOffsetAddress) != sc->cmv_offset) | ||
1280 | goto bad2; | 1983 | goto bad2; |
1281 | 1984 | ||
1282 | sc->data = le32_to_cpu(get_unaligned(&cmv->dwData)); | 1985 | sc->data = le32_to_cpu(get_unaligned(&cmv->dwData)); |
@@ -1289,8 +1992,8 @@ static void uea_dispatch_cmv(struct uea_softc *sc, struct cmv* cmv) | |||
1289 | bad2: | 1992 | bad2: |
1290 | uea_err(INS_TO_USBDEV(sc), "unexpected cmv received," | 1993 | uea_err(INS_TO_USBDEV(sc), "unexpected cmv received," |
1291 | "Function : %d, Subfunction : %d\n", | 1994 | "Function : %d, Subfunction : %d\n", |
1292 | FUNCTION_TYPE(cmv->bFunction), | 1995 | E1_FUNCTION_TYPE(cmv->bFunction), |
1293 | FUNCTION_SUBTYPE(cmv->bFunction)); | 1996 | E1_FUNCTION_SUBTYPE(cmv->bFunction)); |
1294 | uea_leaves(INS_TO_USBDEV(sc)); | 1997 | uea_leaves(INS_TO_USBDEV(sc)); |
1295 | return; | 1998 | return; |
1296 | 1999 | ||
@@ -1301,6 +2004,61 @@ bad1: | |||
1301 | uea_leaves(INS_TO_USBDEV(sc)); | 2004 | uea_leaves(INS_TO_USBDEV(sc)); |
1302 | } | 2005 | } |
1303 | 2006 | ||
2007 | /* The modem send us an ack. First with check if it right */ | ||
2008 | static void uea_dispatch_cmv_e4(struct uea_softc *sc, struct intr_pkt *intr) | ||
2009 | { | ||
2010 | struct cmv_dsc_e4 *dsc = &sc->cmv_dsc.e4; | ||
2011 | struct cmv_e4 *cmv = &intr->u.e4.s2.cmv; | ||
2012 | |||
2013 | uea_enters(INS_TO_USBDEV(sc)); | ||
2014 | uea_dbg(INS_TO_USBDEV(sc), "cmv %x %x %x %x %x %x\n", | ||
2015 | be16_to_cpu(cmv->wGroup), be16_to_cpu(cmv->wFunction), | ||
2016 | be16_to_cpu(cmv->wOffset), be16_to_cpu(cmv->wAddress), | ||
2017 | be32_to_cpu(cmv->dwData[0]), be32_to_cpu(cmv->dwData[1])); | ||
2018 | |||
2019 | if (be16_to_cpu(cmv->wFunction) != dsc->function) | ||
2020 | goto bad2; | ||
2021 | |||
2022 | if (be16_to_cpu(cmv->wFunction) == E4_MAKEFUNCTION(E4_ADSLDIRECTIVE, E4_MODEMREADY, 1)) { | ||
2023 | wake_up_cmv_ack(sc); | ||
2024 | uea_leaves(INS_TO_USBDEV(sc)); | ||
2025 | return; | ||
2026 | } | ||
2027 | |||
2028 | /* in case of MEMACCESS */ | ||
2029 | if (be16_to_cpu(cmv->wOffset) != dsc->offset || | ||
2030 | be16_to_cpu(cmv->wGroup) != dsc->group || | ||
2031 | be16_to_cpu(cmv->wAddress) != dsc->address) | ||
2032 | goto bad2; | ||
2033 | |||
2034 | sc->data = be32_to_cpu(cmv->dwData[0]); | ||
2035 | sc->data1 = be32_to_cpu(cmv->dwData[1]); | ||
2036 | wake_up_cmv_ack(sc); | ||
2037 | uea_leaves(INS_TO_USBDEV(sc)); | ||
2038 | return; | ||
2039 | |||
2040 | bad2: | ||
2041 | uea_err(INS_TO_USBDEV(sc), "unexpected cmv received," | ||
2042 | "Function : %d, Subfunction : %d\n", | ||
2043 | E4_FUNCTION_TYPE(cmv->wFunction), | ||
2044 | E4_FUNCTION_SUBTYPE(cmv->wFunction)); | ||
2045 | uea_leaves(INS_TO_USBDEV(sc)); | ||
2046 | return; | ||
2047 | } | ||
2048 | |||
2049 | static void uea_schedule_load_page_e1(struct uea_softc *sc, struct intr_pkt *intr) | ||
2050 | { | ||
2051 | sc->pageno = intr->e1_bSwapPageNo; | ||
2052 | sc->ovl = intr->e1_bOvl >> 4 | intr->e1_bOvl << 4; | ||
2053 | queue_work(sc->work_q, &sc->task); | ||
2054 | } | ||
2055 | |||
2056 | static void uea_schedule_load_page_e4(struct uea_softc *sc, struct intr_pkt *intr) | ||
2057 | { | ||
2058 | sc->pageno = intr->e4_bSwapPageNo; | ||
2059 | queue_work(sc->work_q, &sc->task); | ||
2060 | } | ||
2061 | |||
1304 | /* | 2062 | /* |
1305 | * interrupt handler | 2063 | * interrupt handler |
1306 | */ | 2064 | */ |
@@ -1308,11 +2066,13 @@ static void uea_intr(struct urb *urb) | |||
1308 | { | 2066 | { |
1309 | struct uea_softc *sc = urb->context; | 2067 | struct uea_softc *sc = urb->context; |
1310 | struct intr_pkt *intr = urb->transfer_buffer; | 2068 | struct intr_pkt *intr = urb->transfer_buffer; |
2069 | int status = urb->status; | ||
2070 | |||
1311 | uea_enters(INS_TO_USBDEV(sc)); | 2071 | uea_enters(INS_TO_USBDEV(sc)); |
1312 | 2072 | ||
1313 | if (unlikely(urb->status < 0)) { | 2073 | if (unlikely(status < 0)) { |
1314 | uea_err(INS_TO_USBDEV(sc), "uea_intr() failed with %d\n", | 2074 | uea_err(INS_TO_USBDEV(sc), "uea_intr() failed with %d\n", |
1315 | urb->status); | 2075 | status); |
1316 | return; | 2076 | return; |
1317 | } | 2077 | } |
1318 | 2078 | ||
@@ -1324,13 +2084,11 @@ static void uea_intr(struct urb *urb) | |||
1324 | 2084 | ||
1325 | switch (le16_to_cpu(intr->wInterrupt)) { | 2085 | switch (le16_to_cpu(intr->wInterrupt)) { |
1326 | case INT_LOADSWAPPAGE: | 2086 | case INT_LOADSWAPPAGE: |
1327 | sc->pageno = intr->bSwapPageNo; | 2087 | sc->schedule_load_page(sc, intr); |
1328 | sc->ovl = intr->bOvl >> 4 | intr->bOvl << 4; | ||
1329 | schedule_work(&sc->task); | ||
1330 | break; | 2088 | break; |
1331 | 2089 | ||
1332 | case INT_INCOMINGCMV: | 2090 | case INT_INCOMINGCMV: |
1333 | uea_dispatch_cmv(sc, &intr->u.s2.cmv); | 2091 | sc->dispatch_cmv(sc, intr); |
1334 | break; | 2092 | break; |
1335 | 2093 | ||
1336 | default: | 2094 | default: |
@@ -1347,35 +2105,55 @@ resubmit: | |||
1347 | */ | 2105 | */ |
1348 | static int uea_boot(struct uea_softc *sc) | 2106 | static int uea_boot(struct uea_softc *sc) |
1349 | { | 2107 | { |
1350 | int ret; | 2108 | int ret, size; |
1351 | struct intr_pkt *intr; | 2109 | struct intr_pkt *intr; |
1352 | 2110 | ||
1353 | uea_enters(INS_TO_USBDEV(sc)); | 2111 | uea_enters(INS_TO_USBDEV(sc)); |
1354 | 2112 | ||
1355 | INIT_WORK(&sc->task, uea_load_page); | 2113 | if (UEA_CHIP_VERSION(sc) == EAGLE_IV) { |
2114 | size = E4_INTR_PKT_SIZE; | ||
2115 | sc->dispatch_cmv = uea_dispatch_cmv_e4; | ||
2116 | sc->schedule_load_page = uea_schedule_load_page_e4; | ||
2117 | sc->stat = uea_stat_e4; | ||
2118 | sc->send_cmvs = uea_send_cmvs_e4; | ||
2119 | INIT_WORK(&sc->task, uea_load_page_e4); | ||
2120 | } else { | ||
2121 | size = E1_INTR_PKT_SIZE; | ||
2122 | sc->dispatch_cmv = uea_dispatch_cmv_e1; | ||
2123 | sc->schedule_load_page = uea_schedule_load_page_e1; | ||
2124 | sc->stat = uea_stat_e1; | ||
2125 | sc->send_cmvs = uea_send_cmvs_e1; | ||
2126 | INIT_WORK(&sc->task, uea_load_page_e1); | ||
2127 | } | ||
2128 | |||
1356 | init_waitqueue_head(&sc->sync_q); | 2129 | init_waitqueue_head(&sc->sync_q); |
1357 | init_waitqueue_head(&sc->cmv_ack_wait); | 2130 | |
2131 | sc->work_q = create_workqueue("ueagle-dsp"); | ||
2132 | if (!sc->work_q) { | ||
2133 | uea_err(INS_TO_USBDEV(sc), "cannot allocate workqueue\n"); | ||
2134 | uea_leaves(INS_TO_USBDEV(sc)); | ||
2135 | return -ENOMEM; | ||
2136 | } | ||
1358 | 2137 | ||
1359 | if (UEA_CHIP_VERSION(sc) == ADI930) | 2138 | if (UEA_CHIP_VERSION(sc) == ADI930) |
1360 | load_XILINX_firmware(sc); | 2139 | load_XILINX_firmware(sc); |
1361 | 2140 | ||
1362 | intr = kmalloc(INTR_PKT_SIZE, GFP_KERNEL); | 2141 | intr = kmalloc(size, GFP_KERNEL); |
1363 | if (!intr) { | 2142 | if (!intr) { |
1364 | uea_err(INS_TO_USBDEV(sc), | 2143 | uea_err(INS_TO_USBDEV(sc), |
1365 | "cannot allocate interrupt package\n"); | 2144 | "cannot allocate interrupt package\n"); |
1366 | uea_leaves(INS_TO_USBDEV(sc)); | 2145 | goto err0; |
1367 | return -ENOMEM; | ||
1368 | } | 2146 | } |
1369 | 2147 | ||
1370 | sc->urb_int = usb_alloc_urb(0, GFP_KERNEL); | 2148 | sc->urb_int = usb_alloc_urb(0, GFP_KERNEL); |
1371 | if (!sc->urb_int) { | 2149 | if (!sc->urb_int) { |
1372 | uea_err(INS_TO_USBDEV(sc), "cannot allocate interrupt URB\n"); | 2150 | uea_err(INS_TO_USBDEV(sc), "cannot allocate interrupt URB\n"); |
1373 | goto err; | 2151 | goto err1; |
1374 | } | 2152 | } |
1375 | 2153 | ||
1376 | usb_fill_int_urb(sc->urb_int, sc->usb_dev, | 2154 | usb_fill_int_urb(sc->urb_int, sc->usb_dev, |
1377 | usb_rcvintpipe(sc->usb_dev, UEA_INTR_PIPE), | 2155 | usb_rcvintpipe(sc->usb_dev, UEA_INTR_PIPE), |
1378 | intr, INTR_PKT_SIZE, uea_intr, sc, | 2156 | intr, size, uea_intr, sc, |
1379 | sc->usb_dev->actconfig->interface[0]->altsetting[0]. | 2157 | sc->usb_dev->actconfig->interface[0]->altsetting[0]. |
1380 | endpoint[0].desc.bInterval); | 2158 | endpoint[0].desc.bInterval); |
1381 | 2159 | ||
@@ -1383,7 +2161,7 @@ static int uea_boot(struct uea_softc *sc) | |||
1383 | if (ret < 0) { | 2161 | if (ret < 0) { |
1384 | uea_err(INS_TO_USBDEV(sc), | 2162 | uea_err(INS_TO_USBDEV(sc), |
1385 | "urb submition failed with error %d\n", ret); | 2163 | "urb submition failed with error %d\n", ret); |
1386 | goto err; | 2164 | goto err1; |
1387 | } | 2165 | } |
1388 | 2166 | ||
1389 | sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm"); | 2167 | sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm"); |
@@ -1397,10 +2175,12 @@ static int uea_boot(struct uea_softc *sc) | |||
1397 | 2175 | ||
1398 | err2: | 2176 | err2: |
1399 | usb_kill_urb(sc->urb_int); | 2177 | usb_kill_urb(sc->urb_int); |
1400 | err: | 2178 | err1: |
1401 | usb_free_urb(sc->urb_int); | 2179 | usb_free_urb(sc->urb_int); |
1402 | sc->urb_int = NULL; | 2180 | sc->urb_int = NULL; |
1403 | kfree(intr); | 2181 | kfree(intr); |
2182 | err0: | ||
2183 | destroy_workqueue(sc->work_q); | ||
1404 | uea_leaves(INS_TO_USBDEV(sc)); | 2184 | uea_leaves(INS_TO_USBDEV(sc)); |
1405 | return -ENOMEM; | 2185 | return -ENOMEM; |
1406 | } | 2186 | } |
@@ -1415,15 +2195,15 @@ static void uea_stop(struct uea_softc *sc) | |||
1415 | ret = kthread_stop(sc->kthread); | 2195 | ret = kthread_stop(sc->kthread); |
1416 | uea_dbg(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret); | 2196 | uea_dbg(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret); |
1417 | 2197 | ||
1418 | /* stop any pending boot process */ | ||
1419 | flush_scheduled_work(); | ||
1420 | |||
1421 | uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL); | 2198 | uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL); |
1422 | 2199 | ||
1423 | usb_kill_urb(sc->urb_int); | 2200 | usb_kill_urb(sc->urb_int); |
1424 | kfree(sc->urb_int->transfer_buffer); | 2201 | kfree(sc->urb_int->transfer_buffer); |
1425 | usb_free_urb(sc->urb_int); | 2202 | usb_free_urb(sc->urb_int); |
1426 | 2203 | ||
2204 | /* stop any pending boot process, when no one can schedule work */ | ||
2205 | destroy_workqueue(sc->work_q); | ||
2206 | |||
1427 | if (sc->dsp_firm) | 2207 | if (sc->dsp_firm) |
1428 | release_firmware(sc->dsp_firm); | 2208 | release_firmware(sc->dsp_firm); |
1429 | uea_leaves(INS_TO_USBDEV(sc)); | 2209 | uea_leaves(INS_TO_USBDEV(sc)); |
@@ -1485,6 +2265,7 @@ static ssize_t read_human_status(struct device *dev, struct device_attribute *at | |||
1485 | char *buf) | 2265 | char *buf) |
1486 | { | 2266 | { |
1487 | int ret = -ENODEV; | 2267 | int ret = -ENODEV; |
2268 | int modem_state; | ||
1488 | struct uea_softc *sc; | 2269 | struct uea_softc *sc; |
1489 | 2270 | ||
1490 | mutex_lock(&uea_mutex); | 2271 | mutex_lock(&uea_mutex); |
@@ -1492,7 +2273,34 @@ static ssize_t read_human_status(struct device *dev, struct device_attribute *at | |||
1492 | if (!sc) | 2273 | if (!sc) |
1493 | goto out; | 2274 | goto out; |
1494 | 2275 | ||
1495 | switch (GET_STATUS(sc->stats.phy.state)) { | 2276 | if (UEA_CHIP_VERSION(sc) == EAGLE_IV) { |
2277 | switch (sc->stats.phy.state) { | ||
2278 | case 0x0: /* not yet synchronized */ | ||
2279 | case 0x1: | ||
2280 | case 0x3: | ||
2281 | case 0x4: | ||
2282 | modem_state = 0; | ||
2283 | break; | ||
2284 | case 0x5: /* initialization */ | ||
2285 | case 0x6: | ||
2286 | case 0x9: | ||
2287 | case 0xa: | ||
2288 | modem_state = 1; | ||
2289 | break; | ||
2290 | case 0x7: /* operational */ | ||
2291 | modem_state = 2; | ||
2292 | break; | ||
2293 | case 0x2: /* fail ... */ | ||
2294 | modem_state = 3; | ||
2295 | break; | ||
2296 | default: /* unknown */ | ||
2297 | modem_state = 4; | ||
2298 | break; | ||
2299 | } | ||
2300 | } else | ||
2301 | modem_state = GET_STATUS(sc->stats.phy.state); | ||
2302 | |||
2303 | switch (modem_state) { | ||
1496 | case 0: | 2304 | case 0: |
1497 | ret = sprintf(buf, "Modem is booting\n"); | 2305 | ret = sprintf(buf, "Modem is booting\n"); |
1498 | break; | 2306 | break; |
@@ -1502,9 +2310,12 @@ static ssize_t read_human_status(struct device *dev, struct device_attribute *at | |||
1502 | case 2: | 2310 | case 2: |
1503 | ret = sprintf(buf, "Modem is operational\n"); | 2311 | ret = sprintf(buf, "Modem is operational\n"); |
1504 | break; | 2312 | break; |
1505 | default: | 2313 | case 3: |
1506 | ret = sprintf(buf, "Modem synchronization failed\n"); | 2314 | ret = sprintf(buf, "Modem synchronization failed\n"); |
1507 | break; | 2315 | break; |
2316 | default: | ||
2317 | ret = sprintf(buf, "Modem state is unknown\n"); | ||
2318 | break; | ||
1508 | } | 2319 | } |
1509 | out: | 2320 | out: |
1510 | mutex_unlock(&uea_mutex); | 2321 | mutex_unlock(&uea_mutex); |
@@ -1518,18 +2329,26 @@ static ssize_t read_delin(struct device *dev, struct device_attribute *attr, | |||
1518 | { | 2329 | { |
1519 | int ret = -ENODEV; | 2330 | int ret = -ENODEV; |
1520 | struct uea_softc *sc; | 2331 | struct uea_softc *sc; |
2332 | char *delin = "GOOD"; | ||
1521 | 2333 | ||
1522 | mutex_lock(&uea_mutex); | 2334 | mutex_lock(&uea_mutex); |
1523 | sc = dev_to_uea(dev); | 2335 | sc = dev_to_uea(dev); |
1524 | if (!sc) | 2336 | if (!sc) |
1525 | goto out; | 2337 | goto out; |
1526 | 2338 | ||
1527 | if (sc->stats.phy.flags & 0x0C00) | 2339 | if (UEA_CHIP_VERSION(sc) == EAGLE_IV) { |
1528 | ret = sprintf(buf, "ERROR\n"); | 2340 | if (sc->stats.phy.flags & 0x4000) |
1529 | else if (sc->stats.phy.flags & 0x0030) | 2341 | delin = "RESET"; |
1530 | ret = sprintf(buf, "LOSS\n"); | 2342 | else if (sc->stats.phy.flags & 0x0001) |
1531 | else | 2343 | delin = "LOSS"; |
1532 | ret = sprintf(buf, "GOOD\n"); | 2344 | } else { |
2345 | if (sc->stats.phy.flags & 0x0C00) | ||
2346 | delin = "ERROR"; | ||
2347 | else if (sc->stats.phy.flags & 0x0030) | ||
2348 | delin = "LOSS"; | ||
2349 | } | ||
2350 | |||
2351 | ret = sprintf(buf, "%s\n", delin); | ||
1533 | out: | 2352 | out: |
1534 | mutex_unlock(&uea_mutex); | 2353 | mutex_unlock(&uea_mutex); |
1535 | return ret; | 2354 | return ret; |
@@ -1660,6 +2479,7 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, | |||
1660 | struct usb_device *usb = interface_to_usbdev(intf); | 2479 | struct usb_device *usb = interface_to_usbdev(intf); |
1661 | struct uea_softc *sc; | 2480 | struct uea_softc *sc; |
1662 | int ret, ifnum = intf->altsetting->desc.bInterfaceNumber; | 2481 | int ret, ifnum = intf->altsetting->desc.bInterfaceNumber; |
2482 | unsigned int alt; | ||
1663 | 2483 | ||
1664 | uea_enters(usb); | 2484 | uea_enters(usb); |
1665 | 2485 | ||
@@ -1694,22 +2514,29 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, | |||
1694 | sc->modem_index = (modem_index < NB_MODEM) ? modem_index++ : 0; | 2514 | sc->modem_index = (modem_index < NB_MODEM) ? modem_index++ : 0; |
1695 | sc->driver_info = id->driver_info; | 2515 | sc->driver_info = id->driver_info; |
1696 | 2516 | ||
1697 | /* ADI930 don't support iso */ | 2517 | /* first try to use module parameter */ |
1698 | if (UEA_CHIP_VERSION(id) != ADI930 && use_iso[sc->modem_index]) { | 2518 | if (annex[sc->modem_index] == 1) |
1699 | int i; | 2519 | sc->annex = ANNEXA; |
1700 | 2520 | else if (annex[sc->modem_index] == 2) | |
1701 | /* try set fastest alternate for inbound traffic interface */ | 2521 | sc->annex = ANNEXB; |
1702 | for (i = FASTEST_ISO_INTF; i > 0; i--) | 2522 | /* try to autodetect annex */ |
1703 | if (usb_set_interface(usb, UEA_DS_IFACE_NO, i) == 0) | 2523 | else if (sc->driver_info & AUTO_ANNEX_A) |
1704 | break; | 2524 | sc->annex = ANNEXA; |
2525 | else if (sc->driver_info & AUTO_ANNEX_B) | ||
2526 | sc->annex = ANNEXB; | ||
2527 | else | ||
2528 | sc->annex = (le16_to_cpu(sc->usb_dev->descriptor.bcdDevice) & 0x80)?ANNEXB:ANNEXA; | ||
1705 | 2529 | ||
1706 | if (i > 0) { | 2530 | alt = altsetting[sc->modem_index]; |
1707 | uea_dbg(usb, "set alternate %d for 2 interface\n", i); | 2531 | /* ADI930 don't support iso */ |
2532 | if (UEA_CHIP_VERSION(id) != ADI930 && alt > 0) { | ||
2533 | if (alt <= 8 && usb_set_interface(usb, UEA_DS_IFACE_NO, alt) == 0) { | ||
2534 | uea_dbg(usb, "set alternate %u for 2 interface\n", alt); | ||
1708 | uea_info(usb, "using iso mode\n"); | 2535 | uea_info(usb, "using iso mode\n"); |
1709 | usbatm->flags |= UDSL_USE_ISOC | UDSL_IGNORE_EILSEQ; | 2536 | usbatm->flags |= UDSL_USE_ISOC | UDSL_IGNORE_EILSEQ; |
1710 | } else { | 2537 | } else { |
1711 | uea_err(usb, "setting any alternate failed for " | 2538 | uea_err(usb, "setting alternate %u failed for " |
1712 | "2 interface, using bulk mode\n"); | 2539 | "2 interface, using bulk mode\n", alt); |
1713 | } | 2540 | } |
1714 | } | 2541 | } |
1715 | 2542 | ||
@@ -1719,9 +2546,12 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf, | |||
1719 | 2546 | ||
1720 | ret = uea_boot(sc); | 2547 | ret = uea_boot(sc); |
1721 | if (ret < 0) | 2548 | if (ret < 0) |
1722 | goto error; | 2549 | goto error_rm_grp; |
1723 | 2550 | ||
1724 | return 0; | 2551 | return 0; |
2552 | |||
2553 | error_rm_grp: | ||
2554 | sysfs_remove_group(&intf->dev.kobj, &attr_grp); | ||
1725 | error: | 2555 | error: |
1726 | kfree(sc); | 2556 | kfree(sc); |
1727 | return ret; | 2557 | return ret; |
@@ -1752,10 +2582,11 @@ static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id) | |||
1752 | struct usb_device *usb = interface_to_usbdev(intf); | 2582 | struct usb_device *usb = interface_to_usbdev(intf); |
1753 | 2583 | ||
1754 | uea_enters(usb); | 2584 | uea_enters(usb); |
1755 | uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) : %s %s\n", | 2585 | uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) Rev (%#X): %s\n", |
1756 | le16_to_cpu(usb->descriptor.idVendor), | 2586 | le16_to_cpu(usb->descriptor.idVendor), |
1757 | le16_to_cpu(usb->descriptor.idProduct), | 2587 | le16_to_cpu(usb->descriptor.idProduct), |
1758 | chip_name[UEA_CHIP_VERSION(id)], IS_ISDN(usb)?"isdn":"pots"); | 2588 | le16_to_cpu(usb->descriptor.bcdDevice), |
2589 | chip_name[UEA_CHIP_VERSION(id)]); | ||
1759 | 2590 | ||
1760 | usb_reset_device(usb); | 2591 | usb_reset_device(usb); |
1761 | 2592 | ||
@@ -1788,24 +2619,40 @@ static void uea_disconnect(struct usb_interface *intf) | |||
1788 | * List of supported VID/PID | 2619 | * List of supported VID/PID |
1789 | */ | 2620 | */ |
1790 | static const struct usb_device_id uea_ids[] = { | 2621 | static const struct usb_device_id uea_ids[] = { |
2622 | {USB_DEVICE(ANALOG_VID, ADI930_PID_PREFIRM), .driver_info = ADI930 | PREFIRM}, | ||
2623 | {USB_DEVICE(ANALOG_VID, ADI930_PID_PSTFIRM), .driver_info = ADI930 | PSTFIRM}, | ||
2624 | {USB_DEVICE(ANALOG_VID, EAGLE_I_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | ||
2625 | {USB_DEVICE(ANALOG_VID, EAGLE_I_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM}, | ||
2626 | {USB_DEVICE(ANALOG_VID, EAGLE_II_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | ||
2627 | {USB_DEVICE(ANALOG_VID, EAGLE_II_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM}, | ||
2628 | {USB_DEVICE(ANALOG_VID, EAGLE_IIC_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | ||
2629 | {USB_DEVICE(ANALOG_VID, EAGLE_IIC_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM}, | ||
2630 | {USB_DEVICE(ANALOG_VID, EAGLE_III_PID_PREFIRM), .driver_info = EAGLE_III | PREFIRM}, | ||
2631 | {USB_DEVICE(ANALOG_VID, EAGLE_III_PID_PSTFIRM), .driver_info = EAGLE_III | PSTFIRM}, | ||
2632 | {USB_DEVICE(ANALOG_VID, EAGLE_IV_PID_PREFIRM), .driver_info = EAGLE_IV | PREFIRM}, | ||
2633 | {USB_DEVICE(ANALOG_VID, EAGLE_IV_PID_PSTFIRM), .driver_info = EAGLE_IV | PSTFIRM}, | ||
2634 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_I_A_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | ||
2635 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_I_A_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM | AUTO_ANNEX_A}, | ||
2636 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_I_B_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | ||
2637 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_I_B_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM | AUTO_ANNEX_B}, | ||
2638 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_II_A_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | ||
2639 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_II_A_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM | AUTO_ANNEX_A}, | ||
2640 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_II_B_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | ||
2641 | {USB_DEVICE(DEVOLO_VID, DEVOLO_EAGLE_II_B_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM | AUTO_ANNEX_B}, | ||
1791 | {USB_DEVICE(ELSA_VID, ELSA_PID_PREFIRM), .driver_info = ADI930 | PREFIRM}, | 2642 | {USB_DEVICE(ELSA_VID, ELSA_PID_PREFIRM), .driver_info = ADI930 | PREFIRM}, |
1792 | {USB_DEVICE(ELSA_VID, ELSA_PID_PSTFIRM), .driver_info = ADI930 | PSTFIRM}, | 2643 | {USB_DEVICE(ELSA_VID, ELSA_PID_PSTFIRM), .driver_info = ADI930 | PSTFIRM}, |
1793 | {USB_DEVICE(EAGLE_VID, EAGLE_I_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | 2644 | {USB_DEVICE(ELSA_VID, ELSA_PID_A_PREFIRM), .driver_info = ADI930 | PREFIRM}, |
1794 | {USB_DEVICE(EAGLE_VID, EAGLE_I_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM}, | 2645 | {USB_DEVICE(ELSA_VID, ELSA_PID_A_PSTFIRM), .driver_info = ADI930 | PSTFIRM | AUTO_ANNEX_A}, |
1795 | {USB_DEVICE(EAGLE_VID, EAGLE_II_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | 2646 | {USB_DEVICE(ELSA_VID, ELSA_PID_B_PREFIRM), .driver_info = ADI930 | PREFIRM}, |
1796 | {USB_DEVICE(EAGLE_VID, EAGLE_II_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM}, | 2647 | {USB_DEVICE(ELSA_VID, ELSA_PID_B_PSTFIRM), .driver_info = ADI930 | PSTFIRM | AUTO_ANNEX_B}, |
1797 | {USB_DEVICE(EAGLE_VID, EAGLE_IIC_PID_PREFIRM), .driver_info = EAGLE_II | PREFIRM}, | ||
1798 | {USB_DEVICE(EAGLE_VID, EAGLE_IIC_PID_PSTFIRM), .driver_info = EAGLE_II | PSTFIRM}, | ||
1799 | {USB_DEVICE(EAGLE_VID, EAGLE_III_PID_PREFIRM), .driver_info = EAGLE_III | PREFIRM}, | ||
1800 | {USB_DEVICE(EAGLE_VID, EAGLE_III_PID_PSTFIRM), .driver_info = EAGLE_III | PSTFIRM}, | ||
1801 | {USB_DEVICE(USR_VID, MILLER_A_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | 2648 | {USB_DEVICE(USR_VID, MILLER_A_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, |
1802 | {USB_DEVICE(USR_VID, MILLER_A_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM}, | 2649 | {USB_DEVICE(USR_VID, MILLER_A_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM | AUTO_ANNEX_A}, |
1803 | {USB_DEVICE(USR_VID, MILLER_B_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, | 2650 | {USB_DEVICE(USR_VID, MILLER_B_PID_PREFIRM), .driver_info = EAGLE_I | PREFIRM}, |
1804 | {USB_DEVICE(USR_VID, MILLER_B_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM}, | 2651 | {USB_DEVICE(USR_VID, MILLER_B_PID_PSTFIRM), .driver_info = EAGLE_I | PSTFIRM | AUTO_ANNEX_B}, |
1805 | {USB_DEVICE(USR_VID, HEINEKEN_A_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM}, | 2652 | {USB_DEVICE(USR_VID, HEINEKEN_A_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM}, |
1806 | {USB_DEVICE(USR_VID, HEINEKEN_A_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM}, | 2653 | {USB_DEVICE(USR_VID, HEINEKEN_A_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM | AUTO_ANNEX_A}, |
1807 | {USB_DEVICE(USR_VID, HEINEKEN_B_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM}, | 2654 | {USB_DEVICE(USR_VID, HEINEKEN_B_PID_PREFIRM),.driver_info = EAGLE_I | PREFIRM}, |
1808 | {USB_DEVICE(USR_VID, HEINEKEN_B_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM}, | 2655 | {USB_DEVICE(USR_VID, HEINEKEN_B_PID_PSTFIRM),.driver_info = EAGLE_I | PSTFIRM | AUTO_ANNEX_B}, |
1809 | {} | 2656 | {} |
1810 | }; | 2657 | }; |
1811 | 2658 | ||
diff --git a/drivers/usb/atm/usbatm.c b/drivers/usb/atm/usbatm.c index 11e9b15ca45..e717f5b1cae 100644 --- a/drivers/usb/atm/usbatm.c +++ b/drivers/usb/atm/usbatm.c | |||
@@ -257,9 +257,10 @@ static void usbatm_complete(struct urb *urb) | |||
257 | { | 257 | { |
258 | struct usbatm_channel *channel = urb->context; | 258 | struct usbatm_channel *channel = urb->context; |
259 | unsigned long flags; | 259 | unsigned long flags; |
260 | int status = urb->status; | ||
260 | 261 | ||
261 | vdbg("%s: urb 0x%p, status %d, actual_length %d", | 262 | vdbg("%s: urb 0x%p, status %d, actual_length %d", |
262 | __func__, urb, urb->status, urb->actual_length); | 263 | __func__, urb, status, urb->actual_length); |
263 | 264 | ||
264 | /* usually in_interrupt(), but not always */ | 265 | /* usually in_interrupt(), but not always */ |
265 | spin_lock_irqsave(&channel->lock, flags); | 266 | spin_lock_irqsave(&channel->lock, flags); |
@@ -269,16 +270,16 @@ static void usbatm_complete(struct urb *urb) | |||
269 | 270 | ||
270 | spin_unlock_irqrestore(&channel->lock, flags); | 271 | spin_unlock_irqrestore(&channel->lock, flags); |
271 | 272 | ||
272 | if (unlikely(urb->status) && | 273 | if (unlikely(status) && |
273 | (!(channel->usbatm->flags & UDSL_IGNORE_EILSEQ) || | 274 | (!(channel->usbatm->flags & UDSL_IGNORE_EILSEQ) || |
274 | urb->status != -EILSEQ )) | 275 | status != -EILSEQ )) |
275 | { | 276 | { |
276 | if (urb->status == -ESHUTDOWN) | 277 | if (status == -ESHUTDOWN) |
277 | return; | 278 | return; |
278 | 279 | ||
279 | if (printk_ratelimit()) | 280 | if (printk_ratelimit()) |
280 | atm_warn(channel->usbatm, "%s: urb 0x%p failed (%d)!\n", | 281 | atm_warn(channel->usbatm, "%s: urb 0x%p failed (%d)!\n", |
281 | __func__, urb, urb->status); | 282 | __func__, urb, status); |
282 | /* throttle processing in case of an error */ | 283 | /* throttle processing in case of an error */ |
283 | mod_timer(&channel->delay, jiffies + msecs_to_jiffies(THROTTLE_MSECS)); | 284 | mod_timer(&channel->delay, jiffies + msecs_to_jiffies(THROTTLE_MSECS)); |
284 | } else | 285 | } else |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index cd51520c7e7..f51e22490ed 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -257,9 +257,10 @@ static void acm_ctrl_irq(struct urb *urb) | |||
257 | struct usb_cdc_notification *dr = urb->transfer_buffer; | 257 | struct usb_cdc_notification *dr = urb->transfer_buffer; |
258 | unsigned char *data; | 258 | unsigned char *data; |
259 | int newctrl; | 259 | int newctrl; |
260 | int status; | 260 | int retval; |
261 | int status = urb->status; | ||
261 | 262 | ||
262 | switch (urb->status) { | 263 | switch (status) { |
263 | case 0: | 264 | case 0: |
264 | /* success */ | 265 | /* success */ |
265 | break; | 266 | break; |
@@ -267,10 +268,10 @@ static void acm_ctrl_irq(struct urb *urb) | |||
267 | case -ENOENT: | 268 | case -ENOENT: |
268 | case -ESHUTDOWN: | 269 | case -ESHUTDOWN: |
269 | /* this urb is terminated, clean up */ | 270 | /* this urb is terminated, clean up */ |
270 | dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); | 271 | dbg("%s - urb shutting down with status: %d", __FUNCTION__, status); |
271 | return; | 272 | return; |
272 | default: | 273 | default: |
273 | dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); | 274 | dbg("%s - nonzero urb status received: %d", __FUNCTION__, status); |
274 | goto exit; | 275 | goto exit; |
275 | } | 276 | } |
276 | 277 | ||
@@ -311,10 +312,10 @@ static void acm_ctrl_irq(struct urb *urb) | |||
311 | break; | 312 | break; |
312 | } | 313 | } |
313 | exit: | 314 | exit: |
314 | status = usb_submit_urb (urb, GFP_ATOMIC); | 315 | retval = usb_submit_urb (urb, GFP_ATOMIC); |
315 | if (status) | 316 | if (retval) |
316 | err ("%s - usb_submit_urb failed with result %d", | 317 | err ("%s - usb_submit_urb failed with result %d", |
317 | __FUNCTION__, status); | 318 | __FUNCTION__, retval); |
318 | } | 319 | } |
319 | 320 | ||
320 | /* data interface returns incoming bytes, or we got unthrottled */ | 321 | /* data interface returns incoming bytes, or we got unthrottled */ |
@@ -324,7 +325,8 @@ static void acm_read_bulk(struct urb *urb) | |||
324 | struct acm_ru *rcv = urb->context; | 325 | struct acm_ru *rcv = urb->context; |
325 | struct acm *acm = rcv->instance; | 326 | struct acm *acm = rcv->instance; |
326 | int status = urb->status; | 327 | int status = urb->status; |
327 | dbg("Entering acm_read_bulk with status %d", urb->status); | 328 | |
329 | dbg("Entering acm_read_bulk with status %d", status); | ||
328 | 330 | ||
329 | if (!ACM_READY(acm)) | 331 | if (!ACM_READY(acm)) |
330 | return; | 332 | return; |
@@ -919,6 +921,10 @@ skip_normal_probe: | |||
919 | return -EINVAL; | 921 | return -EINVAL; |
920 | } | 922 | } |
921 | } | 923 | } |
924 | |||
925 | /* Accept probe requests only for the control interface */ | ||
926 | if (intf != control_interface) | ||
927 | return -ENODEV; | ||
922 | 928 | ||
923 | if (usb_interface_claimed(data_interface)) { /* valid in this context */ | 929 | if (usb_interface_claimed(data_interface)) { /* valid in this context */ |
924 | dev_dbg(&intf->dev,"The data interface isn't available"); | 930 | dev_dbg(&intf->dev,"The data interface isn't available"); |
@@ -1107,10 +1113,12 @@ static void acm_disconnect(struct usb_interface *intf) | |||
1107 | return; | 1113 | return; |
1108 | } | 1114 | } |
1109 | if (acm->country_codes){ | 1115 | if (acm->country_codes){ |
1110 | device_remove_file(&intf->dev, &dev_attr_wCountryCodes); | 1116 | device_remove_file(&acm->control->dev, |
1111 | device_remove_file(&intf->dev, &dev_attr_iCountryCodeRelDate); | 1117 | &dev_attr_wCountryCodes); |
1118 | device_remove_file(&acm->control->dev, | ||
1119 | &dev_attr_iCountryCodeRelDate); | ||
1112 | } | 1120 | } |
1113 | device_remove_file(&intf->dev, &dev_attr_bmCapabilities); | 1121 | device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities); |
1114 | acm->dev = NULL; | 1122 | acm->dev = NULL; |
1115 | usb_set_intfdata(acm->control, NULL); | 1123 | usb_set_intfdata(acm->control, NULL); |
1116 | usb_set_intfdata(acm->data, NULL); | 1124 | usb_set_intfdata(acm->data, NULL); |
diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 9a1478972bf..ad632f2d6f9 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c | |||
@@ -28,6 +28,7 @@ | |||
28 | * v0.12 - add hpoj.sourceforge.net ioctls (David Paschal) | 28 | * v0.12 - add hpoj.sourceforge.net ioctls (David Paschal) |
29 | * v0.13 - alloc space for statusbuf (<status> not on stack); | 29 | * v0.13 - alloc space for statusbuf (<status> not on stack); |
30 | * use usb_buffer_alloc() for read buf & write buf; | 30 | * use usb_buffer_alloc() for read buf & write buf; |
31 | * none - Maintained in Linux kernel after v0.13 | ||
31 | */ | 32 | */ |
32 | 33 | ||
33 | /* | 34 | /* |
@@ -69,7 +70,6 @@ | |||
69 | #define USBLP_DEVICE_ID_SIZE 1024 | 70 | #define USBLP_DEVICE_ID_SIZE 1024 |
70 | 71 | ||
71 | /* ioctls: */ | 72 | /* ioctls: */ |
72 | #define LPGETSTATUS 0x060b /* same as in drivers/char/lp.c */ | ||
73 | #define IOCNR_GET_DEVICE_ID 1 | 73 | #define IOCNR_GET_DEVICE_ID 1 |
74 | #define IOCNR_GET_PROTOCOLS 2 | 74 | #define IOCNR_GET_PROTOCOLS 2 |
75 | #define IOCNR_SET_PROTOCOL 3 | 75 | #define IOCNR_SET_PROTOCOL 3 |
@@ -115,7 +115,7 @@ MFG:HEWLETT-PACKARD;MDL:DESKJET 970C;CMD:MLC,PCL,PML;CLASS:PRINTER;DESCRIPTION:H | |||
115 | #define USBLP_MINORS 16 | 115 | #define USBLP_MINORS 16 |
116 | #define USBLP_MINOR_BASE 0 | 116 | #define USBLP_MINOR_BASE 0 |
117 | 117 | ||
118 | #define USBLP_WRITE_TIMEOUT (5000) /* 5 seconds */ | 118 | #define USBLP_CTL_TIMEOUT 5000 /* 5 seconds */ |
119 | 119 | ||
120 | #define USBLP_FIRST_PROTOCOL 1 | 120 | #define USBLP_FIRST_PROTOCOL 1 |
121 | #define USBLP_LAST_PROTOCOL 3 | 121 | #define USBLP_LAST_PROTOCOL 3 |
@@ -159,10 +159,12 @@ struct usblp { | |||
159 | int wstatus; /* bytes written or error */ | 159 | int wstatus; /* bytes written or error */ |
160 | int rstatus; /* bytes ready or error */ | 160 | int rstatus; /* bytes ready or error */ |
161 | unsigned int quirks; /* quirks flags */ | 161 | unsigned int quirks; /* quirks flags */ |
162 | unsigned int flags; /* mode flags */ | ||
162 | unsigned char used; /* True if open */ | 163 | unsigned char used; /* True if open */ |
163 | unsigned char present; /* True if not disconnected */ | 164 | unsigned char present; /* True if not disconnected */ |
164 | unsigned char bidir; /* interface is bidirectional */ | 165 | unsigned char bidir; /* interface is bidirectional */ |
165 | unsigned char sleeping; /* interface is suspended */ | 166 | unsigned char sleeping; /* interface is suspended */ |
167 | unsigned char no_paper; /* Paper Out happened */ | ||
166 | unsigned char *device_id_string; /* IEEE 1284 DEVICE ID string (ptr) */ | 168 | unsigned char *device_id_string; /* IEEE 1284 DEVICE ID string (ptr) */ |
167 | /* first 2 bytes are (big-endian) length */ | 169 | /* first 2 bytes are (big-endian) length */ |
168 | }; | 170 | }; |
@@ -259,7 +261,7 @@ static int usblp_ctrl_msg(struct usblp *usblp, int request, int type, int dir, i | |||
259 | 261 | ||
260 | retval = usb_control_msg(usblp->dev, | 262 | retval = usb_control_msg(usblp->dev, |
261 | dir ? usb_rcvctrlpipe(usblp->dev, 0) : usb_sndctrlpipe(usblp->dev, 0), | 263 | dir ? usb_rcvctrlpipe(usblp->dev, 0) : usb_sndctrlpipe(usblp->dev, 0), |
262 | request, type | dir | recip, value, index, buf, len, USBLP_WRITE_TIMEOUT); | 264 | request, type | dir | recip, value, index, buf, len, USBLP_CTL_TIMEOUT); |
263 | dbg("usblp_control_msg: rq: 0x%02x dir: %d recip: %d value: %d idx: %d len: %#x result: %d", | 265 | dbg("usblp_control_msg: rq: 0x%02x dir: %d recip: %d value: %d idx: %d len: %#x result: %d", |
264 | request, !!dir, recip, value, index, len, retval); | 266 | request, !!dir, recip, value, index, len, retval); |
265 | return retval < 0 ? retval : 0; | 267 | return retval < 0 ? retval : 0; |
@@ -289,16 +291,17 @@ static int proto_bias = -1; | |||
289 | static void usblp_bulk_read(struct urb *urb) | 291 | static void usblp_bulk_read(struct urb *urb) |
290 | { | 292 | { |
291 | struct usblp *usblp = urb->context; | 293 | struct usblp *usblp = urb->context; |
294 | int status = urb->status; | ||
292 | 295 | ||
293 | if (usblp->present && usblp->used) { | 296 | if (usblp->present && usblp->used) { |
294 | if (urb->status) | 297 | if (status) |
295 | printk(KERN_WARNING "usblp%d: " | 298 | printk(KERN_WARNING "usblp%d: " |
296 | "nonzero read bulk status received: %d\n", | 299 | "nonzero read bulk status received: %d\n", |
297 | usblp->minor, urb->status); | 300 | usblp->minor, status); |
298 | } | 301 | } |
299 | spin_lock(&usblp->lock); | 302 | spin_lock(&usblp->lock); |
300 | if (urb->status < 0) | 303 | if (status < 0) |
301 | usblp->rstatus = urb->status; | 304 | usblp->rstatus = status; |
302 | else | 305 | else |
303 | usblp->rstatus = urb->actual_length; | 306 | usblp->rstatus = urb->actual_length; |
304 | usblp->rcomplete = 1; | 307 | usblp->rcomplete = 1; |
@@ -311,25 +314,24 @@ static void usblp_bulk_read(struct urb *urb) | |||
311 | static void usblp_bulk_write(struct urb *urb) | 314 | static void usblp_bulk_write(struct urb *urb) |
312 | { | 315 | { |
313 | struct usblp *usblp = urb->context; | 316 | struct usblp *usblp = urb->context; |
317 | int status = urb->status; | ||
314 | 318 | ||
315 | if (usblp->present && usblp->used) { | 319 | if (usblp->present && usblp->used) { |
316 | if (urb->status) | 320 | if (status) |
317 | printk(KERN_WARNING "usblp%d: " | 321 | printk(KERN_WARNING "usblp%d: " |
318 | "nonzero write bulk status received: %d\n", | 322 | "nonzero write bulk status received: %d\n", |
319 | usblp->minor, urb->status); | 323 | usblp->minor, status); |
320 | } | 324 | } |
321 | spin_lock(&usblp->lock); | 325 | spin_lock(&usblp->lock); |
322 | if (urb->status < 0) | 326 | if (status < 0) |
323 | usblp->wstatus = urb->status; | 327 | usblp->wstatus = status; |
324 | else | 328 | else |
325 | usblp->wstatus = urb->actual_length; | 329 | usblp->wstatus = urb->actual_length; |
330 | usblp->no_paper = 0; | ||
326 | usblp->wcomplete = 1; | 331 | usblp->wcomplete = 1; |
327 | wake_up(&usblp->wwait); | 332 | wake_up(&usblp->wwait); |
328 | spin_unlock(&usblp->lock); | 333 | spin_unlock(&usblp->lock); |
329 | 334 | ||
330 | /* XXX Use usb_setup_bulk_urb when available. Talk to Marcel. */ | ||
331 | kfree(urb->transfer_buffer); | ||
332 | urb->transfer_buffer = NULL; /* Not refcounted, so to be safe... */ | ||
333 | usb_free_urb(urb); | 335 | usb_free_urb(urb); |
334 | } | 336 | } |
335 | 337 | ||
@@ -344,16 +346,17 @@ static int usblp_check_status(struct usblp *usblp, int err) | |||
344 | unsigned char status, newerr = 0; | 346 | unsigned char status, newerr = 0; |
345 | int error; | 347 | int error; |
346 | 348 | ||
347 | error = usblp_read_status (usblp, usblp->statusbuf); | 349 | mutex_lock(&usblp->mut); |
348 | if (error < 0) { | 350 | if ((error = usblp_read_status(usblp, usblp->statusbuf)) < 0) { |
351 | mutex_unlock(&usblp->mut); | ||
349 | if (printk_ratelimit()) | 352 | if (printk_ratelimit()) |
350 | printk(KERN_ERR | 353 | printk(KERN_ERR |
351 | "usblp%d: error %d reading printer status\n", | 354 | "usblp%d: error %d reading printer status\n", |
352 | usblp->minor, error); | 355 | usblp->minor, error); |
353 | return 0; | 356 | return 0; |
354 | } | 357 | } |
355 | |||
356 | status = *usblp->statusbuf; | 358 | status = *usblp->statusbuf; |
359 | mutex_unlock(&usblp->mut); | ||
357 | 360 | ||
358 | if (~status & LP_PERRORP) | 361 | if (~status & LP_PERRORP) |
359 | newerr = 3; | 362 | newerr = 3; |
@@ -409,18 +412,10 @@ static int usblp_open(struct inode *inode, struct file *file) | |||
409 | goto out; | 412 | goto out; |
410 | 413 | ||
411 | /* | 414 | /* |
412 | * TODO: need to implement LP_ABORTOPEN + O_NONBLOCK as in drivers/char/lp.c ??? | 415 | * We do not implement LP_ABORTOPEN/LPABORTOPEN for two reasons: |
413 | * This is #if 0-ed because we *don't* want to fail an open | 416 | * - We do not want persistent state which close(2) does not clear |
414 | * just because the printer is off-line. | 417 | * - It is not used anyway, according to CUPS people |
415 | */ | 418 | */ |
416 | #if 0 | ||
417 | if ((retval = usblp_check_status(usblp, 0))) { | ||
418 | retval = retval > 1 ? -EIO : -ENOSPC; | ||
419 | goto out; | ||
420 | } | ||
421 | #else | ||
422 | retval = 0; | ||
423 | #endif | ||
424 | 419 | ||
425 | retval = usb_autopm_get_interface(intf); | 420 | retval = usb_autopm_get_interface(intf); |
426 | if (retval < 0) | 421 | if (retval < 0) |
@@ -461,6 +456,8 @@ static int usblp_release(struct inode *inode, struct file *file) | |||
461 | { | 456 | { |
462 | struct usblp *usblp = file->private_data; | 457 | struct usblp *usblp = file->private_data; |
463 | 458 | ||
459 | usblp->flags &= ~LP_ABORT; | ||
460 | |||
464 | mutex_lock (&usblp_mutex); | 461 | mutex_lock (&usblp_mutex); |
465 | usblp->used = 0; | 462 | usblp->used = 0; |
466 | if (usblp->present) { | 463 | if (usblp->present) { |
@@ -483,8 +480,8 @@ static unsigned int usblp_poll(struct file *file, struct poll_table_struct *wait | |||
483 | poll_wait(file, &usblp->rwait, wait); | 480 | poll_wait(file, &usblp->rwait, wait); |
484 | poll_wait(file, &usblp->wwait, wait); | 481 | poll_wait(file, &usblp->wwait, wait); |
485 | spin_lock_irqsave(&usblp->lock, flags); | 482 | spin_lock_irqsave(&usblp->lock, flags); |
486 | ret = ((!usblp->bidir || !usblp->rcomplete) ? 0 : POLLIN | POLLRDNORM) | 483 | ret = ((usblp->bidir && usblp->rcomplete) ? POLLIN | POLLRDNORM : 0) | |
487 | | (!usblp->wcomplete ? 0 : POLLOUT | POLLWRNORM); | 484 | ((usblp->no_paper || usblp->wcomplete) ? POLLOUT | POLLWRNORM : 0); |
488 | spin_unlock_irqrestore(&usblp->lock, flags); | 485 | spin_unlock_irqrestore(&usblp->lock, flags); |
489 | return ret; | 486 | return ret; |
490 | } | 487 | } |
@@ -673,6 +670,13 @@ static long usblp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
673 | retval = -EFAULT; | 670 | retval = -EFAULT; |
674 | break; | 671 | break; |
675 | 672 | ||
673 | case LPABORT: | ||
674 | if (arg) | ||
675 | usblp->flags |= LP_ABORT; | ||
676 | else | ||
677 | usblp->flags &= ~LP_ABORT; | ||
678 | break; | ||
679 | |||
676 | default: | 680 | default: |
677 | retval = -ENOTTY; | 681 | retval = -ENOTTY; |
678 | } | 682 | } |
@@ -682,10 +686,30 @@ done: | |||
682 | return retval; | 686 | return retval; |
683 | } | 687 | } |
684 | 688 | ||
689 | static struct urb *usblp_new_writeurb(struct usblp *usblp, int transfer_length) | ||
690 | { | ||
691 | struct urb *urb; | ||
692 | char *writebuf; | ||
693 | |||
694 | if ((writebuf = kmalloc(transfer_length, GFP_KERNEL)) == NULL) | ||
695 | return NULL; | ||
696 | if ((urb = usb_alloc_urb(0, GFP_KERNEL)) == NULL) { | ||
697 | kfree(writebuf); | ||
698 | return NULL; | ||
699 | } | ||
700 | |||
701 | usb_fill_bulk_urb(urb, usblp->dev, | ||
702 | usb_sndbulkpipe(usblp->dev, | ||
703 | usblp->protocol[usblp->current_protocol].epwrite->bEndpointAddress), | ||
704 | writebuf, transfer_length, usblp_bulk_write, usblp); | ||
705 | urb->transfer_flags |= URB_FREE_BUFFER; | ||
706 | |||
707 | return urb; | ||
708 | } | ||
709 | |||
685 | static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) | 710 | static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos) |
686 | { | 711 | { |
687 | struct usblp *usblp = file->private_data; | 712 | struct usblp *usblp = file->private_data; |
688 | char *writebuf; | ||
689 | struct urb *writeurb; | 713 | struct urb *writeurb; |
690 | int rv; | 714 | int rv; |
691 | int transfer_length; | 715 | int transfer_length; |
@@ -706,17 +730,11 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
706 | transfer_length = USBLP_BUF_SIZE; | 730 | transfer_length = USBLP_BUF_SIZE; |
707 | 731 | ||
708 | rv = -ENOMEM; | 732 | rv = -ENOMEM; |
709 | if ((writebuf = kmalloc(USBLP_BUF_SIZE, GFP_KERNEL)) == NULL) | 733 | if ((writeurb = usblp_new_writeurb(usblp, transfer_length)) == NULL) |
710 | goto raise_buf; | ||
711 | if ((writeurb = usb_alloc_urb(0, GFP_KERNEL)) == NULL) | ||
712 | goto raise_urb; | 734 | goto raise_urb; |
713 | usb_fill_bulk_urb(writeurb, usblp->dev, | ||
714 | usb_sndbulkpipe(usblp->dev, | ||
715 | usblp->protocol[usblp->current_protocol].epwrite->bEndpointAddress), | ||
716 | writebuf, transfer_length, usblp_bulk_write, usblp); | ||
717 | usb_anchor_urb(writeurb, &usblp->urbs); | 735 | usb_anchor_urb(writeurb, &usblp->urbs); |
718 | 736 | ||
719 | if (copy_from_user(writebuf, | 737 | if (copy_from_user(writeurb->transfer_buffer, |
720 | buffer + writecount, transfer_length)) { | 738 | buffer + writecount, transfer_length)) { |
721 | rv = -EFAULT; | 739 | rv = -EFAULT; |
722 | goto raise_badaddr; | 740 | goto raise_badaddr; |
@@ -728,6 +746,7 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
728 | if ((rv = usb_submit_urb(writeurb, GFP_KERNEL)) < 0) { | 746 | if ((rv = usb_submit_urb(writeurb, GFP_KERNEL)) < 0) { |
729 | usblp->wstatus = 0; | 747 | usblp->wstatus = 0; |
730 | spin_lock_irq(&usblp->lock); | 748 | spin_lock_irq(&usblp->lock); |
749 | usblp->no_paper = 0; | ||
731 | usblp->wcomplete = 1; | 750 | usblp->wcomplete = 1; |
732 | wake_up(&usblp->wwait); | 751 | wake_up(&usblp->wwait); |
733 | spin_unlock_irq(&usblp->lock); | 752 | spin_unlock_irq(&usblp->lock); |
@@ -741,15 +760,21 @@ static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t | |||
741 | */ | 760 | */ |
742 | rv = usblp_wwait(usblp, !!(file->f_flags&O_NONBLOCK)); | 761 | rv = usblp_wwait(usblp, !!(file->f_flags&O_NONBLOCK)); |
743 | if (rv < 0) { | 762 | if (rv < 0) { |
744 | /* | 763 | if (rv == -EAGAIN) { |
745 | * If interrupted, we simply leave the URB to dangle, | 764 | /* Presume that it's going to complete well. */ |
746 | * so the ->release will call usb_kill_urb(). | 765 | writecount += transfer_length; |
747 | */ | 766 | } |
767 | if (rv == -ENOSPC) { | ||
768 | spin_lock_irq(&usblp->lock); | ||
769 | usblp->no_paper = 1; /* Mark for poll(2) */ | ||
770 | spin_unlock_irq(&usblp->lock); | ||
771 | writecount += transfer_length; | ||
772 | } | ||
773 | /* Leave URB dangling, to be cleaned on close. */ | ||
748 | goto collect_error; | 774 | goto collect_error; |
749 | } | 775 | } |
750 | 776 | ||
751 | if (usblp->wstatus < 0) { | 777 | if (usblp->wstatus < 0) { |
752 | usblp_check_status(usblp, 0); | ||
753 | rv = -EIO; | 778 | rv = -EIO; |
754 | goto collect_error; | 779 | goto collect_error; |
755 | } | 780 | } |
@@ -768,8 +793,6 @@ raise_badaddr: | |||
768 | usb_unanchor_urb(writeurb); | 793 | usb_unanchor_urb(writeurb); |
769 | usb_free_urb(writeurb); | 794 | usb_free_urb(writeurb); |
770 | raise_urb: | 795 | raise_urb: |
771 | kfree(writebuf); | ||
772 | raise_buf: | ||
773 | raise_wait: | 796 | raise_wait: |
774 | collect_error: /* Out of raise sequence */ | 797 | collect_error: /* Out of raise sequence */ |
775 | mutex_unlock(&usblp->wmut); | 798 | mutex_unlock(&usblp->wmut); |
@@ -835,32 +858,36 @@ done: | |||
835 | * when O_NONBLOCK is set. So, applications setting O_NONBLOCK must use | 858 | * when O_NONBLOCK is set. So, applications setting O_NONBLOCK must use |
836 | * select(2) or poll(2) to wait for the buffer to drain before closing. | 859 | * select(2) or poll(2) to wait for the buffer to drain before closing. |
837 | * Alternatively, set blocking mode with fcntl and issue a zero-size write. | 860 | * Alternatively, set blocking mode with fcntl and issue a zero-size write. |
838 | * | ||
839 | * Old v0.13 code had a non-functional timeout for wait_event(). Someone forgot | ||
840 | * to check the return code for timeout expiration, so it had no effect. | ||
841 | * Apparently, it was intended to check for error conditons, such as out | ||
842 | * of paper. It is going to return when we settle things with CUPS. XXX | ||
843 | */ | 861 | */ |
844 | static int usblp_wwait(struct usblp *usblp, int nonblock) | 862 | static int usblp_wwait(struct usblp *usblp, int nonblock) |
845 | { | 863 | { |
846 | DECLARE_WAITQUEUE(waita, current); | 864 | DECLARE_WAITQUEUE(waita, current); |
847 | int rc; | 865 | int rc; |
866 | int err = 0; | ||
848 | 867 | ||
849 | add_wait_queue(&usblp->wwait, &waita); | 868 | add_wait_queue(&usblp->wwait, &waita); |
850 | for (;;) { | 869 | for (;;) { |
870 | set_current_state(TASK_INTERRUPTIBLE); | ||
851 | if (mutex_lock_interruptible(&usblp->mut)) { | 871 | if (mutex_lock_interruptible(&usblp->mut)) { |
852 | rc = -EINTR; | 872 | rc = -EINTR; |
853 | break; | 873 | break; |
854 | } | 874 | } |
855 | set_current_state(TASK_INTERRUPTIBLE); | 875 | rc = usblp_wtest(usblp, nonblock); |
856 | if ((rc = usblp_wtest(usblp, nonblock)) < 0) { | ||
857 | mutex_unlock(&usblp->mut); | ||
858 | break; | ||
859 | } | ||
860 | mutex_unlock(&usblp->mut); | 876 | mutex_unlock(&usblp->mut); |
861 | if (rc == 0) | 877 | if (rc <= 0) |
862 | break; | 878 | break; |
863 | schedule(); | 879 | |
880 | if (usblp->flags & LP_ABORT) { | ||
881 | if (schedule_timeout(msecs_to_jiffies(5000)) == 0) { | ||
882 | err = usblp_check_status(usblp, err); | ||
883 | if (err == 1) { /* Paper out */ | ||
884 | rc = -ENOSPC; | ||
885 | break; | ||
886 | } | ||
887 | } | ||
888 | } else { | ||
889 | schedule(); | ||
890 | } | ||
864 | } | 891 | } |
865 | set_current_state(TASK_RUNNING); | 892 | set_current_state(TASK_RUNNING); |
866 | remove_wait_queue(&usblp->wwait, &waita); | 893 | remove_wait_queue(&usblp->wwait, &waita); |
diff --git a/drivers/usb/core/config.c b/drivers/usb/core/config.c index cb69aa1e02e..1a8edcee7f3 100644 --- a/drivers/usb/core/config.c +++ b/drivers/usb/core/config.c | |||
@@ -507,18 +507,30 @@ void usb_destroy_configuration(struct usb_device *dev) | |||
507 | } | 507 | } |
508 | 508 | ||
509 | 509 | ||
510 | // hub-only!! ... and only in reset path, or usb_new_device() | 510 | /* |
511 | // (used by real hubs and virtual root hubs) | 511 | * Get the USB config descriptors, cache and parse'em |
512 | * | ||
513 | * hub-only!! ... and only in reset path, or usb_new_device() | ||
514 | * (used by real hubs and virtual root hubs) | ||
515 | * | ||
516 | * NOTE: if this is a WUSB device and is not authorized, we skip the | ||
517 | * whole thing. A non-authorized USB device has no | ||
518 | * configurations. | ||
519 | */ | ||
512 | int usb_get_configuration(struct usb_device *dev) | 520 | int usb_get_configuration(struct usb_device *dev) |
513 | { | 521 | { |
514 | struct device *ddev = &dev->dev; | 522 | struct device *ddev = &dev->dev; |
515 | int ncfg = dev->descriptor.bNumConfigurations; | 523 | int ncfg = dev->descriptor.bNumConfigurations; |
516 | int result = -ENOMEM; | 524 | int result = 0; |
517 | unsigned int cfgno, length; | 525 | unsigned int cfgno, length; |
518 | unsigned char *buffer; | 526 | unsigned char *buffer; |
519 | unsigned char *bigbuffer; | 527 | unsigned char *bigbuffer; |
520 | struct usb_config_descriptor *desc; | 528 | struct usb_config_descriptor *desc; |
521 | 529 | ||
530 | cfgno = 0; | ||
531 | if (dev->authorized == 0) /* Not really an error */ | ||
532 | goto out_not_authorized; | ||
533 | result = -ENOMEM; | ||
522 | if (ncfg > USB_MAXCONFIG) { | 534 | if (ncfg > USB_MAXCONFIG) { |
523 | dev_warn(ddev, "too many configurations: %d, " | 535 | dev_warn(ddev, "too many configurations: %d, " |
524 | "using maximum allowed: %d\n", ncfg, USB_MAXCONFIG); | 536 | "using maximum allowed: %d\n", ncfg, USB_MAXCONFIG); |
@@ -545,14 +557,15 @@ int usb_get_configuration(struct usb_device *dev) | |||
545 | goto err2; | 557 | goto err2; |
546 | desc = (struct usb_config_descriptor *)buffer; | 558 | desc = (struct usb_config_descriptor *)buffer; |
547 | 559 | ||
548 | for (cfgno = 0; cfgno < ncfg; cfgno++) { | 560 | result = 0; |
561 | for (; cfgno < ncfg; cfgno++) { | ||
549 | /* We grab just the first descriptor so we know how long | 562 | /* We grab just the first descriptor so we know how long |
550 | * the whole configuration is */ | 563 | * the whole configuration is */ |
551 | result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, | 564 | result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, |
552 | buffer, USB_DT_CONFIG_SIZE); | 565 | buffer, USB_DT_CONFIG_SIZE); |
553 | if (result < 0) { | 566 | if (result < 0) { |
554 | dev_err(ddev, "unable to read config index %d " | 567 | dev_err(ddev, "unable to read config index %d " |
555 | "descriptor/%s\n", cfgno, "start"); | 568 | "descriptor/%s: %d\n", cfgno, "start", result); |
556 | dev_err(ddev, "chopping to %d config(s)\n", cfgno); | 569 | dev_err(ddev, "chopping to %d config(s)\n", cfgno); |
557 | dev->descriptor.bNumConfigurations = cfgno; | 570 | dev->descriptor.bNumConfigurations = cfgno; |
558 | break; | 571 | break; |
@@ -599,6 +612,7 @@ int usb_get_configuration(struct usb_device *dev) | |||
599 | 612 | ||
600 | err: | 613 | err: |
601 | kfree(buffer); | 614 | kfree(buffer); |
615 | out_not_authorized: | ||
602 | dev->descriptor.bNumConfigurations = cfgno; | 616 | dev->descriptor.bNumConfigurations = cfgno; |
603 | err2: | 617 | err2: |
604 | if (result == -ENOMEM) | 618 | if (result == -ENOMEM) |
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 927a181120a..f013b4012c9 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c | |||
@@ -71,6 +71,7 @@ struct async { | |||
71 | void __user *userbuffer; | 71 | void __user *userbuffer; |
72 | void __user *userurb; | 72 | void __user *userurb; |
73 | struct urb *urb; | 73 | struct urb *urb; |
74 | int status; | ||
74 | u32 secid; | 75 | u32 secid; |
75 | }; | 76 | }; |
76 | 77 | ||
@@ -289,10 +290,8 @@ static void snoop_urb(struct urb *urb, void __user *userurb) | |||
289 | if (!usbfs_snoop) | 290 | if (!usbfs_snoop) |
290 | return; | 291 | return; |
291 | 292 | ||
292 | if (urb->pipe & USB_DIR_IN) | 293 | dev_info(&urb->dev->dev, "direction=%s\n", |
293 | dev_info(&urb->dev->dev, "direction=IN\n"); | 294 | usb_urb_dir_in(urb) ? "IN" : "OUT"); |
294 | else | ||
295 | dev_info(&urb->dev->dev, "direction=OUT\n"); | ||
296 | dev_info(&urb->dev->dev, "userurb=%p\n", userurb); | 295 | dev_info(&urb->dev->dev, "userurb=%p\n", userurb); |
297 | dev_info(&urb->dev->dev, "transfer_buffer_length=%d\n", | 296 | dev_info(&urb->dev->dev, "transfer_buffer_length=%d\n", |
298 | urb->transfer_buffer_length); | 297 | urb->transfer_buffer_length); |
@@ -312,9 +311,10 @@ static void async_completed(struct urb *urb) | |||
312 | spin_lock(&ps->lock); | 311 | spin_lock(&ps->lock); |
313 | list_move_tail(&as->asynclist, &ps->async_completed); | 312 | list_move_tail(&as->asynclist, &ps->async_completed); |
314 | spin_unlock(&ps->lock); | 313 | spin_unlock(&ps->lock); |
314 | as->status = urb->status; | ||
315 | if (as->signr) { | 315 | if (as->signr) { |
316 | sinfo.si_signo = as->signr; | 316 | sinfo.si_signo = as->signr; |
317 | sinfo.si_errno = as->urb->status; | 317 | sinfo.si_errno = as->status; |
318 | sinfo.si_code = SI_ASYNCIO; | 318 | sinfo.si_code = SI_ASYNCIO; |
319 | sinfo.si_addr = as->userurb; | 319 | sinfo.si_addr = as->userurb; |
320 | kill_pid_info_as_uid(as->signr, &sinfo, as->pid, as->uid, | 320 | kill_pid_info_as_uid(as->signr, &sinfo, as->pid, as->uid, |
@@ -910,6 +910,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
910 | struct usb_ctrlrequest *dr = NULL; | 910 | struct usb_ctrlrequest *dr = NULL; |
911 | unsigned int u, totlen, isofrmlen; | 911 | unsigned int u, totlen, isofrmlen; |
912 | int ret, ifnum = -1; | 912 | int ret, ifnum = -1; |
913 | int is_in; | ||
913 | 914 | ||
914 | if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP|USBDEVFS_URB_SHORT_NOT_OK| | 915 | if (uurb->flags & ~(USBDEVFS_URB_ISO_ASAP|USBDEVFS_URB_SHORT_NOT_OK| |
915 | URB_NO_FSBR|URB_ZERO_PACKET)) | 916 | URB_NO_FSBR|URB_ZERO_PACKET)) |
@@ -924,16 +925,18 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
924 | if ((ret = checkintf(ps, ifnum))) | 925 | if ((ret = checkintf(ps, ifnum))) |
925 | return ret; | 926 | return ret; |
926 | } | 927 | } |
927 | if ((uurb->endpoint & USB_ENDPOINT_DIR_MASK) != 0) | 928 | if ((uurb->endpoint & USB_ENDPOINT_DIR_MASK) != 0) { |
928 | ep = ps->dev->ep_in [uurb->endpoint & USB_ENDPOINT_NUMBER_MASK]; | 929 | is_in = 1; |
929 | else | 930 | ep = ps->dev->ep_in[uurb->endpoint & USB_ENDPOINT_NUMBER_MASK]; |
930 | ep = ps->dev->ep_out [uurb->endpoint & USB_ENDPOINT_NUMBER_MASK]; | 931 | } else { |
932 | is_in = 0; | ||
933 | ep = ps->dev->ep_out[uurb->endpoint & USB_ENDPOINT_NUMBER_MASK]; | ||
934 | } | ||
931 | if (!ep) | 935 | if (!ep) |
932 | return -ENOENT; | 936 | return -ENOENT; |
933 | switch(uurb->type) { | 937 | switch(uurb->type) { |
934 | case USBDEVFS_URB_TYPE_CONTROL: | 938 | case USBDEVFS_URB_TYPE_CONTROL: |
935 | if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 939 | if (!usb_endpoint_xfer_control(&ep->desc)) |
936 | != USB_ENDPOINT_XFER_CONTROL) | ||
937 | return -EINVAL; | 940 | return -EINVAL; |
938 | /* min 8 byte setup packet, max 8 byte setup plus an arbitrary data stage */ | 941 | /* min 8 byte setup packet, max 8 byte setup plus an arbitrary data stage */ |
939 | if (uurb->buffer_length < 8 || uurb->buffer_length > (8 + MAX_USBFS_BUFFER_SIZE)) | 942 | if (uurb->buffer_length < 8 || uurb->buffer_length > (8 + MAX_USBFS_BUFFER_SIZE)) |
@@ -952,23 +955,32 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
952 | kfree(dr); | 955 | kfree(dr); |
953 | return ret; | 956 | return ret; |
954 | } | 957 | } |
955 | uurb->endpoint = (uurb->endpoint & ~USB_ENDPOINT_DIR_MASK) | (dr->bRequestType & USB_ENDPOINT_DIR_MASK); | ||
956 | uurb->number_of_packets = 0; | 958 | uurb->number_of_packets = 0; |
957 | uurb->buffer_length = le16_to_cpup(&dr->wLength); | 959 | uurb->buffer_length = le16_to_cpup(&dr->wLength); |
958 | uurb->buffer += 8; | 960 | uurb->buffer += 8; |
959 | if (!access_ok((uurb->endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb->buffer, uurb->buffer_length)) { | 961 | if ((dr->bRequestType & USB_DIR_IN) && uurb->buffer_length) { |
962 | is_in = 1; | ||
963 | uurb->endpoint |= USB_DIR_IN; | ||
964 | } else { | ||
965 | is_in = 0; | ||
966 | uurb->endpoint &= ~USB_DIR_IN; | ||
967 | } | ||
968 | if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ, | ||
969 | uurb->buffer, uurb->buffer_length)) { | ||
960 | kfree(dr); | 970 | kfree(dr); |
961 | return -EFAULT; | 971 | return -EFAULT; |
962 | } | 972 | } |
963 | snoop(&ps->dev->dev, "control urb: bRequest=%02x " | 973 | snoop(&ps->dev->dev, "control urb: bRequest=%02x " |
964 | "bRrequestType=%02x wValue=%04x " | 974 | "bRrequestType=%02x wValue=%04x " |
965 | "wIndex=%04x wLength=%04x\n", | 975 | "wIndex=%04x wLength=%04x\n", |
966 | dr->bRequest, dr->bRequestType, dr->wValue, | 976 | dr->bRequest, dr->bRequestType, |
967 | dr->wIndex, dr->wLength); | 977 | __le16_to_cpup(&dr->wValue), |
978 | __le16_to_cpup(&dr->wIndex), | ||
979 | __le16_to_cpup(&dr->wLength)); | ||
968 | break; | 980 | break; |
969 | 981 | ||
970 | case USBDEVFS_URB_TYPE_BULK: | 982 | case USBDEVFS_URB_TYPE_BULK: |
971 | switch (ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | 983 | switch (usb_endpoint_type(&ep->desc)) { |
972 | case USB_ENDPOINT_XFER_CONTROL: | 984 | case USB_ENDPOINT_XFER_CONTROL: |
973 | case USB_ENDPOINT_XFER_ISOC: | 985 | case USB_ENDPOINT_XFER_ISOC: |
974 | return -EINVAL; | 986 | return -EINVAL; |
@@ -977,7 +989,8 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
977 | uurb->number_of_packets = 0; | 989 | uurb->number_of_packets = 0; |
978 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) | 990 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) |
979 | return -EINVAL; | 991 | return -EINVAL; |
980 | if (!access_ok((uurb->endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb->buffer, uurb->buffer_length)) | 992 | if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ, |
993 | uurb->buffer, uurb->buffer_length)) | ||
981 | return -EFAULT; | 994 | return -EFAULT; |
982 | snoop(&ps->dev->dev, "bulk urb\n"); | 995 | snoop(&ps->dev->dev, "bulk urb\n"); |
983 | break; | 996 | break; |
@@ -986,8 +999,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
986 | /* arbitrary limit */ | 999 | /* arbitrary limit */ |
987 | if (uurb->number_of_packets < 1 || uurb->number_of_packets > 128) | 1000 | if (uurb->number_of_packets < 1 || uurb->number_of_packets > 128) |
988 | return -EINVAL; | 1001 | return -EINVAL; |
989 | if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 1002 | if (!usb_endpoint_xfer_isoc(&ep->desc)) |
990 | != USB_ENDPOINT_XFER_ISOC) | ||
991 | return -EINVAL; | 1003 | return -EINVAL; |
992 | isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * uurb->number_of_packets; | 1004 | isofrmlen = sizeof(struct usbdevfs_iso_packet_desc) * uurb->number_of_packets; |
993 | if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL))) | 1005 | if (!(isopkt = kmalloc(isofrmlen, GFP_KERNEL))) |
@@ -1014,12 +1026,12 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1014 | 1026 | ||
1015 | case USBDEVFS_URB_TYPE_INTERRUPT: | 1027 | case USBDEVFS_URB_TYPE_INTERRUPT: |
1016 | uurb->number_of_packets = 0; | 1028 | uurb->number_of_packets = 0; |
1017 | if ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 1029 | if (!usb_endpoint_xfer_int(&ep->desc)) |
1018 | != USB_ENDPOINT_XFER_INT) | ||
1019 | return -EINVAL; | 1030 | return -EINVAL; |
1020 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) | 1031 | if (uurb->buffer_length > MAX_USBFS_BUFFER_SIZE) |
1021 | return -EINVAL; | 1032 | return -EINVAL; |
1022 | if (!access_ok((uurb->endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb->buffer, uurb->buffer_length)) | 1033 | if (!access_ok(is_in ? VERIFY_WRITE : VERIFY_READ, |
1034 | uurb->buffer, uurb->buffer_length)) | ||
1023 | return -EFAULT; | 1035 | return -EFAULT; |
1024 | snoop(&ps->dev->dev, "interrupt urb\n"); | 1036 | snoop(&ps->dev->dev, "interrupt urb\n"); |
1025 | break; | 1037 | break; |
@@ -1039,8 +1051,11 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1039 | return -ENOMEM; | 1051 | return -ENOMEM; |
1040 | } | 1052 | } |
1041 | as->urb->dev = ps->dev; | 1053 | as->urb->dev = ps->dev; |
1042 | as->urb->pipe = (uurb->type << 30) | __create_pipe(ps->dev, uurb->endpoint & 0xf) | (uurb->endpoint & USB_DIR_IN); | 1054 | as->urb->pipe = (uurb->type << 30) | |
1043 | as->urb->transfer_flags = uurb->flags; | 1055 | __create_pipe(ps->dev, uurb->endpoint & 0xf) | |
1056 | (uurb->endpoint & USB_DIR_IN); | ||
1057 | as->urb->transfer_flags = uurb->flags | | ||
1058 | (is_in ? URB_DIR_IN : URB_DIR_OUT); | ||
1044 | as->urb->transfer_buffer_length = uurb->buffer_length; | 1059 | as->urb->transfer_buffer_length = uurb->buffer_length; |
1045 | as->urb->setup_packet = (unsigned char*)dr; | 1060 | as->urb->setup_packet = (unsigned char*)dr; |
1046 | as->urb->start_frame = uurb->start_frame; | 1061 | as->urb->start_frame = uurb->start_frame; |
@@ -1070,13 +1085,13 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, | |||
1070 | as->uid = current->uid; | 1085 | as->uid = current->uid; |
1071 | as->euid = current->euid; | 1086 | as->euid = current->euid; |
1072 | security_task_getsecid(current, &as->secid); | 1087 | security_task_getsecid(current, &as->secid); |
1073 | if (!(uurb->endpoint & USB_DIR_IN)) { | 1088 | if (!is_in) { |
1074 | if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, as->urb->transfer_buffer_length)) { | 1089 | if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, |
1090 | as->urb->transfer_buffer_length)) { | ||
1075 | free_async(as); | 1091 | free_async(as); |
1076 | return -EFAULT; | 1092 | return -EFAULT; |
1077 | } | 1093 | } |
1078 | } | 1094 | } |
1079 | snoop(&as->urb->dev->dev, "submit urb\n"); | ||
1080 | snoop_urb(as->urb, as->userurb); | 1095 | snoop_urb(as->urb, as->userurb); |
1081 | async_newpending(as); | 1096 | async_newpending(as); |
1082 | if ((ret = usb_submit_urb(as->urb, GFP_KERNEL))) { | 1097 | if ((ret = usb_submit_urb(as->urb, GFP_KERNEL))) { |
@@ -1119,14 +1134,14 @@ static int processcompl(struct async *as, void __user * __user *arg) | |||
1119 | if (as->userbuffer) | 1134 | if (as->userbuffer) |
1120 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, urb->transfer_buffer_length)) | 1135 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, urb->transfer_buffer_length)) |
1121 | return -EFAULT; | 1136 | return -EFAULT; |
1122 | if (put_user(urb->status, &userurb->status)) | 1137 | if (put_user(as->status, &userurb->status)) |
1123 | return -EFAULT; | 1138 | return -EFAULT; |
1124 | if (put_user(urb->actual_length, &userurb->actual_length)) | 1139 | if (put_user(urb->actual_length, &userurb->actual_length)) |
1125 | return -EFAULT; | 1140 | return -EFAULT; |
1126 | if (put_user(urb->error_count, &userurb->error_count)) | 1141 | if (put_user(urb->error_count, &userurb->error_count)) |
1127 | return -EFAULT; | 1142 | return -EFAULT; |
1128 | 1143 | ||
1129 | if (usb_pipeisoc(urb->pipe)) { | 1144 | if (usb_endpoint_xfer_isoc(&urb->ep->desc)) { |
1130 | for (i = 0; i < urb->number_of_packets; i++) { | 1145 | for (i = 0; i < urb->number_of_packets; i++) { |
1131 | if (put_user(urb->iso_frame_desc[i].actual_length, | 1146 | if (put_user(urb->iso_frame_desc[i].actual_length, |
1132 | &userurb->iso_frame_desc[i].actual_length)) | 1147 | &userurb->iso_frame_desc[i].actual_length)) |
@@ -1233,14 +1248,14 @@ static int processcompl_compat(struct async *as, void __user * __user *arg) | |||
1233 | if (as->userbuffer) | 1248 | if (as->userbuffer) |
1234 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, urb->transfer_buffer_length)) | 1249 | if (copy_to_user(as->userbuffer, urb->transfer_buffer, urb->transfer_buffer_length)) |
1235 | return -EFAULT; | 1250 | return -EFAULT; |
1236 | if (put_user(urb->status, &userurb->status)) | 1251 | if (put_user(as->status, &userurb->status)) |
1237 | return -EFAULT; | 1252 | return -EFAULT; |
1238 | if (put_user(urb->actual_length, &userurb->actual_length)) | 1253 | if (put_user(urb->actual_length, &userurb->actual_length)) |
1239 | return -EFAULT; | 1254 | return -EFAULT; |
1240 | if (put_user(urb->error_count, &userurb->error_count)) | 1255 | if (put_user(urb->error_count, &userurb->error_count)) |
1241 | return -EFAULT; | 1256 | return -EFAULT; |
1242 | 1257 | ||
1243 | if (usb_pipeisoc(urb->pipe)) { | 1258 | if (usb_endpoint_xfer_isoc(&urb->ep->desc)) { |
1244 | for (i = 0; i < urb->number_of_packets; i++) { | 1259 | for (i = 0; i < urb->number_of_packets; i++) { |
1245 | if (put_user(urb->iso_frame_desc[i].actual_length, | 1260 | if (put_user(urb->iso_frame_desc[i].actual_length, |
1246 | &userurb->iso_frame_desc[i].actual_length)) | 1261 | &userurb->iso_frame_desc[i].actual_length)) |
@@ -1576,6 +1591,7 @@ static unsigned int usbdev_poll(struct file *file, struct poll_table_struct *wai | |||
1576 | } | 1591 | } |
1577 | 1592 | ||
1578 | const struct file_operations usbdev_file_operations = { | 1593 | const struct file_operations usbdev_file_operations = { |
1594 | .owner = THIS_MODULE, | ||
1579 | .llseek = usbdev_lseek, | 1595 | .llseek = usbdev_lseek, |
1580 | .read = usbdev_read, | 1596 | .read = usbdev_read, |
1581 | .poll = usbdev_poll, | 1597 | .poll = usbdev_poll, |
@@ -1625,10 +1641,7 @@ static struct notifier_block usbdev_nb = { | |||
1625 | }; | 1641 | }; |
1626 | #endif | 1642 | #endif |
1627 | 1643 | ||
1628 | static struct cdev usb_device_cdev = { | 1644 | static struct cdev usb_device_cdev; |
1629 | .kobj = {.name = "usb_device", }, | ||
1630 | .owner = THIS_MODULE, | ||
1631 | }; | ||
1632 | 1645 | ||
1633 | int __init usb_devio_init(void) | 1646 | int __init usb_devio_init(void) |
1634 | { | 1647 | { |
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index 73c49362cd4..8586817698a 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c | |||
@@ -29,13 +29,6 @@ | |||
29 | #include "hcd.h" | 29 | #include "hcd.h" |
30 | #include "usb.h" | 30 | #include "usb.h" |
31 | 31 | ||
32 | #define VERBOSE_DEBUG 0 | ||
33 | |||
34 | #if VERBOSE_DEBUG | ||
35 | #define dev_vdbg dev_dbg | ||
36 | #else | ||
37 | #define dev_vdbg(dev, fmt, args...) do { } while (0) | ||
38 | #endif | ||
39 | 32 | ||
40 | #ifdef CONFIG_HOTPLUG | 33 | #ifdef CONFIG_HOTPLUG |
41 | 34 | ||
@@ -67,7 +60,7 @@ ssize_t usb_store_new_id(struct usb_dynids *dynids, | |||
67 | dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE; | 60 | dynid->id.match_flags = USB_DEVICE_ID_MATCH_DEVICE; |
68 | 61 | ||
69 | spin_lock(&dynids->lock); | 62 | spin_lock(&dynids->lock); |
70 | list_add_tail(&dynids->list, &dynid->node); | 63 | list_add_tail(&dynid->node, &dynids->list); |
71 | spin_unlock(&dynids->lock); | 64 | spin_unlock(&dynids->lock); |
72 | 65 | ||
73 | if (get_driver(driver)) { | 66 | if (get_driver(driver)) { |
@@ -209,6 +202,11 @@ static int usb_probe_interface(struct device *dev) | |||
209 | intf = to_usb_interface(dev); | 202 | intf = to_usb_interface(dev); |
210 | udev = interface_to_usbdev(intf); | 203 | udev = interface_to_usbdev(intf); |
211 | 204 | ||
205 | if (udev->authorized == 0) { | ||
206 | dev_err(&intf->dev, "Device is not authorized for usage\n"); | ||
207 | return -ENODEV; | ||
208 | } | ||
209 | |||
212 | id = usb_match_id(intf, driver->id_table); | 210 | id = usb_match_id(intf, driver->id_table); |
213 | if (!id) | 211 | if (!id) |
214 | id = usb_match_dynamic_id(intf, driver); | 212 | id = usb_match_dynamic_id(intf, driver); |
@@ -583,12 +581,9 @@ static int usb_device_match(struct device *dev, struct device_driver *drv) | |||
583 | } | 581 | } |
584 | 582 | ||
585 | #ifdef CONFIG_HOTPLUG | 583 | #ifdef CONFIG_HOTPLUG |
586 | static int usb_uevent(struct device *dev, char **envp, int num_envp, | 584 | static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) |
587 | char *buffer, int buffer_size) | ||
588 | { | 585 | { |
589 | struct usb_device *usb_dev; | 586 | struct usb_device *usb_dev; |
590 | int i = 0; | ||
591 | int length = 0; | ||
592 | 587 | ||
593 | if (!dev) | 588 | if (!dev) |
594 | return -ENODEV; | 589 | return -ENODEV; |
@@ -617,51 +612,39 @@ static int usb_uevent(struct device *dev, char **envp, int num_envp, | |||
617 | * all the device descriptors we don't tell them about. Or | 612 | * all the device descriptors we don't tell them about. Or |
618 | * act as usermode drivers. | 613 | * act as usermode drivers. |
619 | */ | 614 | */ |
620 | if (add_uevent_var(envp, num_envp, &i, | 615 | if (add_uevent_var(env, "DEVICE=/proc/bus/usb/%03d/%03d", |
621 | buffer, buffer_size, &length, | ||
622 | "DEVICE=/proc/bus/usb/%03d/%03d", | ||
623 | usb_dev->bus->busnum, usb_dev->devnum)) | 616 | usb_dev->bus->busnum, usb_dev->devnum)) |
624 | return -ENOMEM; | 617 | return -ENOMEM; |
625 | #endif | 618 | #endif |
626 | 619 | ||
627 | /* per-device configurations are common */ | 620 | /* per-device configurations are common */ |
628 | if (add_uevent_var(envp, num_envp, &i, | 621 | if (add_uevent_var(env, "PRODUCT=%x/%x/%x", |
629 | buffer, buffer_size, &length, | ||
630 | "PRODUCT=%x/%x/%x", | ||
631 | le16_to_cpu(usb_dev->descriptor.idVendor), | 622 | le16_to_cpu(usb_dev->descriptor.idVendor), |
632 | le16_to_cpu(usb_dev->descriptor.idProduct), | 623 | le16_to_cpu(usb_dev->descriptor.idProduct), |
633 | le16_to_cpu(usb_dev->descriptor.bcdDevice))) | 624 | le16_to_cpu(usb_dev->descriptor.bcdDevice))) |
634 | return -ENOMEM; | 625 | return -ENOMEM; |
635 | 626 | ||
636 | /* class-based driver binding models */ | 627 | /* class-based driver binding models */ |
637 | if (add_uevent_var(envp, num_envp, &i, | 628 | if (add_uevent_var(env, "TYPE=%d/%d/%d", |
638 | buffer, buffer_size, &length, | ||
639 | "TYPE=%d/%d/%d", | ||
640 | usb_dev->descriptor.bDeviceClass, | 629 | usb_dev->descriptor.bDeviceClass, |
641 | usb_dev->descriptor.bDeviceSubClass, | 630 | usb_dev->descriptor.bDeviceSubClass, |
642 | usb_dev->descriptor.bDeviceProtocol)) | 631 | usb_dev->descriptor.bDeviceProtocol)) |
643 | return -ENOMEM; | 632 | return -ENOMEM; |
644 | 633 | ||
645 | if (add_uevent_var(envp, num_envp, &i, | 634 | if (add_uevent_var(env, "BUSNUM=%03d", |
646 | buffer, buffer_size, &length, | ||
647 | "BUSNUM=%03d", | ||
648 | usb_dev->bus->busnum)) | 635 | usb_dev->bus->busnum)) |
649 | return -ENOMEM; | 636 | return -ENOMEM; |
650 | 637 | ||
651 | if (add_uevent_var(envp, num_envp, &i, | 638 | if (add_uevent_var(env, "DEVNUM=%03d", |
652 | buffer, buffer_size, &length, | ||
653 | "DEVNUM=%03d", | ||
654 | usb_dev->devnum)) | 639 | usb_dev->devnum)) |
655 | return -ENOMEM; | 640 | return -ENOMEM; |
656 | 641 | ||
657 | envp[i] = NULL; | ||
658 | return 0; | 642 | return 0; |
659 | } | 643 | } |
660 | 644 | ||
661 | #else | 645 | #else |
662 | 646 | ||
663 | static int usb_uevent(struct device *dev, char **envp, | 647 | static int usb_uevent(struct device *dev, struct kobj_uevent_env *env) |
664 | int num_envp, char *buffer, int buffer_size) | ||
665 | { | 648 | { |
666 | return -ENODEV; | 649 | return -ENODEV; |
667 | } | 650 | } |
@@ -952,11 +935,11 @@ done: | |||
952 | #ifdef CONFIG_USB_SUSPEND | 935 | #ifdef CONFIG_USB_SUSPEND |
953 | 936 | ||
954 | /* Internal routine to check whether we may autosuspend a device. */ | 937 | /* Internal routine to check whether we may autosuspend a device. */ |
955 | static int autosuspend_check(struct usb_device *udev) | 938 | static int autosuspend_check(struct usb_device *udev, int reschedule) |
956 | { | 939 | { |
957 | int i; | 940 | int i; |
958 | struct usb_interface *intf; | 941 | struct usb_interface *intf; |
959 | unsigned long suspend_time; | 942 | unsigned long suspend_time, j; |
960 | 943 | ||
961 | /* For autosuspend, fail fast if anything is in use or autosuspend | 944 | /* For autosuspend, fail fast if anything is in use or autosuspend |
962 | * is disabled. Also fail if any interfaces require remote wakeup | 945 | * is disabled. Also fail if any interfaces require remote wakeup |
@@ -998,20 +981,20 @@ static int autosuspend_check(struct usb_device *udev) | |||
998 | } | 981 | } |
999 | 982 | ||
1000 | /* If everything is okay but the device hasn't been idle for long | 983 | /* If everything is okay but the device hasn't been idle for long |
1001 | * enough, queue a delayed autosuspend request. | 984 | * enough, queue a delayed autosuspend request. If the device |
985 | * _has_ been idle for long enough and the reschedule flag is set, | ||
986 | * likewise queue a delayed (1 second) autosuspend request. | ||
1002 | */ | 987 | */ |
1003 | if (time_after(suspend_time, jiffies)) { | 988 | j = jiffies; |
989 | if (time_before(j, suspend_time)) | ||
990 | reschedule = 1; | ||
991 | else | ||
992 | suspend_time = j + HZ; | ||
993 | if (reschedule) { | ||
1004 | if (!timer_pending(&udev->autosuspend.timer)) { | 994 | if (!timer_pending(&udev->autosuspend.timer)) { |
1005 | |||
1006 | /* The value of jiffies may change between the | ||
1007 | * time_after() comparison above and the subtraction | ||
1008 | * below. That's okay; the system behaves sanely | ||
1009 | * when a timer is registered for the present moment | ||
1010 | * or for the past. | ||
1011 | */ | ||
1012 | queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, | 995 | queue_delayed_work(ksuspend_usb_wq, &udev->autosuspend, |
1013 | round_jiffies_relative(suspend_time - jiffies)); | 996 | round_jiffies_relative(suspend_time - j)); |
1014 | } | 997 | } |
1015 | return -EAGAIN; | 998 | return -EAGAIN; |
1016 | } | 999 | } |
1017 | return 0; | 1000 | return 0; |
@@ -1019,7 +1002,7 @@ static int autosuspend_check(struct usb_device *udev) | |||
1019 | 1002 | ||
1020 | #else | 1003 | #else |
1021 | 1004 | ||
1022 | static inline int autosuspend_check(struct usb_device *udev) | 1005 | static inline int autosuspend_check(struct usb_device *udev, int reschedule) |
1023 | { | 1006 | { |
1024 | return 0; | 1007 | return 0; |
1025 | } | 1008 | } |
@@ -1076,7 +1059,7 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) | |||
1076 | udev->do_remote_wakeup = device_may_wakeup(&udev->dev); | 1059 | udev->do_remote_wakeup = device_may_wakeup(&udev->dev); |
1077 | 1060 | ||
1078 | if (udev->auto_pm) { | 1061 | if (udev->auto_pm) { |
1079 | status = autosuspend_check(udev); | 1062 | status = autosuspend_check(udev, 0); |
1080 | if (status < 0) | 1063 | if (status < 0) |
1081 | goto done; | 1064 | goto done; |
1082 | } | 1065 | } |
@@ -1090,15 +1073,8 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) | |||
1090 | break; | 1073 | break; |
1091 | } | 1074 | } |
1092 | } | 1075 | } |
1093 | if (status == 0) { | 1076 | if (status == 0) |
1094 | |||
1095 | /* Non-root devices don't need to do anything for FREEZE | ||
1096 | * or PRETHAW. */ | ||
1097 | if (udev->parent && (msg.event == PM_EVENT_FREEZE || | ||
1098 | msg.event == PM_EVENT_PRETHAW)) | ||
1099 | goto done; | ||
1100 | status = usb_suspend_device(udev, msg); | 1077 | status = usb_suspend_device(udev, msg); |
1101 | } | ||
1102 | 1078 | ||
1103 | /* If the suspend failed, resume interfaces that did get suspended */ | 1079 | /* If the suspend failed, resume interfaces that did get suspended */ |
1104 | if (status != 0) { | 1080 | if (status != 0) { |
@@ -1109,12 +1085,24 @@ static int usb_suspend_both(struct usb_device *udev, pm_message_t msg) | |||
1109 | 1085 | ||
1110 | /* Try another autosuspend when the interfaces aren't busy */ | 1086 | /* Try another autosuspend when the interfaces aren't busy */ |
1111 | if (udev->auto_pm) | 1087 | if (udev->auto_pm) |
1112 | autosuspend_check(udev); | 1088 | autosuspend_check(udev, status == -EBUSY); |
1113 | 1089 | ||
1114 | /* If the suspend succeeded, propagate it up the tree */ | 1090 | /* If the suspend succeeded then prevent any more URB submissions, |
1091 | * flush any outstanding URBs, and propagate the suspend up the tree. | ||
1092 | */ | ||
1115 | } else { | 1093 | } else { |
1116 | cancel_delayed_work(&udev->autosuspend); | 1094 | cancel_delayed_work(&udev->autosuspend); |
1117 | if (parent) | 1095 | udev->can_submit = 0; |
1096 | for (i = 0; i < 16; ++i) { | ||
1097 | usb_hcd_flush_endpoint(udev, udev->ep_out[i]); | ||
1098 | usb_hcd_flush_endpoint(udev, udev->ep_in[i]); | ||
1099 | } | ||
1100 | |||
1101 | /* If this is just a FREEZE or a PRETHAW, udev might | ||
1102 | * not really be suspended. Only true suspends get | ||
1103 | * propagated up the device tree. | ||
1104 | */ | ||
1105 | if (parent && udev->state == USB_STATE_SUSPENDED) | ||
1118 | usb_autosuspend_device(parent); | 1106 | usb_autosuspend_device(parent); |
1119 | } | 1107 | } |
1120 | 1108 | ||
@@ -1163,6 +1151,7 @@ static int usb_resume_both(struct usb_device *udev) | |||
1163 | status = -ENODEV; | 1151 | status = -ENODEV; |
1164 | goto done; | 1152 | goto done; |
1165 | } | 1153 | } |
1154 | udev->can_submit = 1; | ||
1166 | 1155 | ||
1167 | /* Propagate the resume up the tree, if necessary */ | 1156 | /* Propagate the resume up the tree, if necessary */ |
1168 | if (udev->state == USB_STATE_SUSPENDED) { | 1157 | if (udev->state == USB_STATE_SUSPENDED) { |
@@ -1231,6 +1220,8 @@ static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt) | |||
1231 | udev->auto_pm = 1; | 1220 | udev->auto_pm = 1; |
1232 | udev->pm_usage_cnt += inc_usage_cnt; | 1221 | udev->pm_usage_cnt += inc_usage_cnt; |
1233 | WARN_ON(udev->pm_usage_cnt < 0); | 1222 | WARN_ON(udev->pm_usage_cnt < 0); |
1223 | if (inc_usage_cnt) | ||
1224 | udev->last_busy = jiffies; | ||
1234 | if (inc_usage_cnt >= 0 && udev->pm_usage_cnt > 0) { | 1225 | if (inc_usage_cnt >= 0 && udev->pm_usage_cnt > 0) { |
1235 | if (udev->state == USB_STATE_SUSPENDED) | 1226 | if (udev->state == USB_STATE_SUSPENDED) |
1236 | status = usb_resume_both(udev); | 1227 | status = usb_resume_both(udev); |
@@ -1239,8 +1230,6 @@ static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt) | |||
1239 | else if (inc_usage_cnt) | 1230 | else if (inc_usage_cnt) |
1240 | udev->last_busy = jiffies; | 1231 | udev->last_busy = jiffies; |
1241 | } else if (inc_usage_cnt <= 0 && udev->pm_usage_cnt <= 0) { | 1232 | } else if (inc_usage_cnt <= 0 && udev->pm_usage_cnt <= 0) { |
1242 | if (inc_usage_cnt) | ||
1243 | udev->last_busy = jiffies; | ||
1244 | status = usb_suspend_both(udev, PMSG_SUSPEND); | 1233 | status = usb_suspend_both(udev, PMSG_SUSPEND); |
1245 | } | 1234 | } |
1246 | usb_pm_unlock(udev); | 1235 | usb_pm_unlock(udev); |
@@ -1349,16 +1338,15 @@ static int usb_autopm_do_interface(struct usb_interface *intf, | |||
1349 | else { | 1338 | else { |
1350 | udev->auto_pm = 1; | 1339 | udev->auto_pm = 1; |
1351 | intf->pm_usage_cnt += inc_usage_cnt; | 1340 | intf->pm_usage_cnt += inc_usage_cnt; |
1341 | udev->last_busy = jiffies; | ||
1352 | if (inc_usage_cnt >= 0 && intf->pm_usage_cnt > 0) { | 1342 | if (inc_usage_cnt >= 0 && intf->pm_usage_cnt > 0) { |
1353 | if (udev->state == USB_STATE_SUSPENDED) | 1343 | if (udev->state == USB_STATE_SUSPENDED) |
1354 | status = usb_resume_both(udev); | 1344 | status = usb_resume_both(udev); |
1355 | if (status != 0) | 1345 | if (status != 0) |
1356 | intf->pm_usage_cnt -= inc_usage_cnt; | 1346 | intf->pm_usage_cnt -= inc_usage_cnt; |
1357 | else if (inc_usage_cnt) | 1347 | else |
1358 | udev->last_busy = jiffies; | 1348 | udev->last_busy = jiffies; |
1359 | } else if (inc_usage_cnt <= 0 && intf->pm_usage_cnt <= 0) { | 1349 | } else if (inc_usage_cnt <= 0 && intf->pm_usage_cnt <= 0) { |
1360 | if (inc_usage_cnt) | ||
1361 | udev->last_busy = jiffies; | ||
1362 | status = usb_suspend_both(udev, PMSG_SUSPEND); | 1350 | status = usb_suspend_both(udev, PMSG_SUSPEND); |
1363 | } | 1351 | } |
1364 | } | 1352 | } |
@@ -1537,9 +1525,21 @@ int usb_external_resume_device(struct usb_device *udev) | |||
1537 | 1525 | ||
1538 | static int usb_suspend(struct device *dev, pm_message_t message) | 1526 | static int usb_suspend(struct device *dev, pm_message_t message) |
1539 | { | 1527 | { |
1528 | struct usb_device *udev; | ||
1529 | |||
1540 | if (!is_usb_device(dev)) /* Ignore PM for interfaces */ | 1530 | if (!is_usb_device(dev)) /* Ignore PM for interfaces */ |
1541 | return 0; | 1531 | return 0; |
1542 | return usb_external_suspend_device(to_usb_device(dev), message); | 1532 | udev = to_usb_device(dev); |
1533 | |||
1534 | /* If udev is already suspended, we can skip this suspend and | ||
1535 | * we should also skip the upcoming system resume. */ | ||
1536 | if (udev->state == USB_STATE_SUSPENDED) { | ||
1537 | udev->skip_sys_resume = 1; | ||
1538 | return 0; | ||
1539 | } | ||
1540 | |||
1541 | udev->skip_sys_resume = 0; | ||
1542 | return usb_external_suspend_device(udev, message); | ||
1543 | } | 1543 | } |
1544 | 1544 | ||
1545 | static int usb_resume(struct device *dev) | 1545 | static int usb_resume(struct device *dev) |
@@ -1550,13 +1550,14 @@ static int usb_resume(struct device *dev) | |||
1550 | return 0; | 1550 | return 0; |
1551 | udev = to_usb_device(dev); | 1551 | udev = to_usb_device(dev); |
1552 | 1552 | ||
1553 | /* If autoresume is disabled then we also want to prevent resume | 1553 | /* If udev->skip_sys_resume is set then udev was already suspended |
1554 | * during system wakeup. However, a "persistent-device" reset-resume | 1554 | * when the system suspend started, so we don't want to resume |
1555 | * after power loss counts as a wakeup event. So allow a | 1555 | * udev during this system wakeup. However a reset-resume counts |
1556 | * reset-resume to occur if remote wakeup is enabled. */ | 1556 | * as a wakeup event, so allow a reset-resume to occur if remote |
1557 | if (udev->autoresume_disabled) { | 1557 | * wakeup is enabled. */ |
1558 | if (udev->skip_sys_resume) { | ||
1558 | if (!(udev->reset_resume && udev->do_remote_wakeup)) | 1559 | if (!(udev->reset_resume && udev->do_remote_wakeup)) |
1559 | return -EPERM; | 1560 | return -EHOSTUNREACH; |
1560 | } | 1561 | } |
1561 | return usb_external_resume_device(udev); | 1562 | return usb_external_resume_device(udev); |
1562 | } | 1563 | } |
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c index e0ec7045e86..7dc123d6b2d 100644 --- a/drivers/usb/core/endpoint.c +++ b/drivers/usb/core/endpoint.c | |||
@@ -267,7 +267,6 @@ static void ep_device_release(struct device *dev) | |||
267 | { | 267 | { |
268 | struct ep_device *ep_dev = to_ep_device(dev); | 268 | struct ep_device *ep_dev = to_ep_device(dev); |
269 | 269 | ||
270 | dev_dbg(dev, "%s called for %s\n", __FUNCTION__, dev->bus_id); | ||
271 | endpoint_free_minor(ep_dev); | 270 | endpoint_free_minor(ep_dev); |
272 | kfree(ep_dev); | 271 | kfree(ep_dev); |
273 | } | 272 | } |
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c index b2fc2b11525..c1cb94e9f24 100644 --- a/drivers/usb/core/generic.c +++ b/drivers/usb/core/generic.c | |||
@@ -40,7 +40,7 @@ static int is_activesync(struct usb_interface_descriptor *desc) | |||
40 | && desc->bInterfaceProtocol == 1; | 40 | && desc->bInterfaceProtocol == 1; |
41 | } | 41 | } |
42 | 42 | ||
43 | static int choose_configuration(struct usb_device *udev) | 43 | int usb_choose_configuration(struct usb_device *udev) |
44 | { | 44 | { |
45 | int i; | 45 | int i; |
46 | int num_configs; | 46 | int num_configs; |
@@ -161,17 +161,20 @@ static int generic_probe(struct usb_device *udev) | |||
161 | /* Choose and set the configuration. This registers the interfaces | 161 | /* Choose and set the configuration. This registers the interfaces |
162 | * with the driver core and lets interface drivers bind to them. | 162 | * with the driver core and lets interface drivers bind to them. |
163 | */ | 163 | */ |
164 | c = choose_configuration(udev); | 164 | if (udev->authorized == 0) |
165 | if (c >= 0) { | 165 | dev_err(&udev->dev, "Device is not authorized for usage\n"); |
166 | err = usb_set_configuration(udev, c); | 166 | else { |
167 | if (err) { | 167 | c = usb_choose_configuration(udev); |
168 | dev_err(&udev->dev, "can't set config #%d, error %d\n", | 168 | if (c >= 0) { |
169 | err = usb_set_configuration(udev, c); | ||
170 | if (err) { | ||
171 | dev_err(&udev->dev, "can't set config #%d, error %d\n", | ||
169 | c, err); | 172 | c, err); |
170 | /* This need not be fatal. The user can try to | 173 | /* This need not be fatal. The user can try to |
171 | * set other configurations. */ | 174 | * set other configurations. */ |
175 | } | ||
172 | } | 176 | } |
173 | } | 177 | } |
174 | |||
175 | /* USB device state == configured ... usable */ | 178 | /* USB device state == configured ... usable */ |
176 | usb_notify_add_device(udev); | 179 | usb_notify_add_device(udev); |
177 | 180 | ||
@@ -203,8 +206,13 @@ static int generic_suspend(struct usb_device *udev, pm_message_t msg) | |||
203 | */ | 206 | */ |
204 | if (!udev->parent) | 207 | if (!udev->parent) |
205 | rc = hcd_bus_suspend(udev); | 208 | rc = hcd_bus_suspend(udev); |
209 | |||
210 | /* Non-root devices don't need to do anything for FREEZE or PRETHAW */ | ||
211 | else if (msg.event == PM_EVENT_FREEZE || msg.event == PM_EVENT_PRETHAW) | ||
212 | rc = 0; | ||
206 | else | 213 | else |
207 | rc = usb_port_suspend(udev); | 214 | rc = usb_port_suspend(udev); |
215 | |||
208 | return rc; | 216 | return rc; |
209 | } | 217 | } |
210 | 218 | ||
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 963520fbef9..3dd997df850 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c | |||
@@ -99,12 +99,17 @@ EXPORT_SYMBOL_GPL (usb_bus_list_lock); | |||
99 | /* used for controlling access to virtual root hubs */ | 99 | /* used for controlling access to virtual root hubs */ |
100 | static DEFINE_SPINLOCK(hcd_root_hub_lock); | 100 | static DEFINE_SPINLOCK(hcd_root_hub_lock); |
101 | 101 | ||
102 | /* used when updating hcd data */ | 102 | /* used when updating an endpoint's URB list */ |
103 | static DEFINE_SPINLOCK(hcd_data_lock); | 103 | static DEFINE_SPINLOCK(hcd_urb_list_lock); |
104 | 104 | ||
105 | /* wait queue for synchronous unlinks */ | 105 | /* wait queue for synchronous unlinks */ |
106 | DECLARE_WAIT_QUEUE_HEAD(usb_kill_urb_queue); | 106 | DECLARE_WAIT_QUEUE_HEAD(usb_kill_urb_queue); |
107 | 107 | ||
108 | static inline int is_root_hub(struct usb_device *udev) | ||
109 | { | ||
110 | return (udev->parent == NULL); | ||
111 | } | ||
112 | |||
108 | /*-------------------------------------------------------------------------*/ | 113 | /*-------------------------------------------------------------------------*/ |
109 | 114 | ||
110 | /* | 115 | /* |
@@ -351,10 +356,18 @@ static int rh_call_control (struct usb_hcd *hcd, struct urb *urb) | |||
351 | const u8 *bufp = tbuf; | 356 | const u8 *bufp = tbuf; |
352 | int len = 0; | 357 | int len = 0; |
353 | int patch_wakeup = 0; | 358 | int patch_wakeup = 0; |
354 | unsigned long flags; | 359 | int status; |
355 | int status = 0; | ||
356 | int n; | 360 | int n; |
357 | 361 | ||
362 | might_sleep(); | ||
363 | |||
364 | spin_lock_irq(&hcd_root_hub_lock); | ||
365 | status = usb_hcd_link_urb_to_ep(hcd, urb); | ||
366 | spin_unlock_irq(&hcd_root_hub_lock); | ||
367 | if (status) | ||
368 | return status; | ||
369 | urb->hcpriv = hcd; /* Indicate it's queued */ | ||
370 | |||
358 | cmd = (struct usb_ctrlrequest *) urb->setup_packet; | 371 | cmd = (struct usb_ctrlrequest *) urb->setup_packet; |
359 | typeReq = (cmd->bRequestType << 8) | cmd->bRequest; | 372 | typeReq = (cmd->bRequestType << 8) | cmd->bRequest; |
360 | wValue = le16_to_cpu (cmd->wValue); | 373 | wValue = le16_to_cpu (cmd->wValue); |
@@ -518,13 +531,18 @@ error: | |||
518 | } | 531 | } |
519 | 532 | ||
520 | /* any errors get returned through the urb completion */ | 533 | /* any errors get returned through the urb completion */ |
521 | local_irq_save (flags); | 534 | spin_lock_irq(&hcd_root_hub_lock); |
522 | spin_lock (&urb->lock); | 535 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
523 | if (urb->status == -EINPROGRESS) | 536 | |
524 | urb->status = status; | 537 | /* This peculiar use of spinlocks echoes what real HC drivers do. |
525 | spin_unlock (&urb->lock); | 538 | * Avoiding calls to local_irq_disable/enable makes the code |
526 | usb_hcd_giveback_urb (hcd, urb); | 539 | * RT-friendly. |
527 | local_irq_restore (flags); | 540 | */ |
541 | spin_unlock(&hcd_root_hub_lock); | ||
542 | usb_hcd_giveback_urb(hcd, urb, status); | ||
543 | spin_lock(&hcd_root_hub_lock); | ||
544 | |||
545 | spin_unlock_irq(&hcd_root_hub_lock); | ||
528 | return 0; | 546 | return 0; |
529 | } | 547 | } |
530 | 548 | ||
@@ -554,31 +572,23 @@ void usb_hcd_poll_rh_status(struct usb_hcd *hcd) | |||
554 | if (length > 0) { | 572 | if (length > 0) { |
555 | 573 | ||
556 | /* try to complete the status urb */ | 574 | /* try to complete the status urb */ |
557 | local_irq_save (flags); | 575 | spin_lock_irqsave(&hcd_root_hub_lock, flags); |
558 | spin_lock(&hcd_root_hub_lock); | ||
559 | urb = hcd->status_urb; | 576 | urb = hcd->status_urb; |
560 | if (urb) { | 577 | if (urb) { |
561 | spin_lock(&urb->lock); | 578 | hcd->poll_pending = 0; |
562 | if (urb->status == -EINPROGRESS) { | 579 | hcd->status_urb = NULL; |
563 | hcd->poll_pending = 0; | 580 | urb->actual_length = length; |
564 | hcd->status_urb = NULL; | 581 | memcpy(urb->transfer_buffer, buffer, length); |
565 | urb->status = 0; | ||
566 | urb->hcpriv = NULL; | ||
567 | urb->actual_length = length; | ||
568 | memcpy(urb->transfer_buffer, buffer, length); | ||
569 | } else /* urb has been unlinked */ | ||
570 | length = 0; | ||
571 | spin_unlock(&urb->lock); | ||
572 | } else | ||
573 | length = 0; | ||
574 | spin_unlock(&hcd_root_hub_lock); | ||
575 | 582 | ||
576 | /* local irqs are always blocked in completions */ | 583 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
577 | if (length > 0) | 584 | spin_unlock(&hcd_root_hub_lock); |
578 | usb_hcd_giveback_urb (hcd, urb); | 585 | usb_hcd_giveback_urb(hcd, urb, 0); |
579 | else | 586 | spin_lock(&hcd_root_hub_lock); |
587 | } else { | ||
588 | length = 0; | ||
580 | hcd->poll_pending = 1; | 589 | hcd->poll_pending = 1; |
581 | local_irq_restore (flags); | 590 | } |
591 | spin_unlock_irqrestore(&hcd_root_hub_lock, flags); | ||
582 | } | 592 | } |
583 | 593 | ||
584 | /* The USB 2.0 spec says 256 ms. This is close enough and won't | 594 | /* The USB 2.0 spec says 256 ms. This is close enough and won't |
@@ -606,33 +616,35 @@ static int rh_queue_status (struct usb_hcd *hcd, struct urb *urb) | |||
606 | int len = 1 + (urb->dev->maxchild / 8); | 616 | int len = 1 + (urb->dev->maxchild / 8); |
607 | 617 | ||
608 | spin_lock_irqsave (&hcd_root_hub_lock, flags); | 618 | spin_lock_irqsave (&hcd_root_hub_lock, flags); |
609 | if (urb->status != -EINPROGRESS) /* already unlinked */ | 619 | if (hcd->status_urb || urb->transfer_buffer_length < len) { |
610 | retval = urb->status; | ||
611 | else if (hcd->status_urb || urb->transfer_buffer_length < len) { | ||
612 | dev_dbg (hcd->self.controller, "not queuing rh status urb\n"); | 620 | dev_dbg (hcd->self.controller, "not queuing rh status urb\n"); |
613 | retval = -EINVAL; | 621 | retval = -EINVAL; |
614 | } else { | 622 | goto done; |
615 | hcd->status_urb = urb; | 623 | } |
616 | urb->hcpriv = hcd; /* indicate it's queued */ | ||
617 | 624 | ||
618 | if (!hcd->uses_new_polling) | 625 | retval = usb_hcd_link_urb_to_ep(hcd, urb); |
619 | mod_timer (&hcd->rh_timer, | 626 | if (retval) |
620 | (jiffies/(HZ/4) + 1) * (HZ/4)); | 627 | goto done; |
621 | 628 | ||
622 | /* If a status change has already occurred, report it ASAP */ | 629 | hcd->status_urb = urb; |
623 | else if (hcd->poll_pending) | 630 | urb->hcpriv = hcd; /* indicate it's queued */ |
624 | mod_timer (&hcd->rh_timer, jiffies); | 631 | if (!hcd->uses_new_polling) |
625 | retval = 0; | 632 | mod_timer(&hcd->rh_timer, (jiffies/(HZ/4) + 1) * (HZ/4)); |
626 | } | 633 | |
634 | /* If a status change has already occurred, report it ASAP */ | ||
635 | else if (hcd->poll_pending) | ||
636 | mod_timer(&hcd->rh_timer, jiffies); | ||
637 | retval = 0; | ||
638 | done: | ||
627 | spin_unlock_irqrestore (&hcd_root_hub_lock, flags); | 639 | spin_unlock_irqrestore (&hcd_root_hub_lock, flags); |
628 | return retval; | 640 | return retval; |
629 | } | 641 | } |
630 | 642 | ||
631 | static int rh_urb_enqueue (struct usb_hcd *hcd, struct urb *urb) | 643 | static int rh_urb_enqueue (struct usb_hcd *hcd, struct urb *urb) |
632 | { | 644 | { |
633 | if (usb_pipeint (urb->pipe)) | 645 | if (usb_endpoint_xfer_int(&urb->ep->desc)) |
634 | return rh_queue_status (hcd, urb); | 646 | return rh_queue_status (hcd, urb); |
635 | if (usb_pipecontrol (urb->pipe)) | 647 | if (usb_endpoint_xfer_control(&urb->ep->desc)) |
636 | return rh_call_control (hcd, urb); | 648 | return rh_call_control (hcd, urb); |
637 | return -EINVAL; | 649 | return -EINVAL; |
638 | } | 650 | } |
@@ -642,32 +654,96 @@ static int rh_urb_enqueue (struct usb_hcd *hcd, struct urb *urb) | |||
642 | /* Unlinks of root-hub control URBs are legal, but they don't do anything | 654 | /* Unlinks of root-hub control URBs are legal, but they don't do anything |
643 | * since these URBs always execute synchronously. | 655 | * since these URBs always execute synchronously. |
644 | */ | 656 | */ |
645 | static int usb_rh_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) | 657 | static int usb_rh_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) |
646 | { | 658 | { |
647 | unsigned long flags; | 659 | unsigned long flags; |
660 | int rc; | ||
648 | 661 | ||
649 | if (usb_pipeendpoint(urb->pipe) == 0) { /* Control URB */ | 662 | spin_lock_irqsave(&hcd_root_hub_lock, flags); |
663 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); | ||
664 | if (rc) | ||
665 | goto done; | ||
666 | |||
667 | if (usb_endpoint_num(&urb->ep->desc) == 0) { /* Control URB */ | ||
650 | ; /* Do nothing */ | 668 | ; /* Do nothing */ |
651 | 669 | ||
652 | } else { /* Status URB */ | 670 | } else { /* Status URB */ |
653 | if (!hcd->uses_new_polling) | 671 | if (!hcd->uses_new_polling) |
654 | del_timer (&hcd->rh_timer); | 672 | del_timer (&hcd->rh_timer); |
655 | local_irq_save (flags); | ||
656 | spin_lock (&hcd_root_hub_lock); | ||
657 | if (urb == hcd->status_urb) { | 673 | if (urb == hcd->status_urb) { |
658 | hcd->status_urb = NULL; | 674 | hcd->status_urb = NULL; |
659 | urb->hcpriv = NULL; | 675 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
660 | } else | 676 | |
661 | urb = NULL; /* wasn't fully queued */ | 677 | spin_unlock(&hcd_root_hub_lock); |
662 | spin_unlock (&hcd_root_hub_lock); | 678 | usb_hcd_giveback_urb(hcd, urb, status); |
663 | if (urb) | 679 | spin_lock(&hcd_root_hub_lock); |
664 | usb_hcd_giveback_urb (hcd, urb); | 680 | } |
665 | local_irq_restore (flags); | ||
666 | } | 681 | } |
682 | done: | ||
683 | spin_unlock_irqrestore(&hcd_root_hub_lock, flags); | ||
684 | return rc; | ||
685 | } | ||
667 | 686 | ||
668 | return 0; | 687 | |
688 | |||
689 | /* | ||
690 | * Show & store the current value of authorized_default | ||
691 | */ | ||
692 | static ssize_t usb_host_authorized_default_show(struct device *dev, | ||
693 | struct device_attribute *attr, | ||
694 | char *buf) | ||
695 | { | ||
696 | struct usb_device *rh_usb_dev = to_usb_device(dev); | ||
697 | struct usb_bus *usb_bus = rh_usb_dev->bus; | ||
698 | struct usb_hcd *usb_hcd; | ||
699 | |||
700 | if (usb_bus == NULL) /* FIXME: not sure if this case is possible */ | ||
701 | return -ENODEV; | ||
702 | usb_hcd = bus_to_hcd(usb_bus); | ||
703 | return snprintf(buf, PAGE_SIZE, "%u\n", usb_hcd->authorized_default); | ||
704 | } | ||
705 | |||
706 | static ssize_t usb_host_authorized_default_store(struct device *dev, | ||
707 | struct device_attribute *attr, | ||
708 | const char *buf, size_t size) | ||
709 | { | ||
710 | ssize_t result; | ||
711 | unsigned val; | ||
712 | struct usb_device *rh_usb_dev = to_usb_device(dev); | ||
713 | struct usb_bus *usb_bus = rh_usb_dev->bus; | ||
714 | struct usb_hcd *usb_hcd; | ||
715 | |||
716 | if (usb_bus == NULL) /* FIXME: not sure if this case is possible */ | ||
717 | return -ENODEV; | ||
718 | usb_hcd = bus_to_hcd(usb_bus); | ||
719 | result = sscanf(buf, "%u\n", &val); | ||
720 | if (result == 1) { | ||
721 | usb_hcd->authorized_default = val? 1 : 0; | ||
722 | result = size; | ||
723 | } | ||
724 | else | ||
725 | result = -EINVAL; | ||
726 | return result; | ||
669 | } | 727 | } |
670 | 728 | ||
729 | static DEVICE_ATTR(authorized_default, 0644, | ||
730 | usb_host_authorized_default_show, | ||
731 | usb_host_authorized_default_store); | ||
732 | |||
733 | |||
734 | /* Group all the USB bus attributes */ | ||
735 | static struct attribute *usb_bus_attrs[] = { | ||
736 | &dev_attr_authorized_default.attr, | ||
737 | NULL, | ||
738 | }; | ||
739 | |||
740 | static struct attribute_group usb_bus_attr_group = { | ||
741 | .name = NULL, /* we want them in the same directory */ | ||
742 | .attrs = usb_bus_attrs, | ||
743 | }; | ||
744 | |||
745 | |||
746 | |||
671 | /*-------------------------------------------------------------------------*/ | 747 | /*-------------------------------------------------------------------------*/ |
672 | 748 | ||
673 | static struct class *usb_host_class; | 749 | static struct class *usb_host_class; |
@@ -721,27 +797,23 @@ static void usb_bus_init (struct usb_bus *bus) | |||
721 | */ | 797 | */ |
722 | static int usb_register_bus(struct usb_bus *bus) | 798 | static int usb_register_bus(struct usb_bus *bus) |
723 | { | 799 | { |
800 | int result = -E2BIG; | ||
724 | int busnum; | 801 | int busnum; |
725 | 802 | ||
726 | mutex_lock(&usb_bus_list_lock); | 803 | mutex_lock(&usb_bus_list_lock); |
727 | busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1); | 804 | busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1); |
728 | if (busnum < USB_MAXBUS) { | 805 | if (busnum >= USB_MAXBUS) { |
729 | set_bit (busnum, busmap.busmap); | ||
730 | bus->busnum = busnum; | ||
731 | } else { | ||
732 | printk (KERN_ERR "%s: too many buses\n", usbcore_name); | 806 | printk (KERN_ERR "%s: too many buses\n", usbcore_name); |
733 | mutex_unlock(&usb_bus_list_lock); | 807 | goto error_find_busnum; |
734 | return -E2BIG; | ||
735 | } | 808 | } |
736 | 809 | set_bit (busnum, busmap.busmap); | |
810 | bus->busnum = busnum; | ||
737 | bus->class_dev = class_device_create(usb_host_class, NULL, MKDEV(0,0), | 811 | bus->class_dev = class_device_create(usb_host_class, NULL, MKDEV(0,0), |
738 | bus->controller, "usb_host%d", busnum); | 812 | bus->controller, "usb_host%d", |
739 | if (IS_ERR(bus->class_dev)) { | 813 | busnum); |
740 | clear_bit(busnum, busmap.busmap); | 814 | result = PTR_ERR(bus->class_dev); |
741 | mutex_unlock(&usb_bus_list_lock); | 815 | if (IS_ERR(bus->class_dev)) |
742 | return PTR_ERR(bus->class_dev); | 816 | goto error_create_class_dev; |
743 | } | ||
744 | |||
745 | class_set_devdata(bus->class_dev, bus); | 817 | class_set_devdata(bus->class_dev, bus); |
746 | 818 | ||
747 | /* Add it to the local list of buses */ | 819 | /* Add it to the local list of buses */ |
@@ -750,8 +822,15 @@ static int usb_register_bus(struct usb_bus *bus) | |||
750 | 822 | ||
751 | usb_notify_add_bus(bus); | 823 | usb_notify_add_bus(bus); |
752 | 824 | ||
753 | dev_info (bus->controller, "new USB bus registered, assigned bus number %d\n", bus->busnum); | 825 | dev_info (bus->controller, "new USB bus registered, assigned bus " |
826 | "number %d\n", bus->busnum); | ||
754 | return 0; | 827 | return 0; |
828 | |||
829 | error_create_class_dev: | ||
830 | clear_bit(busnum, busmap.busmap); | ||
831 | error_find_busnum: | ||
832 | mutex_unlock(&usb_bus_list_lock); | ||
833 | return result; | ||
755 | } | 834 | } |
756 | 835 | ||
757 | /** | 836 | /** |
@@ -903,104 +982,145 @@ EXPORT_SYMBOL (usb_calc_bus_time); | |||
903 | 982 | ||
904 | /*-------------------------------------------------------------------------*/ | 983 | /*-------------------------------------------------------------------------*/ |
905 | 984 | ||
906 | static void urb_unlink(struct usb_hcd *hcd, struct urb *urb) | 985 | /** |
986 | * usb_hcd_link_urb_to_ep - add an URB to its endpoint queue | ||
987 | * @hcd: host controller to which @urb was submitted | ||
988 | * @urb: URB being submitted | ||
989 | * | ||
990 | * Host controller drivers should call this routine in their enqueue() | ||
991 | * method. The HCD's private spinlock must be held and interrupts must | ||
992 | * be disabled. The actions carried out here are required for URB | ||
993 | * submission, as well as for endpoint shutdown and for usb_kill_urb. | ||
994 | * | ||
995 | * Returns 0 for no error, otherwise a negative error code (in which case | ||
996 | * the enqueue() method must fail). If no error occurs but enqueue() fails | ||
997 | * anyway, it must call usb_hcd_unlink_urb_from_ep() before releasing | ||
998 | * the private spinlock and returning. | ||
999 | */ | ||
1000 | int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb) | ||
907 | { | 1001 | { |
908 | unsigned long flags; | 1002 | int rc = 0; |
909 | int at_root_hub = (urb->dev == hcd->self.root_hub); | ||
910 | 1003 | ||
911 | /* clear all state linking urb to this dev (and hcd) */ | 1004 | spin_lock(&hcd_urb_list_lock); |
912 | spin_lock_irqsave (&hcd_data_lock, flags); | ||
913 | list_del_init (&urb->urb_list); | ||
914 | spin_unlock_irqrestore (&hcd_data_lock, flags); | ||
915 | 1005 | ||
916 | if (hcd->self.uses_dma && !at_root_hub) { | 1006 | /* Check that the URB isn't being killed */ |
917 | if (usb_pipecontrol (urb->pipe) | 1007 | if (unlikely(urb->reject)) { |
918 | && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) | 1008 | rc = -EPERM; |
919 | dma_unmap_single (hcd->self.controller, urb->setup_dma, | 1009 | goto done; |
920 | sizeof (struct usb_ctrlrequest), | ||
921 | DMA_TO_DEVICE); | ||
922 | if (urb->transfer_buffer_length != 0 | ||
923 | && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) | ||
924 | dma_unmap_single (hcd->self.controller, | ||
925 | urb->transfer_dma, | ||
926 | urb->transfer_buffer_length, | ||
927 | usb_pipein (urb->pipe) | ||
928 | ? DMA_FROM_DEVICE | ||
929 | : DMA_TO_DEVICE); | ||
930 | } | 1010 | } |
931 | } | ||
932 | |||
933 | /* may be called in any context with a valid urb->dev usecount | ||
934 | * caller surrenders "ownership" of urb | ||
935 | * expects usb_submit_urb() to have sanity checked and conditioned all | ||
936 | * inputs in the urb | ||
937 | */ | ||
938 | int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) | ||
939 | { | ||
940 | int status; | ||
941 | struct usb_hcd *hcd = bus_to_hcd(urb->dev->bus); | ||
942 | struct usb_host_endpoint *ep; | ||
943 | unsigned long flags; | ||
944 | 1011 | ||
945 | if (!hcd) | 1012 | if (unlikely(!urb->ep->enabled)) { |
946 | return -ENODEV; | 1013 | rc = -ENOENT; |
1014 | goto done; | ||
1015 | } | ||
947 | 1016 | ||
948 | usbmon_urb_submit(&hcd->self, urb); | 1017 | if (unlikely(!urb->dev->can_submit)) { |
1018 | rc = -EHOSTUNREACH; | ||
1019 | goto done; | ||
1020 | } | ||
949 | 1021 | ||
950 | /* | 1022 | /* |
951 | * Atomically queue the urb, first to our records, then to the HCD. | 1023 | * Check the host controller's state and add the URB to the |
952 | * Access to urb->status is controlled by urb->lock ... changes on | 1024 | * endpoint's queue. |
953 | * i/o completion (normal or fault) or unlinking. | ||
954 | */ | 1025 | */ |
955 | 1026 | switch (hcd->state) { | |
956 | // FIXME: verify that quiescing hc works right (RH cleans up) | ||
957 | |||
958 | spin_lock_irqsave (&hcd_data_lock, flags); | ||
959 | ep = (usb_pipein(urb->pipe) ? urb->dev->ep_in : urb->dev->ep_out) | ||
960 | [usb_pipeendpoint(urb->pipe)]; | ||
961 | if (unlikely (!ep)) | ||
962 | status = -ENOENT; | ||
963 | else if (unlikely (urb->reject)) | ||
964 | status = -EPERM; | ||
965 | else switch (hcd->state) { | ||
966 | case HC_STATE_RUNNING: | 1027 | case HC_STATE_RUNNING: |
967 | case HC_STATE_RESUMING: | 1028 | case HC_STATE_RESUMING: |
968 | list_add_tail (&urb->urb_list, &ep->urb_list); | 1029 | urb->unlinked = 0; |
969 | status = 0; | 1030 | list_add_tail(&urb->urb_list, &urb->ep->urb_list); |
970 | break; | 1031 | break; |
971 | default: | 1032 | default: |
972 | status = -ESHUTDOWN; | 1033 | rc = -ESHUTDOWN; |
973 | break; | 1034 | goto done; |
974 | } | 1035 | } |
975 | spin_unlock_irqrestore (&hcd_data_lock, flags); | 1036 | done: |
976 | if (status) { | 1037 | spin_unlock(&hcd_urb_list_lock); |
977 | INIT_LIST_HEAD (&urb->urb_list); | 1038 | return rc; |
978 | usbmon_urb_submit_error(&hcd->self, urb, status); | 1039 | } |
979 | return status; | 1040 | EXPORT_SYMBOL_GPL(usb_hcd_link_urb_to_ep); |
1041 | |||
1042 | /** | ||
1043 | * usb_hcd_check_unlink_urb - check whether an URB may be unlinked | ||
1044 | * @hcd: host controller to which @urb was submitted | ||
1045 | * @urb: URB being checked for unlinkability | ||
1046 | * @status: error code to store in @urb if the unlink succeeds | ||
1047 | * | ||
1048 | * Host controller drivers should call this routine in their dequeue() | ||
1049 | * method. The HCD's private spinlock must be held and interrupts must | ||
1050 | * be disabled. The actions carried out here are required for making | ||
1051 | * sure than an unlink is valid. | ||
1052 | * | ||
1053 | * Returns 0 for no error, otherwise a negative error code (in which case | ||
1054 | * the dequeue() method must fail). The possible error codes are: | ||
1055 | * | ||
1056 | * -EIDRM: @urb was not submitted or has already completed. | ||
1057 | * The completion function may not have been called yet. | ||
1058 | * | ||
1059 | * -EBUSY: @urb has already been unlinked. | ||
1060 | */ | ||
1061 | int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb, | ||
1062 | int status) | ||
1063 | { | ||
1064 | struct list_head *tmp; | ||
1065 | |||
1066 | /* insist the urb is still queued */ | ||
1067 | list_for_each(tmp, &urb->ep->urb_list) { | ||
1068 | if (tmp == &urb->urb_list) | ||
1069 | break; | ||
980 | } | 1070 | } |
1071 | if (tmp != &urb->urb_list) | ||
1072 | return -EIDRM; | ||
981 | 1073 | ||
982 | /* increment urb's reference count as part of giving it to the HCD | 1074 | /* Any status except -EINPROGRESS means something already started to |
983 | * (which now controls it). HCD guarantees that it either returns | 1075 | * unlink this URB from the hardware. So there's no more work to do. |
984 | * an error or calls giveback(), but not both. | ||
985 | */ | 1076 | */ |
986 | urb = usb_get_urb (urb); | 1077 | if (urb->unlinked) |
987 | atomic_inc (&urb->use_count); | 1078 | return -EBUSY; |
988 | 1079 | urb->unlinked = status; | |
989 | if (urb->dev == hcd->self.root_hub) { | 1080 | |
990 | /* NOTE: requirement on hub callers (usbfs and the hub | 1081 | /* IRQ setup can easily be broken so that USB controllers |
991 | * driver, for now) that URBs' urb->transfer_buffer be | 1082 | * never get completion IRQs ... maybe even the ones we need to |
992 | * valid and usb_buffer_{sync,unmap}() not be needed, since | 1083 | * finish unlinking the initial failed usb_set_address() |
993 | * they could clobber root hub response data. | 1084 | * or device descriptor fetch. |
994 | */ | 1085 | */ |
995 | status = rh_urb_enqueue (hcd, urb); | 1086 | if (!test_bit(HCD_FLAG_SAW_IRQ, &hcd->flags) && |
996 | goto done; | 1087 | !is_root_hub(urb->dev)) { |
1088 | dev_warn(hcd->self.controller, "Unlink after no-IRQ? " | ||
1089 | "Controller is probably using the wrong IRQ.\n"); | ||
1090 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); | ||
997 | } | 1091 | } |
998 | 1092 | ||
999 | /* lower level hcd code should use *_dma exclusively, | 1093 | return 0; |
1094 | } | ||
1095 | EXPORT_SYMBOL_GPL(usb_hcd_check_unlink_urb); | ||
1096 | |||
1097 | /** | ||
1098 | * usb_hcd_unlink_urb_from_ep - remove an URB from its endpoint queue | ||
1099 | * @hcd: host controller to which @urb was submitted | ||
1100 | * @urb: URB being unlinked | ||
1101 | * | ||
1102 | * Host controller drivers should call this routine before calling | ||
1103 | * usb_hcd_giveback_urb(). The HCD's private spinlock must be held and | ||
1104 | * interrupts must be disabled. The actions carried out here are required | ||
1105 | * for URB completion. | ||
1106 | */ | ||
1107 | void usb_hcd_unlink_urb_from_ep(struct usb_hcd *hcd, struct urb *urb) | ||
1108 | { | ||
1109 | /* clear all state linking urb to this dev (and hcd) */ | ||
1110 | spin_lock(&hcd_urb_list_lock); | ||
1111 | list_del_init(&urb->urb_list); | ||
1112 | spin_unlock(&hcd_urb_list_lock); | ||
1113 | } | ||
1114 | EXPORT_SYMBOL_GPL(usb_hcd_unlink_urb_from_ep); | ||
1115 | |||
1116 | static void map_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) | ||
1117 | { | ||
1118 | /* Map the URB's buffers for DMA access. | ||
1119 | * Lower level HCD code should use *_dma exclusively, | ||
1000 | * unless it uses pio or talks to another transport. | 1120 | * unless it uses pio or talks to another transport. |
1001 | */ | 1121 | */ |
1002 | if (hcd->self.uses_dma) { | 1122 | if (hcd->self.uses_dma && !is_root_hub(urb->dev)) { |
1003 | if (usb_pipecontrol (urb->pipe) | 1123 | if (usb_endpoint_xfer_control(&urb->ep->desc) |
1004 | && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) | 1124 | && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) |
1005 | urb->setup_dma = dma_map_single ( | 1125 | urb->setup_dma = dma_map_single ( |
1006 | hcd->self.controller, | 1126 | hcd->self.controller, |
@@ -1013,34 +1133,77 @@ int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) | |||
1013 | hcd->self.controller, | 1133 | hcd->self.controller, |
1014 | urb->transfer_buffer, | 1134 | urb->transfer_buffer, |
1015 | urb->transfer_buffer_length, | 1135 | urb->transfer_buffer_length, |
1016 | usb_pipein (urb->pipe) | 1136 | usb_urb_dir_in(urb) |
1017 | ? DMA_FROM_DEVICE | 1137 | ? DMA_FROM_DEVICE |
1018 | : DMA_TO_DEVICE); | 1138 | : DMA_TO_DEVICE); |
1019 | } | 1139 | } |
1140 | } | ||
1020 | 1141 | ||
1021 | status = hcd->driver->urb_enqueue (hcd, ep, urb, mem_flags); | 1142 | static void unmap_urb_for_dma(struct usb_hcd *hcd, struct urb *urb) |
1022 | done: | 1143 | { |
1023 | if (unlikely (status)) { | 1144 | if (hcd->self.uses_dma && !is_root_hub(urb->dev)) { |
1024 | urb_unlink(hcd, urb); | 1145 | if (usb_endpoint_xfer_control(&urb->ep->desc) |
1025 | atomic_dec (&urb->use_count); | 1146 | && !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) |
1026 | if (urb->reject) | 1147 | dma_unmap_single(hcd->self.controller, urb->setup_dma, |
1027 | wake_up (&usb_kill_urb_queue); | 1148 | sizeof(struct usb_ctrlrequest), |
1028 | usbmon_urb_submit_error(&hcd->self, urb, status); | 1149 | DMA_TO_DEVICE); |
1029 | usb_put_urb (urb); | 1150 | if (urb->transfer_buffer_length != 0 |
1151 | && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) | ||
1152 | dma_unmap_single(hcd->self.controller, | ||
1153 | urb->transfer_dma, | ||
1154 | urb->transfer_buffer_length, | ||
1155 | usb_urb_dir_in(urb) | ||
1156 | ? DMA_FROM_DEVICE | ||
1157 | : DMA_TO_DEVICE); | ||
1030 | } | 1158 | } |
1031 | return status; | ||
1032 | } | 1159 | } |
1033 | 1160 | ||
1034 | /*-------------------------------------------------------------------------*/ | 1161 | /*-------------------------------------------------------------------------*/ |
1035 | 1162 | ||
1036 | /* called in any context */ | 1163 | /* may be called in any context with a valid urb->dev usecount |
1037 | int usb_hcd_get_frame_number (struct usb_device *udev) | 1164 | * caller surrenders "ownership" of urb |
1165 | * expects usb_submit_urb() to have sanity checked and conditioned all | ||
1166 | * inputs in the urb | ||
1167 | */ | ||
1168 | int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags) | ||
1038 | { | 1169 | { |
1039 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | 1170 | int status; |
1171 | struct usb_hcd *hcd = bus_to_hcd(urb->dev->bus); | ||
1040 | 1172 | ||
1041 | if (!HC_IS_RUNNING (hcd->state)) | 1173 | /* increment urb's reference count as part of giving it to the HCD |
1042 | return -ESHUTDOWN; | 1174 | * (which will control it). HCD guarantees that it either returns |
1043 | return hcd->driver->get_frame_number (hcd); | 1175 | * an error or calls giveback(), but not both. |
1176 | */ | ||
1177 | usb_get_urb(urb); | ||
1178 | atomic_inc(&urb->use_count); | ||
1179 | atomic_inc(&urb->dev->urbnum); | ||
1180 | usbmon_urb_submit(&hcd->self, urb); | ||
1181 | |||
1182 | /* NOTE requirements on root-hub callers (usbfs and the hub | ||
1183 | * driver, for now): URBs' urb->transfer_buffer must be | ||
1184 | * valid and usb_buffer_{sync,unmap}() not be needed, since | ||
1185 | * they could clobber root hub response data. Also, control | ||
1186 | * URBs must be submitted in process context with interrupts | ||
1187 | * enabled. | ||
1188 | */ | ||
1189 | map_urb_for_dma(hcd, urb); | ||
1190 | if (is_root_hub(urb->dev)) | ||
1191 | status = rh_urb_enqueue(hcd, urb); | ||
1192 | else | ||
1193 | status = hcd->driver->urb_enqueue(hcd, urb, mem_flags); | ||
1194 | |||
1195 | if (unlikely(status)) { | ||
1196 | usbmon_urb_submit_error(&hcd->self, urb, status); | ||
1197 | unmap_urb_for_dma(hcd, urb); | ||
1198 | urb->hcpriv = NULL; | ||
1199 | INIT_LIST_HEAD(&urb->urb_list); | ||
1200 | atomic_dec(&urb->use_count); | ||
1201 | atomic_dec(&urb->dev->urbnum); | ||
1202 | if (urb->reject) | ||
1203 | wake_up(&usb_kill_urb_queue); | ||
1204 | usb_put_urb(urb); | ||
1205 | } | ||
1206 | return status; | ||
1044 | } | 1207 | } |
1045 | 1208 | ||
1046 | /*-------------------------------------------------------------------------*/ | 1209 | /*-------------------------------------------------------------------------*/ |
@@ -1050,24 +1213,19 @@ int usb_hcd_get_frame_number (struct usb_device *udev) | |||
1050 | * soon as practical. we've already set up the urb's return status, | 1213 | * soon as practical. we've already set up the urb's return status, |
1051 | * but we can't know if the callback completed already. | 1214 | * but we can't know if the callback completed already. |
1052 | */ | 1215 | */ |
1053 | static int | 1216 | static int unlink1(struct usb_hcd *hcd, struct urb *urb, int status) |
1054 | unlink1 (struct usb_hcd *hcd, struct urb *urb) | ||
1055 | { | 1217 | { |
1056 | int value; | 1218 | int value; |
1057 | 1219 | ||
1058 | if (urb->dev == hcd->self.root_hub) | 1220 | if (is_root_hub(urb->dev)) |
1059 | value = usb_rh_urb_dequeue (hcd, urb); | 1221 | value = usb_rh_urb_dequeue(hcd, urb, status); |
1060 | else { | 1222 | else { |
1061 | 1223 | ||
1062 | /* The only reason an HCD might fail this call is if | 1224 | /* The only reason an HCD might fail this call is if |
1063 | * it has not yet fully queued the urb to begin with. | 1225 | * it has not yet fully queued the urb to begin with. |
1064 | * Such failures should be harmless. */ | 1226 | * Such failures should be harmless. */ |
1065 | value = hcd->driver->urb_dequeue (hcd, urb); | 1227 | value = hcd->driver->urb_dequeue(hcd, urb, status); |
1066 | } | 1228 | } |
1067 | |||
1068 | if (value != 0) | ||
1069 | dev_dbg (hcd->self.controller, "dequeue %p --> %d\n", | ||
1070 | urb, value); | ||
1071 | return value; | 1229 | return value; |
1072 | } | 1230 | } |
1073 | 1231 | ||
@@ -1079,168 +1237,122 @@ unlink1 (struct usb_hcd *hcd, struct urb *urb) | |||
1079 | */ | 1237 | */ |
1080 | int usb_hcd_unlink_urb (struct urb *urb, int status) | 1238 | int usb_hcd_unlink_urb (struct urb *urb, int status) |
1081 | { | 1239 | { |
1082 | struct usb_host_endpoint *ep; | 1240 | struct usb_hcd *hcd; |
1083 | struct usb_hcd *hcd = NULL; | 1241 | int retval; |
1084 | struct device *sys = NULL; | ||
1085 | unsigned long flags; | ||
1086 | struct list_head *tmp; | ||
1087 | int retval; | ||
1088 | |||
1089 | if (!urb) | ||
1090 | return -EINVAL; | ||
1091 | if (!urb->dev || !urb->dev->bus) | ||
1092 | return -ENODEV; | ||
1093 | ep = (usb_pipein(urb->pipe) ? urb->dev->ep_in : urb->dev->ep_out) | ||
1094 | [usb_pipeendpoint(urb->pipe)]; | ||
1095 | if (!ep) | ||
1096 | return -ENODEV; | ||
1097 | |||
1098 | /* | ||
1099 | * we contend for urb->status with the hcd core, | ||
1100 | * which changes it while returning the urb. | ||
1101 | * | ||
1102 | * Caller guaranteed that the urb pointer hasn't been freed, and | ||
1103 | * that it was submitted. But as a rule it can't know whether or | ||
1104 | * not it's already been unlinked ... so we respect the reversed | ||
1105 | * lock sequence needed for the usb_hcd_giveback_urb() code paths | ||
1106 | * (urb lock, then hcd_data_lock) in case some other CPU is now | ||
1107 | * unlinking it. | ||
1108 | */ | ||
1109 | spin_lock_irqsave (&urb->lock, flags); | ||
1110 | spin_lock (&hcd_data_lock); | ||
1111 | 1242 | ||
1112 | sys = &urb->dev->dev; | ||
1113 | hcd = bus_to_hcd(urb->dev->bus); | 1243 | hcd = bus_to_hcd(urb->dev->bus); |
1114 | if (hcd == NULL) { | 1244 | retval = unlink1(hcd, urb, status); |
1115 | retval = -ENODEV; | ||
1116 | goto done; | ||
1117 | } | ||
1118 | |||
1119 | /* insist the urb is still queued */ | ||
1120 | list_for_each(tmp, &ep->urb_list) { | ||
1121 | if (tmp == &urb->urb_list) | ||
1122 | break; | ||
1123 | } | ||
1124 | if (tmp != &urb->urb_list) { | ||
1125 | retval = -EIDRM; | ||
1126 | goto done; | ||
1127 | } | ||
1128 | |||
1129 | /* Any status except -EINPROGRESS means something already started to | ||
1130 | * unlink this URB from the hardware. So there's no more work to do. | ||
1131 | */ | ||
1132 | if (urb->status != -EINPROGRESS) { | ||
1133 | retval = -EBUSY; | ||
1134 | goto done; | ||
1135 | } | ||
1136 | |||
1137 | /* IRQ setup can easily be broken so that USB controllers | ||
1138 | * never get completion IRQs ... maybe even the ones we need to | ||
1139 | * finish unlinking the initial failed usb_set_address() | ||
1140 | * or device descriptor fetch. | ||
1141 | */ | ||
1142 | if (!test_bit(HCD_FLAG_SAW_IRQ, &hcd->flags) | ||
1143 | && hcd->self.root_hub != urb->dev) { | ||
1144 | dev_warn (hcd->self.controller, "Unlink after no-IRQ? " | ||
1145 | "Controller is probably using the wrong IRQ." | ||
1146 | "\n"); | ||
1147 | set_bit(HCD_FLAG_SAW_IRQ, &hcd->flags); | ||
1148 | } | ||
1149 | |||
1150 | urb->status = status; | ||
1151 | 1245 | ||
1152 | spin_unlock (&hcd_data_lock); | ||
1153 | spin_unlock_irqrestore (&urb->lock, flags); | ||
1154 | |||
1155 | retval = unlink1 (hcd, urb); | ||
1156 | if (retval == 0) | 1246 | if (retval == 0) |
1157 | retval = -EINPROGRESS; | 1247 | retval = -EINPROGRESS; |
1158 | return retval; | 1248 | else if (retval != -EIDRM && retval != -EBUSY) |
1159 | 1249 | dev_dbg(&urb->dev->dev, "hcd_unlink_urb %p fail %d\n", | |
1160 | done: | 1250 | urb, retval); |
1161 | spin_unlock (&hcd_data_lock); | ||
1162 | spin_unlock_irqrestore (&urb->lock, flags); | ||
1163 | if (retval != -EIDRM && sys && sys->driver) | ||
1164 | dev_dbg (sys, "hcd_unlink_urb %p fail %d\n", urb, retval); | ||
1165 | return retval; | 1251 | return retval; |
1166 | } | 1252 | } |
1167 | 1253 | ||
1168 | /*-------------------------------------------------------------------------*/ | 1254 | /*-------------------------------------------------------------------------*/ |
1169 | 1255 | ||
1170 | /* disables the endpoint: cancels any pending urbs, then synchronizes with | 1256 | /** |
1171 | * the hcd to make sure all endpoint state is gone from hardware, and then | 1257 | * usb_hcd_giveback_urb - return URB from HCD to device driver |
1172 | * waits until the endpoint's queue is completely drained. use for | 1258 | * @hcd: host controller returning the URB |
1173 | * set_configuration, set_interface, driver removal, physical disconnect. | 1259 | * @urb: urb being returned to the USB device driver. |
1260 | * @status: completion status code for the URB. | ||
1261 | * Context: in_interrupt() | ||
1174 | * | 1262 | * |
1175 | * example: a qh stored in ep->hcpriv, holding state related to endpoint | 1263 | * This hands the URB from HCD to its USB device driver, using its |
1176 | * type, maxpacket size, toggle, halt status, and scheduling. | 1264 | * completion function. The HCD has freed all per-urb resources |
1265 | * (and is done using urb->hcpriv). It also released all HCD locks; | ||
1266 | * the device driver won't cause problems if it frees, modifies, | ||
1267 | * or resubmits this URB. | ||
1268 | * | ||
1269 | * If @urb was unlinked, the value of @status will be overridden by | ||
1270 | * @urb->unlinked. Erroneous short transfers are detected in case | ||
1271 | * the HCD hasn't checked for them. | ||
1272 | */ | ||
1273 | void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, int status) | ||
1274 | { | ||
1275 | urb->hcpriv = NULL; | ||
1276 | if (unlikely(urb->unlinked)) | ||
1277 | status = urb->unlinked; | ||
1278 | else if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) && | ||
1279 | urb->actual_length < urb->transfer_buffer_length && | ||
1280 | !status)) | ||
1281 | status = -EREMOTEIO; | ||
1282 | |||
1283 | unmap_urb_for_dma(hcd, urb); | ||
1284 | usbmon_urb_complete(&hcd->self, urb, status); | ||
1285 | usb_unanchor_urb(urb); | ||
1286 | |||
1287 | /* pass ownership to the completion handler */ | ||
1288 | urb->status = status; | ||
1289 | urb->complete (urb); | ||
1290 | atomic_dec (&urb->use_count); | ||
1291 | if (unlikely (urb->reject)) | ||
1292 | wake_up (&usb_kill_urb_queue); | ||
1293 | usb_put_urb (urb); | ||
1294 | } | ||
1295 | EXPORT_SYMBOL (usb_hcd_giveback_urb); | ||
1296 | |||
1297 | /*-------------------------------------------------------------------------*/ | ||
1298 | |||
1299 | /* Cancel all URBs pending on this endpoint and wait for the endpoint's | ||
1300 | * queue to drain completely. The caller must first insure that no more | ||
1301 | * URBs can be submitted for this endpoint. | ||
1177 | */ | 1302 | */ |
1178 | void usb_hcd_endpoint_disable (struct usb_device *udev, | 1303 | void usb_hcd_flush_endpoint(struct usb_device *udev, |
1179 | struct usb_host_endpoint *ep) | 1304 | struct usb_host_endpoint *ep) |
1180 | { | 1305 | { |
1181 | struct usb_hcd *hcd; | 1306 | struct usb_hcd *hcd; |
1182 | struct urb *urb; | 1307 | struct urb *urb; |
1183 | 1308 | ||
1309 | if (!ep) | ||
1310 | return; | ||
1311 | might_sleep(); | ||
1184 | hcd = bus_to_hcd(udev->bus); | 1312 | hcd = bus_to_hcd(udev->bus); |
1185 | local_irq_disable (); | ||
1186 | 1313 | ||
1187 | /* ep is already gone from udev->ep_{in,out}[]; no more submits */ | 1314 | /* No more submits can occur */ |
1188 | rescan: | 1315 | rescan: |
1189 | spin_lock (&hcd_data_lock); | 1316 | spin_lock_irq(&hcd_urb_list_lock); |
1190 | list_for_each_entry (urb, &ep->urb_list, urb_list) { | 1317 | list_for_each_entry (urb, &ep->urb_list, urb_list) { |
1191 | int tmp; | 1318 | int is_in; |
1192 | 1319 | ||
1193 | /* the urb may already have been unlinked */ | 1320 | if (urb->unlinked) |
1194 | if (urb->status != -EINPROGRESS) | ||
1195 | continue; | 1321 | continue; |
1196 | usb_get_urb (urb); | 1322 | usb_get_urb (urb); |
1197 | spin_unlock (&hcd_data_lock); | 1323 | is_in = usb_urb_dir_in(urb); |
1198 | 1324 | spin_unlock(&hcd_urb_list_lock); | |
1199 | spin_lock (&urb->lock); | 1325 | |
1200 | tmp = urb->status; | 1326 | /* kick hcd */ |
1201 | if (tmp == -EINPROGRESS) | 1327 | unlink1(hcd, urb, -ESHUTDOWN); |
1202 | urb->status = -ESHUTDOWN; | 1328 | dev_dbg (hcd->self.controller, |
1203 | spin_unlock (&urb->lock); | 1329 | "shutdown urb %p ep%d%s%s\n", |
1204 | 1330 | urb, usb_endpoint_num(&ep->desc), | |
1205 | /* kick hcd unless it's already returning this */ | 1331 | is_in ? "in" : "out", |
1206 | if (tmp == -EINPROGRESS) { | 1332 | ({ char *s; |
1207 | tmp = urb->pipe; | 1333 | |
1208 | unlink1 (hcd, urb); | 1334 | switch (usb_endpoint_type(&ep->desc)) { |
1209 | dev_dbg (hcd->self.controller, | 1335 | case USB_ENDPOINT_XFER_CONTROL: |
1210 | "shutdown urb %p pipe %08x ep%d%s%s\n", | 1336 | s = ""; break; |
1211 | urb, tmp, usb_pipeendpoint (tmp), | 1337 | case USB_ENDPOINT_XFER_BULK: |
1212 | (tmp & USB_DIR_IN) ? "in" : "out", | 1338 | s = "-bulk"; break; |
1213 | ({ char *s; \ | 1339 | case USB_ENDPOINT_XFER_INT: |
1214 | switch (usb_pipetype (tmp)) { \ | 1340 | s = "-intr"; break; |
1215 | case PIPE_CONTROL: s = ""; break; \ | 1341 | default: |
1216 | case PIPE_BULK: s = "-bulk"; break; \ | 1342 | s = "-iso"; break; |
1217 | case PIPE_INTERRUPT: s = "-intr"; break; \ | 1343 | }; |
1218 | default: s = "-iso"; break; \ | 1344 | s; |
1219 | }; s;})); | 1345 | })); |
1220 | } | ||
1221 | usb_put_urb (urb); | 1346 | usb_put_urb (urb); |
1222 | 1347 | ||
1223 | /* list contents may have changed */ | 1348 | /* list contents may have changed */ |
1224 | goto rescan; | 1349 | goto rescan; |
1225 | } | 1350 | } |
1226 | spin_unlock (&hcd_data_lock); | 1351 | spin_unlock_irq(&hcd_urb_list_lock); |
1227 | local_irq_enable (); | ||
1228 | |||
1229 | /* synchronize with the hardware, so old configuration state | ||
1230 | * clears out immediately (and will be freed). | ||
1231 | */ | ||
1232 | might_sleep (); | ||
1233 | if (hcd->driver->endpoint_disable) | ||
1234 | hcd->driver->endpoint_disable (hcd, ep); | ||
1235 | 1352 | ||
1236 | /* Wait until the endpoint queue is completely empty. Most HCDs | 1353 | /* Wait until the endpoint queue is completely empty */ |
1237 | * will have done this already in their endpoint_disable method, | ||
1238 | * but some might not. And there could be root-hub control URBs | ||
1239 | * still pending since they aren't affected by the HCDs' | ||
1240 | * endpoint_disable methods. | ||
1241 | */ | ||
1242 | while (!list_empty (&ep->urb_list)) { | 1354 | while (!list_empty (&ep->urb_list)) { |
1243 | spin_lock_irq (&hcd_data_lock); | 1355 | spin_lock_irq(&hcd_urb_list_lock); |
1244 | 1356 | ||
1245 | /* The list may have changed while we acquired the spinlock */ | 1357 | /* The list may have changed while we acquired the spinlock */ |
1246 | urb = NULL; | 1358 | urb = NULL; |
@@ -1249,7 +1361,7 @@ rescan: | |||
1249 | urb_list); | 1361 | urb_list); |
1250 | usb_get_urb (urb); | 1362 | usb_get_urb (urb); |
1251 | } | 1363 | } |
1252 | spin_unlock_irq (&hcd_data_lock); | 1364 | spin_unlock_irq(&hcd_urb_list_lock); |
1253 | 1365 | ||
1254 | if (urb) { | 1366 | if (urb) { |
1255 | usb_kill_urb (urb); | 1367 | usb_kill_urb (urb); |
@@ -1258,6 +1370,37 @@ rescan: | |||
1258 | } | 1370 | } |
1259 | } | 1371 | } |
1260 | 1372 | ||
1373 | /* Disables the endpoint: synchronizes with the hcd to make sure all | ||
1374 | * endpoint state is gone from hardware. usb_hcd_flush_endpoint() must | ||
1375 | * have been called previously. Use for set_configuration, set_interface, | ||
1376 | * driver removal, physical disconnect. | ||
1377 | * | ||
1378 | * example: a qh stored in ep->hcpriv, holding state related to endpoint | ||
1379 | * type, maxpacket size, toggle, halt status, and scheduling. | ||
1380 | */ | ||
1381 | void usb_hcd_disable_endpoint(struct usb_device *udev, | ||
1382 | struct usb_host_endpoint *ep) | ||
1383 | { | ||
1384 | struct usb_hcd *hcd; | ||
1385 | |||
1386 | might_sleep(); | ||
1387 | hcd = bus_to_hcd(udev->bus); | ||
1388 | if (hcd->driver->endpoint_disable) | ||
1389 | hcd->driver->endpoint_disable(hcd, ep); | ||
1390 | } | ||
1391 | |||
1392 | /*-------------------------------------------------------------------------*/ | ||
1393 | |||
1394 | /* called in any context */ | ||
1395 | int usb_hcd_get_frame_number (struct usb_device *udev) | ||
1396 | { | ||
1397 | struct usb_hcd *hcd = bus_to_hcd(udev->bus); | ||
1398 | |||
1399 | if (!HC_IS_RUNNING (hcd->state)) | ||
1400 | return -ESHUTDOWN; | ||
1401 | return hcd->driver->get_frame_number (hcd); | ||
1402 | } | ||
1403 | |||
1261 | /*-------------------------------------------------------------------------*/ | 1404 | /*-------------------------------------------------------------------------*/ |
1262 | 1405 | ||
1263 | #ifdef CONFIG_PM | 1406 | #ifdef CONFIG_PM |
@@ -1395,35 +1538,6 @@ EXPORT_SYMBOL (usb_bus_start_enum); | |||
1395 | /*-------------------------------------------------------------------------*/ | 1538 | /*-------------------------------------------------------------------------*/ |
1396 | 1539 | ||
1397 | /** | 1540 | /** |
1398 | * usb_hcd_giveback_urb - return URB from HCD to device driver | ||
1399 | * @hcd: host controller returning the URB | ||
1400 | * @urb: urb being returned to the USB device driver. | ||
1401 | * Context: in_interrupt() | ||
1402 | * | ||
1403 | * This hands the URB from HCD to its USB device driver, using its | ||
1404 | * completion function. The HCD has freed all per-urb resources | ||
1405 | * (and is done using urb->hcpriv). It also released all HCD locks; | ||
1406 | * the device driver won't cause problems if it frees, modifies, | ||
1407 | * or resubmits this URB. | ||
1408 | */ | ||
1409 | void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb) | ||
1410 | { | ||
1411 | urb_unlink(hcd, urb); | ||
1412 | usbmon_urb_complete (&hcd->self, urb); | ||
1413 | usb_unanchor_urb(urb); | ||
1414 | |||
1415 | /* pass ownership to the completion handler */ | ||
1416 | urb->complete (urb); | ||
1417 | atomic_dec (&urb->use_count); | ||
1418 | if (unlikely (urb->reject)) | ||
1419 | wake_up (&usb_kill_urb_queue); | ||
1420 | usb_put_urb (urb); | ||
1421 | } | ||
1422 | EXPORT_SYMBOL (usb_hcd_giveback_urb); | ||
1423 | |||
1424 | /*-------------------------------------------------------------------------*/ | ||
1425 | |||
1426 | /** | ||
1427 | * usb_hcd_irq - hook IRQs to HCD framework (bus glue) | 1541 | * usb_hcd_irq - hook IRQs to HCD framework (bus glue) |
1428 | * @irq: the IRQ being raised | 1542 | * @irq: the IRQ being raised |
1429 | * @__hcd: pointer to the HCD whose IRQ is being signaled | 1543 | * @__hcd: pointer to the HCD whose IRQ is being signaled |
@@ -1522,7 +1636,6 @@ struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, | |||
1522 | hcd->driver = driver; | 1636 | hcd->driver = driver; |
1523 | hcd->product_desc = (driver->product_desc) ? driver->product_desc : | 1637 | hcd->product_desc = (driver->product_desc) ? driver->product_desc : |
1524 | "USB Host Controller"; | 1638 | "USB Host Controller"; |
1525 | |||
1526 | return hcd; | 1639 | return hcd; |
1527 | } | 1640 | } |
1528 | EXPORT_SYMBOL (usb_create_hcd); | 1641 | EXPORT_SYMBOL (usb_create_hcd); |
@@ -1567,6 +1680,7 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
1567 | 1680 | ||
1568 | dev_info(hcd->self.controller, "%s\n", hcd->product_desc); | 1681 | dev_info(hcd->self.controller, "%s\n", hcd->product_desc); |
1569 | 1682 | ||
1683 | hcd->authorized_default = hcd->wireless? 0 : 1; | ||
1570 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | 1684 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
1571 | 1685 | ||
1572 | /* HC is in reset state, but accessible. Now do the one-time init, | 1686 | /* HC is in reset state, but accessible. Now do the one-time init, |
@@ -1643,10 +1757,20 @@ int usb_add_hcd(struct usb_hcd *hcd, | |||
1643 | if ((retval = register_root_hub(hcd)) != 0) | 1757 | if ((retval = register_root_hub(hcd)) != 0) |
1644 | goto err_register_root_hub; | 1758 | goto err_register_root_hub; |
1645 | 1759 | ||
1760 | retval = sysfs_create_group(&rhdev->dev.kobj, &usb_bus_attr_group); | ||
1761 | if (retval < 0) { | ||
1762 | printk(KERN_ERR "Cannot register USB bus sysfs attributes: %d\n", | ||
1763 | retval); | ||
1764 | goto error_create_attr_group; | ||
1765 | } | ||
1646 | if (hcd->uses_new_polling && hcd->poll_rh) | 1766 | if (hcd->uses_new_polling && hcd->poll_rh) |
1647 | usb_hcd_poll_rh_status(hcd); | 1767 | usb_hcd_poll_rh_status(hcd); |
1648 | return retval; | 1768 | return retval; |
1649 | 1769 | ||
1770 | error_create_attr_group: | ||
1771 | mutex_lock(&usb_bus_list_lock); | ||
1772 | usb_disconnect(&hcd->self.root_hub); | ||
1773 | mutex_unlock(&usb_bus_list_lock); | ||
1650 | err_register_root_hub: | 1774 | err_register_root_hub: |
1651 | hcd->driver->stop(hcd); | 1775 | hcd->driver->stop(hcd); |
1652 | err_hcd_driver_start: | 1776 | err_hcd_driver_start: |
@@ -1688,6 +1812,7 @@ void usb_remove_hcd(struct usb_hcd *hcd) | |||
1688 | cancel_work_sync(&hcd->wakeup_work); | 1812 | cancel_work_sync(&hcd->wakeup_work); |
1689 | #endif | 1813 | #endif |
1690 | 1814 | ||
1815 | sysfs_remove_group(&hcd->self.root_hub->dev.kobj, &usb_bus_attr_group); | ||
1691 | mutex_lock(&usb_bus_list_lock); | 1816 | mutex_lock(&usb_bus_list_lock); |
1692 | usb_disconnect(&hcd->self.root_hub); | 1817 | usb_disconnect(&hcd->self.root_hub); |
1693 | mutex_unlock(&usb_bus_list_lock); | 1818 | mutex_unlock(&usb_bus_list_lock); |
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index b5ebb73c233..98e24194a4a 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h | |||
@@ -19,6 +19,8 @@ | |||
19 | 19 | ||
20 | #ifdef __KERNEL__ | 20 | #ifdef __KERNEL__ |
21 | 21 | ||
22 | #include <linux/rwsem.h> | ||
23 | |||
22 | /* This file contains declarations of usbcore internals that are mostly | 24 | /* This file contains declarations of usbcore internals that are mostly |
23 | * used or exposed by Host Controller Drivers. | 25 | * used or exposed by Host Controller Drivers. |
24 | */ | 26 | */ |
@@ -51,6 +53,12 @@ | |||
51 | * | 53 | * |
52 | * Since "struct usb_bus" is so thin, you can't share much code in it. | 54 | * Since "struct usb_bus" is so thin, you can't share much code in it. |
53 | * This framework is a layer over that, and should be more sharable. | 55 | * This framework is a layer over that, and should be more sharable. |
56 | * | ||
57 | * @authorized_default: Specifies if new devices are authorized to | ||
58 | * connect by default or they require explicit | ||
59 | * user space authorization; this bit is settable | ||
60 | * through /sys/class/usb_host/X/authorized_default. | ||
61 | * For the rest is RO, so we don't lock to r/w it. | ||
54 | */ | 62 | */ |
55 | 63 | ||
56 | /*-------------------------------------------------------------------------*/ | 64 | /*-------------------------------------------------------------------------*/ |
@@ -90,6 +98,7 @@ struct usb_hcd { | |||
90 | unsigned poll_rh:1; /* poll for rh status? */ | 98 | unsigned poll_rh:1; /* poll for rh status? */ |
91 | unsigned poll_pending:1; /* status has changed? */ | 99 | unsigned poll_pending:1; /* status has changed? */ |
92 | unsigned wireless:1; /* Wireless USB HCD */ | 100 | unsigned wireless:1; /* Wireless USB HCD */ |
101 | unsigned authorized_default:1; | ||
93 | 102 | ||
94 | int irq; /* irq allocated */ | 103 | int irq; /* irq allocated */ |
95 | void __iomem *regs; /* device memory/io */ | 104 | void __iomem *regs; /* device memory/io */ |
@@ -182,11 +191,10 @@ struct hc_driver { | |||
182 | int (*get_frame_number) (struct usb_hcd *hcd); | 191 | int (*get_frame_number) (struct usb_hcd *hcd); |
183 | 192 | ||
184 | /* manage i/o requests, device state */ | 193 | /* manage i/o requests, device state */ |
185 | int (*urb_enqueue) (struct usb_hcd *hcd, | 194 | int (*urb_enqueue)(struct usb_hcd *hcd, |
186 | struct usb_host_endpoint *ep, | 195 | struct urb *urb, gfp_t mem_flags); |
187 | struct urb *urb, | 196 | int (*urb_dequeue)(struct usb_hcd *hcd, |
188 | gfp_t mem_flags); | 197 | struct urb *urb, int status); |
189 | int (*urb_dequeue) (struct usb_hcd *hcd, struct urb *urb); | ||
190 | 198 | ||
191 | /* hw synch, freeing endpoint resources that urb_dequeue can't */ | 199 | /* hw synch, freeing endpoint resources that urb_dequeue can't */ |
192 | void (*endpoint_disable)(struct usb_hcd *hcd, | 200 | void (*endpoint_disable)(struct usb_hcd *hcd, |
@@ -204,10 +212,18 @@ struct hc_driver { | |||
204 | /* Needed only if port-change IRQs are level-triggered */ | 212 | /* Needed only if port-change IRQs are level-triggered */ |
205 | }; | 213 | }; |
206 | 214 | ||
215 | extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); | ||
216 | extern int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb, | ||
217 | int status); | ||
218 | extern void usb_hcd_unlink_urb_from_ep(struct usb_hcd *hcd, struct urb *urb); | ||
219 | |||
207 | extern int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags); | 220 | extern int usb_hcd_submit_urb (struct urb *urb, gfp_t mem_flags); |
208 | extern int usb_hcd_unlink_urb (struct urb *urb, int status); | 221 | extern int usb_hcd_unlink_urb (struct urb *urb, int status); |
209 | extern void usb_hcd_giveback_urb (struct usb_hcd *hcd, struct urb *urb); | 222 | extern void usb_hcd_giveback_urb(struct usb_hcd *hcd, struct urb *urb, |
210 | extern void usb_hcd_endpoint_disable (struct usb_device *udev, | 223 | int status); |
224 | extern void usb_hcd_flush_endpoint(struct usb_device *udev, | ||
225 | struct usb_host_endpoint *ep); | ||
226 | extern void usb_hcd_disable_endpoint(struct usb_device *udev, | ||
211 | struct usb_host_endpoint *ep); | 227 | struct usb_host_endpoint *ep); |
212 | extern int usb_hcd_get_frame_number (struct usb_device *udev); | 228 | extern int usb_hcd_get_frame_number (struct usb_device *udev); |
213 | 229 | ||
@@ -402,7 +418,7 @@ static inline void usbfs_cleanup(void) { } | |||
402 | struct usb_mon_operations { | 418 | struct usb_mon_operations { |
403 | void (*urb_submit)(struct usb_bus *bus, struct urb *urb); | 419 | void (*urb_submit)(struct usb_bus *bus, struct urb *urb); |
404 | void (*urb_submit_error)(struct usb_bus *bus, struct urb *urb, int err); | 420 | void (*urb_submit_error)(struct usb_bus *bus, struct urb *urb, int err); |
405 | void (*urb_complete)(struct usb_bus *bus, struct urb *urb); | 421 | void (*urb_complete)(struct usb_bus *bus, struct urb *urb, int status); |
406 | /* void (*urb_unlink)(struct usb_bus *bus, struct urb *urb); */ | 422 | /* void (*urb_unlink)(struct usb_bus *bus, struct urb *urb); */ |
407 | }; | 423 | }; |
408 | 424 | ||
@@ -421,10 +437,11 @@ static inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb, | |||
421 | (*mon_ops->urb_submit_error)(bus, urb, error); | 437 | (*mon_ops->urb_submit_error)(bus, urb, error); |
422 | } | 438 | } |
423 | 439 | ||
424 | static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb) | 440 | static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb, |
441 | int status) | ||
425 | { | 442 | { |
426 | if (bus->monitored) | 443 | if (bus->monitored) |
427 | (*mon_ops->urb_complete)(bus, urb); | 444 | (*mon_ops->urb_complete)(bus, urb, status); |
428 | } | 445 | } |
429 | 446 | ||
430 | int usb_mon_register(struct usb_mon_operations *ops); | 447 | int usb_mon_register(struct usb_mon_operations *ops); |
@@ -435,7 +452,8 @@ void usb_mon_deregister(void); | |||
435 | static inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb) {} | 452 | static inline void usbmon_urb_submit(struct usb_bus *bus, struct urb *urb) {} |
436 | static inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb, | 453 | static inline void usbmon_urb_submit_error(struct usb_bus *bus, struct urb *urb, |
437 | int error) {} | 454 | int error) {} |
438 | static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb) {} | 455 | static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb, |
456 | int status) {} | ||
439 | 457 | ||
440 | #endif /* CONFIG_USB_MON */ | 458 | #endif /* CONFIG_USB_MON */ |
441 | 459 | ||
@@ -454,5 +472,9 @@ static inline void usbmon_urb_complete(struct usb_bus *bus, struct urb *urb) {} | |||
454 | : (in_interrupt () ? "in_interrupt" : "can sleep")) | 472 | : (in_interrupt () ? "in_interrupt" : "can sleep")) |
455 | 473 | ||
456 | 474 | ||
457 | #endif /* __KERNEL__ */ | 475 | /* This rwsem is for use only by the hub driver and ehci-hcd. |
476 | * Nobody else should touch it. | ||
477 | */ | ||
478 | extern struct rw_semaphore ehci_cf_port_reset_rwsem; | ||
458 | 479 | ||
480 | #endif /* __KERNEL__ */ | ||
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index fd74c50b180..d20cb545a6e 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c | |||
@@ -125,6 +125,12 @@ MODULE_PARM_DESC(use_both_schemes, | |||
125 | "try the other device initialization scheme if the " | 125 | "try the other device initialization scheme if the " |
126 | "first one fails"); | 126 | "first one fails"); |
127 | 127 | ||
128 | /* Mutual exclusion for EHCI CF initialization. This interferes with | ||
129 | * port reset on some companion controllers. | ||
130 | */ | ||
131 | DECLARE_RWSEM(ehci_cf_port_reset_rwsem); | ||
132 | EXPORT_SYMBOL_GPL(ehci_cf_port_reset_rwsem); | ||
133 | |||
128 | 134 | ||
129 | static inline char *portspeed(int portstatus) | 135 | static inline char *portspeed(int portstatus) |
130 | { | 136 | { |
@@ -347,11 +353,11 @@ void usb_kick_khubd(struct usb_device *hdev) | |||
347 | static void hub_irq(struct urb *urb) | 353 | static void hub_irq(struct urb *urb) |
348 | { | 354 | { |
349 | struct usb_hub *hub = urb->context; | 355 | struct usb_hub *hub = urb->context; |
350 | int status; | 356 | int status = urb->status; |
351 | int i; | 357 | int i; |
352 | unsigned long bits; | 358 | unsigned long bits; |
353 | 359 | ||
354 | switch (urb->status) { | 360 | switch (status) { |
355 | case -ENOENT: /* synchronous unlink */ | 361 | case -ENOENT: /* synchronous unlink */ |
356 | case -ECONNRESET: /* async unlink */ | 362 | case -ECONNRESET: /* async unlink */ |
357 | case -ESHUTDOWN: /* hardware going away */ | 363 | case -ESHUTDOWN: /* hardware going away */ |
@@ -359,10 +365,10 @@ static void hub_irq(struct urb *urb) | |||
359 | 365 | ||
360 | default: /* presumably an error */ | 366 | default: /* presumably an error */ |
361 | /* Cause a hub reset after 10 consecutive errors */ | 367 | /* Cause a hub reset after 10 consecutive errors */ |
362 | dev_dbg (hub->intfdev, "transfer --> %d\n", urb->status); | 368 | dev_dbg (hub->intfdev, "transfer --> %d\n", status); |
363 | if ((++hub->nerrors < 10) || hub->error) | 369 | if ((++hub->nerrors < 10) || hub->error) |
364 | goto resubmit; | 370 | goto resubmit; |
365 | hub->error = urb->status; | 371 | hub->error = status; |
366 | /* FALL THROUGH */ | 372 | /* FALL THROUGH */ |
367 | 373 | ||
368 | /* let khubd handle things */ | 374 | /* let khubd handle things */ |
@@ -1220,54 +1226,14 @@ static inline void show_string(struct usb_device *udev, char *id, char *string) | |||
1220 | #endif | 1226 | #endif |
1221 | 1227 | ||
1222 | /** | 1228 | /** |
1223 | * usb_new_device - perform initial device setup (usbcore-internal) | 1229 | * usb_configure_device_otg - FIXME (usbcore-internal) |
1224 | * @udev: newly addressed device (in ADDRESS state) | 1230 | * @udev: newly addressed device (in ADDRESS state) |
1225 | * | 1231 | * |
1226 | * This is called with devices which have been enumerated, but not yet | 1232 | * Do configuration for On-The-Go devices |
1227 | * configured. The device descriptor is available, but not descriptors | ||
1228 | * for any device configuration. The caller must have locked either | ||
1229 | * the parent hub (if udev is a normal device) or else the | ||
1230 | * usb_bus_list_lock (if udev is a root hub). The parent's pointer to | ||
1231 | * udev has already been installed, but udev is not yet visible through | ||
1232 | * sysfs or other filesystem code. | ||
1233 | * | ||
1234 | * It will return if the device is configured properly or not. Zero if | ||
1235 | * the interface was registered with the driver core; else a negative | ||
1236 | * errno value. | ||
1237 | * | ||
1238 | * This call is synchronous, and may not be used in an interrupt context. | ||
1239 | * | ||
1240 | * Only the hub driver or root-hub registrar should ever call this. | ||
1241 | */ | 1233 | */ |
1242 | int usb_new_device(struct usb_device *udev) | 1234 | static int usb_configure_device_otg(struct usb_device *udev) |
1243 | { | 1235 | { |
1244 | int err; | 1236 | int err = 0; |
1245 | |||
1246 | /* Determine quirks */ | ||
1247 | usb_detect_quirks(udev); | ||
1248 | |||
1249 | err = usb_get_configuration(udev); | ||
1250 | if (err < 0) { | ||
1251 | dev_err(&udev->dev, "can't read configurations, error %d\n", | ||
1252 | err); | ||
1253 | goto fail; | ||
1254 | } | ||
1255 | |||
1256 | /* read the standard strings and cache them if present */ | ||
1257 | udev->product = usb_cache_string(udev, udev->descriptor.iProduct); | ||
1258 | udev->manufacturer = usb_cache_string(udev, | ||
1259 | udev->descriptor.iManufacturer); | ||
1260 | udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber); | ||
1261 | |||
1262 | /* Tell the world! */ | ||
1263 | dev_dbg(&udev->dev, "new device strings: Mfr=%d, Product=%d, " | ||
1264 | "SerialNumber=%d\n", | ||
1265 | udev->descriptor.iManufacturer, | ||
1266 | udev->descriptor.iProduct, | ||
1267 | udev->descriptor.iSerialNumber); | ||
1268 | show_string(udev, "Product", udev->product); | ||
1269 | show_string(udev, "Manufacturer", udev->manufacturer); | ||
1270 | show_string(udev, "SerialNumber", udev->serial); | ||
1271 | 1237 | ||
1272 | #ifdef CONFIG_USB_OTG | 1238 | #ifdef CONFIG_USB_OTG |
1273 | /* | 1239 | /* |
@@ -1329,12 +1295,90 @@ int usb_new_device(struct usb_device *udev) | |||
1329 | err = -ENOTSUPP; | 1295 | err = -ENOTSUPP; |
1330 | goto fail; | 1296 | goto fail; |
1331 | } | 1297 | } |
1298 | fail: | ||
1332 | #endif | 1299 | #endif |
1300 | return err; | ||
1301 | } | ||
1302 | |||
1303 | |||
1304 | /** | ||
1305 | * usb_configure_device - Detect and probe device intfs/otg (usbcore-internal) | ||
1306 | * @udev: newly addressed device (in ADDRESS state) | ||
1307 | * | ||
1308 | * This is only called by usb_new_device() and usb_authorize_device() | ||
1309 | * and FIXME -- all comments that apply to them apply here wrt to | ||
1310 | * environment. | ||
1311 | * | ||
1312 | * If the device is WUSB and not authorized, we don't attempt to read | ||
1313 | * the string descriptors, as they will be errored out by the device | ||
1314 | * until it has been authorized. | ||
1315 | */ | ||
1316 | static int usb_configure_device(struct usb_device *udev) | ||
1317 | { | ||
1318 | int err; | ||
1319 | |||
1320 | if (udev->config == NULL) { | ||
1321 | err = usb_get_configuration(udev); | ||
1322 | if (err < 0) { | ||
1323 | dev_err(&udev->dev, "can't read configurations, error %d\n", | ||
1324 | err); | ||
1325 | goto fail; | ||
1326 | } | ||
1327 | } | ||
1328 | if (udev->wusb == 1 && udev->authorized == 0) { | ||
1329 | udev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL); | ||
1330 | udev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL); | ||
1331 | udev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL); | ||
1332 | } | ||
1333 | else { | ||
1334 | /* read the standard strings and cache them if present */ | ||
1335 | udev->product = usb_cache_string(udev, udev->descriptor.iProduct); | ||
1336 | udev->manufacturer = usb_cache_string(udev, | ||
1337 | udev->descriptor.iManufacturer); | ||
1338 | udev->serial = usb_cache_string(udev, udev->descriptor.iSerialNumber); | ||
1339 | } | ||
1340 | err = usb_configure_device_otg(udev); | ||
1341 | fail: | ||
1342 | return err; | ||
1343 | } | ||
1344 | |||
1333 | 1345 | ||
1346 | /** | ||
1347 | * usb_new_device - perform initial device setup (usbcore-internal) | ||
1348 | * @udev: newly addressed device (in ADDRESS state) | ||
1349 | * | ||
1350 | * This is called with devices which have been enumerated, but not yet | ||
1351 | * configured. The device descriptor is available, but not descriptors | ||
1352 | * for any device configuration. The caller must have locked either | ||
1353 | * the parent hub (if udev is a normal device) or else the | ||
1354 | * usb_bus_list_lock (if udev is a root hub). The parent's pointer to | ||
1355 | * udev has already been installed, but udev is not yet visible through | ||
1356 | * sysfs or other filesystem code. | ||
1357 | * | ||
1358 | * It will return if the device is configured properly or not. Zero if | ||
1359 | * the interface was registered with the driver core; else a negative | ||
1360 | * errno value. | ||
1361 | * | ||
1362 | * This call is synchronous, and may not be used in an interrupt context. | ||
1363 | * | ||
1364 | * Only the hub driver or root-hub registrar should ever call this. | ||
1365 | */ | ||
1366 | int usb_new_device(struct usb_device *udev) | ||
1367 | { | ||
1368 | int err; | ||
1369 | |||
1370 | usb_detect_quirks(udev); /* Determine quirks */ | ||
1371 | err = usb_configure_device(udev); /* detect & probe dev/intfs */ | ||
1372 | if (err < 0) | ||
1373 | goto fail; | ||
1334 | /* export the usbdev device-node for libusb */ | 1374 | /* export the usbdev device-node for libusb */ |
1335 | udev->dev.devt = MKDEV(USB_DEVICE_MAJOR, | 1375 | udev->dev.devt = MKDEV(USB_DEVICE_MAJOR, |
1336 | (((udev->bus->busnum-1) * 128) + (udev->devnum-1))); | 1376 | (((udev->bus->busnum-1) * 128) + (udev->devnum-1))); |
1337 | 1377 | ||
1378 | /* Increment the parent's count of unsuspended children */ | ||
1379 | if (udev->parent) | ||
1380 | usb_autoresume_device(udev->parent); | ||
1381 | |||
1338 | /* Register the device. The device driver is responsible | 1382 | /* Register the device. The device driver is responsible |
1339 | * for adding the device files to sysfs and for configuring | 1383 | * for adding the device files to sysfs and for configuring |
1340 | * the device. | 1384 | * the device. |
@@ -1345,18 +1389,103 @@ int usb_new_device(struct usb_device *udev) | |||
1345 | goto fail; | 1389 | goto fail; |
1346 | } | 1390 | } |
1347 | 1391 | ||
1348 | /* Increment the parent's count of unsuspended children */ | 1392 | /* Tell the world! */ |
1349 | if (udev->parent) | 1393 | dev_dbg(&udev->dev, "new device strings: Mfr=%d, Product=%d, " |
1350 | usb_autoresume_device(udev->parent); | 1394 | "SerialNumber=%d\n", |
1351 | 1395 | udev->descriptor.iManufacturer, | |
1352 | exit: | 1396 | udev->descriptor.iProduct, |
1397 | udev->descriptor.iSerialNumber); | ||
1398 | show_string(udev, "Product", udev->product); | ||
1399 | show_string(udev, "Manufacturer", udev->manufacturer); | ||
1400 | show_string(udev, "SerialNumber", udev->serial); | ||
1353 | return err; | 1401 | return err; |
1354 | 1402 | ||
1355 | fail: | 1403 | fail: |
1356 | usb_set_device_state(udev, USB_STATE_NOTATTACHED); | 1404 | usb_set_device_state(udev, USB_STATE_NOTATTACHED); |
1357 | goto exit; | 1405 | return err; |
1406 | } | ||
1407 | |||
1408 | |||
1409 | /** | ||
1410 | * Similar to usb_disconnect() | ||
1411 | * | ||
1412 | * We share a lock (that we have) with device_del(), so we need to | ||
1413 | * defer its call. | ||
1414 | */ | ||
1415 | int usb_deauthorize_device(struct usb_device *usb_dev) | ||
1416 | { | ||
1417 | unsigned cnt; | ||
1418 | usb_lock_device(usb_dev); | ||
1419 | if (usb_dev->authorized == 0) | ||
1420 | goto out_unauthorized; | ||
1421 | usb_dev->authorized = 0; | ||
1422 | usb_set_configuration(usb_dev, -1); | ||
1423 | usb_dev->product = kstrdup("n/a (unauthorized)", GFP_KERNEL); | ||
1424 | usb_dev->manufacturer = kstrdup("n/a (unauthorized)", GFP_KERNEL); | ||
1425 | usb_dev->serial = kstrdup("n/a (unauthorized)", GFP_KERNEL); | ||
1426 | kfree(usb_dev->config); | ||
1427 | usb_dev->config = NULL; | ||
1428 | for (cnt = 0; cnt < usb_dev->descriptor.bNumConfigurations; cnt++) | ||
1429 | kfree(usb_dev->rawdescriptors[cnt]); | ||
1430 | usb_dev->descriptor.bNumConfigurations = 0; | ||
1431 | kfree(usb_dev->rawdescriptors); | ||
1432 | out_unauthorized: | ||
1433 | usb_unlock_device(usb_dev); | ||
1434 | return 0; | ||
1435 | } | ||
1436 | |||
1437 | |||
1438 | int usb_authorize_device(struct usb_device *usb_dev) | ||
1439 | { | ||
1440 | int result = 0, c; | ||
1441 | usb_lock_device(usb_dev); | ||
1442 | if (usb_dev->authorized == 1) | ||
1443 | goto out_authorized; | ||
1444 | kfree(usb_dev->product); | ||
1445 | usb_dev->product = NULL; | ||
1446 | kfree(usb_dev->manufacturer); | ||
1447 | usb_dev->manufacturer = NULL; | ||
1448 | kfree(usb_dev->serial); | ||
1449 | usb_dev->serial = NULL; | ||
1450 | result = usb_autoresume_device(usb_dev); | ||
1451 | if (result < 0) { | ||
1452 | dev_err(&usb_dev->dev, | ||
1453 | "can't autoresume for authorization: %d\n", result); | ||
1454 | goto error_autoresume; | ||
1455 | } | ||
1456 | result = usb_get_device_descriptor(usb_dev, sizeof(usb_dev->descriptor)); | ||
1457 | if (result < 0) { | ||
1458 | dev_err(&usb_dev->dev, "can't re-read device descriptor for " | ||
1459 | "authorization: %d\n", result); | ||
1460 | goto error_device_descriptor; | ||
1461 | } | ||
1462 | usb_dev->authorized = 1; | ||
1463 | result = usb_configure_device(usb_dev); | ||
1464 | if (result < 0) | ||
1465 | goto error_configure; | ||
1466 | /* Choose and set the configuration. This registers the interfaces | ||
1467 | * with the driver core and lets interface drivers bind to them. | ||
1468 | */ | ||
1469 | c = usb_choose_configuration(usb_dev); | ||
1470 | if (c >= 0) { | ||
1471 | result = usb_set_configuration(usb_dev, c); | ||
1472 | if (result) { | ||
1473 | dev_err(&usb_dev->dev, | ||
1474 | "can't set config #%d, error %d\n", c, result); | ||
1475 | /* This need not be fatal. The user can try to | ||
1476 | * set other configurations. */ | ||
1477 | } | ||
1478 | } | ||
1479 | dev_info(&usb_dev->dev, "authorized to connect\n"); | ||
1480 | error_configure: | ||
1481 | error_device_descriptor: | ||
1482 | error_autoresume: | ||
1483 | out_authorized: | ||
1484 | usb_unlock_device(usb_dev); // complements locktree | ||
1485 | return result; | ||
1358 | } | 1486 | } |
1359 | 1487 | ||
1488 | |||
1360 | static int hub_port_status(struct usb_hub *hub, int port1, | 1489 | static int hub_port_status(struct usb_hub *hub, int port1, |
1361 | u16 *status, u16 *change) | 1490 | u16 *status, u16 *change) |
1362 | { | 1491 | { |
@@ -1458,6 +1587,11 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
1458 | { | 1587 | { |
1459 | int i, status; | 1588 | int i, status; |
1460 | 1589 | ||
1590 | /* Block EHCI CF initialization during the port reset. | ||
1591 | * Some companion controllers don't like it when they mix. | ||
1592 | */ | ||
1593 | down_read(&ehci_cf_port_reset_rwsem); | ||
1594 | |||
1461 | /* Reset the port */ | 1595 | /* Reset the port */ |
1462 | for (i = 0; i < PORT_RESET_TRIES; i++) { | 1596 | for (i = 0; i < PORT_RESET_TRIES; i++) { |
1463 | status = set_port_feature(hub->hdev, | 1597 | status = set_port_feature(hub->hdev, |
@@ -1479,6 +1613,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
1479 | case 0: | 1613 | case 0: |
1480 | /* TRSTRCY = 10 ms; plus some extra */ | 1614 | /* TRSTRCY = 10 ms; plus some extra */ |
1481 | msleep(10 + 40); | 1615 | msleep(10 + 40); |
1616 | udev->devnum = 0; /* Device now at address 0 */ | ||
1482 | /* FALL THROUGH */ | 1617 | /* FALL THROUGH */ |
1483 | case -ENOTCONN: | 1618 | case -ENOTCONN: |
1484 | case -ENODEV: | 1619 | case -ENODEV: |
@@ -1488,7 +1623,7 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
1488 | usb_set_device_state(udev, status | 1623 | usb_set_device_state(udev, status |
1489 | ? USB_STATE_NOTATTACHED | 1624 | ? USB_STATE_NOTATTACHED |
1490 | : USB_STATE_DEFAULT); | 1625 | : USB_STATE_DEFAULT); |
1491 | return status; | 1626 | goto done; |
1492 | } | 1627 | } |
1493 | 1628 | ||
1494 | dev_dbg (hub->intfdev, | 1629 | dev_dbg (hub->intfdev, |
@@ -1501,6 +1636,8 @@ static int hub_port_reset(struct usb_hub *hub, int port1, | |||
1501 | "Cannot enable port %i. Maybe the USB cable is bad?\n", | 1636 | "Cannot enable port %i. Maybe the USB cable is bad?\n", |
1502 | port1); | 1637 | port1); |
1503 | 1638 | ||
1639 | done: | ||
1640 | up_read(&ehci_cf_port_reset_rwsem); | ||
1504 | return status; | 1641 | return status; |
1505 | } | 1642 | } |
1506 | 1643 | ||
@@ -1642,9 +1779,10 @@ static int finish_port_resume(struct usb_device *udev) | |||
1642 | * and device drivers will know about any resume quirks. | 1779 | * and device drivers will know about any resume quirks. |
1643 | */ | 1780 | */ |
1644 | if (status == 0) { | 1781 | if (status == 0) { |
1782 | devstatus = 0; | ||
1645 | status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); | 1783 | status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus); |
1646 | if (status >= 0) | 1784 | if (status >= 0) |
1647 | status = (status == 2 ? 0 : -ENODEV); | 1785 | status = (status > 0 ? 0 : -ENODEV); |
1648 | } | 1786 | } |
1649 | 1787 | ||
1650 | if (status) { | 1788 | if (status) { |
@@ -1830,14 +1968,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) | |||
1830 | struct usb_device *udev; | 1968 | struct usb_device *udev; |
1831 | 1969 | ||
1832 | udev = hdev->children [port1-1]; | 1970 | udev = hdev->children [port1-1]; |
1833 | if (udev && msg.event == PM_EVENT_SUSPEND && | 1971 | if (udev && udev->can_submit) { |
1834 | #ifdef CONFIG_USB_SUSPEND | ||
1835 | udev->state != USB_STATE_SUSPENDED | ||
1836 | #else | ||
1837 | udev->dev.power.power_state.event | ||
1838 | == PM_EVENT_ON | ||
1839 | #endif | ||
1840 | ) { | ||
1841 | if (!hdev->auto_pm) | 1972 | if (!hdev->auto_pm) |
1842 | dev_dbg(&intf->dev, "port %d nyet suspended\n", | 1973 | dev_dbg(&intf->dev, "port %d nyet suspended\n", |
1843 | port1); | 1974 | port1); |
@@ -1996,26 +2127,27 @@ static void ep0_reinit(struct usb_device *udev) | |||
1996 | { | 2127 | { |
1997 | usb_disable_endpoint(udev, 0 + USB_DIR_IN); | 2128 | usb_disable_endpoint(udev, 0 + USB_DIR_IN); |
1998 | usb_disable_endpoint(udev, 0 + USB_DIR_OUT); | 2129 | usb_disable_endpoint(udev, 0 + USB_DIR_OUT); |
1999 | udev->ep_in[0] = udev->ep_out[0] = &udev->ep0; | 2130 | usb_enable_endpoint(udev, &udev->ep0); |
2000 | } | 2131 | } |
2001 | 2132 | ||
2002 | #define usb_sndaddr0pipe() (PIPE_CONTROL << 30) | 2133 | #define usb_sndaddr0pipe() (PIPE_CONTROL << 30) |
2003 | #define usb_rcvaddr0pipe() ((PIPE_CONTROL << 30) | USB_DIR_IN) | 2134 | #define usb_rcvaddr0pipe() ((PIPE_CONTROL << 30) | USB_DIR_IN) |
2004 | 2135 | ||
2005 | static int hub_set_address(struct usb_device *udev) | 2136 | static int hub_set_address(struct usb_device *udev, int devnum) |
2006 | { | 2137 | { |
2007 | int retval; | 2138 | int retval; |
2008 | 2139 | ||
2009 | if (udev->devnum == 0) | 2140 | if (devnum <= 1) |
2010 | return -EINVAL; | 2141 | return -EINVAL; |
2011 | if (udev->state == USB_STATE_ADDRESS) | 2142 | if (udev->state == USB_STATE_ADDRESS) |
2012 | return 0; | 2143 | return 0; |
2013 | if (udev->state != USB_STATE_DEFAULT) | 2144 | if (udev->state != USB_STATE_DEFAULT) |
2014 | return -EINVAL; | 2145 | return -EINVAL; |
2015 | retval = usb_control_msg(udev, usb_sndaddr0pipe(), | 2146 | retval = usb_control_msg(udev, usb_sndaddr0pipe(), |
2016 | USB_REQ_SET_ADDRESS, 0, udev->devnum, 0, | 2147 | USB_REQ_SET_ADDRESS, 0, devnum, 0, |
2017 | NULL, 0, USB_CTRL_SET_TIMEOUT); | 2148 | NULL, 0, USB_CTRL_SET_TIMEOUT); |
2018 | if (retval == 0) { | 2149 | if (retval == 0) { |
2150 | udev->devnum = devnum; /* Device now using proper address */ | ||
2019 | usb_set_device_state(udev, USB_STATE_ADDRESS); | 2151 | usb_set_device_state(udev, USB_STATE_ADDRESS); |
2020 | ep0_reinit(udev); | 2152 | ep0_reinit(udev); |
2021 | } | 2153 | } |
@@ -2042,6 +2174,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2042 | unsigned delay = HUB_SHORT_RESET_TIME; | 2174 | unsigned delay = HUB_SHORT_RESET_TIME; |
2043 | enum usb_device_speed oldspeed = udev->speed; | 2175 | enum usb_device_speed oldspeed = udev->speed; |
2044 | char *speed, *type; | 2176 | char *speed, *type; |
2177 | int devnum = udev->devnum; | ||
2045 | 2178 | ||
2046 | /* root hub ports have a slightly longer reset period | 2179 | /* root hub ports have a slightly longer reset period |
2047 | * (from USB 2.0 spec, section 7.1.7.5) | 2180 | * (from USB 2.0 spec, section 7.1.7.5) |
@@ -2071,7 +2204,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2071 | goto fail; | 2204 | goto fail; |
2072 | } | 2205 | } |
2073 | oldspeed = udev->speed; | 2206 | oldspeed = udev->speed; |
2074 | 2207 | ||
2075 | /* USB 2.0 section 5.5.3 talks about ep0 maxpacket ... | 2208 | /* USB 2.0 section 5.5.3 talks about ep0 maxpacket ... |
2076 | * it's fixed size except for full speed devices. | 2209 | * it's fixed size except for full speed devices. |
2077 | * For Wireless USB devices, ep0 max packet is always 512 (tho | 2210 | * For Wireless USB devices, ep0 max packet is always 512 (tho |
@@ -2112,7 +2245,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2112 | dev_info (&udev->dev, | 2245 | dev_info (&udev->dev, |
2113 | "%s %s speed %sUSB device using %s and address %d\n", | 2246 | "%s %s speed %sUSB device using %s and address %d\n", |
2114 | (udev->config) ? "reset" : "new", speed, type, | 2247 | (udev->config) ? "reset" : "new", speed, type, |
2115 | udev->bus->controller->driver->name, udev->devnum); | 2248 | udev->bus->controller->driver->name, devnum); |
2116 | 2249 | ||
2117 | /* Set up TT records, if needed */ | 2250 | /* Set up TT records, if needed */ |
2118 | if (hdev->tt) { | 2251 | if (hdev->tt) { |
@@ -2199,7 +2332,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2199 | } | 2332 | } |
2200 | 2333 | ||
2201 | for (j = 0; j < SET_ADDRESS_TRIES; ++j) { | 2334 | for (j = 0; j < SET_ADDRESS_TRIES; ++j) { |
2202 | retval = hub_set_address(udev); | 2335 | retval = hub_set_address(udev, devnum); |
2203 | if (retval >= 0) | 2336 | if (retval >= 0) |
2204 | break; | 2337 | break; |
2205 | msleep(200); | 2338 | msleep(200); |
@@ -2207,7 +2340,7 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2207 | if (retval < 0) { | 2340 | if (retval < 0) { |
2208 | dev_err(&udev->dev, | 2341 | dev_err(&udev->dev, |
2209 | "device not accepting address %d, error %d\n", | 2342 | "device not accepting address %d, error %d\n", |
2210 | udev->devnum, retval); | 2343 | devnum, retval); |
2211 | goto fail; | 2344 | goto fail; |
2212 | } | 2345 | } |
2213 | 2346 | ||
@@ -2260,8 +2393,10 @@ hub_port_init (struct usb_hub *hub, struct usb_device *udev, int port1, | |||
2260 | retval = 0; | 2393 | retval = 0; |
2261 | 2394 | ||
2262 | fail: | 2395 | fail: |
2263 | if (retval) | 2396 | if (retval) { |
2264 | hub_port_disable(hub, port1, 0); | 2397 | hub_port_disable(hub, port1, 0); |
2398 | udev->devnum = devnum; /* for disconnect processing */ | ||
2399 | } | ||
2265 | mutex_unlock(&usb_address0_mutex); | 2400 | mutex_unlock(&usb_address0_mutex); |
2266 | return retval; | 2401 | return retval; |
2267 | } | 2402 | } |
@@ -2696,9 +2831,9 @@ static void hub_events(void) | |||
2696 | clear_hub_feature(hdev, C_HUB_LOCAL_POWER); | 2831 | clear_hub_feature(hdev, C_HUB_LOCAL_POWER); |
2697 | if (hubstatus & HUB_STATUS_LOCAL_POWER) | 2832 | if (hubstatus & HUB_STATUS_LOCAL_POWER) |
2698 | /* FIXME: Is this always true? */ | 2833 | /* FIXME: Is this always true? */ |
2699 | hub->limited_power = 0; | ||
2700 | else | ||
2701 | hub->limited_power = 1; | 2834 | hub->limited_power = 1; |
2835 | else | ||
2836 | hub->limited_power = 0; | ||
2702 | } | 2837 | } |
2703 | if (hubchange & HUB_CHANGE_OVERCURRENT) { | 2838 | if (hubchange & HUB_CHANGE_OVERCURRENT) { |
2704 | dev_dbg (hub_dev, "overcurrent change\n"); | 2839 | dev_dbg (hub_dev, "overcurrent change\n"); |
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index 530e854961c..c021af39037 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c | |||
@@ -18,9 +18,17 @@ | |||
18 | #include "hcd.h" /* for usbcore internals */ | 18 | #include "hcd.h" /* for usbcore internals */ |
19 | #include "usb.h" | 19 | #include "usb.h" |
20 | 20 | ||
21 | struct api_context { | ||
22 | struct completion done; | ||
23 | int status; | ||
24 | }; | ||
25 | |||
21 | static void usb_api_blocking_completion(struct urb *urb) | 26 | static void usb_api_blocking_completion(struct urb *urb) |
22 | { | 27 | { |
23 | complete((struct completion *)urb->context); | 28 | struct api_context *ctx = urb->context; |
29 | |||
30 | ctx->status = urb->status; | ||
31 | complete(&ctx->done); | ||
24 | } | 32 | } |
25 | 33 | ||
26 | 34 | ||
@@ -32,38 +40,37 @@ static void usb_api_blocking_completion(struct urb *urb) | |||
32 | */ | 40 | */ |
33 | static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) | 41 | static int usb_start_wait_urb(struct urb *urb, int timeout, int *actual_length) |
34 | { | 42 | { |
35 | struct completion done; | 43 | struct api_context ctx; |
36 | unsigned long expire; | 44 | unsigned long expire; |
37 | int status; | 45 | int retval; |
38 | 46 | ||
39 | init_completion(&done); | 47 | init_completion(&ctx.done); |
40 | urb->context = &done; | 48 | urb->context = &ctx; |
41 | urb->actual_length = 0; | 49 | urb->actual_length = 0; |
42 | status = usb_submit_urb(urb, GFP_NOIO); | 50 | retval = usb_submit_urb(urb, GFP_NOIO); |
43 | if (unlikely(status)) | 51 | if (unlikely(retval)) |
44 | goto out; | 52 | goto out; |
45 | 53 | ||
46 | expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT; | 54 | expire = timeout ? msecs_to_jiffies(timeout) : MAX_SCHEDULE_TIMEOUT; |
47 | if (!wait_for_completion_timeout(&done, expire)) { | 55 | if (!wait_for_completion_timeout(&ctx.done, expire)) { |
56 | usb_kill_urb(urb); | ||
57 | retval = (ctx.status == -ENOENT ? -ETIMEDOUT : ctx.status); | ||
48 | 58 | ||
49 | dev_dbg(&urb->dev->dev, | 59 | dev_dbg(&urb->dev->dev, |
50 | "%s timed out on ep%d%s len=%d/%d\n", | 60 | "%s timed out on ep%d%s len=%d/%d\n", |
51 | current->comm, | 61 | current->comm, |
52 | usb_pipeendpoint(urb->pipe), | 62 | usb_endpoint_num(&urb->ep->desc), |
53 | usb_pipein(urb->pipe) ? "in" : "out", | 63 | usb_urb_dir_in(urb) ? "in" : "out", |
54 | urb->actual_length, | 64 | urb->actual_length, |
55 | urb->transfer_buffer_length); | 65 | urb->transfer_buffer_length); |
56 | |||
57 | usb_kill_urb(urb); | ||
58 | status = urb->status == -ENOENT ? -ETIMEDOUT : urb->status; | ||
59 | } else | 66 | } else |
60 | status = urb->status; | 67 | retval = ctx.status; |
61 | out: | 68 | out: |
62 | if (actual_length) | 69 | if (actual_length) |
63 | *actual_length = urb->actual_length; | 70 | *actual_length = urb->actual_length; |
64 | 71 | ||
65 | usb_free_urb(urb); | 72 | usb_free_urb(urb); |
66 | return status; | 73 | return retval; |
67 | } | 74 | } |
68 | 75 | ||
69 | /*-------------------------------------------------------------------*/ | 76 | /*-------------------------------------------------------------------*/ |
@@ -243,13 +250,15 @@ static void sg_clean (struct usb_sg_request *io) | |||
243 | io->urbs = NULL; | 250 | io->urbs = NULL; |
244 | } | 251 | } |
245 | if (io->dev->dev.dma_mask != NULL) | 252 | if (io->dev->dev.dma_mask != NULL) |
246 | usb_buffer_unmap_sg (io->dev, io->pipe, io->sg, io->nents); | 253 | usb_buffer_unmap_sg (io->dev, usb_pipein(io->pipe), |
254 | io->sg, io->nents); | ||
247 | io->dev = NULL; | 255 | io->dev = NULL; |
248 | } | 256 | } |
249 | 257 | ||
250 | static void sg_complete (struct urb *urb) | 258 | static void sg_complete (struct urb *urb) |
251 | { | 259 | { |
252 | struct usb_sg_request *io = urb->context; | 260 | struct usb_sg_request *io = urb->context; |
261 | int status = urb->status; | ||
253 | 262 | ||
254 | spin_lock (&io->lock); | 263 | spin_lock (&io->lock); |
255 | 264 | ||
@@ -265,21 +274,21 @@ static void sg_complete (struct urb *urb) | |||
265 | */ | 274 | */ |
266 | if (io->status | 275 | if (io->status |
267 | && (io->status != -ECONNRESET | 276 | && (io->status != -ECONNRESET |
268 | || urb->status != -ECONNRESET) | 277 | || status != -ECONNRESET) |
269 | && urb->actual_length) { | 278 | && urb->actual_length) { |
270 | dev_err (io->dev->bus->controller, | 279 | dev_err (io->dev->bus->controller, |
271 | "dev %s ep%d%s scatterlist error %d/%d\n", | 280 | "dev %s ep%d%s scatterlist error %d/%d\n", |
272 | io->dev->devpath, | 281 | io->dev->devpath, |
273 | usb_pipeendpoint (urb->pipe), | 282 | usb_endpoint_num(&urb->ep->desc), |
274 | usb_pipein (urb->pipe) ? "in" : "out", | 283 | usb_urb_dir_in(urb) ? "in" : "out", |
275 | urb->status, io->status); | 284 | status, io->status); |
276 | // BUG (); | 285 | // BUG (); |
277 | } | 286 | } |
278 | 287 | ||
279 | if (io->status == 0 && urb->status && urb->status != -ECONNRESET) { | 288 | if (io->status == 0 && status && status != -ECONNRESET) { |
280 | int i, found, status; | 289 | int i, found, retval; |
281 | 290 | ||
282 | io->status = urb->status; | 291 | io->status = status; |
283 | 292 | ||
284 | /* the previous urbs, and this one, completed already. | 293 | /* the previous urbs, and this one, completed already. |
285 | * unlink pending urbs so they won't rx/tx bad data. | 294 | * unlink pending urbs so they won't rx/tx bad data. |
@@ -290,13 +299,13 @@ static void sg_complete (struct urb *urb) | |||
290 | if (!io->urbs [i] || !io->urbs [i]->dev) | 299 | if (!io->urbs [i] || !io->urbs [i]->dev) |
291 | continue; | 300 | continue; |
292 | if (found) { | 301 | if (found) { |
293 | status = usb_unlink_urb (io->urbs [i]); | 302 | retval = usb_unlink_urb (io->urbs [i]); |
294 | if (status != -EINPROGRESS | 303 | if (retval != -EINPROGRESS && |
295 | && status != -ENODEV | 304 | retval != -ENODEV && |
296 | && status != -EBUSY) | 305 | retval != -EBUSY) |
297 | dev_err (&io->dev->dev, | 306 | dev_err (&io->dev->dev, |
298 | "%s, unlink --> %d\n", | 307 | "%s, unlink --> %d\n", |
299 | __FUNCTION__, status); | 308 | __FUNCTION__, retval); |
300 | } else if (urb == io->urbs [i]) | 309 | } else if (urb == io->urbs [i]) |
301 | found = 1; | 310 | found = 1; |
302 | } | 311 | } |
@@ -371,7 +380,8 @@ int usb_sg_init ( | |||
371 | */ | 380 | */ |
372 | dma = (dev->dev.dma_mask != NULL); | 381 | dma = (dev->dev.dma_mask != NULL); |
373 | if (dma) | 382 | if (dma) |
374 | io->entries = usb_buffer_map_sg (dev, pipe, sg, nents); | 383 | io->entries = usb_buffer_map_sg(dev, usb_pipein(pipe), |
384 | sg, nents); | ||
375 | else | 385 | else |
376 | io->entries = nents; | 386 | io->entries = nents; |
377 | 387 | ||
@@ -409,15 +419,22 @@ int usb_sg_init ( | |||
409 | * Some systems need to revert to PIO when DMA is temporarily | 419 | * Some systems need to revert to PIO when DMA is temporarily |
410 | * unavailable. For their sakes, both transfer_buffer and | 420 | * unavailable. For their sakes, both transfer_buffer and |
411 | * transfer_dma are set when possible. However this can only | 421 | * transfer_dma are set when possible. However this can only |
412 | * work on systems without HIGHMEM, since DMA buffers located | 422 | * work on systems without: |
413 | * in high memory are not directly addressable by the CPU for | 423 | * |
414 | * PIO ... so when HIGHMEM is in use, transfer_buffer is NULL | 424 | * - HIGHMEM, since DMA buffers located in high memory are |
425 | * not directly addressable by the CPU for PIO; | ||
426 | * | ||
427 | * - IOMMU, since dma_map_sg() is allowed to use an IOMMU to | ||
428 | * make virtually discontiguous buffers be "dma-contiguous" | ||
429 | * so that PIO and DMA need diferent numbers of URBs. | ||
430 | * | ||
431 | * So when HIGHMEM or IOMMU are in use, transfer_buffer is NULL | ||
415 | * to prevent stale pointers and to help spot bugs. | 432 | * to prevent stale pointers and to help spot bugs. |
416 | */ | 433 | */ |
417 | if (dma) { | 434 | if (dma) { |
418 | io->urbs [i]->transfer_dma = sg_dma_address (sg + i); | 435 | io->urbs [i]->transfer_dma = sg_dma_address (sg + i); |
419 | len = sg_dma_len (sg + i); | 436 | len = sg_dma_len (sg + i); |
420 | #ifdef CONFIG_HIGHMEM | 437 | #if defined(CONFIG_HIGHMEM) || defined(CONFIG_IOMMU) |
421 | io->urbs[i]->transfer_buffer = NULL; | 438 | io->urbs[i]->transfer_buffer = NULL; |
422 | #else | 439 | #else |
423 | io->urbs[i]->transfer_buffer = | 440 | io->urbs[i]->transfer_buffer = |
@@ -622,12 +639,12 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char | |||
622 | memset(buf,0,size); // Make sure we parse really received data | 639 | memset(buf,0,size); // Make sure we parse really received data |
623 | 640 | ||
624 | for (i = 0; i < 3; ++i) { | 641 | for (i = 0; i < 3; ++i) { |
625 | /* retry on length 0 or stall; some devices are flakey */ | 642 | /* retry on length 0 or error; some devices are flakey */ |
626 | result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), | 643 | result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), |
627 | USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, | 644 | USB_REQ_GET_DESCRIPTOR, USB_DIR_IN, |
628 | (type << 8) + index, 0, buf, size, | 645 | (type << 8) + index, 0, buf, size, |
629 | USB_CTRL_GET_TIMEOUT); | 646 | USB_CTRL_GET_TIMEOUT); |
630 | if (result == 0 || result == -EPIPE) | 647 | if (result <= 0 && result != -ETIMEDOUT) |
631 | continue; | 648 | continue; |
632 | if (result > 1 && ((u8 *)buf)[1] != type) { | 649 | if (result > 1 && ((u8 *)buf)[1] != type) { |
633 | result = -EPROTO; | 650 | result = -EPROTO; |
@@ -998,8 +1015,11 @@ void usb_disable_endpoint(struct usb_device *dev, unsigned int epaddr) | |||
998 | ep = dev->ep_in[epnum]; | 1015 | ep = dev->ep_in[epnum]; |
999 | dev->ep_in[epnum] = NULL; | 1016 | dev->ep_in[epnum] = NULL; |
1000 | } | 1017 | } |
1001 | if (ep && dev->bus) | 1018 | if (ep) { |
1002 | usb_hcd_endpoint_disable(dev, ep); | 1019 | ep->enabled = 0; |
1020 | usb_hcd_flush_endpoint(dev, ep); | ||
1021 | usb_hcd_disable_endpoint(dev, ep); | ||
1022 | } | ||
1003 | } | 1023 | } |
1004 | 1024 | ||
1005 | /** | 1025 | /** |
@@ -1081,23 +1101,21 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) | |||
1081 | * Resets the endpoint toggle, and sets dev->ep_{in,out} pointers. | 1101 | * Resets the endpoint toggle, and sets dev->ep_{in,out} pointers. |
1082 | * For control endpoints, both the input and output sides are handled. | 1102 | * For control endpoints, both the input and output sides are handled. |
1083 | */ | 1103 | */ |
1084 | static void | 1104 | void usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep) |
1085 | usb_enable_endpoint(struct usb_device *dev, struct usb_host_endpoint *ep) | ||
1086 | { | 1105 | { |
1087 | unsigned int epaddr = ep->desc.bEndpointAddress; | 1106 | int epnum = usb_endpoint_num(&ep->desc); |
1088 | unsigned int epnum = epaddr & USB_ENDPOINT_NUMBER_MASK; | 1107 | int is_out = usb_endpoint_dir_out(&ep->desc); |
1089 | int is_control; | 1108 | int is_control = usb_endpoint_xfer_control(&ep->desc); |
1090 | 1109 | ||
1091 | is_control = ((ep->desc.bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) | 1110 | if (is_out || is_control) { |
1092 | == USB_ENDPOINT_XFER_CONTROL); | ||
1093 | if (usb_endpoint_out(epaddr) || is_control) { | ||
1094 | usb_settoggle(dev, epnum, 1, 0); | 1111 | usb_settoggle(dev, epnum, 1, 0); |
1095 | dev->ep_out[epnum] = ep; | 1112 | dev->ep_out[epnum] = ep; |
1096 | } | 1113 | } |
1097 | if (!usb_endpoint_out(epaddr) || is_control) { | 1114 | if (!is_out || is_control) { |
1098 | usb_settoggle(dev, epnum, 0, 0); | 1115 | usb_settoggle(dev, epnum, 0, 0); |
1099 | dev->ep_in[epnum] = ep; | 1116 | dev->ep_in[epnum] = ep; |
1100 | } | 1117 | } |
1118 | ep->enabled = 1; | ||
1101 | } | 1119 | } |
1102 | 1120 | ||
1103 | /* | 1121 | /* |
@@ -1156,6 +1174,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) | |||
1156 | struct usb_host_interface *alt; | 1174 | struct usb_host_interface *alt; |
1157 | int ret; | 1175 | int ret; |
1158 | int manual = 0; | 1176 | int manual = 0; |
1177 | int changed; | ||
1159 | 1178 | ||
1160 | if (dev->state == USB_STATE_SUSPENDED) | 1179 | if (dev->state == USB_STATE_SUSPENDED) |
1161 | return -EHOSTUNREACH; | 1180 | return -EHOSTUNREACH; |
@@ -1195,7 +1214,8 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) | |||
1195 | */ | 1214 | */ |
1196 | 1215 | ||
1197 | /* prevent submissions using previous endpoint settings */ | 1216 | /* prevent submissions using previous endpoint settings */ |
1198 | if (device_is_registered(&iface->dev)) | 1217 | changed = (iface->cur_altsetting != alt); |
1218 | if (changed && device_is_registered(&iface->dev)) | ||
1199 | usb_remove_sysfs_intf_files(iface); | 1219 | usb_remove_sysfs_intf_files(iface); |
1200 | usb_disable_interface(dev, iface); | 1220 | usb_disable_interface(dev, iface); |
1201 | 1221 | ||
@@ -1232,7 +1252,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate) | |||
1232 | * (Likewise, EP0 never "halts" on well designed devices.) | 1252 | * (Likewise, EP0 never "halts" on well designed devices.) |
1233 | */ | 1253 | */ |
1234 | usb_enable_interface(dev, iface); | 1254 | usb_enable_interface(dev, iface); |
1235 | if (device_is_registered(&iface->dev)) | 1255 | if (changed && device_is_registered(&iface->dev)) |
1236 | usb_create_sysfs_intf_files(iface); | 1256 | usb_create_sysfs_intf_files(iface); |
1237 | 1257 | ||
1238 | return 0; | 1258 | return 0; |
@@ -1313,7 +1333,7 @@ int usb_reset_configuration(struct usb_device *dev) | |||
1313 | return 0; | 1333 | return 0; |
1314 | } | 1334 | } |
1315 | 1335 | ||
1316 | void usb_release_interface(struct device *dev) | 1336 | static void usb_release_interface(struct device *dev) |
1317 | { | 1337 | { |
1318 | struct usb_interface *intf = to_usb_interface(dev); | 1338 | struct usb_interface *intf = to_usb_interface(dev); |
1319 | struct usb_interface_cache *intfc = | 1339 | struct usb_interface_cache *intfc = |
@@ -1324,14 +1344,11 @@ void usb_release_interface(struct device *dev) | |||
1324 | } | 1344 | } |
1325 | 1345 | ||
1326 | #ifdef CONFIG_HOTPLUG | 1346 | #ifdef CONFIG_HOTPLUG |
1327 | static int usb_if_uevent(struct device *dev, char **envp, int num_envp, | 1347 | static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) |
1328 | char *buffer, int buffer_size) | ||
1329 | { | 1348 | { |
1330 | struct usb_device *usb_dev; | 1349 | struct usb_device *usb_dev; |
1331 | struct usb_interface *intf; | 1350 | struct usb_interface *intf; |
1332 | struct usb_host_interface *alt; | 1351 | struct usb_host_interface *alt; |
1333 | int i = 0; | ||
1334 | int length = 0; | ||
1335 | 1352 | ||
1336 | if (!dev) | 1353 | if (!dev) |
1337 | return -ENODEV; | 1354 | return -ENODEV; |
@@ -1343,16 +1360,31 @@ static int usb_if_uevent(struct device *dev, char **envp, int num_envp, | |||
1343 | usb_dev = interface_to_usbdev(intf); | 1360 | usb_dev = interface_to_usbdev(intf); |
1344 | alt = intf->cur_altsetting; | 1361 | alt = intf->cur_altsetting; |
1345 | 1362 | ||
1346 | if (add_uevent_var(envp, num_envp, &i, | 1363 | #ifdef CONFIG_USB_DEVICEFS |
1347 | buffer, buffer_size, &length, | 1364 | if (add_uevent_var(env, "DEVICE=/proc/bus/usb/%03d/%03d", |
1348 | "INTERFACE=%d/%d/%d", | 1365 | usb_dev->bus->busnum, usb_dev->devnum)) |
1366 | return -ENOMEM; | ||
1367 | #endif | ||
1368 | |||
1369 | if (add_uevent_var(env, "PRODUCT=%x/%x/%x", | ||
1370 | le16_to_cpu(usb_dev->descriptor.idVendor), | ||
1371 | le16_to_cpu(usb_dev->descriptor.idProduct), | ||
1372 | le16_to_cpu(usb_dev->descriptor.bcdDevice))) | ||
1373 | return -ENOMEM; | ||
1374 | |||
1375 | if (add_uevent_var(env, "TYPE=%d/%d/%d", | ||
1376 | usb_dev->descriptor.bDeviceClass, | ||
1377 | usb_dev->descriptor.bDeviceSubClass, | ||
1378 | usb_dev->descriptor.bDeviceProtocol)) | ||
1379 | return -ENOMEM; | ||
1380 | |||
1381 | if (add_uevent_var(env, "INTERFACE=%d/%d/%d", | ||
1349 | alt->desc.bInterfaceClass, | 1382 | alt->desc.bInterfaceClass, |
1350 | alt->desc.bInterfaceSubClass, | 1383 | alt->desc.bInterfaceSubClass, |
1351 | alt->desc.bInterfaceProtocol)) | 1384 | alt->desc.bInterfaceProtocol)) |
1352 | return -ENOMEM; | 1385 | return -ENOMEM; |
1353 | 1386 | ||
1354 | if (add_uevent_var(envp, num_envp, &i, | 1387 | if (add_uevent_var(env, |
1355 | buffer, buffer_size, &length, | ||
1356 | "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", | 1388 | "MODALIAS=usb:v%04Xp%04Xd%04Xdc%02Xdsc%02Xdp%02Xic%02Xisc%02Xip%02X", |
1357 | le16_to_cpu(usb_dev->descriptor.idVendor), | 1389 | le16_to_cpu(usb_dev->descriptor.idVendor), |
1358 | le16_to_cpu(usb_dev->descriptor.idProduct), | 1390 | le16_to_cpu(usb_dev->descriptor.idProduct), |
@@ -1365,14 +1397,12 @@ static int usb_if_uevent(struct device *dev, char **envp, int num_envp, | |||
1365 | alt->desc.bInterfaceProtocol)) | 1397 | alt->desc.bInterfaceProtocol)) |
1366 | return -ENOMEM; | 1398 | return -ENOMEM; |
1367 | 1399 | ||
1368 | envp[i] = NULL; | ||
1369 | return 0; | 1400 | return 0; |
1370 | } | 1401 | } |
1371 | 1402 | ||
1372 | #else | 1403 | #else |
1373 | 1404 | ||
1374 | static int usb_if_uevent(struct device *dev, char **envp, | 1405 | static int usb_if_uevent(struct device *dev, struct kobj_uevent_env *env) |
1375 | int num_envp, char *buffer, int buffer_size) | ||
1376 | { | 1406 | { |
1377 | return -ENODEV; | 1407 | return -ENODEV; |
1378 | } | 1408 | } |
@@ -1442,6 +1472,9 @@ static struct usb_interface_assoc_descriptor *find_iad(struct usb_device *dev, | |||
1442 | * channels are available independently; and choosing between open | 1472 | * channels are available independently; and choosing between open |
1443 | * standard device protocols (like CDC) or proprietary ones. | 1473 | * standard device protocols (like CDC) or proprietary ones. |
1444 | * | 1474 | * |
1475 | * Note that a non-authorized device (dev->authorized == 0) will only | ||
1476 | * be put in unconfigured mode. | ||
1477 | * | ||
1445 | * Note that USB has an additional level of device configurability, | 1478 | * Note that USB has an additional level of device configurability, |
1446 | * associated with interfaces. That configurability is accessed using | 1479 | * associated with interfaces. That configurability is accessed using |
1447 | * usb_set_interface(). | 1480 | * usb_set_interface(). |
@@ -1463,7 +1496,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration) | |||
1463 | struct usb_interface **new_interfaces = NULL; | 1496 | struct usb_interface **new_interfaces = NULL; |
1464 | int n, nintf; | 1497 | int n, nintf; |
1465 | 1498 | ||
1466 | if (configuration == -1) | 1499 | if (dev->authorized == 0 || configuration == -1) |
1467 | configuration = 0; | 1500 | configuration = 0; |
1468 | else { | 1501 | else { |
1469 | for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { | 1502 | for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { |
diff --git a/drivers/usb/core/quirks.c b/drivers/usb/core/quirks.c index aa21b38a31c..d42c561c75f 100644 --- a/drivers/usb/core/quirks.c +++ b/drivers/usb/core/quirks.c | |||
@@ -28,42 +28,26 @@ | |||
28 | * devices is broken... | 28 | * devices is broken... |
29 | */ | 29 | */ |
30 | static const struct usb_device_id usb_quirk_list[] = { | 30 | static const struct usb_device_id usb_quirk_list[] = { |
31 | /* CBM - Flash disk */ | ||
32 | { USB_DEVICE(0x0204, 0x6025), .driver_info = USB_QUIRK_RESET_RESUME }, | ||
31 | /* HP 5300/5370C scanner */ | 33 | /* HP 5300/5370C scanner */ |
32 | { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 }, | 34 | { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 }, |
33 | /* Benq S2W 3300U */ | 35 | |
34 | { USB_DEVICE(0x04a5, 0x20b0), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | 36 | /* INTEL VALUE SSD */ |
35 | /* Seiko Epson Corp. Perfection 1200 */ | 37 | { USB_DEVICE(0x8086, 0xf1a5), .driver_info = USB_QUIRK_RESET_RESUME }, |
36 | { USB_DEVICE(0x04b8, 0x0104), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | 38 | |
37 | /* Seiko Epson Corp - Perfection 1670 */ | 39 | /* M-Systems Flash Disk Pioneers */ |
38 | { USB_DEVICE(0x04b8, 0x011f), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | 40 | { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME }, |
39 | /* Samsung ML-2510 Series printer */ | ||
40 | { USB_DEVICE(0x04e8, 0x327e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
41 | /* Elsa MicroLink 56k (V.250) */ | ||
42 | { USB_DEVICE(0x05cc, 0x2267), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
43 | /* Ultima Electronics Corp.*/ | ||
44 | { USB_DEVICE(0x05d8, 0x4005), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
45 | /* Umax [hex] Astra 3400U */ | ||
46 | { USB_DEVICE(0x1606, 0x0060), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
47 | 41 | ||
48 | /* Philips PSC805 audio device */ | 42 | /* Philips PSC805 audio device */ |
49 | { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME }, | 43 | { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME }, |
50 | 44 | ||
51 | /* RIM Blackberry */ | 45 | /* SKYMEDI USB_DRIVE */ |
52 | { USB_DEVICE(0x0fca, 0x0001), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | 46 | { USB_DEVICE(0x1516, 0x8628), .driver_info = USB_QUIRK_RESET_RESUME }, |
53 | { USB_DEVICE(0x0fca, 0x0004), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
54 | { USB_DEVICE(0x0fca, 0x0006), .driver_info = USB_QUIRK_NO_AUTOSUSPEND }, | ||
55 | 47 | ||
56 | { } /* terminating entry must be last */ | 48 | { } /* terminating entry must be last */ |
57 | }; | 49 | }; |
58 | 50 | ||
59 | static void usb_autosuspend_quirk(struct usb_device *udev) | ||
60 | { | ||
61 | #ifdef CONFIG_USB_SUSPEND | ||
62 | /* disable autosuspend, but allow the user to re-enable it via sysfs */ | ||
63 | udev->autosuspend_disabled = 1; | ||
64 | #endif | ||
65 | } | ||
66 | |||
67 | static const struct usb_device_id *find_id(struct usb_device *udev) | 51 | static const struct usb_device_id *find_id(struct usb_device *udev) |
68 | { | 52 | { |
69 | const struct usb_device_id *id = usb_quirk_list; | 53 | const struct usb_device_id *id = usb_quirk_list; |
@@ -90,7 +74,9 @@ void usb_detect_quirks(struct usb_device *udev) | |||
90 | dev_dbg(&udev->dev, "USB quirks for this device: %x\n", | 74 | dev_dbg(&udev->dev, "USB quirks for this device: %x\n", |
91 | udev->quirks); | 75 | udev->quirks); |
92 | 76 | ||
93 | /* do any special quirk handling here if needed */ | 77 | /* By default, disable autosuspend for all non-hubs */ |
94 | if (udev->quirks & USB_QUIRK_NO_AUTOSUSPEND) | 78 | #ifdef CONFIG_USB_SUSPEND |
95 | usb_autosuspend_quirk(udev); | 79 | if (udev->descriptor.bDeviceClass != USB_CLASS_HUB) |
80 | udev->autosuspend_disabled = 1; | ||
81 | #endif | ||
96 | } | 82 | } |
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c index d47ae89154a..b04afd06e50 100644 --- a/drivers/usb/core/sysfs.c +++ b/drivers/usb/core/sysfs.c | |||
@@ -169,6 +169,16 @@ show_quirks(struct device *dev, struct device_attribute *attr, char *buf) | |||
169 | } | 169 | } |
170 | static DEVICE_ATTR(quirks, S_IRUGO, show_quirks, NULL); | 170 | static DEVICE_ATTR(quirks, S_IRUGO, show_quirks, NULL); |
171 | 171 | ||
172 | static ssize_t | ||
173 | show_urbnum(struct device *dev, struct device_attribute *attr, char *buf) | ||
174 | { | ||
175 | struct usb_device *udev; | ||
176 | |||
177 | udev = to_usb_device(dev); | ||
178 | return sprintf(buf, "%d\n", atomic_read(&udev->urbnum)); | ||
179 | } | ||
180 | static DEVICE_ATTR(urbnum, S_IRUGO, show_urbnum, NULL); | ||
181 | |||
172 | 182 | ||
173 | #if defined(CONFIG_USB_PERSIST) || defined(CONFIG_USB_SUSPEND) | 183 | #if defined(CONFIG_USB_PERSIST) || defined(CONFIG_USB_SUSPEND) |
174 | static const char power_group[] = "power"; | 184 | static const char power_group[] = "power"; |
@@ -413,6 +423,44 @@ usb_descriptor_attr(bDeviceProtocol, "%02x\n") | |||
413 | usb_descriptor_attr(bNumConfigurations, "%d\n") | 423 | usb_descriptor_attr(bNumConfigurations, "%d\n") |
414 | usb_descriptor_attr(bMaxPacketSize0, "%d\n") | 424 | usb_descriptor_attr(bMaxPacketSize0, "%d\n") |
415 | 425 | ||
426 | |||
427 | |||
428 | /* show if the device is authorized (1) or not (0) */ | ||
429 | static ssize_t usb_dev_authorized_show(struct device *dev, | ||
430 | struct device_attribute *attr, | ||
431 | char *buf) | ||
432 | { | ||
433 | struct usb_device *usb_dev = to_usb_device(dev); | ||
434 | return snprintf(buf, PAGE_SIZE, "%u\n", usb_dev->authorized); | ||
435 | } | ||
436 | |||
437 | |||
438 | /* | ||
439 | * Authorize a device to be used in the system | ||
440 | * | ||
441 | * Writing a 0 deauthorizes the device, writing a 1 authorizes it. | ||
442 | */ | ||
443 | static ssize_t usb_dev_authorized_store(struct device *dev, | ||
444 | struct device_attribute *attr, | ||
445 | const char *buf, size_t size) | ||
446 | { | ||
447 | ssize_t result; | ||
448 | struct usb_device *usb_dev = to_usb_device(dev); | ||
449 | unsigned val; | ||
450 | result = sscanf(buf, "%u\n", &val); | ||
451 | if (result != 1) | ||
452 | result = -EINVAL; | ||
453 | else if (val == 0) | ||
454 | result = usb_deauthorize_device(usb_dev); | ||
455 | else | ||
456 | result = usb_authorize_device(usb_dev); | ||
457 | return result < 0? result : size; | ||
458 | } | ||
459 | |||
460 | static DEVICE_ATTR(authorized, 0644, | ||
461 | usb_dev_authorized_show, usb_dev_authorized_store); | ||
462 | |||
463 | |||
416 | static struct attribute *dev_attrs[] = { | 464 | static struct attribute *dev_attrs[] = { |
417 | /* current configuration's attributes */ | 465 | /* current configuration's attributes */ |
418 | &dev_attr_configuration.attr, | 466 | &dev_attr_configuration.attr, |
@@ -420,6 +468,7 @@ static struct attribute *dev_attrs[] = { | |||
420 | &dev_attr_bConfigurationValue.attr, | 468 | &dev_attr_bConfigurationValue.attr, |
421 | &dev_attr_bmAttributes.attr, | 469 | &dev_attr_bmAttributes.attr, |
422 | &dev_attr_bMaxPower.attr, | 470 | &dev_attr_bMaxPower.attr, |
471 | &dev_attr_urbnum.attr, | ||
423 | /* device attributes */ | 472 | /* device attributes */ |
424 | &dev_attr_idVendor.attr, | 473 | &dev_attr_idVendor.attr, |
425 | &dev_attr_idProduct.attr, | 474 | &dev_attr_idProduct.attr, |
@@ -435,12 +484,61 @@ static struct attribute *dev_attrs[] = { | |||
435 | &dev_attr_version.attr, | 484 | &dev_attr_version.attr, |
436 | &dev_attr_maxchild.attr, | 485 | &dev_attr_maxchild.attr, |
437 | &dev_attr_quirks.attr, | 486 | &dev_attr_quirks.attr, |
487 | &dev_attr_authorized.attr, | ||
438 | NULL, | 488 | NULL, |
439 | }; | 489 | }; |
440 | static struct attribute_group dev_attr_grp = { | 490 | static struct attribute_group dev_attr_grp = { |
441 | .attrs = dev_attrs, | 491 | .attrs = dev_attrs, |
442 | }; | 492 | }; |
443 | 493 | ||
494 | /* Binary descriptors */ | ||
495 | |||
496 | static ssize_t | ||
497 | read_descriptors(struct kobject *kobj, struct bin_attribute *attr, | ||
498 | char *buf, loff_t off, size_t count) | ||
499 | { | ||
500 | struct usb_device *udev = to_usb_device( | ||
501 | container_of(kobj, struct device, kobj)); | ||
502 | size_t nleft = count; | ||
503 | size_t srclen, n; | ||
504 | |||
505 | usb_lock_device(udev); | ||
506 | |||
507 | /* The binary attribute begins with the device descriptor */ | ||
508 | srclen = sizeof(struct usb_device_descriptor); | ||
509 | if (off < srclen) { | ||
510 | n = min_t(size_t, nleft, srclen - off); | ||
511 | memcpy(buf, off + (char *) &udev->descriptor, n); | ||
512 | nleft -= n; | ||
513 | buf += n; | ||
514 | off = 0; | ||
515 | } else { | ||
516 | off -= srclen; | ||
517 | } | ||
518 | |||
519 | /* Then follows the raw descriptor entry for the current | ||
520 | * configuration (config plus subsidiary descriptors). | ||
521 | */ | ||
522 | if (udev->actconfig) { | ||
523 | int cfgno = udev->actconfig - udev->config; | ||
524 | |||
525 | srclen = __le16_to_cpu(udev->actconfig->desc.wTotalLength); | ||
526 | if (off < srclen) { | ||
527 | n = min_t(size_t, nleft, srclen - off); | ||
528 | memcpy(buf, off + udev->rawdescriptors[cfgno], n); | ||
529 | nleft -= n; | ||
530 | } | ||
531 | } | ||
532 | usb_unlock_device(udev); | ||
533 | return count - nleft; | ||
534 | } | ||
535 | |||
536 | static struct bin_attribute dev_bin_attr_descriptors = { | ||
537 | .attr = {.name = "descriptors", .mode = 0444}, | ||
538 | .read = read_descriptors, | ||
539 | .size = 18 + 65535, /* dev descr + max-size raw descriptor */ | ||
540 | }; | ||
541 | |||
444 | int usb_create_sysfs_dev_files(struct usb_device *udev) | 542 | int usb_create_sysfs_dev_files(struct usb_device *udev) |
445 | { | 543 | { |
446 | struct device *dev = &udev->dev; | 544 | struct device *dev = &udev->dev; |
@@ -450,6 +548,10 @@ int usb_create_sysfs_dev_files(struct usb_device *udev) | |||
450 | if (retval) | 548 | if (retval) |
451 | return retval; | 549 | return retval; |
452 | 550 | ||
551 | retval = device_create_bin_file(dev, &dev_bin_attr_descriptors); | ||
552 | if (retval) | ||
553 | goto error; | ||
554 | |||
453 | retval = add_persist_attributes(dev); | 555 | retval = add_persist_attributes(dev); |
454 | if (retval) | 556 | if (retval) |
455 | goto error; | 557 | goto error; |
@@ -492,6 +594,7 @@ void usb_remove_sysfs_dev_files(struct usb_device *udev) | |||
492 | device_remove_file(dev, &dev_attr_serial); | 594 | device_remove_file(dev, &dev_attr_serial); |
493 | remove_power_attributes(dev); | 595 | remove_power_attributes(dev); |
494 | remove_persist_attributes(dev); | 596 | remove_persist_attributes(dev); |
597 | device_remove_bin_file(dev, &dev_bin_attr_descriptors); | ||
495 | sysfs_remove_group(&dev->kobj, &dev_attr_grp); | 598 | sysfs_remove_group(&dev->kobj, &dev_attr_grp); |
496 | } | 599 | } |
497 | 600 | ||
diff --git a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c index 52ec44b828f..c20c03aaf01 100644 --- a/drivers/usb/core/urb.c +++ b/drivers/usb/core/urb.c | |||
@@ -3,6 +3,7 @@ | |||
3 | #include <linux/bitops.h> | 3 | #include <linux/bitops.h> |
4 | #include <linux/slab.h> | 4 | #include <linux/slab.h> |
5 | #include <linux/init.h> | 5 | #include <linux/init.h> |
6 | #include <linux/log2.h> | ||
6 | #include <linux/usb.h> | 7 | #include <linux/usb.h> |
7 | #include <linux/wait.h> | 8 | #include <linux/wait.h> |
8 | #include "hcd.h" | 9 | #include "hcd.h" |
@@ -38,7 +39,6 @@ void usb_init_urb(struct urb *urb) | |||
38 | if (urb) { | 39 | if (urb) { |
39 | memset(urb, 0, sizeof(*urb)); | 40 | memset(urb, 0, sizeof(*urb)); |
40 | kref_init(&urb->kref); | 41 | kref_init(&urb->kref); |
41 | spin_lock_init(&urb->lock); | ||
42 | INIT_LIST_HEAD(&urb->anchor_list); | 42 | INIT_LIST_HEAD(&urb->anchor_list); |
43 | } | 43 | } |
44 | } | 44 | } |
@@ -277,44 +277,58 @@ EXPORT_SYMBOL_GPL(usb_unanchor_urb); | |||
277 | */ | 277 | */ |
278 | int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | 278 | int usb_submit_urb(struct urb *urb, gfp_t mem_flags) |
279 | { | 279 | { |
280 | int pipe, temp, max; | 280 | int xfertype, max; |
281 | struct usb_device *dev; | 281 | struct usb_device *dev; |
282 | int is_out; | 282 | struct usb_host_endpoint *ep; |
283 | int is_out; | ||
283 | 284 | ||
284 | if (!urb || urb->hcpriv || !urb->complete) | 285 | if (!urb || urb->hcpriv || !urb->complete) |
285 | return -EINVAL; | 286 | return -EINVAL; |
286 | if (!(dev = urb->dev) || | 287 | if (!(dev = urb->dev) || dev->state < USB_STATE_DEFAULT) |
287 | (dev->state < USB_STATE_DEFAULT) || | ||
288 | (!dev->bus) || (dev->devnum <= 0)) | ||
289 | return -ENODEV; | 288 | return -ENODEV; |
290 | if (dev->bus->controller->power.power_state.event != PM_EVENT_ON | ||
291 | || dev->state == USB_STATE_SUSPENDED) | ||
292 | return -EHOSTUNREACH; | ||
293 | 289 | ||
290 | /* For now, get the endpoint from the pipe. Eventually drivers | ||
291 | * will be required to set urb->ep directly and we will eliminate | ||
292 | * urb->pipe. | ||
293 | */ | ||
294 | ep = (usb_pipein(urb->pipe) ? dev->ep_in : dev->ep_out) | ||
295 | [usb_pipeendpoint(urb->pipe)]; | ||
296 | if (!ep) | ||
297 | return -ENOENT; | ||
298 | |||
299 | urb->ep = ep; | ||
294 | urb->status = -EINPROGRESS; | 300 | urb->status = -EINPROGRESS; |
295 | urb->actual_length = 0; | 301 | urb->actual_length = 0; |
296 | 302 | ||
297 | /* Lots of sanity checks, so HCDs can rely on clean data | 303 | /* Lots of sanity checks, so HCDs can rely on clean data |
298 | * and don't need to duplicate tests | 304 | * and don't need to duplicate tests |
299 | */ | 305 | */ |
300 | pipe = urb->pipe; | 306 | xfertype = usb_endpoint_type(&ep->desc); |
301 | temp = usb_pipetype(pipe); | 307 | if (xfertype == USB_ENDPOINT_XFER_CONTROL) { |
302 | is_out = usb_pipeout(pipe); | 308 | struct usb_ctrlrequest *setup = |
309 | (struct usb_ctrlrequest *) urb->setup_packet; | ||
310 | |||
311 | if (!setup) | ||
312 | return -ENOEXEC; | ||
313 | is_out = !(setup->bRequestType & USB_DIR_IN) || | ||
314 | !setup->wLength; | ||
315 | } else { | ||
316 | is_out = usb_endpoint_dir_out(&ep->desc); | ||
317 | } | ||
303 | 318 | ||
304 | if (!usb_pipecontrol(pipe) && dev->state < USB_STATE_CONFIGURED) | 319 | /* Cache the direction for later use */ |
305 | return -ENODEV; | 320 | urb->transfer_flags = (urb->transfer_flags & ~URB_DIR_MASK) | |
321 | (is_out ? URB_DIR_OUT : URB_DIR_IN); | ||
306 | 322 | ||
307 | /* FIXME there should be a sharable lock protecting us against | 323 | if (xfertype != USB_ENDPOINT_XFER_CONTROL && |
308 | * config/altsetting changes and disconnects, kicking in here. | 324 | dev->state < USB_STATE_CONFIGURED) |
309 | * (here == before maxpacket, and eventually endpoint type, | 325 | return -ENODEV; |
310 | * checks get made.) | ||
311 | */ | ||
312 | 326 | ||
313 | max = usb_maxpacket(dev, pipe, is_out); | 327 | max = le16_to_cpu(ep->desc.wMaxPacketSize); |
314 | if (max <= 0) { | 328 | if (max <= 0) { |
315 | dev_dbg(&dev->dev, | 329 | dev_dbg(&dev->dev, |
316 | "bogus endpoint ep%d%s in %s (bad maxpacket %d)\n", | 330 | "bogus endpoint ep%d%s in %s (bad maxpacket %d)\n", |
317 | usb_pipeendpoint(pipe), is_out ? "out" : "in", | 331 | usb_endpoint_num(&ep->desc), is_out ? "out" : "in", |
318 | __FUNCTION__, max); | 332 | __FUNCTION__, max); |
319 | return -EMSGSIZE; | 333 | return -EMSGSIZE; |
320 | } | 334 | } |
@@ -323,7 +337,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
323 | * but drivers only control those sizes for ISO. | 337 | * but drivers only control those sizes for ISO. |
324 | * while we're checking, initialize return status. | 338 | * while we're checking, initialize return status. |
325 | */ | 339 | */ |
326 | if (temp == PIPE_ISOCHRONOUS) { | 340 | if (xfertype == USB_ENDPOINT_XFER_ISOC) { |
327 | int n, len; | 341 | int n, len; |
328 | 342 | ||
329 | /* "high bandwidth" mode, 1-3 packets/uframe? */ | 343 | /* "high bandwidth" mode, 1-3 packets/uframe? */ |
@@ -358,20 +372,20 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
358 | 372 | ||
359 | /* enforce simple/standard policy */ | 373 | /* enforce simple/standard policy */ |
360 | allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | | 374 | allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP | |
361 | URB_NO_INTERRUPT); | 375 | URB_NO_INTERRUPT | URB_DIR_MASK); |
362 | switch (temp) { | 376 | switch (xfertype) { |
363 | case PIPE_BULK: | 377 | case USB_ENDPOINT_XFER_BULK: |
364 | if (is_out) | 378 | if (is_out) |
365 | allowed |= URB_ZERO_PACKET; | 379 | allowed |= URB_ZERO_PACKET; |
366 | /* FALLTHROUGH */ | 380 | /* FALLTHROUGH */ |
367 | case PIPE_CONTROL: | 381 | case USB_ENDPOINT_XFER_CONTROL: |
368 | allowed |= URB_NO_FSBR; /* only affects UHCI */ | 382 | allowed |= URB_NO_FSBR; /* only affects UHCI */ |
369 | /* FALLTHROUGH */ | 383 | /* FALLTHROUGH */ |
370 | default: /* all non-iso endpoints */ | 384 | default: /* all non-iso endpoints */ |
371 | if (!is_out) | 385 | if (!is_out) |
372 | allowed |= URB_SHORT_NOT_OK; | 386 | allowed |= URB_SHORT_NOT_OK; |
373 | break; | 387 | break; |
374 | case PIPE_ISOCHRONOUS: | 388 | case USB_ENDPOINT_XFER_ISOC: |
375 | allowed |= URB_ISO_ASAP; | 389 | allowed |= URB_ISO_ASAP; |
376 | break; | 390 | break; |
377 | } | 391 | } |
@@ -393,9 +407,9 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
393 | * supports different values... this uses EHCI/UHCI defaults (and | 407 | * supports different values... this uses EHCI/UHCI defaults (and |
394 | * EHCI can use smaller non-default values). | 408 | * EHCI can use smaller non-default values). |
395 | */ | 409 | */ |
396 | switch (temp) { | 410 | switch (xfertype) { |
397 | case PIPE_ISOCHRONOUS: | 411 | case USB_ENDPOINT_XFER_ISOC: |
398 | case PIPE_INTERRUPT: | 412 | case USB_ENDPOINT_XFER_INT: |
399 | /* too small? */ | 413 | /* too small? */ |
400 | if (urb->interval <= 0) | 414 | if (urb->interval <= 0) |
401 | return -EINVAL; | 415 | return -EINVAL; |
@@ -405,29 +419,27 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
405 | // NOTE usb handles 2^15 | 419 | // NOTE usb handles 2^15 |
406 | if (urb->interval > (1024 * 8)) | 420 | if (urb->interval > (1024 * 8)) |
407 | urb->interval = 1024 * 8; | 421 | urb->interval = 1024 * 8; |
408 | temp = 1024 * 8; | 422 | max = 1024 * 8; |
409 | break; | 423 | break; |
410 | case USB_SPEED_FULL: /* units are frames/msec */ | 424 | case USB_SPEED_FULL: /* units are frames/msec */ |
411 | case USB_SPEED_LOW: | 425 | case USB_SPEED_LOW: |
412 | if (temp == PIPE_INTERRUPT) { | 426 | if (xfertype == USB_ENDPOINT_XFER_INT) { |
413 | if (urb->interval > 255) | 427 | if (urb->interval > 255) |
414 | return -EINVAL; | 428 | return -EINVAL; |
415 | // NOTE ohci only handles up to 32 | 429 | // NOTE ohci only handles up to 32 |
416 | temp = 128; | 430 | max = 128; |
417 | } else { | 431 | } else { |
418 | if (urb->interval > 1024) | 432 | if (urb->interval > 1024) |
419 | urb->interval = 1024; | 433 | urb->interval = 1024; |
420 | // NOTE usb and ohci handle up to 2^15 | 434 | // NOTE usb and ohci handle up to 2^15 |
421 | temp = 1024; | 435 | max = 1024; |
422 | } | 436 | } |
423 | break; | 437 | break; |
424 | default: | 438 | default: |
425 | return -EINVAL; | 439 | return -EINVAL; |
426 | } | 440 | } |
427 | /* power of two? */ | 441 | /* Round down to a power of 2, no more than max */ |
428 | while (temp > urb->interval) | 442 | urb->interval = min(max, 1 << ilog2(urb->interval)); |
429 | temp >>= 1; | ||
430 | urb->interval = temp; | ||
431 | } | 443 | } |
432 | 444 | ||
433 | return usb_hcd_submit_urb(urb, mem_flags); | 445 | return usb_hcd_submit_urb(urb, mem_flags); |
@@ -440,62 +452,66 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags) | |||
440 | * @urb: pointer to urb describing a previously submitted request, | 452 | * @urb: pointer to urb describing a previously submitted request, |
441 | * may be NULL | 453 | * may be NULL |
442 | * | 454 | * |
443 | * This routine cancels an in-progress request. URBs complete only | 455 | * This routine cancels an in-progress request. URBs complete only once |
444 | * once per submission, and may be canceled only once per submission. | 456 | * per submission, and may be canceled only once per submission. |
445 | * Successful cancellation means the requests's completion handler will | 457 | * Successful cancellation means termination of @urb will be expedited |
446 | * be called with a status code indicating that the request has been | 458 | * and the completion handler will be called with a status code |
447 | * canceled (rather than any other code) and will quickly be removed | 459 | * indicating that the request has been canceled (rather than any other |
448 | * from host controller data structures. | 460 | * code). |
449 | * | 461 | * |
450 | * This request is always asynchronous. | 462 | * This request is always asynchronous. Success is indicated by |
451 | * Success is indicated by returning -EINPROGRESS, | 463 | * returning -EINPROGRESS, at which time the URB will probably not yet |
452 | * at which time the URB will normally have been unlinked but not yet | 464 | * have been given back to the device driver. When it is eventually |
453 | * given back to the device driver. When it is called, the completion | 465 | * called, the completion function will see @urb->status == -ECONNRESET. |
454 | * function will see urb->status == -ECONNRESET. Failure is indicated | 466 | * Failure is indicated by usb_unlink_urb() returning any other value. |
455 | * by any other return value. Unlinking will fail when the URB is not | 467 | * Unlinking will fail when @urb is not currently "linked" (i.e., it was |
456 | * currently "linked" (i.e., it was never submitted, or it was unlinked | 468 | * never submitted, or it was unlinked before, or the hardware is already |
457 | * before, or the hardware is already finished with it), even if the | 469 | * finished with it), even if the completion handler has not yet run. |
458 | * completion handler has not yet run. | ||
459 | * | 470 | * |
460 | * Unlinking and Endpoint Queues: | 471 | * Unlinking and Endpoint Queues: |
461 | * | 472 | * |
473 | * [The behaviors and guarantees described below do not apply to virtual | ||
474 | * root hubs but only to endpoint queues for physical USB devices.] | ||
475 | * | ||
462 | * Host Controller Drivers (HCDs) place all the URBs for a particular | 476 | * Host Controller Drivers (HCDs) place all the URBs for a particular |
463 | * endpoint in a queue. Normally the queue advances as the controller | 477 | * endpoint in a queue. Normally the queue advances as the controller |
464 | * hardware processes each request. But when an URB terminates with an | 478 | * hardware processes each request. But when an URB terminates with an |
465 | * error its queue stops, at least until that URB's completion routine | 479 | * error its queue generally stops (see below), at least until that URB's |
466 | * returns. It is guaranteed that the queue will not restart until all | 480 | * completion routine returns. It is guaranteed that a stopped queue |
467 | * its unlinked URBs have been fully retired, with their completion | 481 | * will not restart until all its unlinked URBs have been fully retired, |
468 | * routines run, even if that's not until some time after the original | 482 | * with their completion routines run, even if that's not until some time |
469 | * completion handler returns. Normally the same behavior and guarantees | 483 | * after the original completion handler returns. The same behavior and |
470 | * apply when an URB terminates because it was unlinked; however if an | 484 | * guarantee apply when an URB terminates because it was unlinked. |
471 | * URB is unlinked before the hardware has started to execute it, then | 485 | * |
472 | * its queue is not guaranteed to stop until all the preceding URBs have | 486 | * Bulk and interrupt endpoint queues are guaranteed to stop whenever an |
473 | * completed. | 487 | * URB terminates with any sort of error, including -ECONNRESET, -ENOENT, |
474 | * | 488 | * and -EREMOTEIO. Control endpoint queues behave the same way except |
475 | * This means that USB device drivers can safely build deep queues for | 489 | * that they are not guaranteed to stop for -EREMOTEIO errors. Queues |
476 | * large or complex transfers, and clean them up reliably after any sort | 490 | * for isochronous endpoints are treated differently, because they must |
477 | * of aborted transfer by unlinking all pending URBs at the first fault. | 491 | * advance at fixed rates. Such queues do not stop when an URB |
478 | * | 492 | * encounters an error or is unlinked. An unlinked isochronous URB may |
479 | * Note that an URB terminating early because a short packet was received | 493 | * leave a gap in the stream of packets; it is undefined whether such |
480 | * will count as an error if and only if the URB_SHORT_NOT_OK flag is set. | 494 | * gaps can be filled in. |
481 | * Also, that all unlinks performed in any URB completion handler must | 495 | * |
482 | * be asynchronous. | 496 | * Note that early termination of an URB because a short packet was |
483 | * | 497 | * received will generate a -EREMOTEIO error if and only if the |
484 | * Queues for isochronous endpoints are treated differently, because they | 498 | * URB_SHORT_NOT_OK flag is set. By setting this flag, USB device |
485 | * advance at fixed rates. Such queues do not stop when an URB is unlinked. | 499 | * drivers can build deep queues for large or complex bulk transfers |
486 | * An unlinked URB may leave a gap in the stream of packets. It is undefined | 500 | * and clean them up reliably after any sort of aborted transfer by |
487 | * whether such gaps can be filled in. | 501 | * unlinking all pending URBs at the first fault. |
488 | * | 502 | * |
489 | * When a control URB terminates with an error, it is likely that the | 503 | * When a control URB terminates with an error other than -EREMOTEIO, it |
490 | * status stage of the transfer will not take place, even if it is merely | 504 | * is quite likely that the status stage of the transfer will not take |
491 | * a soft error resulting from a short-packet with URB_SHORT_NOT_OK set. | 505 | * place. |
492 | */ | 506 | */ |
493 | int usb_unlink_urb(struct urb *urb) | 507 | int usb_unlink_urb(struct urb *urb) |
494 | { | 508 | { |
495 | if (!urb) | 509 | if (!urb) |
496 | return -EINVAL; | 510 | return -EINVAL; |
497 | if (!(urb->dev && urb->dev->bus)) | 511 | if (!urb->dev) |
498 | return -ENODEV; | 512 | return -ENODEV; |
513 | if (!urb->ep) | ||
514 | return -EIDRM; | ||
499 | return usb_hcd_unlink_urb(urb, -ECONNRESET); | 515 | return usb_hcd_unlink_urb(urb, -ECONNRESET); |
500 | } | 516 | } |
501 | 517 | ||
@@ -521,19 +537,21 @@ int usb_unlink_urb(struct urb *urb) | |||
521 | */ | 537 | */ |
522 | void usb_kill_urb(struct urb *urb) | 538 | void usb_kill_urb(struct urb *urb) |
523 | { | 539 | { |
540 | static DEFINE_MUTEX(reject_mutex); | ||
541 | |||
524 | might_sleep(); | 542 | might_sleep(); |
525 | if (!(urb && urb->dev && urb->dev->bus)) | 543 | if (!(urb && urb->dev && urb->ep)) |
526 | return; | 544 | return; |
527 | spin_lock_irq(&urb->lock); | 545 | mutex_lock(&reject_mutex); |
528 | ++urb->reject; | 546 | ++urb->reject; |
529 | spin_unlock_irq(&urb->lock); | 547 | mutex_unlock(&reject_mutex); |
530 | 548 | ||
531 | usb_hcd_unlink_urb(urb, -ENOENT); | 549 | usb_hcd_unlink_urb(urb, -ENOENT); |
532 | wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0); | 550 | wait_event(usb_kill_urb_queue, atomic_read(&urb->use_count) == 0); |
533 | 551 | ||
534 | spin_lock_irq(&urb->lock); | 552 | mutex_lock(&reject_mutex); |
535 | --urb->reject; | 553 | --urb->reject; |
536 | spin_unlock_irq(&urb->lock); | 554 | mutex_unlock(&reject_mutex); |
537 | } | 555 | } |
538 | 556 | ||
539 | /** | 557 | /** |
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 0fee5c66fd6..c99938d5f78 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c | |||
@@ -223,6 +223,15 @@ static void ksuspend_usb_cleanup(void) | |||
223 | 223 | ||
224 | #endif /* CONFIG_PM */ | 224 | #endif /* CONFIG_PM */ |
225 | 225 | ||
226 | |||
227 | /* Returns 1 if @usb_bus is WUSB, 0 otherwise */ | ||
228 | static unsigned usb_bus_is_wusb(struct usb_bus *bus) | ||
229 | { | ||
230 | struct usb_hcd *hcd = container_of(bus, struct usb_hcd, self); | ||
231 | return hcd->wireless; | ||
232 | } | ||
233 | |||
234 | |||
226 | /** | 235 | /** |
227 | * usb_alloc_dev - usb device constructor (usbcore-internal) | 236 | * usb_alloc_dev - usb device constructor (usbcore-internal) |
228 | * @parent: hub to which device is connected; null to allocate a root hub | 237 | * @parent: hub to which device is connected; null to allocate a root hub |
@@ -239,6 +248,8 @@ struct usb_device * | |||
239 | usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | 248 | usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) |
240 | { | 249 | { |
241 | struct usb_device *dev; | 250 | struct usb_device *dev; |
251 | struct usb_hcd *usb_hcd = container_of(bus, struct usb_hcd, self); | ||
252 | unsigned root_hub = 0; | ||
242 | 253 | ||
243 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | 254 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); |
244 | if (!dev) | 255 | if (!dev) |
@@ -255,12 +266,14 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | |||
255 | dev->dev.dma_mask = bus->controller->dma_mask; | 266 | dev->dev.dma_mask = bus->controller->dma_mask; |
256 | set_dev_node(&dev->dev, dev_to_node(bus->controller)); | 267 | set_dev_node(&dev->dev, dev_to_node(bus->controller)); |
257 | dev->state = USB_STATE_ATTACHED; | 268 | dev->state = USB_STATE_ATTACHED; |
269 | atomic_set(&dev->urbnum, 0); | ||
258 | 270 | ||
259 | INIT_LIST_HEAD(&dev->ep0.urb_list); | 271 | INIT_LIST_HEAD(&dev->ep0.urb_list); |
260 | dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE; | 272 | dev->ep0.desc.bLength = USB_DT_ENDPOINT_SIZE; |
261 | dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT; | 273 | dev->ep0.desc.bDescriptorType = USB_DT_ENDPOINT; |
262 | /* ep0 maxpacket comes later, from device descriptor */ | 274 | /* ep0 maxpacket comes later, from device descriptor */ |
263 | dev->ep_in[0] = dev->ep_out[0] = &dev->ep0; | 275 | usb_enable_endpoint(dev, &dev->ep0); |
276 | dev->can_submit = 1; | ||
264 | 277 | ||
265 | /* Save readable and stable topology id, distinguishing devices | 278 | /* Save readable and stable topology id, distinguishing devices |
266 | * by location for diagnostics, tools, driver model, etc. The | 279 | * by location for diagnostics, tools, driver model, etc. The |
@@ -275,6 +288,7 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | |||
275 | 288 | ||
276 | dev->dev.parent = bus->controller; | 289 | dev->dev.parent = bus->controller; |
277 | sprintf(&dev->dev.bus_id[0], "usb%d", bus->busnum); | 290 | sprintf(&dev->dev.bus_id[0], "usb%d", bus->busnum); |
291 | root_hub = 1; | ||
278 | } else { | 292 | } else { |
279 | /* match any labeling on the hubs; it's one-based */ | 293 | /* match any labeling on the hubs; it's one-based */ |
280 | if (parent->devpath[0] == '0') | 294 | if (parent->devpath[0] == '0') |
@@ -301,6 +315,12 @@ usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus, unsigned port1) | |||
301 | INIT_DELAYED_WORK(&dev->autosuspend, usb_autosuspend_work); | 315 | INIT_DELAYED_WORK(&dev->autosuspend, usb_autosuspend_work); |
302 | dev->autosuspend_delay = usb_autosuspend_delay * HZ; | 316 | dev->autosuspend_delay = usb_autosuspend_delay * HZ; |
303 | #endif | 317 | #endif |
318 | if (root_hub) /* Root hub always ok [and always wired] */ | ||
319 | dev->authorized = 1; | ||
320 | else { | ||
321 | dev->authorized = usb_hcd->authorized_default; | ||
322 | dev->wusb = usb_bus_is_wusb(bus)? 1 : 0; | ||
323 | } | ||
304 | return dev; | 324 | return dev; |
305 | } | 325 | } |
306 | 326 | ||
@@ -748,7 +768,7 @@ void usb_buffer_unmap(struct urb *urb) | |||
748 | /** | 768 | /** |
749 | * usb_buffer_map_sg - create scatterlist DMA mapping(s) for an endpoint | 769 | * usb_buffer_map_sg - create scatterlist DMA mapping(s) for an endpoint |
750 | * @dev: device to which the scatterlist will be mapped | 770 | * @dev: device to which the scatterlist will be mapped |
751 | * @pipe: endpoint defining the mapping direction | 771 | * @is_in: mapping transfer direction |
752 | * @sg: the scatterlist to map | 772 | * @sg: the scatterlist to map |
753 | * @nents: the number of entries in the scatterlist | 773 | * @nents: the number of entries in the scatterlist |
754 | * | 774 | * |
@@ -771,14 +791,13 @@ void usb_buffer_unmap(struct urb *urb) | |||
771 | * | 791 | * |
772 | * Reverse the effect of this call with usb_buffer_unmap_sg(). | 792 | * Reverse the effect of this call with usb_buffer_unmap_sg(). |
773 | */ | 793 | */ |
774 | int usb_buffer_map_sg(const struct usb_device *dev, unsigned pipe, | 794 | int usb_buffer_map_sg(const struct usb_device *dev, int is_in, |
775 | struct scatterlist *sg, int nents) | 795 | struct scatterlist *sg, int nents) |
776 | { | 796 | { |
777 | struct usb_bus *bus; | 797 | struct usb_bus *bus; |
778 | struct device *controller; | 798 | struct device *controller; |
779 | 799 | ||
780 | if (!dev | 800 | if (!dev |
781 | || usb_pipecontrol(pipe) | ||
782 | || !(bus = dev->bus) | 801 | || !(bus = dev->bus) |
783 | || !(controller = bus->controller) | 802 | || !(controller = bus->controller) |
784 | || !controller->dma_mask) | 803 | || !controller->dma_mask) |
@@ -786,7 +805,7 @@ int usb_buffer_map_sg(const struct usb_device *dev, unsigned pipe, | |||
786 | 805 | ||
787 | // FIXME generic api broken like pci, can't report errors | 806 | // FIXME generic api broken like pci, can't report errors |
788 | return dma_map_sg(controller, sg, nents, | 807 | return dma_map_sg(controller, sg, nents, |
789 | usb_pipein(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 808 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
790 | } | 809 | } |
791 | 810 | ||
792 | /* XXX DISABLED, no users currently. If you wish to re-enable this | 811 | /* XXX DISABLED, no users currently. If you wish to re-enable this |
@@ -799,14 +818,14 @@ int usb_buffer_map_sg(const struct usb_device *dev, unsigned pipe, | |||
799 | /** | 818 | /** |
800 | * usb_buffer_dmasync_sg - synchronize DMA and CPU view of scatterlist buffer(s) | 819 | * usb_buffer_dmasync_sg - synchronize DMA and CPU view of scatterlist buffer(s) |
801 | * @dev: device to which the scatterlist will be mapped | 820 | * @dev: device to which the scatterlist will be mapped |
802 | * @pipe: endpoint defining the mapping direction | 821 | * @is_in: mapping transfer direction |
803 | * @sg: the scatterlist to synchronize | 822 | * @sg: the scatterlist to synchronize |
804 | * @n_hw_ents: the positive return value from usb_buffer_map_sg | 823 | * @n_hw_ents: the positive return value from usb_buffer_map_sg |
805 | * | 824 | * |
806 | * Use this when you are re-using a scatterlist's data buffers for | 825 | * Use this when you are re-using a scatterlist's data buffers for |
807 | * another USB request. | 826 | * another USB request. |
808 | */ | 827 | */ |
809 | void usb_buffer_dmasync_sg(const struct usb_device *dev, unsigned pipe, | 828 | void usb_buffer_dmasync_sg(const struct usb_device *dev, int is_in, |
810 | struct scatterlist *sg, int n_hw_ents) | 829 | struct scatterlist *sg, int n_hw_ents) |
811 | { | 830 | { |
812 | struct usb_bus *bus; | 831 | struct usb_bus *bus; |
@@ -819,20 +838,20 @@ void usb_buffer_dmasync_sg(const struct usb_device *dev, unsigned pipe, | |||
819 | return; | 838 | return; |
820 | 839 | ||
821 | dma_sync_sg(controller, sg, n_hw_ents, | 840 | dma_sync_sg(controller, sg, n_hw_ents, |
822 | usb_pipein(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 841 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
823 | } | 842 | } |
824 | #endif | 843 | #endif |
825 | 844 | ||
826 | /** | 845 | /** |
827 | * usb_buffer_unmap_sg - free DMA mapping(s) for a scatterlist | 846 | * usb_buffer_unmap_sg - free DMA mapping(s) for a scatterlist |
828 | * @dev: device to which the scatterlist will be mapped | 847 | * @dev: device to which the scatterlist will be mapped |
829 | * @pipe: endpoint defining the mapping direction | 848 | * @is_in: mapping transfer direction |
830 | * @sg: the scatterlist to unmap | 849 | * @sg: the scatterlist to unmap |
831 | * @n_hw_ents: the positive return value from usb_buffer_map_sg | 850 | * @n_hw_ents: the positive return value from usb_buffer_map_sg |
832 | * | 851 | * |
833 | * Reverses the effect of usb_buffer_map_sg(). | 852 | * Reverses the effect of usb_buffer_map_sg(). |
834 | */ | 853 | */ |
835 | void usb_buffer_unmap_sg(const struct usb_device *dev, unsigned pipe, | 854 | void usb_buffer_unmap_sg(const struct usb_device *dev, int is_in, |
836 | struct scatterlist *sg, int n_hw_ents) | 855 | struct scatterlist *sg, int n_hw_ents) |
837 | { | 856 | { |
838 | struct usb_bus *bus; | 857 | struct usb_bus *bus; |
@@ -845,7 +864,7 @@ void usb_buffer_unmap_sg(const struct usb_device *dev, unsigned pipe, | |||
845 | return; | 864 | return; |
846 | 865 | ||
847 | dma_unmap_sg(controller, sg, n_hw_ents, | 866 | dma_unmap_sg(controller, sg, n_hw_ents, |
848 | usb_pipein(pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); | 867 | is_in ? DMA_FROM_DEVICE : DMA_TO_DEVICE); |
849 | } | 868 | } |
850 | 869 | ||
851 | /* format to disable USB on kernel command line is: nousb */ | 870 | /* format to disable USB on kernel command line is: nousb */ |
diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index ad5fa0338f4..c52626c51f7 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h | |||
@@ -8,17 +8,22 @@ extern int usb_create_ep_files(struct device *parent, struct usb_host_endpoint * | |||
8 | struct usb_device *udev); | 8 | struct usb_device *udev); |
9 | extern void usb_remove_ep_files(struct usb_host_endpoint *endpoint); | 9 | extern void usb_remove_ep_files(struct usb_host_endpoint *endpoint); |
10 | 10 | ||
11 | extern void usb_enable_endpoint(struct usb_device *dev, | ||
12 | struct usb_host_endpoint *ep); | ||
11 | extern void usb_disable_endpoint (struct usb_device *dev, unsigned int epaddr); | 13 | extern void usb_disable_endpoint (struct usb_device *dev, unsigned int epaddr); |
12 | extern void usb_disable_interface (struct usb_device *dev, | 14 | extern void usb_disable_interface (struct usb_device *dev, |
13 | struct usb_interface *intf); | 15 | struct usb_interface *intf); |
14 | extern void usb_release_interface_cache(struct kref *ref); | 16 | extern void usb_release_interface_cache(struct kref *ref); |
15 | extern void usb_disable_device (struct usb_device *dev, int skip_ep0); | 17 | extern void usb_disable_device (struct usb_device *dev, int skip_ep0); |
18 | extern int usb_deauthorize_device (struct usb_device *); | ||
19 | extern int usb_authorize_device (struct usb_device *); | ||
16 | extern void usb_detect_quirks(struct usb_device *udev); | 20 | extern void usb_detect_quirks(struct usb_device *udev); |
17 | 21 | ||
18 | extern int usb_get_device_descriptor(struct usb_device *dev, | 22 | extern int usb_get_device_descriptor(struct usb_device *dev, |
19 | unsigned int size); | 23 | unsigned int size); |
20 | extern char *usb_cache_string(struct usb_device *udev, int index); | 24 | extern char *usb_cache_string(struct usb_device *udev, int index); |
21 | extern int usb_set_configuration(struct usb_device *dev, int configuration); | 25 | extern int usb_set_configuration(struct usb_device *dev, int configuration); |
26 | extern int usb_choose_configuration(struct usb_device *udev); | ||
22 | 27 | ||
23 | extern void usb_kick_khubd(struct usb_device *dev); | 28 | extern void usb_kick_khubd(struct usb_device *dev); |
24 | extern int usb_match_device(struct usb_device *dev, | 29 | extern int usb_match_device(struct usb_device *dev, |
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index 45e01e28945..f81d08d6538 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -67,6 +67,17 @@ config USB_GADGET_DEBUG_FILES | |||
67 | driver on a new board. Enable these files by choosing "Y" | 67 | driver on a new board. Enable these files by choosing "Y" |
68 | here. If in doubt, or to conserve kernel memory, say "N". | 68 | here. If in doubt, or to conserve kernel memory, say "N". |
69 | 69 | ||
70 | config USB_GADGET_DEBUG_FS | ||
71 | boolean "Debugging information files in debugfs" | ||
72 | depends on USB_GADGET && DEBUG_FS | ||
73 | help | ||
74 | Some of the drivers in the "gadget" framework can expose | ||
75 | debugging information in files under /sys/kernel/debug/. | ||
76 | The information in these files may help when you're | ||
77 | troubleshooting or bringing up a driver on a new board. | ||
78 | Enable these files by choosing "Y" here. If in doubt, or | ||
79 | to conserve kernel memory, say "N". | ||
80 | |||
70 | config USB_GADGET_SELECTED | 81 | config USB_GADGET_SELECTED |
71 | boolean | 82 | boolean |
72 | 83 | ||
@@ -82,6 +93,41 @@ choice | |||
82 | Many controller drivers are platform-specific; these | 93 | Many controller drivers are platform-specific; these |
83 | often need board-specific hooks. | 94 | often need board-specific hooks. |
84 | 95 | ||
96 | config USB_GADGET_AMD5536UDC | ||
97 | boolean "AMD5536 UDC" | ||
98 | depends on PCI | ||
99 | select USB_GADGET_DUALSPEED | ||
100 | help | ||
101 | The AMD5536 UDC is part of the AMD Geode CS5536, an x86 southbridge. | ||
102 | It is a USB Highspeed DMA capable USB device controller. Beside ep0 | ||
103 | it provides 4 IN and 4 OUT endpoints (bulk or interrupt type). | ||
104 | The UDC port supports OTG operation, and may be used as a host port | ||
105 | if it's not being used to implement peripheral or OTG roles. | ||
106 | |||
107 | Say "y" to link the driver statically, or "m" to build a | ||
108 | dynamically linked module called "amd5536udc" and force all | ||
109 | gadget drivers to also be dynamically linked. | ||
110 | |||
111 | config USB_AMD5536UDC | ||
112 | tristate | ||
113 | depends on USB_GADGET_AMD5536UDC | ||
114 | default USB_GADGET | ||
115 | select USB_GADGET_SELECTED | ||
116 | |||
117 | config USB_GADGET_ATMEL_USBA | ||
118 | boolean "Atmel USBA" | ||
119 | select USB_GADGET_DUALSPEED | ||
120 | depends on AVR32 | ||
121 | help | ||
122 | USBA is the integrated high-speed USB Device controller on | ||
123 | the AT32AP700x processors from Atmel. | ||
124 | |||
125 | config USB_ATMEL_USBA | ||
126 | tristate | ||
127 | depends on USB_GADGET_ATMEL_USBA | ||
128 | default USB_GADGET | ||
129 | select USB_GADGET_SELECTED | ||
130 | |||
85 | config USB_GADGET_FSL_USB2 | 131 | config USB_GADGET_FSL_USB2 |
86 | boolean "Freescale Highspeed USB DR Peripheral Controller" | 132 | boolean "Freescale Highspeed USB DR Peripheral Controller" |
87 | depends on MPC834x || PPC_MPC831x | 133 | depends on MPC834x || PPC_MPC831x |
@@ -156,6 +202,24 @@ config USB_PXA2XX_SMALL | |||
156 | default y if USB_ETH | 202 | default y if USB_ETH |
157 | default y if USB_G_SERIAL | 203 | default y if USB_G_SERIAL |
158 | 204 | ||
205 | config USB_GADGET_M66592 | ||
206 | boolean "Renesas M66592 USB Peripheral Controller" | ||
207 | select USB_GADGET_DUALSPEED | ||
208 | help | ||
209 | M66592 is a discrete USB peripheral controller chip that | ||
210 | supports both full and high speed USB 2.0 data transfers. | ||
211 | It has seven configurable endpoints, and endpoint zero. | ||
212 | |||
213 | Say "y" to link the driver statically, or "m" to build a | ||
214 | dynamically linked module called "m66592_udc" and force all | ||
215 | gadget drivers to also be dynamically linked. | ||
216 | |||
217 | config USB_M66592 | ||
218 | tristate | ||
219 | depends on USB_GADGET_M66592 | ||
220 | default USB_GADGET | ||
221 | select USB_GADGET_SELECTED | ||
222 | |||
159 | config USB_GADGET_GOKU | 223 | config USB_GADGET_GOKU |
160 | boolean "Toshiba TC86C001 'Goku-S'" | 224 | boolean "Toshiba TC86C001 'Goku-S'" |
161 | depends on PCI | 225 | depends on PCI |
@@ -189,7 +253,6 @@ config USB_LH7A40X | |||
189 | default USB_GADGET | 253 | default USB_GADGET |
190 | select USB_GADGET_SELECTED | 254 | select USB_GADGET_SELECTED |
191 | 255 | ||
192 | |||
193 | config USB_GADGET_OMAP | 256 | config USB_GADGET_OMAP |
194 | boolean "OMAP USB Device Controller" | 257 | boolean "OMAP USB Device Controller" |
195 | depends on ARCH_OMAP | 258 | depends on ARCH_OMAP |
@@ -261,24 +324,6 @@ config USB_AT91 | |||
261 | depends on USB_GADGET_AT91 | 324 | depends on USB_GADGET_AT91 |
262 | default USB_GADGET | 325 | default USB_GADGET |
263 | 326 | ||
264 | config USB_GADGET_M66592 | ||
265 | boolean "M66592 driver" | ||
266 | select USB_GADGET_DUALSPEED | ||
267 | help | ||
268 | M66592 is a USB 2.0 peripheral controller. | ||
269 | |||
270 | It has seven configurable endpoints, and endpoint zero. | ||
271 | |||
272 | Say "y" to link the driver statically, or "m" to build a | ||
273 | dynamically linked module called "m66592_udc" and force all | ||
274 | gadget drivers to also be dynamically linked. | ||
275 | |||
276 | config USB_M66592 | ||
277 | tristate | ||
278 | depends on USB_GADGET_M66592 | ||
279 | default USB_GADGET | ||
280 | select USB_GADGET_SELECTED | ||
281 | |||
282 | config USB_GADGET_DUMMY_HCD | 327 | config USB_GADGET_DUMMY_HCD |
283 | boolean "Dummy HCD (DEVELOPMENT)" | 328 | boolean "Dummy HCD (DEVELOPMENT)" |
284 | depends on (USB=y || (USB=m && USB_GADGET=m)) && EXPERIMENTAL | 329 | depends on (USB=y || (USB=m && USB_GADGET=m)) && EXPERIMENTAL |
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 8ae76f73863..904e57bf611 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile | |||
@@ -7,12 +7,14 @@ endif | |||
7 | 7 | ||
8 | obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o | 8 | obj-$(CONFIG_USB_DUMMY_HCD) += dummy_hcd.o |
9 | obj-$(CONFIG_USB_NET2280) += net2280.o | 9 | obj-$(CONFIG_USB_NET2280) += net2280.o |
10 | obj-$(CONFIG_USB_AMD5536UDC) += amd5536udc.o | ||
10 | obj-$(CONFIG_USB_PXA2XX) += pxa2xx_udc.o | 11 | obj-$(CONFIG_USB_PXA2XX) += pxa2xx_udc.o |
11 | obj-$(CONFIG_USB_GOKU) += goku_udc.o | 12 | obj-$(CONFIG_USB_GOKU) += goku_udc.o |
12 | obj-$(CONFIG_USB_OMAP) += omap_udc.o | 13 | obj-$(CONFIG_USB_OMAP) += omap_udc.o |
13 | obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o | 14 | obj-$(CONFIG_USB_LH7A40X) += lh7a40x_udc.o |
14 | obj-$(CONFIG_USB_S3C2410) += s3c2410_udc.o | 15 | obj-$(CONFIG_USB_S3C2410) += s3c2410_udc.o |
15 | obj-$(CONFIG_USB_AT91) += at91_udc.o | 16 | obj-$(CONFIG_USB_AT91) += at91_udc.o |
17 | obj-$(CONFIG_USB_ATMEL_USBA) += atmel_usba_udc.o | ||
16 | obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o | 18 | obj-$(CONFIG_USB_FSL_USB2) += fsl_usb2_udc.o |
17 | obj-$(CONFIG_USB_M66592) += m66592-udc.o | 19 | obj-$(CONFIG_USB_M66592) += m66592-udc.o |
18 | 20 | ||
diff --git a/drivers/usb/gadget/amd5536udc.c b/drivers/usb/gadget/amd5536udc.c new file mode 100644 index 00000000000..1c804060252 --- /dev/null +++ b/drivers/usb/gadget/amd5536udc.c | |||
@@ -0,0 +1,3451 @@ | |||
1 | /* | ||
2 | * amd5536.c -- AMD 5536 UDC high/full speed USB device controller | ||
3 | * | ||
4 | * Copyright (C) 2005-2007 AMD (http://www.amd.com) | ||
5 | * Author: Thomas Dahlmann | ||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | /* | ||
23 | * The AMD5536 UDC is part of the x86 southbridge AMD Geode CS5536. | ||
24 | * It is a USB Highspeed DMA capable USB device controller. Beside ep0 it | ||
25 | * provides 4 IN and 4 OUT endpoints (bulk or interrupt type). | ||
26 | * | ||
27 | * Make sure that UDC is assigned to port 4 by BIOS settings (port can also | ||
28 | * be used as host port) and UOC bits PAD_EN and APU are set (should be done | ||
29 | * by BIOS init). | ||
30 | * | ||
31 | * UDC DMA requires 32-bit aligned buffers so DMA with gadget ether does not | ||
32 | * work without updating NET_IP_ALIGN. Or PIO mode (module param "use_dma=0") | ||
33 | * can be used with gadget ether. | ||
34 | */ | ||
35 | |||
36 | /* debug control */ | ||
37 | /* #define UDC_VERBOSE */ | ||
38 | |||
39 | /* Driver strings */ | ||
40 | #define UDC_MOD_DESCRIPTION "AMD 5536 UDC - USB Device Controller" | ||
41 | #define UDC_DRIVER_VERSION_STRING "01.00.0206 - $Revision: #3 $" | ||
42 | |||
43 | /* system */ | ||
44 | #include <linux/module.h> | ||
45 | #include <linux/pci.h> | ||
46 | #include <linux/kernel.h> | ||
47 | #include <linux/version.h> | ||
48 | #include <linux/delay.h> | ||
49 | #include <linux/ioport.h> | ||
50 | #include <linux/sched.h> | ||
51 | #include <linux/slab.h> | ||
52 | #include <linux/smp_lock.h> | ||
53 | #include <linux/errno.h> | ||
54 | #include <linux/init.h> | ||
55 | #include <linux/timer.h> | ||
56 | #include <linux/list.h> | ||
57 | #include <linux/interrupt.h> | ||
58 | #include <linux/ioctl.h> | ||
59 | #include <linux/fs.h> | ||
60 | #include <linux/dmapool.h> | ||
61 | #include <linux/moduleparam.h> | ||
62 | #include <linux/device.h> | ||
63 | #include <linux/io.h> | ||
64 | #include <linux/irq.h> | ||
65 | |||
66 | #include <asm/byteorder.h> | ||
67 | #include <asm/system.h> | ||
68 | #include <asm/unaligned.h> | ||
69 | |||
70 | /* gadget stack */ | ||
71 | #include <linux/usb/ch9.h> | ||
72 | #include <linux/usb/gadget.h> | ||
73 | |||
74 | /* udc specific */ | ||
75 | #include "amd5536udc.h" | ||
76 | |||
77 | |||
78 | static void udc_tasklet_disconnect(unsigned long); | ||
79 | static void empty_req_queue(struct udc_ep *); | ||
80 | static int udc_probe(struct udc *dev); | ||
81 | static void udc_basic_init(struct udc *dev); | ||
82 | static void udc_setup_endpoints(struct udc *dev); | ||
83 | static void udc_soft_reset(struct udc *dev); | ||
84 | static struct udc_request *udc_alloc_bna_dummy(struct udc_ep *ep); | ||
85 | static void udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq); | ||
86 | static int udc_free_dma_chain(struct udc *dev, struct udc_request *req); | ||
87 | static int udc_create_dma_chain(struct udc_ep *ep, struct udc_request *req, | ||
88 | unsigned long buf_len, gfp_t gfp_flags); | ||
89 | static int udc_remote_wakeup(struct udc *dev); | ||
90 | static int udc_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id); | ||
91 | static void udc_pci_remove(struct pci_dev *pdev); | ||
92 | |||
93 | /* description */ | ||
94 | static const char mod_desc[] = UDC_MOD_DESCRIPTION; | ||
95 | static const char name[] = "amd5536udc"; | ||
96 | |||
97 | /* structure to hold endpoint function pointers */ | ||
98 | static const struct usb_ep_ops udc_ep_ops; | ||
99 | |||
100 | /* received setup data */ | ||
101 | static union udc_setup_data setup_data; | ||
102 | |||
103 | /* pointer to device object */ | ||
104 | static struct udc *udc; | ||
105 | |||
106 | /* irq spin lock for soft reset */ | ||
107 | static DEFINE_SPINLOCK(udc_irq_spinlock); | ||
108 | /* stall spin lock */ | ||
109 | static DEFINE_SPINLOCK(udc_stall_spinlock); | ||
110 | |||
111 | /* | ||
112 | * slave mode: pending bytes in rx fifo after nyet, | ||
113 | * used if EPIN irq came but no req was available | ||
114 | */ | ||
115 | static unsigned int udc_rxfifo_pending; | ||
116 | |||
117 | /* count soft resets after suspend to avoid loop */ | ||
118 | static int soft_reset_occured; | ||
119 | static int soft_reset_after_usbreset_occured; | ||
120 | |||
121 | /* timer */ | ||
122 | static struct timer_list udc_timer; | ||
123 | static int stop_timer; | ||
124 | |||
125 | /* set_rde -- Is used to control enabling of RX DMA. Problem is | ||
126 | * that UDC has only one bit (RDE) to enable/disable RX DMA for | ||
127 | * all OUT endpoints. So we have to handle race conditions like | ||
128 | * when OUT data reaches the fifo but no request was queued yet. | ||
129 | * This cannot be solved by letting the RX DMA disabled until a | ||
130 | * request gets queued because there may be other OUT packets | ||
131 | * in the FIFO (important for not blocking control traffic). | ||
132 | * The value of set_rde controls the correspondig timer. | ||
133 | * | ||
134 | * set_rde -1 == not used, means it is alloed to be set to 0 or 1 | ||
135 | * set_rde 0 == do not touch RDE, do no start the RDE timer | ||
136 | * set_rde 1 == timer function will look whether FIFO has data | ||
137 | * set_rde 2 == set by timer function to enable RX DMA on next call | ||
138 | */ | ||
139 | static int set_rde = -1; | ||
140 | |||
141 | static DECLARE_COMPLETION(on_exit); | ||
142 | static struct timer_list udc_pollstall_timer; | ||
143 | static int stop_pollstall_timer; | ||
144 | static DECLARE_COMPLETION(on_pollstall_exit); | ||
145 | |||
146 | /* tasklet for usb disconnect */ | ||
147 | static DECLARE_TASKLET(disconnect_tasklet, udc_tasklet_disconnect, | ||
148 | (unsigned long) &udc); | ||
149 | |||
150 | |||
151 | /* endpoint names used for print */ | ||
152 | static const char ep0_string[] = "ep0in"; | ||
153 | static const char *ep_string[] = { | ||
154 | ep0_string, | ||
155 | "ep1in-int", "ep2in-bulk", "ep3in-bulk", "ep4in-bulk", "ep5in-bulk", | ||
156 | "ep6in-bulk", "ep7in-bulk", "ep8in-bulk", "ep9in-bulk", "ep10in-bulk", | ||
157 | "ep11in-bulk", "ep12in-bulk", "ep13in-bulk", "ep14in-bulk", | ||
158 | "ep15in-bulk", "ep0out", "ep1out-bulk", "ep2out-bulk", "ep3out-bulk", | ||
159 | "ep4out-bulk", "ep5out-bulk", "ep6out-bulk", "ep7out-bulk", | ||
160 | "ep8out-bulk", "ep9out-bulk", "ep10out-bulk", "ep11out-bulk", | ||
161 | "ep12out-bulk", "ep13out-bulk", "ep14out-bulk", "ep15out-bulk" | ||
162 | }; | ||
163 | |||
164 | /* DMA usage flag */ | ||
165 | static int use_dma = 1; | ||
166 | /* packet per buffer dma */ | ||
167 | static int use_dma_ppb = 1; | ||
168 | /* with per descr. update */ | ||
169 | static int use_dma_ppb_du; | ||
170 | /* buffer fill mode */ | ||
171 | static int use_dma_bufferfill_mode; | ||
172 | /* full speed only mode */ | ||
173 | static int use_fullspeed; | ||
174 | /* tx buffer size for high speed */ | ||
175 | static unsigned long hs_tx_buf = UDC_EPIN_BUFF_SIZE; | ||
176 | |||
177 | /* module parameters */ | ||
178 | module_param(use_dma, bool, S_IRUGO); | ||
179 | MODULE_PARM_DESC(use_dma, "true for DMA"); | ||
180 | module_param(use_dma_ppb, bool, S_IRUGO); | ||
181 | MODULE_PARM_DESC(use_dma_ppb, "true for DMA in packet per buffer mode"); | ||
182 | module_param(use_dma_ppb_du, bool, S_IRUGO); | ||
183 | MODULE_PARM_DESC(use_dma_ppb_du, | ||
184 | "true for DMA in packet per buffer mode with descriptor update"); | ||
185 | module_param(use_fullspeed, bool, S_IRUGO); | ||
186 | MODULE_PARM_DESC(use_fullspeed, "true for fullspeed only"); | ||
187 | |||
188 | /*---------------------------------------------------------------------------*/ | ||
189 | /* Prints UDC device registers and endpoint irq registers */ | ||
190 | static void print_regs(struct udc *dev) | ||
191 | { | ||
192 | DBG(dev, "------- Device registers -------\n"); | ||
193 | DBG(dev, "dev config = %08x\n", readl(&dev->regs->cfg)); | ||
194 | DBG(dev, "dev control = %08x\n", readl(&dev->regs->ctl)); | ||
195 | DBG(dev, "dev status = %08x\n", readl(&dev->regs->sts)); | ||
196 | DBG(dev, "\n"); | ||
197 | DBG(dev, "dev int's = %08x\n", readl(&dev->regs->irqsts)); | ||
198 | DBG(dev, "dev intmask = %08x\n", readl(&dev->regs->irqmsk)); | ||
199 | DBG(dev, "\n"); | ||
200 | DBG(dev, "dev ep int's = %08x\n", readl(&dev->regs->ep_irqsts)); | ||
201 | DBG(dev, "dev ep intmask = %08x\n", readl(&dev->regs->ep_irqmsk)); | ||
202 | DBG(dev, "\n"); | ||
203 | DBG(dev, "USE DMA = %d\n", use_dma); | ||
204 | if (use_dma && use_dma_ppb && !use_dma_ppb_du) { | ||
205 | DBG(dev, "DMA mode = PPBNDU (packet per buffer " | ||
206 | "WITHOUT desc. update)\n"); | ||
207 | dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "PPBNDU"); | ||
208 | } else if (use_dma && use_dma_ppb_du && use_dma_ppb_du) { | ||
209 | DBG(dev, "DMA mode = PPBDU (packet per buffer " | ||
210 | "WITH desc. update)\n"); | ||
211 | dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "PPBDU"); | ||
212 | } | ||
213 | if (use_dma && use_dma_bufferfill_mode) { | ||
214 | DBG(dev, "DMA mode = BF (buffer fill mode)\n"); | ||
215 | dev_info(&dev->pdev->dev, "DMA mode (%s)\n", "BF"); | ||
216 | } | ||
217 | if (!use_dma) { | ||
218 | dev_info(&dev->pdev->dev, "FIFO mode\n"); | ||
219 | } | ||
220 | DBG(dev, "-------------------------------------------------------\n"); | ||
221 | } | ||
222 | |||
223 | /* Masks unused interrupts */ | ||
224 | static int udc_mask_unused_interrupts(struct udc *dev) | ||
225 | { | ||
226 | u32 tmp; | ||
227 | |||
228 | /* mask all dev interrupts */ | ||
229 | tmp = AMD_BIT(UDC_DEVINT_SVC) | | ||
230 | AMD_BIT(UDC_DEVINT_ENUM) | | ||
231 | AMD_BIT(UDC_DEVINT_US) | | ||
232 | AMD_BIT(UDC_DEVINT_UR) | | ||
233 | AMD_BIT(UDC_DEVINT_ES) | | ||
234 | AMD_BIT(UDC_DEVINT_SI) | | ||
235 | AMD_BIT(UDC_DEVINT_SOF)| | ||
236 | AMD_BIT(UDC_DEVINT_SC); | ||
237 | writel(tmp, &dev->regs->irqmsk); | ||
238 | |||
239 | /* mask all ep interrupts */ | ||
240 | writel(UDC_EPINT_MSK_DISABLE_ALL, &dev->regs->ep_irqmsk); | ||
241 | |||
242 | return 0; | ||
243 | } | ||
244 | |||
245 | /* Enables endpoint 0 interrupts */ | ||
246 | static int udc_enable_ep0_interrupts(struct udc *dev) | ||
247 | { | ||
248 | u32 tmp; | ||
249 | |||
250 | DBG(dev, "udc_enable_ep0_interrupts()\n"); | ||
251 | |||
252 | /* read irq mask */ | ||
253 | tmp = readl(&dev->regs->ep_irqmsk); | ||
254 | /* enable ep0 irq's */ | ||
255 | tmp &= AMD_UNMASK_BIT(UDC_EPINT_IN_EP0) | ||
256 | & AMD_UNMASK_BIT(UDC_EPINT_OUT_EP0); | ||
257 | writel(tmp, &dev->regs->ep_irqmsk); | ||
258 | |||
259 | return 0; | ||
260 | } | ||
261 | |||
262 | /* Enables device interrupts for SET_INTF and SET_CONFIG */ | ||
263 | static int udc_enable_dev_setup_interrupts(struct udc *dev) | ||
264 | { | ||
265 | u32 tmp; | ||
266 | |||
267 | DBG(dev, "enable device interrupts for setup data\n"); | ||
268 | |||
269 | /* read irq mask */ | ||
270 | tmp = readl(&dev->regs->irqmsk); | ||
271 | |||
272 | /* enable SET_INTERFACE, SET_CONFIG and other needed irq's */ | ||
273 | tmp &= AMD_UNMASK_BIT(UDC_DEVINT_SI) | ||
274 | & AMD_UNMASK_BIT(UDC_DEVINT_SC) | ||
275 | & AMD_UNMASK_BIT(UDC_DEVINT_UR) | ||
276 | & AMD_UNMASK_BIT(UDC_DEVINT_SVC) | ||
277 | & AMD_UNMASK_BIT(UDC_DEVINT_ENUM); | ||
278 | writel(tmp, &dev->regs->irqmsk); | ||
279 | |||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | /* Calculates fifo start of endpoint based on preceeding endpoints */ | ||
284 | static int udc_set_txfifo_addr(struct udc_ep *ep) | ||
285 | { | ||
286 | struct udc *dev; | ||
287 | u32 tmp; | ||
288 | int i; | ||
289 | |||
290 | if (!ep || !(ep->in)) | ||
291 | return -EINVAL; | ||
292 | |||
293 | dev = ep->dev; | ||
294 | ep->txfifo = dev->txfifo; | ||
295 | |||
296 | /* traverse ep's */ | ||
297 | for (i = 0; i < ep->num; i++) { | ||
298 | if (dev->ep[i].regs) { | ||
299 | /* read fifo size */ | ||
300 | tmp = readl(&dev->ep[i].regs->bufin_framenum); | ||
301 | tmp = AMD_GETBITS(tmp, UDC_EPIN_BUFF_SIZE); | ||
302 | ep->txfifo += tmp; | ||
303 | } | ||
304 | } | ||
305 | return 0; | ||
306 | } | ||
307 | |||
308 | /* CNAK pending field: bit0 = ep0in, bit16 = ep0out */ | ||
309 | static u32 cnak_pending; | ||
310 | |||
311 | static void UDC_QUEUE_CNAK(struct udc_ep *ep, unsigned num) | ||
312 | { | ||
313 | if (readl(&ep->regs->ctl) & AMD_BIT(UDC_EPCTL_NAK)) { | ||
314 | DBG(ep->dev, "NAK could not be cleared for ep%d\n", num); | ||
315 | cnak_pending |= 1 << (num); | ||
316 | ep->naking = 1; | ||
317 | } else | ||
318 | cnak_pending = cnak_pending & (~(1 << (num))); | ||
319 | } | ||
320 | |||
321 | |||
322 | /* Enables endpoint, is called by gadget driver */ | ||
323 | static int | ||
324 | udc_ep_enable(struct usb_ep *usbep, const struct usb_endpoint_descriptor *desc) | ||
325 | { | ||
326 | struct udc_ep *ep; | ||
327 | struct udc *dev; | ||
328 | u32 tmp; | ||
329 | unsigned long iflags; | ||
330 | u8 udc_csr_epix; | ||
331 | |||
332 | if (!usbep | ||
333 | || usbep->name == ep0_string | ||
334 | || !desc | ||
335 | || desc->bDescriptorType != USB_DT_ENDPOINT) | ||
336 | return -EINVAL; | ||
337 | |||
338 | ep = container_of(usbep, struct udc_ep, ep); | ||
339 | dev = ep->dev; | ||
340 | |||
341 | DBG(dev, "udc_ep_enable() ep %d\n", ep->num); | ||
342 | |||
343 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
344 | return -ESHUTDOWN; | ||
345 | |||
346 | spin_lock_irqsave(&dev->lock, iflags); | ||
347 | ep->desc = desc; | ||
348 | |||
349 | ep->halted = 0; | ||
350 | |||
351 | /* set traffic type */ | ||
352 | tmp = readl(&dev->ep[ep->num].regs->ctl); | ||
353 | tmp = AMD_ADDBITS(tmp, desc->bmAttributes, UDC_EPCTL_ET); | ||
354 | writel(tmp, &dev->ep[ep->num].regs->ctl); | ||
355 | |||
356 | /* set max packet size */ | ||
357 | tmp = readl(&dev->ep[ep->num].regs->bufout_maxpkt); | ||
358 | tmp = AMD_ADDBITS(tmp, desc->wMaxPacketSize, UDC_EP_MAX_PKT_SIZE); | ||
359 | ep->ep.maxpacket = desc->wMaxPacketSize; | ||
360 | writel(tmp, &dev->ep[ep->num].regs->bufout_maxpkt); | ||
361 | |||
362 | /* IN ep */ | ||
363 | if (ep->in) { | ||
364 | |||
365 | /* ep ix in UDC CSR register space */ | ||
366 | udc_csr_epix = ep->num; | ||
367 | |||
368 | /* set buffer size (tx fifo entries) */ | ||
369 | tmp = readl(&dev->ep[ep->num].regs->bufin_framenum); | ||
370 | /* double buffering: fifo size = 2 x max packet size */ | ||
371 | tmp = AMD_ADDBITS( | ||
372 | tmp, | ||
373 | desc->wMaxPacketSize * UDC_EPIN_BUFF_SIZE_MULT | ||
374 | / UDC_DWORD_BYTES, | ||
375 | UDC_EPIN_BUFF_SIZE); | ||
376 | writel(tmp, &dev->ep[ep->num].regs->bufin_framenum); | ||
377 | |||
378 | /* calc. tx fifo base addr */ | ||
379 | udc_set_txfifo_addr(ep); | ||
380 | |||
381 | /* flush fifo */ | ||
382 | tmp = readl(&ep->regs->ctl); | ||
383 | tmp |= AMD_BIT(UDC_EPCTL_F); | ||
384 | writel(tmp, &ep->regs->ctl); | ||
385 | |||
386 | /* OUT ep */ | ||
387 | } else { | ||
388 | /* ep ix in UDC CSR register space */ | ||
389 | udc_csr_epix = ep->num - UDC_CSR_EP_OUT_IX_OFS; | ||
390 | |||
391 | /* set max packet size UDC CSR */ | ||
392 | tmp = readl(&dev->csr->ne[ep->num - UDC_CSR_EP_OUT_IX_OFS]); | ||
393 | tmp = AMD_ADDBITS(tmp, desc->wMaxPacketSize, | ||
394 | UDC_CSR_NE_MAX_PKT); | ||
395 | writel(tmp, &dev->csr->ne[ep->num - UDC_CSR_EP_OUT_IX_OFS]); | ||
396 | |||
397 | if (use_dma && !ep->in) { | ||
398 | /* alloc and init BNA dummy request */ | ||
399 | ep->bna_dummy_req = udc_alloc_bna_dummy(ep); | ||
400 | ep->bna_occurred = 0; | ||
401 | } | ||
402 | |||
403 | if (ep->num != UDC_EP0OUT_IX) | ||
404 | dev->data_ep_enabled = 1; | ||
405 | } | ||
406 | |||
407 | /* set ep values */ | ||
408 | tmp = readl(&dev->csr->ne[udc_csr_epix]); | ||
409 | /* max packet */ | ||
410 | tmp = AMD_ADDBITS(tmp, desc->wMaxPacketSize, UDC_CSR_NE_MAX_PKT); | ||
411 | /* ep number */ | ||
412 | tmp = AMD_ADDBITS(tmp, desc->bEndpointAddress, UDC_CSR_NE_NUM); | ||
413 | /* ep direction */ | ||
414 | tmp = AMD_ADDBITS(tmp, ep->in, UDC_CSR_NE_DIR); | ||
415 | /* ep type */ | ||
416 | tmp = AMD_ADDBITS(tmp, desc->bmAttributes, UDC_CSR_NE_TYPE); | ||
417 | /* ep config */ | ||
418 | tmp = AMD_ADDBITS(tmp, ep->dev->cur_config, UDC_CSR_NE_CFG); | ||
419 | /* ep interface */ | ||
420 | tmp = AMD_ADDBITS(tmp, ep->dev->cur_intf, UDC_CSR_NE_INTF); | ||
421 | /* ep alt */ | ||
422 | tmp = AMD_ADDBITS(tmp, ep->dev->cur_alt, UDC_CSR_NE_ALT); | ||
423 | /* write reg */ | ||
424 | writel(tmp, &dev->csr->ne[udc_csr_epix]); | ||
425 | |||
426 | /* enable ep irq */ | ||
427 | tmp = readl(&dev->regs->ep_irqmsk); | ||
428 | tmp &= AMD_UNMASK_BIT(ep->num); | ||
429 | writel(tmp, &dev->regs->ep_irqmsk); | ||
430 | |||
431 | /* | ||
432 | * clear NAK by writing CNAK | ||
433 | * avoid BNA for OUT DMA, don't clear NAK until DMA desc. written | ||
434 | */ | ||
435 | if (!use_dma || ep->in) { | ||
436 | tmp = readl(&ep->regs->ctl); | ||
437 | tmp |= AMD_BIT(UDC_EPCTL_CNAK); | ||
438 | writel(tmp, &ep->regs->ctl); | ||
439 | ep->naking = 0; | ||
440 | UDC_QUEUE_CNAK(ep, ep->num); | ||
441 | } | ||
442 | tmp = desc->bEndpointAddress; | ||
443 | DBG(dev, "%s enabled\n", usbep->name); | ||
444 | |||
445 | spin_unlock_irqrestore(&dev->lock, iflags); | ||
446 | return 0; | ||
447 | } | ||
448 | |||
449 | /* Resets endpoint */ | ||
450 | static void ep_init(struct udc_regs __iomem *regs, struct udc_ep *ep) | ||
451 | { | ||
452 | u32 tmp; | ||
453 | |||
454 | VDBG(ep->dev, "ep-%d reset\n", ep->num); | ||
455 | ep->desc = NULL; | ||
456 | ep->ep.ops = &udc_ep_ops; | ||
457 | INIT_LIST_HEAD(&ep->queue); | ||
458 | |||
459 | ep->ep.maxpacket = (u16) ~0; | ||
460 | /* set NAK */ | ||
461 | tmp = readl(&ep->regs->ctl); | ||
462 | tmp |= AMD_BIT(UDC_EPCTL_SNAK); | ||
463 | writel(tmp, &ep->regs->ctl); | ||
464 | ep->naking = 1; | ||
465 | |||
466 | /* disable interrupt */ | ||
467 | tmp = readl(®s->ep_irqmsk); | ||
468 | tmp |= AMD_BIT(ep->num); | ||
469 | writel(tmp, ®s->ep_irqmsk); | ||
470 | |||
471 | if (ep->in) { | ||
472 | /* unset P and IN bit of potential former DMA */ | ||
473 | tmp = readl(&ep->regs->ctl); | ||
474 | tmp &= AMD_UNMASK_BIT(UDC_EPCTL_P); | ||
475 | writel(tmp, &ep->regs->ctl); | ||
476 | |||
477 | tmp = readl(&ep->regs->sts); | ||
478 | tmp |= AMD_BIT(UDC_EPSTS_IN); | ||
479 | writel(tmp, &ep->regs->sts); | ||
480 | |||
481 | /* flush the fifo */ | ||
482 | tmp = readl(&ep->regs->ctl); | ||
483 | tmp |= AMD_BIT(UDC_EPCTL_F); | ||
484 | writel(tmp, &ep->regs->ctl); | ||
485 | |||
486 | } | ||
487 | /* reset desc pointer */ | ||
488 | writel(0, &ep->regs->desptr); | ||
489 | } | ||
490 | |||
491 | /* Disables endpoint, is called by gadget driver */ | ||
492 | static int udc_ep_disable(struct usb_ep *usbep) | ||
493 | { | ||
494 | struct udc_ep *ep = NULL; | ||
495 | unsigned long iflags; | ||
496 | |||
497 | if (!usbep) | ||
498 | return -EINVAL; | ||
499 | |||
500 | ep = container_of(usbep, struct udc_ep, ep); | ||
501 | if (usbep->name == ep0_string || !ep->desc) | ||
502 | return -EINVAL; | ||
503 | |||
504 | DBG(ep->dev, "Disable ep-%d\n", ep->num); | ||
505 | |||
506 | spin_lock_irqsave(&ep->dev->lock, iflags); | ||
507 | udc_free_request(&ep->ep, &ep->bna_dummy_req->req); | ||
508 | empty_req_queue(ep); | ||
509 | ep_init(ep->dev->regs, ep); | ||
510 | spin_unlock_irqrestore(&ep->dev->lock, iflags); | ||
511 | |||
512 | return 0; | ||
513 | } | ||
514 | |||
515 | /* Allocates request packet, called by gadget driver */ | ||
516 | static struct usb_request * | ||
517 | udc_alloc_request(struct usb_ep *usbep, gfp_t gfp) | ||
518 | { | ||
519 | struct udc_request *req; | ||
520 | struct udc_data_dma *dma_desc; | ||
521 | struct udc_ep *ep; | ||
522 | |||
523 | if (!usbep) | ||
524 | return NULL; | ||
525 | |||
526 | ep = container_of(usbep, struct udc_ep, ep); | ||
527 | |||
528 | VDBG(ep->dev, "udc_alloc_req(): ep%d\n", ep->num); | ||
529 | req = kzalloc(sizeof(struct udc_request), gfp); | ||
530 | if (!req) | ||
531 | return NULL; | ||
532 | |||
533 | req->req.dma = DMA_DONT_USE; | ||
534 | INIT_LIST_HEAD(&req->queue); | ||
535 | |||
536 | if (ep->dma) { | ||
537 | /* ep0 in requests are allocated from data pool here */ | ||
538 | dma_desc = pci_pool_alloc(ep->dev->data_requests, gfp, | ||
539 | &req->td_phys); | ||
540 | if (!dma_desc) { | ||
541 | kfree(req); | ||
542 | return NULL; | ||
543 | } | ||
544 | |||
545 | VDBG(ep->dev, "udc_alloc_req: req = %p dma_desc = %p, " | ||
546 | "td_phys = %lx\n", | ||
547 | req, dma_desc, | ||
548 | (unsigned long)req->td_phys); | ||
549 | /* prevent from using desc. - set HOST BUSY */ | ||
550 | dma_desc->status = AMD_ADDBITS(dma_desc->status, | ||
551 | UDC_DMA_STP_STS_BS_HOST_BUSY, | ||
552 | UDC_DMA_STP_STS_BS); | ||
553 | dma_desc->bufptr = __constant_cpu_to_le32(DMA_DONT_USE); | ||
554 | req->td_data = dma_desc; | ||
555 | req->td_data_last = NULL; | ||
556 | req->chain_len = 1; | ||
557 | } | ||
558 | |||
559 | return &req->req; | ||
560 | } | ||
561 | |||
562 | /* Frees request packet, called by gadget driver */ | ||
563 | static void | ||
564 | udc_free_request(struct usb_ep *usbep, struct usb_request *usbreq) | ||
565 | { | ||
566 | struct udc_ep *ep; | ||
567 | struct udc_request *req; | ||
568 | |||
569 | if (!usbep || !usbreq) | ||
570 | return; | ||
571 | |||
572 | ep = container_of(usbep, struct udc_ep, ep); | ||
573 | req = container_of(usbreq, struct udc_request, req); | ||
574 | VDBG(ep->dev, "free_req req=%p\n", req); | ||
575 | BUG_ON(!list_empty(&req->queue)); | ||
576 | if (req->td_data) { | ||
577 | VDBG(ep->dev, "req->td_data=%p\n", req->td_data); | ||
578 | |||
579 | /* free dma chain if created */ | ||
580 | if (req->chain_len > 1) { | ||
581 | udc_free_dma_chain(ep->dev, req); | ||
582 | } | ||
583 | |||
584 | pci_pool_free(ep->dev->data_requests, req->td_data, | ||
585 | req->td_phys); | ||
586 | } | ||
587 | kfree(req); | ||
588 | } | ||
589 | |||
590 | /* Init BNA dummy descriptor for HOST BUSY and pointing to itself */ | ||
591 | static void udc_init_bna_dummy(struct udc_request *req) | ||
592 | { | ||
593 | if (req) { | ||
594 | /* set last bit */ | ||
595 | req->td_data->status |= AMD_BIT(UDC_DMA_IN_STS_L); | ||
596 | /* set next pointer to itself */ | ||
597 | req->td_data->next = req->td_phys; | ||
598 | /* set HOST BUSY */ | ||
599 | req->td_data->status | ||
600 | = AMD_ADDBITS(req->td_data->status, | ||
601 | UDC_DMA_STP_STS_BS_DMA_DONE, | ||
602 | UDC_DMA_STP_STS_BS); | ||
603 | #ifdef UDC_VERBOSE | ||
604 | pr_debug("bna desc = %p, sts = %08x\n", | ||
605 | req->td_data, req->td_data->status); | ||
606 | #endif | ||
607 | } | ||
608 | } | ||
609 | |||
610 | /* Allocate BNA dummy descriptor */ | ||
611 | static struct udc_request *udc_alloc_bna_dummy(struct udc_ep *ep) | ||
612 | { | ||
613 | struct udc_request *req = NULL; | ||
614 | struct usb_request *_req = NULL; | ||
615 | |||
616 | /* alloc the dummy request */ | ||
617 | _req = udc_alloc_request(&ep->ep, GFP_ATOMIC); | ||
618 | if (_req) { | ||
619 | req = container_of(_req, struct udc_request, req); | ||
620 | ep->bna_dummy_req = req; | ||
621 | udc_init_bna_dummy(req); | ||
622 | } | ||
623 | return req; | ||
624 | } | ||
625 | |||
626 | /* Write data to TX fifo for IN packets */ | ||
627 | static void | ||
628 | udc_txfifo_write(struct udc_ep *ep, struct usb_request *req) | ||
629 | { | ||
630 | u8 *req_buf; | ||
631 | u32 *buf; | ||
632 | int i, j; | ||
633 | unsigned bytes = 0; | ||
634 | unsigned remaining = 0; | ||
635 | |||
636 | if (!req || !ep) | ||
637 | return; | ||
638 | |||
639 | req_buf = req->buf + req->actual; | ||
640 | prefetch(req_buf); | ||
641 | remaining = req->length - req->actual; | ||
642 | |||
643 | buf = (u32 *) req_buf; | ||
644 | |||
645 | bytes = ep->ep.maxpacket; | ||
646 | if (bytes > remaining) | ||
647 | bytes = remaining; | ||
648 | |||
649 | /* dwords first */ | ||
650 | for (i = 0; i < bytes / UDC_DWORD_BYTES; i++) { | ||
651 | writel(*(buf + i), ep->txfifo); | ||
652 | } | ||
653 | |||
654 | /* remaining bytes must be written by byte access */ | ||
655 | for (j = 0; j < bytes % UDC_DWORD_BYTES; j++) { | ||
656 | writeb((u8)(*(buf + i) >> (j << UDC_BITS_PER_BYTE_SHIFT)), | ||
657 | ep->txfifo); | ||
658 | } | ||
659 | |||
660 | /* dummy write confirm */ | ||
661 | writel(0, &ep->regs->confirm); | ||
662 | } | ||
663 | |||
664 | /* Read dwords from RX fifo for OUT transfers */ | ||
665 | static int udc_rxfifo_read_dwords(struct udc *dev, u32 *buf, int dwords) | ||
666 | { | ||
667 | int i; | ||
668 | |||
669 | VDBG(dev, "udc_read_dwords(): %d dwords\n", dwords); | ||
670 | |||
671 | for (i = 0; i < dwords; i++) { | ||
672 | *(buf + i) = readl(dev->rxfifo); | ||
673 | } | ||
674 | return 0; | ||
675 | } | ||
676 | |||
677 | /* Read bytes from RX fifo for OUT transfers */ | ||
678 | static int udc_rxfifo_read_bytes(struct udc *dev, u8 *buf, int bytes) | ||
679 | { | ||
680 | int i, j; | ||
681 | u32 tmp; | ||
682 | |||
683 | VDBG(dev, "udc_read_bytes(): %d bytes\n", bytes); | ||
684 | |||
685 | /* dwords first */ | ||
686 | for (i = 0; i < bytes / UDC_DWORD_BYTES; i++) { | ||
687 | *((u32 *)(buf + (i<<2))) = readl(dev->rxfifo); | ||
688 | } | ||
689 | |||
690 | /* remaining bytes must be read by byte access */ | ||
691 | if (bytes % UDC_DWORD_BYTES) { | ||
692 | tmp = readl(dev->rxfifo); | ||
693 | for (j = 0; j < bytes % UDC_DWORD_BYTES; j++) { | ||
694 | *(buf + (i<<2) + j) = (u8)(tmp & UDC_BYTE_MASK); | ||
695 | tmp = tmp >> UDC_BITS_PER_BYTE; | ||
696 | } | ||
697 | } | ||
698 | |||
699 | return 0; | ||
700 | } | ||
701 | |||
702 | /* Read data from RX fifo for OUT transfers */ | ||
703 | static int | ||
704 | udc_rxfifo_read(struct udc_ep *ep, struct udc_request *req) | ||
705 | { | ||
706 | u8 *buf; | ||
707 | unsigned buf_space; | ||
708 | unsigned bytes = 0; | ||
709 | unsigned finished = 0; | ||
710 | |||
711 | /* received number bytes */ | ||
712 | bytes = readl(&ep->regs->sts); | ||
713 | bytes = AMD_GETBITS(bytes, UDC_EPSTS_RX_PKT_SIZE); | ||
714 | |||
715 | buf_space = req->req.length - req->req.actual; | ||
716 | buf = req->req.buf + req->req.actual; | ||
717 | if (bytes > buf_space) { | ||
718 | if ((buf_space % ep->ep.maxpacket) != 0) { | ||
719 | DBG(ep->dev, | ||
720 | "%s: rx %d bytes, rx-buf space = %d bytesn\n", | ||
721 | ep->ep.name, bytes, buf_space); | ||
722 | req->req.status = -EOVERFLOW; | ||
723 | } | ||
724 | bytes = buf_space; | ||
725 | } | ||
726 | req->req.actual += bytes; | ||
727 | |||
728 | /* last packet ? */ | ||
729 | if (((bytes % ep->ep.maxpacket) != 0) || (!bytes) | ||
730 | || ((req->req.actual == req->req.length) && !req->req.zero)) | ||
731 | finished = 1; | ||
732 | |||
733 | /* read rx fifo bytes */ | ||
734 | VDBG(ep->dev, "ep %s: rxfifo read %d bytes\n", ep->ep.name, bytes); | ||
735 | udc_rxfifo_read_bytes(ep->dev, buf, bytes); | ||
736 | |||
737 | return finished; | ||
738 | } | ||
739 | |||
740 | /* create/re-init a DMA descriptor or a DMA descriptor chain */ | ||
741 | static int prep_dma(struct udc_ep *ep, struct udc_request *req, gfp_t gfp) | ||
742 | { | ||
743 | int retval = 0; | ||
744 | u32 tmp; | ||
745 | |||
746 | VDBG(ep->dev, "prep_dma\n"); | ||
747 | VDBG(ep->dev, "prep_dma ep%d req->td_data=%p\n", | ||
748 | ep->num, req->td_data); | ||
749 | |||
750 | /* set buffer pointer */ | ||
751 | req->td_data->bufptr = req->req.dma; | ||
752 | |||
753 | /* set last bit */ | ||
754 | req->td_data->status |= AMD_BIT(UDC_DMA_IN_STS_L); | ||
755 | |||
756 | /* build/re-init dma chain if maxpkt scatter mode, not for EP0 */ | ||
757 | if (use_dma_ppb) { | ||
758 | |||
759 | retval = udc_create_dma_chain(ep, req, ep->ep.maxpacket, gfp); | ||
760 | if (retval != 0) { | ||
761 | if (retval == -ENOMEM) | ||
762 | DBG(ep->dev, "Out of DMA memory\n"); | ||
763 | return retval; | ||
764 | } | ||
765 | if (ep->in) { | ||
766 | if (req->req.length == ep->ep.maxpacket) { | ||
767 | /* write tx bytes */ | ||
768 | req->td_data->status = | ||
769 | AMD_ADDBITS(req->td_data->status, | ||
770 | ep->ep.maxpacket, | ||
771 | UDC_DMA_IN_STS_TXBYTES); | ||
772 | |||
773 | } | ||
774 | } | ||
775 | |||
776 | } | ||
777 | |||
778 | if (ep->in) { | ||
779 | VDBG(ep->dev, "IN: use_dma_ppb=%d req->req.len=%d " | ||
780 | "maxpacket=%d ep%d\n", | ||
781 | use_dma_ppb, req->req.length, | ||
782 | ep->ep.maxpacket, ep->num); | ||
783 | /* | ||
784 | * if bytes < max packet then tx bytes must | ||
785 | * be written in packet per buffer mode | ||
786 | */ | ||
787 | if (!use_dma_ppb || req->req.length < ep->ep.maxpacket | ||
788 | || ep->num == UDC_EP0OUT_IX | ||
789 | || ep->num == UDC_EP0IN_IX) { | ||
790 | /* write tx bytes */ | ||
791 | req->td_data->status = | ||
792 | AMD_ADDBITS(req->td_data->status, | ||
793 | req->req.length, | ||
794 | UDC_DMA_IN_STS_TXBYTES); | ||
795 | /* reset frame num */ | ||
796 | req->td_data->status = | ||
797 | AMD_ADDBITS(req->td_data->status, | ||
798 | 0, | ||
799 | UDC_DMA_IN_STS_FRAMENUM); | ||
800 | } | ||
801 | /* set HOST BUSY */ | ||
802 | req->td_data->status = | ||
803 | AMD_ADDBITS(req->td_data->status, | ||
804 | UDC_DMA_STP_STS_BS_HOST_BUSY, | ||
805 | UDC_DMA_STP_STS_BS); | ||
806 | } else { | ||
807 | VDBG(ep->dev, "OUT set host ready\n"); | ||
808 | /* set HOST READY */ | ||
809 | req->td_data->status = | ||
810 | AMD_ADDBITS(req->td_data->status, | ||
811 | UDC_DMA_STP_STS_BS_HOST_READY, | ||
812 | UDC_DMA_STP_STS_BS); | ||
813 | |||
814 | |||
815 | /* clear NAK by writing CNAK */ | ||
816 | if (ep->naking) { | ||
817 | tmp = readl(&ep->regs->ctl); | ||
818 | tmp |= AMD_BIT(UDC_EPCTL_CNAK); | ||
819 | writel(tmp, &ep->regs->ctl); | ||
820 | ep->naking = 0; | ||
821 | UDC_QUEUE_CNAK(ep, ep->num); | ||
822 | } | ||
823 | |||
824 | } | ||
825 | |||
826 | return retval; | ||
827 | } | ||
828 | |||
829 | /* Completes request packet ... caller MUST hold lock */ | ||
830 | static void | ||
831 | complete_req(struct udc_ep *ep, struct udc_request *req, int sts) | ||
832 | __releases(ep->dev->lock) | ||
833 | __acquires(ep->dev->lock) | ||
834 | { | ||
835 | struct udc *dev; | ||
836 | unsigned halted; | ||
837 | |||
838 | VDBG(ep->dev, "complete_req(): ep%d\n", ep->num); | ||
839 | |||
840 | dev = ep->dev; | ||
841 | /* unmap DMA */ | ||
842 | if (req->dma_mapping) { | ||
843 | if (ep->in) | ||
844 | pci_unmap_single(dev->pdev, | ||
845 | req->req.dma, | ||
846 | req->req.length, | ||
847 | PCI_DMA_TODEVICE); | ||
848 | else | ||
849 | pci_unmap_single(dev->pdev, | ||
850 | req->req.dma, | ||
851 | req->req.length, | ||
852 | PCI_DMA_FROMDEVICE); | ||
853 | req->dma_mapping = 0; | ||
854 | req->req.dma = DMA_DONT_USE; | ||
855 | } | ||
856 | |||
857 | halted = ep->halted; | ||
858 | ep->halted = 1; | ||
859 | |||
860 | /* set new status if pending */ | ||
861 | if (req->req.status == -EINPROGRESS) | ||
862 | req->req.status = sts; | ||
863 | |||
864 | /* remove from ep queue */ | ||
865 | list_del_init(&req->queue); | ||
866 | |||
867 | VDBG(ep->dev, "req %p => complete %d bytes at %s with sts %d\n", | ||
868 | &req->req, req->req.length, ep->ep.name, sts); | ||
869 | |||
870 | spin_unlock(&dev->lock); | ||
871 | req->req.complete(&ep->ep, &req->req); | ||
872 | spin_lock(&dev->lock); | ||
873 | ep->halted = halted; | ||
874 | } | ||
875 | |||
876 | /* frees pci pool descriptors of a DMA chain */ | ||
877 | static int udc_free_dma_chain(struct udc *dev, struct udc_request *req) | ||
878 | { | ||
879 | |||
880 | int ret_val = 0; | ||
881 | struct udc_data_dma *td; | ||
882 | struct udc_data_dma *td_last = NULL; | ||
883 | unsigned int i; | ||
884 | |||
885 | DBG(dev, "free chain req = %p\n", req); | ||
886 | |||
887 | /* do not free first desc., will be done by free for request */ | ||
888 | td_last = req->td_data; | ||
889 | td = phys_to_virt(td_last->next); | ||
890 | |||
891 | for (i = 1; i < req->chain_len; i++) { | ||
892 | |||
893 | pci_pool_free(dev->data_requests, td, | ||
894 | (dma_addr_t) td_last->next); | ||
895 | td_last = td; | ||
896 | td = phys_to_virt(td_last->next); | ||
897 | } | ||
898 | |||
899 | return ret_val; | ||
900 | } | ||
901 | |||
902 | /* Iterates to the end of a DMA chain and returns last descriptor */ | ||
903 | static struct udc_data_dma *udc_get_last_dma_desc(struct udc_request *req) | ||
904 | { | ||
905 | struct udc_data_dma *td; | ||
906 | |||
907 | td = req->td_data; | ||
908 | while (td && !(td->status & AMD_BIT(UDC_DMA_IN_STS_L))) { | ||
909 | td = phys_to_virt(td->next); | ||
910 | } | ||
911 | |||
912 | return td; | ||
913 | |||
914 | } | ||
915 | |||
916 | /* Iterates to the end of a DMA chain and counts bytes received */ | ||
917 | static u32 udc_get_ppbdu_rxbytes(struct udc_request *req) | ||
918 | { | ||
919 | struct udc_data_dma *td; | ||
920 | u32 count; | ||
921 | |||
922 | td = req->td_data; | ||
923 | /* received number bytes */ | ||
924 | count = AMD_GETBITS(td->status, UDC_DMA_OUT_STS_RXBYTES); | ||
925 | |||
926 | while (td && !(td->status & AMD_BIT(UDC_DMA_IN_STS_L))) { | ||
927 | td = phys_to_virt(td->next); | ||
928 | /* received number bytes */ | ||
929 | if (td) { | ||
930 | count += AMD_GETBITS(td->status, | ||
931 | UDC_DMA_OUT_STS_RXBYTES); | ||
932 | } | ||
933 | } | ||
934 | |||
935 | return count; | ||
936 | |||
937 | } | ||
938 | |||
939 | /* Creates or re-inits a DMA chain */ | ||
940 | static int udc_create_dma_chain( | ||
941 | struct udc_ep *ep, | ||
942 | struct udc_request *req, | ||
943 | unsigned long buf_len, gfp_t gfp_flags | ||
944 | ) | ||
945 | { | ||
946 | unsigned long bytes = req->req.length; | ||
947 | unsigned int i; | ||
948 | dma_addr_t dma_addr; | ||
949 | struct udc_data_dma *td = NULL; | ||
950 | struct udc_data_dma *last = NULL; | ||
951 | unsigned long txbytes; | ||
952 | unsigned create_new_chain = 0; | ||
953 | unsigned len; | ||
954 | |||
955 | VDBG(ep->dev, "udc_create_dma_chain: bytes=%ld buf_len=%ld\n", | ||
956 | bytes, buf_len); | ||
957 | dma_addr = DMA_DONT_USE; | ||
958 | |||
959 | /* unset L bit in first desc for OUT */ | ||
960 | if (!ep->in) { | ||
961 | req->td_data->status &= AMD_CLEAR_BIT(UDC_DMA_IN_STS_L); | ||
962 | } | ||
963 | |||
964 | /* alloc only new desc's if not already available */ | ||
965 | len = req->req.length / ep->ep.maxpacket; | ||
966 | if (req->req.length % ep->ep.maxpacket) { | ||
967 | len++; | ||
968 | } | ||
969 | |||
970 | if (len > req->chain_len) { | ||
971 | /* shorter chain already allocated before */ | ||
972 | if (req->chain_len > 1) { | ||
973 | udc_free_dma_chain(ep->dev, req); | ||
974 | } | ||
975 | req->chain_len = len; | ||
976 | create_new_chain = 1; | ||
977 | } | ||
978 | |||
979 | td = req->td_data; | ||
980 | /* gen. required number of descriptors and buffers */ | ||
981 | for (i = buf_len; i < bytes; i += buf_len) { | ||
982 | /* create or determine next desc. */ | ||
983 | if (create_new_chain) { | ||
984 | |||
985 | td = pci_pool_alloc(ep->dev->data_requests, | ||
986 | gfp_flags, &dma_addr); | ||
987 | if (!td) | ||
988 | return -ENOMEM; | ||
989 | |||
990 | td->status = 0; | ||
991 | } else if (i == buf_len) { | ||
992 | /* first td */ | ||
993 | td = (struct udc_data_dma *) phys_to_virt( | ||
994 | req->td_data->next); | ||
995 | td->status = 0; | ||
996 | } else { | ||
997 | td = (struct udc_data_dma *) phys_to_virt(last->next); | ||
998 | td->status = 0; | ||
999 | } | ||
1000 | |||
1001 | |||
1002 | if (td) | ||
1003 | td->bufptr = req->req.dma + i; /* assign buffer */ | ||
1004 | else | ||
1005 | break; | ||
1006 | |||
1007 | /* short packet ? */ | ||
1008 | if ((bytes - i) >= buf_len) { | ||
1009 | txbytes = buf_len; | ||
1010 | } else { | ||
1011 | /* short packet */ | ||
1012 | txbytes = bytes - i; | ||
1013 | } | ||
1014 | |||
1015 | /* link td and assign tx bytes */ | ||
1016 | if (i == buf_len) { | ||
1017 | if (create_new_chain) { | ||
1018 | req->td_data->next = dma_addr; | ||
1019 | } else { | ||
1020 | /* req->td_data->next = virt_to_phys(td); */ | ||
1021 | } | ||
1022 | /* write tx bytes */ | ||
1023 | if (ep->in) { | ||
1024 | /* first desc */ | ||
1025 | req->td_data->status = | ||
1026 | AMD_ADDBITS(req->td_data->status, | ||
1027 | ep->ep.maxpacket, | ||
1028 | UDC_DMA_IN_STS_TXBYTES); | ||
1029 | /* second desc */ | ||
1030 | td->status = AMD_ADDBITS(td->status, | ||
1031 | txbytes, | ||
1032 | UDC_DMA_IN_STS_TXBYTES); | ||
1033 | } | ||
1034 | } else { | ||
1035 | if (create_new_chain) { | ||
1036 | last->next = dma_addr; | ||
1037 | } else { | ||
1038 | /* last->next = virt_to_phys(td); */ | ||
1039 | } | ||
1040 | if (ep->in) { | ||
1041 | /* write tx bytes */ | ||
1042 | td->status = AMD_ADDBITS(td->status, | ||
1043 | txbytes, | ||
1044 | UDC_DMA_IN_STS_TXBYTES); | ||
1045 | } | ||
1046 | } | ||
1047 | last = td; | ||
1048 | } | ||
1049 | /* set last bit */ | ||
1050 | if (td) { | ||
1051 | td->status |= AMD_BIT(UDC_DMA_IN_STS_L); | ||
1052 | /* last desc. points to itself */ | ||
1053 | req->td_data_last = td; | ||
1054 | } | ||
1055 | |||
1056 | return 0; | ||
1057 | } | ||
1058 | |||
1059 | /* Enabling RX DMA */ | ||
1060 | static void udc_set_rde(struct udc *dev) | ||
1061 | { | ||
1062 | u32 tmp; | ||
1063 | |||
1064 | VDBG(dev, "udc_set_rde()\n"); | ||
1065 | /* stop RDE timer */ | ||
1066 | if (timer_pending(&udc_timer)) { | ||
1067 | set_rde = 0; | ||
1068 | mod_timer(&udc_timer, jiffies - 1); | ||
1069 | } | ||
1070 | /* set RDE */ | ||
1071 | tmp = readl(&dev->regs->ctl); | ||
1072 | tmp |= AMD_BIT(UDC_DEVCTL_RDE); | ||
1073 | writel(tmp, &dev->regs->ctl); | ||
1074 | } | ||
1075 | |||
1076 | /* Queues a request packet, called by gadget driver */ | ||
1077 | static int | ||
1078 | udc_queue(struct usb_ep *usbep, struct usb_request *usbreq, gfp_t gfp) | ||
1079 | { | ||
1080 | int retval = 0; | ||
1081 | u8 open_rxfifo = 0; | ||
1082 | unsigned long iflags; | ||
1083 | struct udc_ep *ep; | ||
1084 | struct udc_request *req; | ||
1085 | struct udc *dev; | ||
1086 | u32 tmp; | ||
1087 | |||
1088 | /* check the inputs */ | ||
1089 | req = container_of(usbreq, struct udc_request, req); | ||
1090 | |||
1091 | if (!usbep || !usbreq || !usbreq->complete || !usbreq->buf | ||
1092 | || !list_empty(&req->queue)) | ||
1093 | return -EINVAL; | ||
1094 | |||
1095 | ep = container_of(usbep, struct udc_ep, ep); | ||
1096 | if (!ep->desc && (ep->num != 0 && ep->num != UDC_EP0OUT_IX)) | ||
1097 | return -EINVAL; | ||
1098 | |||
1099 | VDBG(ep->dev, "udc_queue(): ep%d-in=%d\n", ep->num, ep->in); | ||
1100 | dev = ep->dev; | ||
1101 | |||
1102 | if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
1103 | return -ESHUTDOWN; | ||
1104 | |||
1105 | /* map dma (usually done before) */ | ||
1106 | if (ep->dma && usbreq->length != 0 | ||
1107 | && (usbreq->dma == DMA_DONT_USE || usbreq->dma == 0)) { | ||
1108 | VDBG(dev, "DMA map req %p\n", req); | ||
1109 | if (ep->in) | ||
1110 | usbreq->dma = pci_map_single(dev->pdev, | ||
1111 | usbreq->buf, | ||
1112 | usbreq->length, | ||
1113 | PCI_DMA_TODEVICE); | ||
1114 | else | ||
1115 | usbreq->dma = pci_map_single(dev->pdev, | ||
1116 | usbreq->buf, | ||
1117 | usbreq->length, | ||
1118 | PCI_DMA_FROMDEVICE); | ||
1119 | req->dma_mapping = 1; | ||
1120 | } | ||
1121 | |||
1122 | VDBG(dev, "%s queue req %p, len %d req->td_data=%p buf %p\n", | ||
1123 | usbep->name, usbreq, usbreq->length, | ||
1124 | req->td_data, usbreq->buf); | ||
1125 | |||
1126 | spin_lock_irqsave(&dev->lock, iflags); | ||
1127 | usbreq->actual = 0; | ||
1128 | usbreq->status = -EINPROGRESS; | ||
1129 | req->dma_done = 0; | ||
1130 | |||
1131 | /* on empty queue just do first transfer */ | ||
1132 | if (list_empty(&ep->queue)) { | ||
1133 | /* zlp */ | ||
1134 | if (usbreq->length == 0) { | ||
1135 | /* IN zlp's are handled by hardware */ | ||
1136 | complete_req(ep, req, 0); | ||
1137 | VDBG(dev, "%s: zlp\n", ep->ep.name); | ||
1138 | /* | ||
1139 | * if set_config or set_intf is waiting for ack by zlp | ||
1140 | * then set CSR_DONE | ||
1141 | */ | ||
1142 | if (dev->set_cfg_not_acked) { | ||
1143 | tmp = readl(&dev->regs->ctl); | ||
1144 | tmp |= AMD_BIT(UDC_DEVCTL_CSR_DONE); | ||
1145 | writel(tmp, &dev->regs->ctl); | ||
1146 | dev->set_cfg_not_acked = 0; | ||
1147 | } | ||
1148 | /* setup command is ACK'ed now by zlp */ | ||
1149 | if (dev->waiting_zlp_ack_ep0in) { | ||
1150 | /* clear NAK by writing CNAK in EP0_IN */ | ||
1151 | tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
1152 | tmp |= AMD_BIT(UDC_EPCTL_CNAK); | ||
1153 | writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
1154 | dev->ep[UDC_EP0IN_IX].naking = 0; | ||
1155 | UDC_QUEUE_CNAK(&dev->ep[UDC_EP0IN_IX], | ||
1156 | UDC_EP0IN_IX); | ||
1157 | dev->waiting_zlp_ack_ep0in = 0; | ||
1158 | } | ||
1159 | goto finished; | ||
1160 | } | ||
1161 | if (ep->dma) { | ||
1162 | retval = prep_dma(ep, req, gfp); | ||
1163 | if (retval != 0) | ||
1164 | goto finished; | ||
1165 | /* write desc pointer to enable DMA */ | ||
1166 | if (ep->in) { | ||
1167 | /* set HOST READY */ | ||
1168 | req->td_data->status = | ||
1169 | AMD_ADDBITS(req->td_data->status, | ||
1170 | UDC_DMA_IN_STS_BS_HOST_READY, | ||
1171 | UDC_DMA_IN_STS_BS); | ||
1172 | } | ||
1173 | |||
1174 | /* disabled rx dma while descriptor update */ | ||
1175 | if (!ep->in) { | ||
1176 | /* stop RDE timer */ | ||
1177 | if (timer_pending(&udc_timer)) { | ||
1178 | set_rde = 0; | ||
1179 | mod_timer(&udc_timer, jiffies - 1); | ||
1180 | } | ||
1181 | /* clear RDE */ | ||
1182 | tmp = readl(&dev->regs->ctl); | ||
1183 | tmp &= AMD_UNMASK_BIT(UDC_DEVCTL_RDE); | ||
1184 | writel(tmp, &dev->regs->ctl); | ||
1185 | open_rxfifo = 1; | ||
1186 | |||
1187 | /* | ||
1188 | * if BNA occurred then let BNA dummy desc. | ||
1189 | * point to current desc. | ||
1190 | */ | ||
1191 | if (ep->bna_occurred) { | ||
1192 | VDBG(dev, "copy to BNA dummy desc.\n"); | ||
1193 | memcpy(ep->bna_dummy_req->td_data, | ||
1194 | req->td_data, | ||
1195 | sizeof(struct udc_data_dma)); | ||
1196 | } | ||
1197 | } | ||
1198 | /* write desc pointer */ | ||
1199 | writel(req->td_phys, &ep->regs->desptr); | ||
1200 | |||
1201 | /* clear NAK by writing CNAK */ | ||
1202 | if (ep->naking) { | ||
1203 | tmp = readl(&ep->regs->ctl); | ||
1204 | tmp |= AMD_BIT(UDC_EPCTL_CNAK); | ||
1205 | writel(tmp, &ep->regs->ctl); | ||
1206 | ep->naking = 0; | ||
1207 | UDC_QUEUE_CNAK(ep, ep->num); | ||
1208 | } | ||
1209 | |||
1210 | if (ep->in) { | ||
1211 | /* enable ep irq */ | ||
1212 | tmp = readl(&dev->regs->ep_irqmsk); | ||
1213 | tmp &= AMD_UNMASK_BIT(ep->num); | ||
1214 | writel(tmp, &dev->regs->ep_irqmsk); | ||
1215 | } | ||
1216 | } | ||
1217 | |||
1218 | } else if (ep->dma) { | ||
1219 | |||
1220 | /* | ||
1221 | * prep_dma not used for OUT ep's, this is not possible | ||
1222 | * for PPB modes, because of chain creation reasons | ||
1223 | */ | ||
1224 | if (ep->in) { | ||
1225 | retval = prep_dma(ep, req, gfp); | ||
1226 | if (retval != 0) | ||
1227 | goto finished; | ||
1228 | } | ||
1229 | } | ||
1230 | VDBG(dev, "list_add\n"); | ||
1231 | /* add request to ep queue */ | ||
1232 | if (req) { | ||
1233 | |||
1234 | list_add_tail(&req->queue, &ep->queue); | ||
1235 | |||
1236 | /* open rxfifo if out data queued */ | ||
1237 | if (open_rxfifo) { | ||
1238 | /* enable DMA */ | ||
1239 | req->dma_going = 1; | ||
1240 | udc_set_rde(dev); | ||
1241 | if (ep->num != UDC_EP0OUT_IX) | ||
1242 | dev->data_ep_queued = 1; | ||
1243 | } | ||
1244 | /* stop OUT naking */ | ||
1245 | if (!ep->in) { | ||
1246 | if (!use_dma && udc_rxfifo_pending) { | ||
1247 | DBG(dev, "udc_queue(): pending bytes in" | ||
1248 | "rxfifo after nyet\n"); | ||
1249 | /* | ||
1250 | * read pending bytes afer nyet: | ||
1251 | * referring to isr | ||
1252 | */ | ||
1253 | if (udc_rxfifo_read(ep, req)) { | ||
1254 | /* finish */ | ||
1255 | complete_req(ep, req, 0); | ||
1256 | } | ||
1257 | udc_rxfifo_pending = 0; | ||
1258 | |||
1259 | } | ||
1260 | } | ||
1261 | } | ||
1262 | |||
1263 | finished: | ||
1264 | spin_unlock_irqrestore(&dev->lock, iflags); | ||
1265 | return retval; | ||
1266 | } | ||
1267 | |||
1268 | /* Empty request queue of an endpoint; caller holds spinlock */ | ||
1269 | static void empty_req_queue(struct udc_ep *ep) | ||
1270 | { | ||
1271 | struct udc_request *req; | ||
1272 | |||
1273 | ep->halted = 1; | ||
1274 | while (!list_empty(&ep->queue)) { | ||
1275 | req = list_entry(ep->queue.next, | ||
1276 | struct udc_request, | ||
1277 | queue); | ||
1278 | complete_req(ep, req, -ESHUTDOWN); | ||
1279 | } | ||
1280 | } | ||
1281 | |||
1282 | /* Dequeues a request packet, called by gadget driver */ | ||
1283 | static int udc_dequeue(struct usb_ep *usbep, struct usb_request *usbreq) | ||
1284 | { | ||
1285 | struct udc_ep *ep; | ||
1286 | struct udc_request *req; | ||
1287 | unsigned halted; | ||
1288 | unsigned long iflags; | ||
1289 | |||
1290 | ep = container_of(usbep, struct udc_ep, ep); | ||
1291 | if (!usbep || !usbreq || (!ep->desc && (ep->num != 0 | ||
1292 | && ep->num != UDC_EP0OUT_IX))) | ||
1293 | return -EINVAL; | ||
1294 | |||
1295 | req = container_of(usbreq, struct udc_request, req); | ||
1296 | |||
1297 | spin_lock_irqsave(&ep->dev->lock, iflags); | ||
1298 | halted = ep->halted; | ||
1299 | ep->halted = 1; | ||
1300 | /* request in processing or next one */ | ||
1301 | if (ep->queue.next == &req->queue) { | ||
1302 | if (ep->dma && req->dma_going) { | ||
1303 | if (ep->in) | ||
1304 | ep->cancel_transfer = 1; | ||
1305 | else { | ||
1306 | u32 tmp; | ||
1307 | u32 dma_sts; | ||
1308 | /* stop potential receive DMA */ | ||
1309 | tmp = readl(&udc->regs->ctl); | ||
1310 | writel(tmp & AMD_UNMASK_BIT(UDC_DEVCTL_RDE), | ||
1311 | &udc->regs->ctl); | ||
1312 | /* | ||
1313 | * Cancel transfer later in ISR | ||
1314 | * if descriptor was touched. | ||
1315 | */ | ||
1316 | dma_sts = AMD_GETBITS(req->td_data->status, | ||
1317 | UDC_DMA_OUT_STS_BS); | ||
1318 | if (dma_sts != UDC_DMA_OUT_STS_BS_HOST_READY) | ||
1319 | ep->cancel_transfer = 1; | ||
1320 | else { | ||
1321 | udc_init_bna_dummy(ep->req); | ||
1322 | writel(ep->bna_dummy_req->td_phys, | ||
1323 | &ep->regs->desptr); | ||
1324 | } | ||
1325 | writel(tmp, &udc->regs->ctl); | ||
1326 | } | ||
1327 | } | ||
1328 | } | ||
1329 | complete_req(ep, req, -ECONNRESET); | ||
1330 | ep->halted = halted; | ||
1331 | |||
1332 | spin_unlock_irqrestore(&ep->dev->lock, iflags); | ||
1333 | return 0; | ||
1334 | } | ||
1335 | |||
1336 | /* Halt or clear halt of endpoint */ | ||
1337 | static int | ||
1338 | udc_set_halt(struct usb_ep *usbep, int halt) | ||
1339 | { | ||
1340 | struct udc_ep *ep; | ||
1341 | u32 tmp; | ||
1342 | unsigned long iflags; | ||
1343 | int retval = 0; | ||
1344 | |||
1345 | if (!usbep) | ||
1346 | return -EINVAL; | ||
1347 | |||
1348 | pr_debug("set_halt %s: halt=%d\n", usbep->name, halt); | ||
1349 | |||
1350 | ep = container_of(usbep, struct udc_ep, ep); | ||
1351 | if (!ep->desc && (ep->num != 0 && ep->num != UDC_EP0OUT_IX)) | ||
1352 | return -EINVAL; | ||
1353 | if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN) | ||
1354 | return -ESHUTDOWN; | ||
1355 | |||
1356 | spin_lock_irqsave(&udc_stall_spinlock, iflags); | ||
1357 | /* halt or clear halt */ | ||
1358 | if (halt) { | ||
1359 | if (ep->num == 0) | ||
1360 | ep->dev->stall_ep0in = 1; | ||
1361 | else { | ||
1362 | /* | ||
1363 | * set STALL | ||
1364 | * rxfifo empty not taken into acount | ||
1365 | */ | ||
1366 | tmp = readl(&ep->regs->ctl); | ||
1367 | tmp |= AMD_BIT(UDC_EPCTL_S); | ||
1368 | writel(tmp, &ep->regs->ctl); | ||
1369 | ep->halted = 1; | ||
1370 | |||
1371 | /* setup poll timer */ | ||
1372 | if (!timer_pending(&udc_pollstall_timer)) { | ||
1373 | udc_pollstall_timer.expires = jiffies + | ||
1374 | HZ * UDC_POLLSTALL_TIMER_USECONDS | ||
1375 | / (1000 * 1000); | ||
1376 | if (!stop_pollstall_timer) { | ||
1377 | DBG(ep->dev, "start polltimer\n"); | ||
1378 | add_timer(&udc_pollstall_timer); | ||
1379 | } | ||
1380 | } | ||
1381 | } | ||
1382 | } else { | ||
1383 | /* ep is halted by set_halt() before */ | ||
1384 | if (ep->halted) { | ||
1385 | tmp = readl(&ep->regs->ctl); | ||
1386 | /* clear stall bit */ | ||
1387 | tmp = tmp & AMD_CLEAR_BIT(UDC_EPCTL_S); | ||
1388 | /* clear NAK by writing CNAK */ | ||
1389 | tmp |= AMD_BIT(UDC_EPCTL_CNAK); | ||
1390 | writel(tmp, &ep->regs->ctl); | ||
1391 | ep->halted = 0; | ||
1392 | UDC_QUEUE_CNAK(ep, ep->num); | ||
1393 | } | ||
1394 | } | ||
1395 | spin_unlock_irqrestore(&udc_stall_spinlock, iflags); | ||
1396 | return retval; | ||
1397 | } | ||
1398 | |||
1399 | /* gadget interface */ | ||
1400 | static const struct usb_ep_ops udc_ep_ops = { | ||
1401 | .enable = udc_ep_enable, | ||
1402 | .disable = udc_ep_disable, | ||
1403 | |||
1404 | .alloc_request = udc_alloc_request, | ||
1405 | .free_request = udc_free_request, | ||
1406 | |||
1407 | .queue = udc_queue, | ||
1408 | .dequeue = udc_dequeue, | ||
1409 | |||
1410 | .set_halt = udc_set_halt, | ||
1411 | /* fifo ops not implemented */ | ||
1412 | }; | ||
1413 | |||
1414 | /*-------------------------------------------------------------------------*/ | ||
1415 | |||
1416 | /* Get frame counter (not implemented) */ | ||
1417 | static int udc_get_frame(struct usb_gadget *gadget) | ||
1418 | { | ||
1419 | return -EOPNOTSUPP; | ||
1420 | } | ||
1421 | |||
1422 | /* Remote wakeup gadget interface */ | ||
1423 | static int udc_wakeup(struct usb_gadget *gadget) | ||
1424 | { | ||
1425 | struct udc *dev; | ||
1426 | |||
1427 | if (!gadget) | ||
1428 | return -EINVAL; | ||
1429 | dev = container_of(gadget, struct udc, gadget); | ||
1430 | udc_remote_wakeup(dev); | ||
1431 | |||
1432 | return 0; | ||
1433 | } | ||
1434 | |||
1435 | /* gadget operations */ | ||
1436 | static const struct usb_gadget_ops udc_ops = { | ||
1437 | .wakeup = udc_wakeup, | ||
1438 | .get_frame = udc_get_frame, | ||
1439 | }; | ||
1440 | |||
1441 | /* Setups endpoint parameters, adds endpoints to linked list */ | ||
1442 | static void make_ep_lists(struct udc *dev) | ||
1443 | { | ||
1444 | /* make gadget ep lists */ | ||
1445 | INIT_LIST_HEAD(&dev->gadget.ep_list); | ||
1446 | list_add_tail(&dev->ep[UDC_EPIN_STATUS_IX].ep.ep_list, | ||
1447 | &dev->gadget.ep_list); | ||
1448 | list_add_tail(&dev->ep[UDC_EPIN_IX].ep.ep_list, | ||
1449 | &dev->gadget.ep_list); | ||
1450 | list_add_tail(&dev->ep[UDC_EPOUT_IX].ep.ep_list, | ||
1451 | &dev->gadget.ep_list); | ||
1452 | |||
1453 | /* fifo config */ | ||
1454 | dev->ep[UDC_EPIN_STATUS_IX].fifo_depth = UDC_EPIN_SMALLINT_BUFF_SIZE; | ||
1455 | if (dev->gadget.speed == USB_SPEED_FULL) | ||
1456 | dev->ep[UDC_EPIN_IX].fifo_depth = UDC_FS_EPIN_BUFF_SIZE; | ||
1457 | else if (dev->gadget.speed == USB_SPEED_HIGH) | ||
1458 | dev->ep[UDC_EPIN_IX].fifo_depth = hs_tx_buf; | ||
1459 | dev->ep[UDC_EPOUT_IX].fifo_depth = UDC_RXFIFO_SIZE; | ||
1460 | } | ||
1461 | |||
1462 | /* init registers at driver load time */ | ||
1463 | static int startup_registers(struct udc *dev) | ||
1464 | { | ||
1465 | u32 tmp; | ||
1466 | |||
1467 | /* init controller by soft reset */ | ||
1468 | udc_soft_reset(dev); | ||
1469 | |||
1470 | /* mask not needed interrupts */ | ||
1471 | udc_mask_unused_interrupts(dev); | ||
1472 | |||
1473 | /* put into initial config */ | ||
1474 | udc_basic_init(dev); | ||
1475 | /* link up all endpoints */ | ||
1476 | udc_setup_endpoints(dev); | ||
1477 | |||
1478 | /* program speed */ | ||
1479 | tmp = readl(&dev->regs->cfg); | ||
1480 | if (use_fullspeed) { | ||
1481 | tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD); | ||
1482 | } else { | ||
1483 | tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_HS, UDC_DEVCFG_SPD); | ||
1484 | } | ||
1485 | writel(tmp, &dev->regs->cfg); | ||
1486 | |||
1487 | return 0; | ||
1488 | } | ||
1489 | |||
1490 | /* Inits UDC context */ | ||
1491 | static void udc_basic_init(struct udc *dev) | ||
1492 | { | ||
1493 | u32 tmp; | ||
1494 | |||
1495 | DBG(dev, "udc_basic_init()\n"); | ||
1496 | |||
1497 | dev->gadget.speed = USB_SPEED_UNKNOWN; | ||
1498 | |||
1499 | /* stop RDE timer */ | ||
1500 | if (timer_pending(&udc_timer)) { | ||
1501 | set_rde = 0; | ||
1502 | mod_timer(&udc_timer, jiffies - 1); | ||
1503 | } | ||
1504 | /* stop poll stall timer */ | ||
1505 | if (timer_pending(&udc_pollstall_timer)) { | ||
1506 | mod_timer(&udc_pollstall_timer, jiffies - 1); | ||
1507 | } | ||
1508 | /* disable DMA */ | ||
1509 | tmp = readl(&dev->regs->ctl); | ||
1510 | tmp &= AMD_UNMASK_BIT(UDC_DEVCTL_RDE); | ||
1511 | tmp &= AMD_UNMASK_BIT(UDC_DEVCTL_TDE); | ||
1512 | writel(tmp, &dev->regs->ctl); | ||
1513 | |||
1514 | /* enable dynamic CSR programming */ | ||
1515 | tmp = readl(&dev->regs->cfg); | ||
1516 | tmp |= AMD_BIT(UDC_DEVCFG_CSR_PRG); | ||
1517 | /* set self powered */ | ||
1518 | tmp |= AMD_BIT(UDC_DEVCFG_SP); | ||
1519 | /* set remote wakeupable */ | ||
1520 | tmp |= AMD_BIT(UDC_DEVCFG_RWKP); | ||
1521 | writel(tmp, &dev->regs->cfg); | ||
1522 | |||
1523 | make_ep_lists(dev); | ||
1524 | |||
1525 | dev->data_ep_enabled = 0; | ||
1526 | dev->data_ep_queued = 0; | ||
1527 | } | ||
1528 | |||
1529 | /* Sets initial endpoint parameters */ | ||
1530 | static void udc_setup_endpoints(struct udc *dev) | ||
1531 | { | ||
1532 | struct udc_ep *ep; | ||
1533 | u32 tmp; | ||
1534 | u32 reg; | ||
1535 | |||
1536 | DBG(dev, "udc_setup_endpoints()\n"); | ||
1537 | |||
1538 | /* read enum speed */ | ||
1539 | tmp = readl(&dev->regs->sts); | ||
1540 | tmp = AMD_GETBITS(tmp, UDC_DEVSTS_ENUM_SPEED); | ||
1541 | if (tmp == UDC_DEVSTS_ENUM_SPEED_HIGH) { | ||
1542 | dev->gadget.speed = USB_SPEED_HIGH; | ||
1543 | } else if (tmp == UDC_DEVSTS_ENUM_SPEED_FULL) { | ||
1544 | dev->gadget.speed = USB_SPEED_FULL; | ||
1545 | } | ||
1546 | |||
1547 | /* set basic ep parameters */ | ||
1548 | for (tmp = 0; tmp < UDC_EP_NUM; tmp++) { | ||
1549 | ep = &dev->ep[tmp]; | ||
1550 | ep->dev = dev; | ||
1551 | ep->ep.name = ep_string[tmp]; | ||
1552 | ep->num = tmp; | ||
1553 | /* txfifo size is calculated at enable time */ | ||
1554 | ep->txfifo = dev->txfifo; | ||
1555 | |||
1556 | /* fifo size */ | ||
1557 | if (tmp < UDC_EPIN_NUM) { | ||
1558 | ep->fifo_depth = UDC_TXFIFO_SIZE; | ||
1559 | ep->in = 1; | ||
1560 | } else { | ||
1561 | ep->fifo_depth = UDC_RXFIFO_SIZE; | ||
1562 | ep->in = 0; | ||
1563 | |||
1564 | } | ||
1565 | ep->regs = &dev->ep_regs[tmp]; | ||
1566 | /* | ||
1567 | * ep will be reset only if ep was not enabled before to avoid | ||
1568 | * disabling ep interrupts when ENUM interrupt occurs but ep is | ||
1569 | * not enabled by gadget driver | ||
1570 | */ | ||
1571 | if (!ep->desc) { | ||
1572 | ep_init(dev->regs, ep); | ||
1573 | } | ||
1574 | |||
1575 | if (use_dma) { | ||
1576 | /* | ||
1577 | * ep->dma is not really used, just to indicate that | ||
1578 | * DMA is active: remove this | ||
1579 | * dma regs = dev control regs | ||
1580 | */ | ||
1581 | ep->dma = &dev->regs->ctl; | ||
1582 | |||
1583 | /* nak OUT endpoints until enable - not for ep0 */ | ||
1584 | if (tmp != UDC_EP0IN_IX && tmp != UDC_EP0OUT_IX | ||
1585 | && tmp > UDC_EPIN_NUM) { | ||
1586 | /* set NAK */ | ||
1587 | reg = readl(&dev->ep[tmp].regs->ctl); | ||
1588 | reg |= AMD_BIT(UDC_EPCTL_SNAK); | ||
1589 | writel(reg, &dev->ep[tmp].regs->ctl); | ||
1590 | dev->ep[tmp].naking = 1; | ||
1591 | |||
1592 | } | ||
1593 | } | ||
1594 | } | ||
1595 | /* EP0 max packet */ | ||
1596 | if (dev->gadget.speed == USB_SPEED_FULL) { | ||
1597 | dev->ep[UDC_EP0IN_IX].ep.maxpacket = UDC_FS_EP0IN_MAX_PKT_SIZE; | ||
1598 | dev->ep[UDC_EP0OUT_IX].ep.maxpacket = | ||
1599 | UDC_FS_EP0OUT_MAX_PKT_SIZE; | ||
1600 | } else if (dev->gadget.speed == USB_SPEED_HIGH) { | ||
1601 | dev->ep[UDC_EP0IN_IX].ep.maxpacket = UDC_EP0IN_MAX_PKT_SIZE; | ||
1602 | dev->ep[UDC_EP0OUT_IX].ep.maxpacket = UDC_EP0OUT_MAX_PKT_SIZE; | ||
1603 | } | ||
1604 | |||
1605 | /* | ||
1606 | * with suspend bug workaround, ep0 params for gadget driver | ||
1607 | * are set at gadget driver bind() call | ||
1608 | */ | ||
1609 | dev->gadget.ep0 = &dev->ep[UDC_EP0IN_IX].ep; | ||
1610 | dev->ep[UDC_EP0IN_IX].halted = 0; | ||
1611 | INIT_LIST_HEAD(&dev->gadget.ep0->ep_list); | ||
1612 | |||
1613 | /* init cfg/alt/int */ | ||
1614 | dev->cur_config = 0; | ||
1615 | dev->cur_intf = 0; | ||
1616 | dev->cur_alt = 0; | ||
1617 | } | ||
1618 | |||
1619 | /* Bringup after Connect event, initial bringup to be ready for ep0 events */ | ||
1620 | static void usb_connect(struct udc *dev) | ||
1621 | { | ||
1622 | |||
1623 | dev_info(&dev->pdev->dev, "USB Connect\n"); | ||
1624 | |||
1625 | dev->connected = 1; | ||
1626 | |||
1627 | /* put into initial config */ | ||
1628 | udc_basic_init(dev); | ||
1629 | |||
1630 | /* enable device setup interrupts */ | ||
1631 | udc_enable_dev_setup_interrupts(dev); | ||
1632 | } | ||
1633 | |||
1634 | /* | ||
1635 | * Calls gadget with disconnect event and resets the UDC and makes | ||
1636 | * initial bringup to be ready for ep0 events | ||
1637 | */ | ||
1638 | static void usb_disconnect(struct udc *dev) | ||
1639 | { | ||
1640 | |||
1641 | dev_info(&dev->pdev->dev, "USB Disconnect\n"); | ||
1642 | |||
1643 | dev->connected = 0; | ||
1644 | |||
1645 | /* mask interrupts */ | ||
1646 | udc_mask_unused_interrupts(dev); | ||
1647 | |||
1648 | /* REVISIT there doesn't seem to be a point to having this | ||
1649 | * talk to a tasklet ... do it directly, we already hold | ||
1650 | * the spinlock needed to process the disconnect. | ||
1651 | */ | ||
1652 | |||
1653 | tasklet_schedule(&disconnect_tasklet); | ||
1654 | } | ||
1655 | |||
1656 | /* Tasklet for disconnect to be outside of interrupt context */ | ||
1657 | static void udc_tasklet_disconnect(unsigned long par) | ||
1658 | { | ||
1659 | struct udc *dev = (struct udc *)(*((struct udc **) par)); | ||
1660 | u32 tmp; | ||
1661 | |||
1662 | DBG(dev, "Tasklet disconnect\n"); | ||
1663 | spin_lock_irq(&dev->lock); | ||
1664 | |||
1665 | if (dev->driver) { | ||
1666 | spin_unlock(&dev->lock); | ||
1667 | dev->driver->disconnect(&dev->gadget); | ||
1668 | spin_lock(&dev->lock); | ||
1669 | |||
1670 | /* empty queues */ | ||
1671 | for (tmp = 0; tmp < UDC_EP_NUM; tmp++) { | ||
1672 | empty_req_queue(&dev->ep[tmp]); | ||
1673 | } | ||
1674 | |||
1675 | } | ||
1676 | |||
1677 | /* disable ep0 */ | ||
1678 | ep_init(dev->regs, | ||
1679 | &dev->ep[UDC_EP0IN_IX]); | ||
1680 | |||
1681 | |||
1682 | if (!soft_reset_occured) { | ||
1683 | /* init controller by soft reset */ | ||
1684 | udc_soft_reset(dev); | ||
1685 | soft_reset_occured++; | ||
1686 | } | ||
1687 | |||
1688 | /* re-enable dev interrupts */ | ||
1689 | udc_enable_dev_setup_interrupts(dev); | ||
1690 | /* back to full speed ? */ | ||
1691 | if (use_fullspeed) { | ||
1692 | tmp = readl(&dev->regs->cfg); | ||
1693 | tmp = AMD_ADDBITS(tmp, UDC_DEVCFG_SPD_FS, UDC_DEVCFG_SPD); | ||
1694 | writel(tmp, &dev->regs->cfg); | ||
1695 | } | ||
1696 | |||
1697 | spin_unlock_irq(&dev->lock); | ||
1698 | } | ||
1699 | |||
1700 | /* Reset the UDC core */ | ||
1701 | static void udc_soft_reset(struct udc *dev) | ||
1702 | { | ||
1703 | unsigned long flags; | ||
1704 | |||
1705 | DBG(dev, "Soft reset\n"); | ||
1706 | /* | ||
1707 | * reset possible waiting interrupts, because int. | ||
1708 | * status is lost after soft reset, | ||
1709 | * ep int. status reset | ||
1710 | */ | ||
1711 | writel(UDC_EPINT_MSK_DISABLE_ALL, &dev->regs->ep_irqsts); | ||
1712 | /* device int. status reset */ | ||
1713 | writel(UDC_DEV_MSK_DISABLE, &dev->regs->irqsts); | ||
1714 | |||
1715 | spin_lock_irqsave(&udc_irq_spinlock, flags); | ||
1716 | writel(AMD_BIT(UDC_DEVCFG_SOFTRESET), &dev->regs->cfg); | ||
1717 | readl(&dev->regs->cfg); | ||
1718 | spin_unlock_irqrestore(&udc_irq_spinlock, flags); | ||
1719 | |||
1720 | } | ||
1721 | |||
1722 | /* RDE timer callback to set RDE bit */ | ||
1723 | static void udc_timer_function(unsigned long v) | ||
1724 | { | ||
1725 | u32 tmp; | ||
1726 | |||
1727 | spin_lock_irq(&udc_irq_spinlock); | ||
1728 | |||
1729 | if (set_rde > 0) { | ||
1730 | /* | ||
1731 | * open the fifo if fifo was filled on last timer call | ||
1732 | * conditionally | ||
1733 | */ | ||
1734 | if (set_rde > 1) { | ||
1735 | /* set RDE to receive setup data */ | ||
1736 | tmp = readl(&udc->regs->ctl); | ||
1737 | tmp |= AMD_BIT(UDC_DEVCTL_RDE); | ||
1738 | writel(tmp, &udc->regs->ctl); | ||
1739 | set_rde = -1; | ||
1740 | } else if (readl(&udc->regs->sts) | ||
1741 | & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY)) { | ||
1742 | /* | ||
1743 | * if fifo empty setup polling, do not just | ||
1744 | * open the fifo | ||
1745 | */ | ||
1746 | udc_timer.expires = jiffies + HZ/UDC_RDE_TIMER_DIV; | ||
1747 | if (!stop_timer) { | ||
1748 | add_timer(&udc_timer); | ||
1749 | } | ||
1750 | } else { | ||
1751 | /* | ||
1752 | * fifo contains data now, setup timer for opening | ||
1753 | * the fifo when timer expires to be able to receive | ||
1754 | * setup packets, when data packets gets queued by | ||
1755 | * gadget layer then timer will forced to expire with | ||
1756 | * set_rde=0 (RDE is set in udc_queue()) | ||
1757 | */ | ||
1758 | set_rde++; | ||
1759 | /* debug: lhadmot_timer_start = 221070 */ | ||
1760 | udc_timer.expires = jiffies + HZ*UDC_RDE_TIMER_SECONDS; | ||
1761 | if (!stop_timer) { | ||
1762 | add_timer(&udc_timer); | ||
1763 | } | ||
1764 | } | ||
1765 | |||
1766 | } else | ||
1767 | set_rde = -1; /* RDE was set by udc_queue() */ | ||
1768 | spin_unlock_irq(&udc_irq_spinlock); | ||
1769 | if (stop_timer) | ||
1770 | complete(&on_exit); | ||
1771 | |||
1772 | } | ||
1773 | |||
1774 | /* Handle halt state, used in stall poll timer */ | ||
1775 | static void udc_handle_halt_state(struct udc_ep *ep) | ||
1776 | { | ||
1777 | u32 tmp; | ||
1778 | /* set stall as long not halted */ | ||
1779 | if (ep->halted == 1) { | ||
1780 | tmp = readl(&ep->regs->ctl); | ||
1781 | /* STALL cleared ? */ | ||
1782 | if (!(tmp & AMD_BIT(UDC_EPCTL_S))) { | ||
1783 | /* | ||
1784 | * FIXME: MSC spec requires that stall remains | ||
1785 | * even on receivng of CLEAR_FEATURE HALT. So | ||
1786 | * we would set STALL again here to be compliant. | ||
1787 | * But with current mass storage drivers this does | ||
1788 | * not work (would produce endless host retries). | ||
1789 | * So we clear halt on CLEAR_FEATURE. | ||
1790 | * | ||
1791 | DBG(ep->dev, "ep %d: set STALL again\n", ep->num); | ||
1792 | tmp |= AMD_BIT(UDC_EPCTL_S); | ||
1793 | writel(tmp, &ep->regs->ctl);*/ | ||
1794 | |||
1795 | /* clear NAK by writing CNAK */ | ||
1796 | tmp |= AMD_BIT(UDC_EPCTL_CNAK); | ||
1797 | writel(tmp, &ep->regs->ctl); | ||
1798 | ep->halted = 0; | ||
1799 | UDC_QUEUE_CNAK(ep, ep->num); | ||
1800 | } | ||
1801 | } | ||
1802 | } | ||
1803 | |||
1804 | /* Stall timer callback to poll S bit and set it again after */ | ||
1805 | static void udc_pollstall_timer_function(unsigned long v) | ||
1806 | { | ||
1807 | struct udc_ep *ep; | ||
1808 | int halted = 0; | ||
1809 | |||
1810 | spin_lock_irq(&udc_stall_spinlock); | ||
1811 | /* | ||
1812 | * only one IN and OUT endpoints are handled | ||
1813 | * IN poll stall | ||
1814 | */ | ||
1815 | ep = &udc->ep[UDC_EPIN_IX]; | ||
1816 | udc_handle_halt_state(ep); | ||
1817 | if (ep->halted) | ||
1818 | halted = 1; | ||
1819 | /* OUT poll stall */ | ||
1820 | ep = &udc->ep[UDC_EPOUT_IX]; | ||
1821 | udc_handle_halt_state(ep); | ||
1822 | if (ep->halted) | ||
1823 | halted = 1; | ||
1824 | |||
1825 | /* setup timer again when still halted */ | ||
1826 | if (!stop_pollstall_timer && halted) { | ||
1827 | udc_pollstall_timer.expires = jiffies + | ||
1828 | HZ * UDC_POLLSTALL_TIMER_USECONDS | ||
1829 | / (1000 * 1000); | ||
1830 | add_timer(&udc_pollstall_timer); | ||
1831 | } | ||
1832 | spin_unlock_irq(&udc_stall_spinlock); | ||
1833 | |||
1834 | if (stop_pollstall_timer) | ||
1835 | complete(&on_pollstall_exit); | ||
1836 | } | ||
1837 | |||
1838 | /* Inits endpoint 0 so that SETUP packets are processed */ | ||
1839 | static void activate_control_endpoints(struct udc *dev) | ||
1840 | { | ||
1841 | u32 tmp; | ||
1842 | |||
1843 | DBG(dev, "activate_control_endpoints\n"); | ||
1844 | |||
1845 | /* flush fifo */ | ||
1846 | tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
1847 | tmp |= AMD_BIT(UDC_EPCTL_F); | ||
1848 | writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
1849 | |||
1850 | /* set ep0 directions */ | ||
1851 | dev->ep[UDC_EP0IN_IX].in = 1; | ||
1852 | dev->ep[UDC_EP0OUT_IX].in = 0; | ||
1853 | |||
1854 | /* set buffer size (tx fifo entries) of EP0_IN */ | ||
1855 | tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->bufin_framenum); | ||
1856 | if (dev->gadget.speed == USB_SPEED_FULL) | ||
1857 | tmp = AMD_ADDBITS(tmp, UDC_FS_EPIN0_BUFF_SIZE, | ||
1858 | UDC_EPIN_BUFF_SIZE); | ||
1859 | else if (dev->gadget.speed == USB_SPEED_HIGH) | ||
1860 | tmp = AMD_ADDBITS(tmp, UDC_EPIN0_BUFF_SIZE, | ||
1861 | UDC_EPIN_BUFF_SIZE); | ||
1862 | writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->bufin_framenum); | ||
1863 | |||
1864 | /* set max packet size of EP0_IN */ | ||
1865 | tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->bufout_maxpkt); | ||
1866 | if (dev->gadget.speed == USB_SPEED_FULL) | ||
1867 | tmp = AMD_ADDBITS(tmp, UDC_FS_EP0IN_MAX_PKT_SIZE, | ||
1868 | UDC_EP_MAX_PKT_SIZE); | ||
1869 | else if (dev->gadget.speed == USB_SPEED_HIGH) | ||
1870 | tmp = AMD_ADDBITS(tmp, UDC_EP0IN_MAX_PKT_SIZE, | ||
1871 | UDC_EP_MAX_PKT_SIZE); | ||
1872 | writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->bufout_maxpkt); | ||
1873 | |||
1874 | /* set max packet size of EP0_OUT */ | ||
1875 | tmp = readl(&dev->ep[UDC_EP0OUT_IX].regs->bufout_maxpkt); | ||
1876 | if (dev->gadget.speed == USB_SPEED_FULL) | ||
1877 | tmp = AMD_ADDBITS(tmp, UDC_FS_EP0OUT_MAX_PKT_SIZE, | ||
1878 | UDC_EP_MAX_PKT_SIZE); | ||
1879 | else if (dev->gadget.speed == USB_SPEED_HIGH) | ||
1880 | tmp = AMD_ADDBITS(tmp, UDC_EP0OUT_MAX_PKT_SIZE, | ||
1881 | UDC_EP_MAX_PKT_SIZE); | ||
1882 | writel(tmp, &dev->ep[UDC_EP0OUT_IX].regs->bufout_maxpkt); | ||
1883 | |||
1884 | /* set max packet size of EP0 in UDC CSR */ | ||
1885 | tmp = readl(&dev->csr->ne[0]); | ||
1886 | if (dev->gadget.speed == USB_SPEED_FULL) | ||
1887 | tmp = AMD_ADDBITS(tmp, UDC_FS_EP0OUT_MAX_PKT_SIZE, | ||
1888 | UDC_CSR_NE_MAX_PKT); | ||
1889 | else if (dev->gadget.speed == USB_SPEED_HIGH) | ||
1890 | tmp = AMD_ADDBITS(tmp, UDC_EP0OUT_MAX_PKT_SIZE, | ||
1891 | UDC_CSR_NE_MAX_PKT); | ||
1892 | writel(tmp, &dev->csr->ne[0]); | ||
1893 | |||
1894 | if (use_dma) { | ||
1895 | dev->ep[UDC_EP0OUT_IX].td->status |= | ||
1896 | AMD_BIT(UDC_DMA_OUT_STS_L); | ||
1897 | /* write dma desc address */ | ||
1898 | writel(dev->ep[UDC_EP0OUT_IX].td_stp_dma, | ||
1899 | &dev->ep[UDC_EP0OUT_IX].regs->subptr); | ||
1900 | writel(dev->ep[UDC_EP0OUT_IX].td_phys, | ||
1901 | &dev->ep[UDC_EP0OUT_IX].regs->desptr); | ||
1902 | /* stop RDE timer */ | ||
1903 | if (timer_pending(&udc_timer)) { | ||
1904 | set_rde = 0; | ||
1905 | mod_timer(&udc_timer, jiffies - 1); | ||
1906 | } | ||
1907 | /* stop pollstall timer */ | ||
1908 | if (timer_pending(&udc_pollstall_timer)) { | ||
1909 | mod_timer(&udc_pollstall_timer, jiffies - 1); | ||
1910 | } | ||
1911 | /* enable DMA */ | ||
1912 | tmp = readl(&dev->regs->ctl); | ||
1913 | tmp |= AMD_BIT(UDC_DEVCTL_MODE) | ||
1914 | | AMD_BIT(UDC_DEVCTL_RDE) | ||
1915 | | AMD_BIT(UDC_DEVCTL_TDE); | ||
1916 | if (use_dma_bufferfill_mode) { | ||
1917 | tmp |= AMD_BIT(UDC_DEVCTL_BF); | ||
1918 | } else if (use_dma_ppb_du) { | ||
1919 | tmp |= AMD_BIT(UDC_DEVCTL_DU); | ||
1920 | } | ||
1921 | writel(tmp, &dev->regs->ctl); | ||
1922 | } | ||
1923 | |||
1924 | /* clear NAK by writing CNAK for EP0IN */ | ||
1925 | tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
1926 | tmp |= AMD_BIT(UDC_EPCTL_CNAK); | ||
1927 | writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
1928 | dev->ep[UDC_EP0IN_IX].naking = 0; | ||
1929 | UDC_QUEUE_CNAK(&dev->ep[UDC_EP0IN_IX], UDC_EP0IN_IX); | ||
1930 | |||
1931 | /* clear NAK by writing CNAK for EP0OUT */ | ||
1932 | tmp = readl(&dev->ep[UDC_EP0OUT_IX].regs->ctl); | ||
1933 | tmp |= AMD_BIT(UDC_EPCTL_CNAK); | ||
1934 | writel(tmp, &dev->ep[UDC_EP0OUT_IX].regs->ctl); | ||
1935 | dev->ep[UDC_EP0OUT_IX].naking = 0; | ||
1936 | UDC_QUEUE_CNAK(&dev->ep[UDC_EP0OUT_IX], UDC_EP0OUT_IX); | ||
1937 | } | ||
1938 | |||
1939 | /* Make endpoint 0 ready for control traffic */ | ||
1940 | static int setup_ep0(struct udc *dev) | ||
1941 | { | ||
1942 | activate_control_endpoints(dev); | ||
1943 | /* enable ep0 interrupts */ | ||
1944 | udc_enable_ep0_interrupts(dev); | ||
1945 | /* enable device setup interrupts */ | ||
1946 | udc_enable_dev_setup_interrupts(dev); | ||
1947 | |||
1948 | return 0; | ||
1949 | } | ||
1950 | |||
1951 | /* Called by gadget driver to register itself */ | ||
1952 | int usb_gadget_register_driver(struct usb_gadget_driver *driver) | ||
1953 | { | ||
1954 | struct udc *dev = udc; | ||
1955 | int retval; | ||
1956 | u32 tmp; | ||
1957 | |||
1958 | if (!driver || !driver->bind || !driver->setup | ||
1959 | || driver->speed != USB_SPEED_HIGH) | ||
1960 | return -EINVAL; | ||
1961 | if (!dev) | ||
1962 | return -ENODEV; | ||
1963 | if (dev->driver) | ||
1964 | return -EBUSY; | ||
1965 | |||
1966 | driver->driver.bus = NULL; | ||
1967 | dev->driver = driver; | ||
1968 | dev->gadget.dev.driver = &driver->driver; | ||
1969 | |||
1970 | retval = driver->bind(&dev->gadget); | ||
1971 | |||
1972 | /* Some gadget drivers use both ep0 directions. | ||
1973 | * NOTE: to gadget driver, ep0 is just one endpoint... | ||
1974 | */ | ||
1975 | dev->ep[UDC_EP0OUT_IX].ep.driver_data = | ||
1976 | dev->ep[UDC_EP0IN_IX].ep.driver_data; | ||
1977 | |||
1978 | if (retval) { | ||
1979 | DBG(dev, "binding to %s returning %d\n", | ||
1980 | driver->driver.name, retval); | ||
1981 | dev->driver = NULL; | ||
1982 | dev->gadget.dev.driver = NULL; | ||
1983 | return retval; | ||
1984 | } | ||
1985 | |||
1986 | /* get ready for ep0 traffic */ | ||
1987 | setup_ep0(dev); | ||
1988 | |||
1989 | /* clear SD */ | ||
1990 | tmp = readl(&dev->regs->ctl); | ||
1991 | tmp = tmp & AMD_CLEAR_BIT(UDC_DEVCTL_SD); | ||
1992 | writel(tmp, &dev->regs->ctl); | ||
1993 | |||
1994 | usb_connect(dev); | ||
1995 | |||
1996 | return 0; | ||
1997 | } | ||
1998 | EXPORT_SYMBOL(usb_gadget_register_driver); | ||
1999 | |||
2000 | /* shutdown requests and disconnect from gadget */ | ||
2001 | static void | ||
2002 | shutdown(struct udc *dev, struct usb_gadget_driver *driver) | ||
2003 | __releases(dev->lock) | ||
2004 | __acquires(dev->lock) | ||
2005 | { | ||
2006 | int tmp; | ||
2007 | |||
2008 | /* empty queues and init hardware */ | ||
2009 | udc_basic_init(dev); | ||
2010 | for (tmp = 0; tmp < UDC_EP_NUM; tmp++) { | ||
2011 | empty_req_queue(&dev->ep[tmp]); | ||
2012 | } | ||
2013 | |||
2014 | if (dev->gadget.speed != USB_SPEED_UNKNOWN) { | ||
2015 | spin_unlock(&dev->lock); | ||
2016 | driver->disconnect(&dev->gadget); | ||
2017 | spin_lock(&dev->lock); | ||
2018 | } | ||
2019 | /* init */ | ||
2020 | udc_setup_endpoints(dev); | ||
2021 | } | ||
2022 | |||
2023 | /* Called by gadget driver to unregister itself */ | ||
2024 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | ||
2025 | { | ||
2026 | struct udc *dev = udc; | ||
2027 | unsigned long flags; | ||
2028 | u32 tmp; | ||
2029 | |||
2030 | if (!dev) | ||
2031 | return -ENODEV; | ||
2032 | if (!driver || driver != dev->driver || !driver->unbind) | ||
2033 | return -EINVAL; | ||
2034 | |||
2035 | spin_lock_irqsave(&dev->lock, flags); | ||
2036 | udc_mask_unused_interrupts(dev); | ||
2037 | shutdown(dev, driver); | ||
2038 | spin_unlock_irqrestore(&dev->lock, flags); | ||
2039 | |||
2040 | driver->unbind(&dev->gadget); | ||
2041 | dev->driver = NULL; | ||
2042 | |||
2043 | /* set SD */ | ||
2044 | tmp = readl(&dev->regs->ctl); | ||
2045 | tmp |= AMD_BIT(UDC_DEVCTL_SD); | ||
2046 | writel(tmp, &dev->regs->ctl); | ||
2047 | |||
2048 | |||
2049 | DBG(dev, "%s: unregistered\n", driver->driver.name); | ||
2050 | |||
2051 | return 0; | ||
2052 | } | ||
2053 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | ||
2054 | |||
2055 | |||
2056 | /* Clear pending NAK bits */ | ||
2057 | static void udc_process_cnak_queue(struct udc *dev) | ||
2058 | { | ||
2059 | u32 tmp; | ||
2060 | u32 reg; | ||
2061 | |||
2062 | /* check epin's */ | ||
2063 | DBG(dev, "CNAK pending queue processing\n"); | ||
2064 | for (tmp = 0; tmp < UDC_EPIN_NUM_USED; tmp++) { | ||
2065 | if (cnak_pending & (1 << tmp)) { | ||
2066 | DBG(dev, "CNAK pending for ep%d\n", tmp); | ||
2067 | /* clear NAK by writing CNAK */ | ||
2068 | reg = readl(&dev->ep[tmp].regs->ctl); | ||
2069 | reg |= AMD_BIT(UDC_EPCTL_CNAK); | ||
2070 | writel(reg, &dev->ep[tmp].regs->ctl); | ||
2071 | dev->ep[tmp].naking = 0; | ||
2072 | UDC_QUEUE_CNAK(&dev->ep[tmp], dev->ep[tmp].num); | ||
2073 | } | ||
2074 | } | ||
2075 | /* ... and ep0out */ | ||
2076 | if (cnak_pending & (1 << UDC_EP0OUT_IX)) { | ||
2077 | DBG(dev, "CNAK pending for ep%d\n", UDC_EP0OUT_IX); | ||
2078 | /* clear NAK by writing CNAK */ | ||
2079 | reg = readl(&dev->ep[UDC_EP0OUT_IX].regs->ctl); | ||
2080 | reg |= AMD_BIT(UDC_EPCTL_CNAK); | ||
2081 | writel(reg, &dev->ep[UDC_EP0OUT_IX].regs->ctl); | ||
2082 | dev->ep[UDC_EP0OUT_IX].naking = 0; | ||
2083 | UDC_QUEUE_CNAK(&dev->ep[UDC_EP0OUT_IX], | ||
2084 | dev->ep[UDC_EP0OUT_IX].num); | ||
2085 | } | ||
2086 | } | ||
2087 | |||
2088 | /* Enabling RX DMA after setup packet */ | ||
2089 | static void udc_ep0_set_rde(struct udc *dev) | ||
2090 | { | ||
2091 | if (use_dma) { | ||
2092 | /* | ||
2093 | * only enable RXDMA when no data endpoint enabled | ||
2094 | * or data is queued | ||
2095 | */ | ||
2096 | if (!dev->data_ep_enabled || dev->data_ep_queued) { | ||
2097 | udc_set_rde(dev); | ||
2098 | } else { | ||
2099 | /* | ||
2100 | * setup timer for enabling RDE (to not enable | ||
2101 | * RXFIFO DMA for data endpoints to early) | ||
2102 | */ | ||
2103 | if (set_rde != 0 && !timer_pending(&udc_timer)) { | ||
2104 | udc_timer.expires = | ||
2105 | jiffies + HZ/UDC_RDE_TIMER_DIV; | ||
2106 | set_rde = 1; | ||
2107 | if (!stop_timer) { | ||
2108 | add_timer(&udc_timer); | ||
2109 | } | ||
2110 | } | ||
2111 | } | ||
2112 | } | ||
2113 | } | ||
2114 | |||
2115 | |||
2116 | /* Interrupt handler for data OUT traffic */ | ||
2117 | static irqreturn_t udc_data_out_isr(struct udc *dev, int ep_ix) | ||
2118 | { | ||
2119 | irqreturn_t ret_val = IRQ_NONE; | ||
2120 | u32 tmp; | ||
2121 | struct udc_ep *ep; | ||
2122 | struct udc_request *req; | ||
2123 | unsigned int count; | ||
2124 | struct udc_data_dma *td = NULL; | ||
2125 | unsigned dma_done; | ||
2126 | |||
2127 | VDBG(dev, "ep%d irq\n", ep_ix); | ||
2128 | ep = &dev->ep[ep_ix]; | ||
2129 | |||
2130 | tmp = readl(&ep->regs->sts); | ||
2131 | if (use_dma) { | ||
2132 | /* BNA event ? */ | ||
2133 | if (tmp & AMD_BIT(UDC_EPSTS_BNA)) { | ||
2134 | DBG(dev, "BNA ep%dout occured - DESPTR = %x \n", | ||
2135 | ep->num, readl(&ep->regs->desptr)); | ||
2136 | /* clear BNA */ | ||
2137 | writel(tmp | AMD_BIT(UDC_EPSTS_BNA), &ep->regs->sts); | ||
2138 | if (!ep->cancel_transfer) | ||
2139 | ep->bna_occurred = 1; | ||
2140 | else | ||
2141 | ep->cancel_transfer = 0; | ||
2142 | ret_val = IRQ_HANDLED; | ||
2143 | goto finished; | ||
2144 | } | ||
2145 | } | ||
2146 | /* HE event ? */ | ||
2147 | if (tmp & AMD_BIT(UDC_EPSTS_HE)) { | ||
2148 | dev_err(&dev->pdev->dev, "HE ep%dout occured\n", ep->num); | ||
2149 | |||
2150 | /* clear HE */ | ||
2151 | writel(tmp | AMD_BIT(UDC_EPSTS_HE), &ep->regs->sts); | ||
2152 | ret_val = IRQ_HANDLED; | ||
2153 | goto finished; | ||
2154 | } | ||
2155 | |||
2156 | if (!list_empty(&ep->queue)) { | ||
2157 | |||
2158 | /* next request */ | ||
2159 | req = list_entry(ep->queue.next, | ||
2160 | struct udc_request, queue); | ||
2161 | } else { | ||
2162 | req = NULL; | ||
2163 | udc_rxfifo_pending = 1; | ||
2164 | } | ||
2165 | VDBG(dev, "req = %p\n", req); | ||
2166 | /* fifo mode */ | ||
2167 | if (!use_dma) { | ||
2168 | |||
2169 | /* read fifo */ | ||
2170 | if (req && udc_rxfifo_read(ep, req)) { | ||
2171 | ret_val = IRQ_HANDLED; | ||
2172 | |||
2173 | /* finish */ | ||
2174 | complete_req(ep, req, 0); | ||
2175 | /* next request */ | ||
2176 | if (!list_empty(&ep->queue) && !ep->halted) { | ||
2177 | req = list_entry(ep->queue.next, | ||
2178 | struct udc_request, queue); | ||
2179 | } else | ||
2180 | req = NULL; | ||
2181 | } | ||
2182 | |||
2183 | /* DMA */ | ||
2184 | } else if (!ep->cancel_transfer && req != NULL) { | ||
2185 | ret_val = IRQ_HANDLED; | ||
2186 | |||
2187 | /* check for DMA done */ | ||
2188 | if (!use_dma_ppb) { | ||
2189 | dma_done = AMD_GETBITS(req->td_data->status, | ||
2190 | UDC_DMA_OUT_STS_BS); | ||
2191 | /* packet per buffer mode - rx bytes */ | ||
2192 | } else { | ||
2193 | /* | ||
2194 | * if BNA occurred then recover desc. from | ||
2195 | * BNA dummy desc. | ||
2196 | */ | ||
2197 | if (ep->bna_occurred) { | ||
2198 | VDBG(dev, "Recover desc. from BNA dummy\n"); | ||
2199 | memcpy(req->td_data, ep->bna_dummy_req->td_data, | ||
2200 | sizeof(struct udc_data_dma)); | ||
2201 | ep->bna_occurred = 0; | ||
2202 | udc_init_bna_dummy(ep->req); | ||
2203 | } | ||
2204 | td = udc_get_last_dma_desc(req); | ||
2205 | dma_done = AMD_GETBITS(td->status, UDC_DMA_OUT_STS_BS); | ||
2206 | } | ||
2207 | if (dma_done == UDC_DMA_OUT_STS_BS_DMA_DONE) { | ||
2208 | /* buffer fill mode - rx bytes */ | ||
2209 | if (!use_dma_ppb) { | ||
2210 | /* received number bytes */ | ||
2211 | count = AMD_GETBITS(req->td_data->status, | ||
2212 | UDC_DMA_OUT_STS_RXBYTES); | ||
2213 | VDBG(dev, "rx bytes=%u\n", count); | ||
2214 | /* packet per buffer mode - rx bytes */ | ||
2215 | } else { | ||
2216 | VDBG(dev, "req->td_data=%p\n", req->td_data); | ||
2217 | VDBG(dev, "last desc = %p\n", td); | ||
2218 | /* received number bytes */ | ||
2219 | if (use_dma_ppb_du) { | ||
2220 | /* every desc. counts bytes */ | ||
2221 | count = udc_get_ppbdu_rxbytes(req); | ||
2222 | } else { | ||
2223 | /* last desc. counts bytes */ | ||
2224 | count = AMD_GETBITS(td->status, | ||
2225 | UDC_DMA_OUT_STS_RXBYTES); | ||
2226 | if (!count && req->req.length | ||
2227 | == UDC_DMA_MAXPACKET) { | ||
2228 | /* | ||
2229 | * on 64k packets the RXBYTES | ||
2230 | * field is zero | ||
2231 | */ | ||
2232 | count = UDC_DMA_MAXPACKET; | ||
2233 | } | ||
2234 | } | ||
2235 | VDBG(dev, "last desc rx bytes=%u\n", count); | ||
2236 | } | ||
2237 | |||
2238 | tmp = req->req.length - req->req.actual; | ||
2239 | if (count > tmp) { | ||
2240 | if ((tmp % ep->ep.maxpacket) != 0) { | ||
2241 | DBG(dev, "%s: rx %db, space=%db\n", | ||
2242 | ep->ep.name, count, tmp); | ||
2243 | req->req.status = -EOVERFLOW; | ||
2244 | } | ||
2245 | count = tmp; | ||
2246 | } | ||
2247 | req->req.actual += count; | ||
2248 | req->dma_going = 0; | ||
2249 | /* complete request */ | ||
2250 | complete_req(ep, req, 0); | ||
2251 | |||
2252 | /* next request */ | ||
2253 | if (!list_empty(&ep->queue) && !ep->halted) { | ||
2254 | req = list_entry(ep->queue.next, | ||
2255 | struct udc_request, | ||
2256 | queue); | ||
2257 | /* | ||
2258 | * DMA may be already started by udc_queue() | ||
2259 | * called by gadget drivers completion | ||
2260 | * routine. This happens when queue | ||
2261 | * holds one request only. | ||
2262 | */ | ||
2263 | if (req->dma_going == 0) { | ||
2264 | /* next dma */ | ||
2265 | if (prep_dma(ep, req, GFP_ATOMIC) != 0) | ||
2266 | goto finished; | ||
2267 | /* write desc pointer */ | ||
2268 | writel(req->td_phys, | ||
2269 | &ep->regs->desptr); | ||
2270 | req->dma_going = 1; | ||
2271 | /* enable DMA */ | ||
2272 | udc_set_rde(dev); | ||
2273 | } | ||
2274 | } else { | ||
2275 | /* | ||
2276 | * implant BNA dummy descriptor to allow | ||
2277 | * RXFIFO opening by RDE | ||
2278 | */ | ||
2279 | if (ep->bna_dummy_req) { | ||
2280 | /* write desc pointer */ | ||
2281 | writel(ep->bna_dummy_req->td_phys, | ||
2282 | &ep->regs->desptr); | ||
2283 | ep->bna_occurred = 0; | ||
2284 | } | ||
2285 | |||
2286 | /* | ||
2287 | * schedule timer for setting RDE if queue | ||
2288 | * remains empty to allow ep0 packets pass | ||
2289 | * through | ||
2290 | */ | ||
2291 | if (set_rde != 0 | ||
2292 | && !timer_pending(&udc_timer)) { | ||
2293 | udc_timer.expires = | ||
2294 | jiffies | ||
2295 | + HZ*UDC_RDE_TIMER_SECONDS; | ||
2296 | set_rde = 1; | ||
2297 | if (!stop_timer) { | ||
2298 | add_timer(&udc_timer); | ||
2299 | } | ||
2300 | } | ||
2301 | if (ep->num != UDC_EP0OUT_IX) | ||
2302 | dev->data_ep_queued = 0; | ||
2303 | } | ||
2304 | |||
2305 | } else { | ||
2306 | /* | ||
2307 | * RX DMA must be reenabled for each desc in PPBDU mode | ||
2308 | * and must be enabled for PPBNDU mode in case of BNA | ||
2309 | */ | ||
2310 | udc_set_rde(dev); | ||
2311 | } | ||
2312 | |||
2313 | } else if (ep->cancel_transfer) { | ||
2314 | ret_val = IRQ_HANDLED; | ||
2315 | ep->cancel_transfer = 0; | ||
2316 | } | ||
2317 | |||
2318 | /* check pending CNAKS */ | ||
2319 | if (cnak_pending) { | ||
2320 | /* CNAk processing when rxfifo empty only */ | ||
2321 | if (readl(&dev->regs->sts) & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY)) { | ||
2322 | udc_process_cnak_queue(dev); | ||
2323 | } | ||
2324 | } | ||
2325 | |||
2326 | /* clear OUT bits in ep status */ | ||
2327 | writel(UDC_EPSTS_OUT_CLEAR, &ep->regs->sts); | ||
2328 | finished: | ||
2329 | return ret_val; | ||
2330 | } | ||
2331 | |||
2332 | /* Interrupt handler for data IN traffic */ | ||
2333 | static irqreturn_t udc_data_in_isr(struct udc *dev, int ep_ix) | ||
2334 | { | ||
2335 | irqreturn_t ret_val = IRQ_NONE; | ||
2336 | u32 tmp; | ||
2337 | u32 epsts; | ||
2338 | struct udc_ep *ep; | ||
2339 | struct udc_request *req; | ||
2340 | struct udc_data_dma *td; | ||
2341 | unsigned dma_done; | ||
2342 | unsigned len; | ||
2343 | |||
2344 | ep = &dev->ep[ep_ix]; | ||
2345 | |||
2346 | epsts = readl(&ep->regs->sts); | ||
2347 | if (use_dma) { | ||
2348 | /* BNA ? */ | ||
2349 | if (epsts & AMD_BIT(UDC_EPSTS_BNA)) { | ||
2350 | dev_err(&dev->pdev->dev, | ||
2351 | "BNA ep%din occured - DESPTR = %08lx \n", | ||
2352 | ep->num, | ||
2353 | (unsigned long) readl(&ep->regs->desptr)); | ||
2354 | |||
2355 | /* clear BNA */ | ||
2356 | writel(epsts, &ep->regs->sts); | ||
2357 | ret_val = IRQ_HANDLED; | ||
2358 | goto finished; | ||
2359 | } | ||
2360 | } | ||
2361 | /* HE event ? */ | ||
2362 | if (epsts & AMD_BIT(UDC_EPSTS_HE)) { | ||
2363 | dev_err(&dev->pdev->dev, | ||
2364 | "HE ep%dn occured - DESPTR = %08lx \n", | ||
2365 | ep->num, (unsigned long) readl(&ep->regs->desptr)); | ||
2366 | |||
2367 | /* clear HE */ | ||
2368 | writel(epsts | AMD_BIT(UDC_EPSTS_HE), &ep->regs->sts); | ||
2369 | ret_val = IRQ_HANDLED; | ||
2370 | goto finished; | ||
2371 | } | ||
2372 | |||
2373 | /* DMA completion */ | ||
2374 | if (epsts & AMD_BIT(UDC_EPSTS_TDC)) { | ||
2375 | VDBG(dev, "TDC set- completion\n"); | ||
2376 | ret_val = IRQ_HANDLED; | ||
2377 | if (!ep->cancel_transfer && !list_empty(&ep->queue)) { | ||
2378 | req = list_entry(ep->queue.next, | ||
2379 | struct udc_request, queue); | ||
2380 | if (req) { | ||
2381 | /* | ||
2382 | * length bytes transfered | ||
2383 | * check dma done of last desc. in PPBDU mode | ||
2384 | */ | ||
2385 | if (use_dma_ppb_du) { | ||
2386 | td = udc_get_last_dma_desc(req); | ||
2387 | if (td) { | ||
2388 | dma_done = | ||
2389 | AMD_GETBITS(td->status, | ||
2390 | UDC_DMA_IN_STS_BS); | ||
2391 | /* don't care DMA done */ | ||
2392 | req->req.actual = | ||
2393 | req->req.length; | ||
2394 | } | ||
2395 | } else { | ||
2396 | /* assume all bytes transferred */ | ||
2397 | req->req.actual = req->req.length; | ||
2398 | } | ||
2399 | |||
2400 | if (req->req.actual == req->req.length) { | ||
2401 | /* complete req */ | ||
2402 | complete_req(ep, req, 0); | ||
2403 | req->dma_going = 0; | ||
2404 | /* further request available ? */ | ||
2405 | if (list_empty(&ep->queue)) { | ||
2406 | /* disable interrupt */ | ||
2407 | tmp = readl( | ||
2408 | &dev->regs->ep_irqmsk); | ||
2409 | tmp |= AMD_BIT(ep->num); | ||
2410 | writel(tmp, | ||
2411 | &dev->regs->ep_irqmsk); | ||
2412 | } | ||
2413 | |||
2414 | } | ||
2415 | } | ||
2416 | } | ||
2417 | ep->cancel_transfer = 0; | ||
2418 | |||
2419 | } | ||
2420 | /* | ||
2421 | * status reg has IN bit set and TDC not set (if TDC was handled, | ||
2422 | * IN must not be handled (UDC defect) ? | ||
2423 | */ | ||
2424 | if ((epsts & AMD_BIT(UDC_EPSTS_IN)) | ||
2425 | && !(epsts & AMD_BIT(UDC_EPSTS_TDC))) { | ||
2426 | ret_val = IRQ_HANDLED; | ||
2427 | if (!list_empty(&ep->queue)) { | ||
2428 | /* next request */ | ||
2429 | req = list_entry(ep->queue.next, | ||
2430 | struct udc_request, queue); | ||
2431 | /* FIFO mode */ | ||
2432 | if (!use_dma) { | ||
2433 | /* write fifo */ | ||
2434 | udc_txfifo_write(ep, &req->req); | ||
2435 | len = req->req.length - req->req.actual; | ||
2436 | if (len > ep->ep.maxpacket) | ||
2437 | len = ep->ep.maxpacket; | ||
2438 | req->req.actual += len; | ||
2439 | if (req->req.actual == req->req.length | ||
2440 | || (len != ep->ep.maxpacket)) { | ||
2441 | /* complete req */ | ||
2442 | complete_req(ep, req, 0); | ||
2443 | } | ||
2444 | /* DMA */ | ||
2445 | } else if (req && !req->dma_going) { | ||
2446 | VDBG(dev, "IN DMA : req=%p req->td_data=%p\n", | ||
2447 | req, req->td_data); | ||
2448 | if (req->td_data) { | ||
2449 | |||
2450 | req->dma_going = 1; | ||
2451 | |||
2452 | /* | ||
2453 | * unset L bit of first desc. | ||
2454 | * for chain | ||
2455 | */ | ||
2456 | if (use_dma_ppb && req->req.length > | ||
2457 | ep->ep.maxpacket) { | ||
2458 | req->td_data->status &= | ||
2459 | AMD_CLEAR_BIT( | ||
2460 | UDC_DMA_IN_STS_L); | ||
2461 | } | ||
2462 | |||
2463 | /* write desc pointer */ | ||
2464 | writel(req->td_phys, &ep->regs->desptr); | ||
2465 | |||
2466 | /* set HOST READY */ | ||
2467 | req->td_data->status = | ||
2468 | AMD_ADDBITS( | ||
2469 | req->td_data->status, | ||
2470 | UDC_DMA_IN_STS_BS_HOST_READY, | ||
2471 | UDC_DMA_IN_STS_BS); | ||
2472 | |||
2473 | /* set poll demand bit */ | ||
2474 | tmp = readl(&ep->regs->ctl); | ||
2475 | tmp |= AMD_BIT(UDC_EPCTL_P); | ||
2476 | writel(tmp, &ep->regs->ctl); | ||
2477 | } | ||
2478 | } | ||
2479 | |||
2480 | } | ||
2481 | } | ||
2482 | /* clear status bits */ | ||
2483 | writel(epsts, &ep->regs->sts); | ||
2484 | |||
2485 | finished: | ||
2486 | return ret_val; | ||
2487 | |||
2488 | } | ||
2489 | |||
2490 | /* Interrupt handler for Control OUT traffic */ | ||
2491 | static irqreturn_t udc_control_out_isr(struct udc *dev) | ||
2492 | __releases(dev->lock) | ||
2493 | __acquires(dev->lock) | ||
2494 | { | ||
2495 | irqreturn_t ret_val = IRQ_NONE; | ||
2496 | u32 tmp; | ||
2497 | int setup_supported; | ||
2498 | u32 count; | ||
2499 | int set = 0; | ||
2500 | struct udc_ep *ep; | ||
2501 | struct udc_ep *ep_tmp; | ||
2502 | |||
2503 | ep = &dev->ep[UDC_EP0OUT_IX]; | ||
2504 | |||
2505 | /* clear irq */ | ||
2506 | writel(AMD_BIT(UDC_EPINT_OUT_EP0), &dev->regs->ep_irqsts); | ||
2507 | |||
2508 | tmp = readl(&dev->ep[UDC_EP0OUT_IX].regs->sts); | ||
2509 | /* check BNA and clear if set */ | ||
2510 | if (tmp & AMD_BIT(UDC_EPSTS_BNA)) { | ||
2511 | VDBG(dev, "ep0: BNA set\n"); | ||
2512 | writel(AMD_BIT(UDC_EPSTS_BNA), | ||
2513 | &dev->ep[UDC_EP0OUT_IX].regs->sts); | ||
2514 | ep->bna_occurred = 1; | ||
2515 | ret_val = IRQ_HANDLED; | ||
2516 | goto finished; | ||
2517 | } | ||
2518 | |||
2519 | /* type of data: SETUP or DATA 0 bytes */ | ||
2520 | tmp = AMD_GETBITS(tmp, UDC_EPSTS_OUT); | ||
2521 | VDBG(dev, "data_typ = %x\n", tmp); | ||
2522 | |||
2523 | /* setup data */ | ||
2524 | if (tmp == UDC_EPSTS_OUT_SETUP) { | ||
2525 | ret_val = IRQ_HANDLED; | ||
2526 | |||
2527 | ep->dev->stall_ep0in = 0; | ||
2528 | dev->waiting_zlp_ack_ep0in = 0; | ||
2529 | |||
2530 | /* set NAK for EP0_IN */ | ||
2531 | tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
2532 | tmp |= AMD_BIT(UDC_EPCTL_SNAK); | ||
2533 | writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
2534 | dev->ep[UDC_EP0IN_IX].naking = 1; | ||
2535 | /* get setup data */ | ||
2536 | if (use_dma) { | ||
2537 | |||
2538 | /* clear OUT bits in ep status */ | ||
2539 | writel(UDC_EPSTS_OUT_CLEAR, | ||
2540 | &dev->ep[UDC_EP0OUT_IX].regs->sts); | ||
2541 | |||
2542 | setup_data.data[0] = | ||
2543 | dev->ep[UDC_EP0OUT_IX].td_stp->data12; | ||
2544 | setup_data.data[1] = | ||
2545 | dev->ep[UDC_EP0OUT_IX].td_stp->data34; | ||
2546 | /* set HOST READY */ | ||
2547 | dev->ep[UDC_EP0OUT_IX].td_stp->status = | ||
2548 | UDC_DMA_STP_STS_BS_HOST_READY; | ||
2549 | } else { | ||
2550 | /* read fifo */ | ||
2551 | udc_rxfifo_read_dwords(dev, setup_data.data, 2); | ||
2552 | } | ||
2553 | |||
2554 | /* determine direction of control data */ | ||
2555 | if ((setup_data.request.bRequestType & USB_DIR_IN) != 0) { | ||
2556 | dev->gadget.ep0 = &dev->ep[UDC_EP0IN_IX].ep; | ||
2557 | /* enable RDE */ | ||
2558 | udc_ep0_set_rde(dev); | ||
2559 | set = 0; | ||
2560 | } else { | ||
2561 | dev->gadget.ep0 = &dev->ep[UDC_EP0OUT_IX].ep; | ||
2562 | /* | ||
2563 | * implant BNA dummy descriptor to allow RXFIFO opening | ||
2564 | * by RDE | ||
2565 | */ | ||
2566 | if (ep->bna_dummy_req) { | ||
2567 | /* write desc pointer */ | ||
2568 | writel(ep->bna_dummy_req->td_phys, | ||
2569 | &dev->ep[UDC_EP0OUT_IX].regs->desptr); | ||
2570 | ep->bna_occurred = 0; | ||
2571 | } | ||
2572 | |||
2573 | set = 1; | ||
2574 | dev->ep[UDC_EP0OUT_IX].naking = 1; | ||
2575 | /* | ||
2576 | * setup timer for enabling RDE (to not enable | ||
2577 | * RXFIFO DMA for data to early) | ||
2578 | */ | ||
2579 | set_rde = 1; | ||
2580 | if (!timer_pending(&udc_timer)) { | ||
2581 | udc_timer.expires = jiffies + | ||
2582 | HZ/UDC_RDE_TIMER_DIV; | ||
2583 | if (!stop_timer) { | ||
2584 | add_timer(&udc_timer); | ||
2585 | } | ||
2586 | } | ||
2587 | } | ||
2588 | |||
2589 | /* | ||
2590 | * mass storage reset must be processed here because | ||
2591 | * next packet may be a CLEAR_FEATURE HALT which would not | ||
2592 | * clear the stall bit when no STALL handshake was received | ||
2593 | * before (autostall can cause this) | ||
2594 | */ | ||
2595 | if (setup_data.data[0] == UDC_MSCRES_DWORD0 | ||
2596 | && setup_data.data[1] == UDC_MSCRES_DWORD1) { | ||
2597 | DBG(dev, "MSC Reset\n"); | ||
2598 | /* | ||
2599 | * clear stall bits | ||
2600 | * only one IN and OUT endpoints are handled | ||
2601 | */ | ||
2602 | ep_tmp = &udc->ep[UDC_EPIN_IX]; | ||
2603 | udc_set_halt(&ep_tmp->ep, 0); | ||
2604 | ep_tmp = &udc->ep[UDC_EPOUT_IX]; | ||
2605 | udc_set_halt(&ep_tmp->ep, 0); | ||
2606 | } | ||
2607 | |||
2608 | /* call gadget with setup data received */ | ||
2609 | spin_unlock(&dev->lock); | ||
2610 | setup_supported = dev->driver->setup(&dev->gadget, | ||
2611 | &setup_data.request); | ||
2612 | spin_lock(&dev->lock); | ||
2613 | |||
2614 | tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
2615 | /* ep0 in returns data (not zlp) on IN phase */ | ||
2616 | if (setup_supported >= 0 && setup_supported < | ||
2617 | UDC_EP0IN_MAXPACKET) { | ||
2618 | /* clear NAK by writing CNAK in EP0_IN */ | ||
2619 | tmp |= AMD_BIT(UDC_EPCTL_CNAK); | ||
2620 | writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
2621 | dev->ep[UDC_EP0IN_IX].naking = 0; | ||
2622 | UDC_QUEUE_CNAK(&dev->ep[UDC_EP0IN_IX], UDC_EP0IN_IX); | ||
2623 | |||
2624 | /* if unsupported request then stall */ | ||
2625 | } else if (setup_supported < 0) { | ||
2626 | tmp |= AMD_BIT(UDC_EPCTL_S); | ||
2627 | writel(tmp, &dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
2628 | } else | ||
2629 | dev->waiting_zlp_ack_ep0in = 1; | ||
2630 | |||
2631 | |||
2632 | /* clear NAK by writing CNAK in EP0_OUT */ | ||
2633 | if (!set) { | ||
2634 | tmp = readl(&dev->ep[UDC_EP0OUT_IX].regs->ctl); | ||
2635 | tmp |= AMD_BIT(UDC_EPCTL_CNAK); | ||
2636 | writel(tmp, &dev->ep[UDC_EP0OUT_IX].regs->ctl); | ||
2637 | dev->ep[UDC_EP0OUT_IX].naking = 0; | ||
2638 | UDC_QUEUE_CNAK(&dev->ep[UDC_EP0OUT_IX], UDC_EP0OUT_IX); | ||
2639 | } | ||
2640 | |||
2641 | if (!use_dma) { | ||
2642 | /* clear OUT bits in ep status */ | ||
2643 | writel(UDC_EPSTS_OUT_CLEAR, | ||
2644 | &dev->ep[UDC_EP0OUT_IX].regs->sts); | ||
2645 | } | ||
2646 | |||
2647 | /* data packet 0 bytes */ | ||
2648 | } else if (tmp == UDC_EPSTS_OUT_DATA) { | ||
2649 | /* clear OUT bits in ep status */ | ||
2650 | writel(UDC_EPSTS_OUT_CLEAR, &dev->ep[UDC_EP0OUT_IX].regs->sts); | ||
2651 | |||
2652 | /* get setup data: only 0 packet */ | ||
2653 | if (use_dma) { | ||
2654 | /* no req if 0 packet, just reactivate */ | ||
2655 | if (list_empty(&dev->ep[UDC_EP0OUT_IX].queue)) { | ||
2656 | VDBG(dev, "ZLP\n"); | ||
2657 | |||
2658 | /* set HOST READY */ | ||
2659 | dev->ep[UDC_EP0OUT_IX].td->status = | ||
2660 | AMD_ADDBITS( | ||
2661 | dev->ep[UDC_EP0OUT_IX].td->status, | ||
2662 | UDC_DMA_OUT_STS_BS_HOST_READY, | ||
2663 | UDC_DMA_OUT_STS_BS); | ||
2664 | /* enable RDE */ | ||
2665 | udc_ep0_set_rde(dev); | ||
2666 | ret_val = IRQ_HANDLED; | ||
2667 | |||
2668 | } else { | ||
2669 | /* control write */ | ||
2670 | ret_val |= udc_data_out_isr(dev, UDC_EP0OUT_IX); | ||
2671 | /* re-program desc. pointer for possible ZLPs */ | ||
2672 | writel(dev->ep[UDC_EP0OUT_IX].td_phys, | ||
2673 | &dev->ep[UDC_EP0OUT_IX].regs->desptr); | ||
2674 | /* enable RDE */ | ||
2675 | udc_ep0_set_rde(dev); | ||
2676 | } | ||
2677 | } else { | ||
2678 | |||
2679 | /* received number bytes */ | ||
2680 | count = readl(&dev->ep[UDC_EP0OUT_IX].regs->sts); | ||
2681 | count = AMD_GETBITS(count, UDC_EPSTS_RX_PKT_SIZE); | ||
2682 | /* out data for fifo mode not working */ | ||
2683 | count = 0; | ||
2684 | |||
2685 | /* 0 packet or real data ? */ | ||
2686 | if (count != 0) { | ||
2687 | ret_val |= udc_data_out_isr(dev, UDC_EP0OUT_IX); | ||
2688 | } else { | ||
2689 | /* dummy read confirm */ | ||
2690 | readl(&dev->ep[UDC_EP0OUT_IX].regs->confirm); | ||
2691 | ret_val = IRQ_HANDLED; | ||
2692 | } | ||
2693 | } | ||
2694 | } | ||
2695 | |||
2696 | /* check pending CNAKS */ | ||
2697 | if (cnak_pending) { | ||
2698 | /* CNAk processing when rxfifo empty only */ | ||
2699 | if (readl(&dev->regs->sts) & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY)) { | ||
2700 | udc_process_cnak_queue(dev); | ||
2701 | } | ||
2702 | } | ||
2703 | |||
2704 | finished: | ||
2705 | return ret_val; | ||
2706 | } | ||
2707 | |||
2708 | /* Interrupt handler for Control IN traffic */ | ||
2709 | static irqreturn_t udc_control_in_isr(struct udc *dev) | ||
2710 | { | ||
2711 | irqreturn_t ret_val = IRQ_NONE; | ||
2712 | u32 tmp; | ||
2713 | struct udc_ep *ep; | ||
2714 | struct udc_request *req; | ||
2715 | unsigned len; | ||
2716 | |||
2717 | ep = &dev->ep[UDC_EP0IN_IX]; | ||
2718 | |||
2719 | /* clear irq */ | ||
2720 | writel(AMD_BIT(UDC_EPINT_IN_EP0), &dev->regs->ep_irqsts); | ||
2721 | |||
2722 | tmp = readl(&dev->ep[UDC_EP0IN_IX].regs->sts); | ||
2723 | /* DMA completion */ | ||
2724 | if (tmp & AMD_BIT(UDC_EPSTS_TDC)) { | ||
2725 | VDBG(dev, "isr: TDC clear \n"); | ||
2726 | ret_val = IRQ_HANDLED; | ||
2727 | |||
2728 | /* clear TDC bit */ | ||
2729 | writel(AMD_BIT(UDC_EPSTS_TDC), | ||
2730 | &dev->ep[UDC_EP0IN_IX].regs->sts); | ||
2731 | |||
2732 | /* status reg has IN bit set ? */ | ||
2733 | } else if (tmp & AMD_BIT(UDC_EPSTS_IN)) { | ||
2734 | ret_val = IRQ_HANDLED; | ||
2735 | |||
2736 | if (ep->dma) { | ||
2737 | /* clear IN bit */ | ||
2738 | writel(AMD_BIT(UDC_EPSTS_IN), | ||
2739 | &dev->ep[UDC_EP0IN_IX].regs->sts); | ||
2740 | } | ||
2741 | if (dev->stall_ep0in) { | ||
2742 | DBG(dev, "stall ep0in\n"); | ||
2743 | /* halt ep0in */ | ||
2744 | tmp = readl(&ep->regs->ctl); | ||
2745 | tmp |= AMD_BIT(UDC_EPCTL_S); | ||
2746 | writel(tmp, &ep->regs->ctl); | ||
2747 | } else { | ||
2748 | if (!list_empty(&ep->queue)) { | ||
2749 | /* next request */ | ||
2750 | req = list_entry(ep->queue.next, | ||
2751 | struct udc_request, queue); | ||
2752 | |||
2753 | if (ep->dma) { | ||
2754 | /* write desc pointer */ | ||
2755 | writel(req->td_phys, &ep->regs->desptr); | ||
2756 | /* set HOST READY */ | ||
2757 | req->td_data->status = | ||
2758 | AMD_ADDBITS( | ||
2759 | req->td_data->status, | ||
2760 | UDC_DMA_STP_STS_BS_HOST_READY, | ||
2761 | UDC_DMA_STP_STS_BS); | ||
2762 | |||
2763 | /* set poll demand bit */ | ||
2764 | tmp = | ||
2765 | readl(&dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
2766 | tmp |= AMD_BIT(UDC_EPCTL_P); | ||
2767 | writel(tmp, | ||
2768 | &dev->ep[UDC_EP0IN_IX].regs->ctl); | ||
2769 | |||
2770 | /* all bytes will be transferred */ | ||
2771 | req->req.actual = req->req.length; | ||
2772 | |||
2773 | /* complete req */ | ||
2774 | complete_req(ep, req, 0); | ||
2775 | |||
2776 | } else { | ||
2777 | /* write fifo */ | ||
2778 | udc_txfifo_write(ep, &req->req); | ||
2779 | |||
2780 | /* lengh bytes transfered */ | ||
2781 | len = req->req.length - req->req.actual; | ||
2782 | if (len > ep->ep.maxpacket) | ||
2783 | len = ep->ep.maxpacket; | ||
2784 | |||
2785 | req->req.actual += len; | ||
2786 | if (req->req.actual == req->req.length | ||
2787 | || (len != ep->ep.maxpacket)) { | ||
2788 | /* complete req */ | ||
2789 | complete_req(ep, req, 0); | ||
2790 | } | ||
2791 | } | ||
2792 | |||
2793 | } | ||
2794 | } | ||
2795 | ep->halted = 0; | ||
2796 | dev->stall_ep0in = 0; | ||
2797 | if (!ep->dma) { | ||
2798 | /* clear IN bit */ | ||
2799 | writel(AMD_BIT(UDC_EPSTS_IN), | ||
2800 | &dev->ep[UDC_EP0IN_IX].regs->sts); | ||
2801 | } | ||
2802 | } | ||
2803 | |||
2804 | return ret_val; | ||
2805 | } | ||
2806 | |||
2807 | |||
2808 | /* Interrupt handler for global device events */ | ||
2809 | static irqreturn_t udc_dev_isr(struct udc *dev, u32 dev_irq) | ||
2810 | __releases(dev->lock) | ||
2811 | __acquires(dev->lock) | ||
2812 | { | ||
2813 | irqreturn_t ret_val = IRQ_NONE; | ||
2814 | u32 tmp; | ||
2815 | u32 cfg; | ||
2816 | struct udc_ep *ep; | ||
2817 | u16 i; | ||
2818 | u8 udc_csr_epix; | ||
2819 | |||
2820 | /* SET_CONFIG irq ? */ | ||
2821 | if (dev_irq & AMD_BIT(UDC_DEVINT_SC)) { | ||
2822 | ret_val = IRQ_HANDLED; | ||
2823 | |||
2824 | /* read config value */ | ||
2825 | tmp = readl(&dev->regs->sts); | ||
2826 | cfg = AMD_GETBITS(tmp, UDC_DEVSTS_CFG); | ||
2827 | DBG(dev, "SET_CONFIG interrupt: config=%d\n", cfg); | ||
2828 | dev->cur_config = cfg; | ||
2829 | dev->set_cfg_not_acked = 1; | ||
2830 | |||
2831 | /* make usb request for gadget driver */ | ||
2832 | memset(&setup_data, 0 , sizeof(union udc_setup_data)); | ||
2833 | setup_data.request.bRequest = USB_REQ_SET_CONFIGURATION; | ||
2834 | setup_data.request.wValue = dev->cur_config; | ||
2835 | |||
2836 | /* programm the NE registers */ | ||
2837 | for (i = 0; i < UDC_EP_NUM; i++) { | ||
2838 | ep = &dev->ep[i]; | ||
2839 | if (ep->in) { | ||
2840 | |||
2841 | /* ep ix in UDC CSR register space */ | ||
2842 | udc_csr_epix = ep->num; | ||
2843 | |||
2844 | |||
2845 | /* OUT ep */ | ||
2846 | } else { | ||
2847 | /* ep ix in UDC CSR register space */ | ||
2848 | udc_csr_epix = ep->num - UDC_CSR_EP_OUT_IX_OFS; | ||
2849 | } | ||
2850 | |||
2851 | tmp = readl(&dev->csr->ne[udc_csr_epix]); | ||
2852 | /* ep cfg */ | ||
2853 | tmp = AMD_ADDBITS(tmp, ep->dev->cur_config, | ||
2854 | UDC_CSR_NE_CFG); | ||
2855 | /* write reg */ | ||
2856 | writel(tmp, &dev->csr->ne[udc_csr_epix]); | ||
2857 | |||
2858 | /* clear stall bits */ | ||
2859 | ep->halted = 0; | ||
2860 | tmp = readl(&ep->regs->ctl); | ||
2861 | tmp = tmp & AMD_CLEAR_BIT(UDC_EPCTL_S); | ||
2862 | writel(tmp, &ep->regs->ctl); | ||
2863 | } | ||
2864 | /* call gadget zero with setup data received */ | ||
2865 | spin_unlock(&dev->lock); | ||
2866 | tmp = dev->driver->setup(&dev->gadget, &setup_data.request); | ||
2867 | spin_lock(&dev->lock); | ||
2868 | |||
2869 | } /* SET_INTERFACE ? */ | ||
2870 | if (dev_irq & AMD_BIT(UDC_DEVINT_SI)) { | ||
2871 | ret_val = IRQ_HANDLED; | ||
2872 | |||
2873 | dev->set_cfg_not_acked = 1; | ||
2874 | /* read interface and alt setting values */ | ||
2875 | tmp = readl(&dev->regs->sts); | ||
2876 | dev->cur_alt = AMD_GETBITS(tmp, UDC_DEVSTS_ALT); | ||
2877 | dev->cur_intf = AMD_GETBITS(tmp, UDC_DEVSTS_INTF); | ||
2878 | |||
2879 | /* make usb request for gadget driver */ | ||
2880 | memset(&setup_data, 0 , sizeof(union udc_setup_data)); | ||
2881 | setup_data.request.bRequest = USB_REQ_SET_INTERFACE; | ||
2882 | setup_data.request.bRequestType = USB_RECIP_INTERFACE; | ||
2883 | setup_data.request.wValue = dev->cur_alt; | ||
2884 | setup_data.request.wIndex = dev->cur_intf; | ||
2885 | |||
2886 | DBG(dev, "SET_INTERFACE interrupt: alt=%d intf=%d\n", | ||
2887 | dev->cur_alt, dev->cur_intf); | ||
2888 | |||
2889 | /* programm the NE registers */ | ||
2890 | for (i = 0; i < UDC_EP_NUM; i++) { | ||
2891 | ep = &dev->ep[i]; | ||
2892 | if (ep->in) { | ||
2893 | |||
2894 | /* ep ix in UDC CSR register space */ | ||
2895 | udc_csr_epix = ep->num; | ||
2896 | |||
2897 | |||
2898 | /* OUT ep */ | ||
2899 | } else { | ||
2900 | /* ep ix in UDC CSR register space */ | ||
2901 | udc_csr_epix = ep->num - UDC_CSR_EP_OUT_IX_OFS; | ||
2902 | } | ||
2903 | |||
2904 | /* UDC CSR reg */ | ||
2905 | /* set ep values */ | ||
2906 | tmp = readl(&dev->csr->ne[udc_csr_epix]); | ||
2907 | /* ep interface */ | ||
2908 | tmp = AMD_ADDBITS(tmp, ep->dev->cur_intf, | ||
2909 | UDC_CSR_NE_INTF); | ||
2910 | /* tmp = AMD_ADDBITS(tmp, 2, UDC_CSR_NE_INTF); */ | ||
2911 | /* ep alt */ | ||
2912 | tmp = AMD_ADDBITS(tmp, ep->dev->cur_alt, | ||
2913 | UDC_CSR_NE_ALT); | ||
2914 | /* write reg */ | ||
2915 | writel(tmp, &dev->csr->ne[udc_csr_epix]); | ||
2916 | |||
2917 | /* clear stall bits */ | ||
2918 | ep->halted = 0; | ||
2919 | tmp = readl(&ep->regs->ctl); | ||
2920 | tmp = tmp & AMD_CLEAR_BIT(UDC_EPCTL_S); | ||
2921 | writel(tmp, &ep->regs->ctl); | ||
2922 | } | ||
2923 | |||
2924 | /* call gadget zero with setup data received */ | ||
2925 | spin_unlock(&dev->lock); | ||
2926 | tmp = dev->driver->setup(&dev->gadget, &setup_data.request); | ||
2927 | spin_lock(&dev->lock); | ||
2928 | |||
2929 | } /* USB reset */ | ||
2930 | if (dev_irq & AMD_BIT(UDC_DEVINT_UR)) { | ||
2931 | DBG(dev, "USB Reset interrupt\n"); | ||
2932 | ret_val = IRQ_HANDLED; | ||
2933 | |||
2934 | /* allow soft reset when suspend occurs */ | ||
2935 | soft_reset_occured = 0; | ||
2936 | |||
2937 | dev->waiting_zlp_ack_ep0in = 0; | ||
2938 | dev->set_cfg_not_acked = 0; | ||
2939 | |||
2940 | /* mask not needed interrupts */ | ||
2941 | udc_mask_unused_interrupts(dev); | ||
2942 | |||
2943 | /* call gadget to resume and reset configs etc. */ | ||
2944 | spin_unlock(&dev->lock); | ||
2945 | if (dev->sys_suspended && dev->driver->resume) { | ||
2946 | dev->driver->resume(&dev->gadget); | ||
2947 | dev->sys_suspended = 0; | ||
2948 | } | ||
2949 | dev->driver->disconnect(&dev->gadget); | ||
2950 | spin_lock(&dev->lock); | ||
2951 | |||
2952 | /* disable ep0 to empty req queue */ | ||
2953 | empty_req_queue(&dev->ep[UDC_EP0IN_IX]); | ||
2954 | ep_init(dev->regs, &dev->ep[UDC_EP0IN_IX]); | ||
2955 | |||
2956 | /* soft reset when rxfifo not empty */ | ||
2957 | tmp = readl(&dev->regs->sts); | ||
2958 | if (!(tmp & AMD_BIT(UDC_DEVSTS_RXFIFO_EMPTY)) | ||
2959 | && !soft_reset_after_usbreset_occured) { | ||
2960 | udc_soft_reset(dev); | ||
2961 | soft_reset_after_usbreset_occured++; | ||
2962 | } | ||
2963 | |||
2964 | /* | ||
2965 | * DMA reset to kill potential old DMA hw hang, | ||
2966 | * POLL bit is already reset by ep_init() through | ||
2967 | * disconnect() | ||
2968 | */ | ||
2969 | DBG(dev, "DMA machine reset\n"); | ||
2970 | tmp = readl(&dev->regs->cfg); | ||
2971 | writel(tmp | AMD_BIT(UDC_DEVCFG_DMARST), &dev->regs->cfg); | ||
2972 | writel(tmp, &dev->regs->cfg); | ||
2973 | |||
2974 | /* put into initial config */ | ||
2975 | udc_basic_init(dev); | ||
2976 | |||
2977 | /* enable device setup interrupts */ | ||
2978 | udc_enable_dev_setup_interrupts(dev); | ||
2979 | |||
2980 | /* enable suspend interrupt */ | ||
2981 | tmp = readl(&dev->regs->irqmsk); | ||
2982 | tmp &= AMD_UNMASK_BIT(UDC_DEVINT_US); | ||
2983 | writel(tmp, &dev->regs->irqmsk); | ||
2984 | |||
2985 | } /* USB suspend */ | ||
2986 | if (dev_irq & AMD_BIT(UDC_DEVINT_US)) { | ||
2987 | DBG(dev, "USB Suspend interrupt\n"); | ||
2988 | ret_val = IRQ_HANDLED; | ||
2989 | if (dev->driver->suspend) { | ||
2990 | spin_unlock(&dev->lock); | ||
2991 | dev->sys_suspended = 1; | ||
2992 | dev->driver->suspend(&dev->gadget); | ||
2993 | spin_lock(&dev->lock); | ||
2994 | } | ||
2995 | } /* new speed ? */ | ||
2996 | if (dev_irq & AMD_BIT(UDC_DEVINT_ENUM)) { | ||
2997 | DBG(dev, "ENUM interrupt\n"); | ||
2998 | ret_val = IRQ_HANDLED; | ||
2999 | soft_reset_after_usbreset_occured = 0; | ||
3000 | |||
3001 | /* disable ep0 to empty req queue */ | ||
3002 | empty_req_queue(&dev->ep[UDC_EP0IN_IX]); | ||
3003 | ep_init(dev->regs, &dev->ep[UDC_EP0IN_IX]); | ||
3004 | |||
3005 | /* link up all endpoints */ | ||
3006 | udc_setup_endpoints(dev); | ||
3007 | if (dev->gadget.speed == USB_SPEED_HIGH) { | ||
3008 | dev_info(&dev->pdev->dev, "Connect: speed = %s\n", | ||
3009 | "high"); | ||
3010 | } else if (dev->gadget.speed == USB_SPEED_FULL) { | ||
3011 | dev_info(&dev->pdev->dev, "Connect: speed = %s\n", | ||
3012 | "full"); | ||
3013 | } | ||
3014 | |||
3015 | /* init ep 0 */ | ||
3016 | activate_control_endpoints(dev); | ||
3017 | |||
3018 | /* enable ep0 interrupts */ | ||
3019 | udc_enable_ep0_interrupts(dev); | ||
3020 | } | ||
3021 | /* session valid change interrupt */ | ||
3022 | if (dev_irq & AMD_BIT(UDC_DEVINT_SVC)) { | ||
3023 | DBG(dev, "USB SVC interrupt\n"); | ||
3024 | ret_val = IRQ_HANDLED; | ||
3025 | |||
3026 | /* check that session is not valid to detect disconnect */ | ||
3027 | tmp = readl(&dev->regs->sts); | ||
3028 | if (!(tmp & AMD_BIT(UDC_DEVSTS_SESSVLD))) { | ||
3029 | /* disable suspend interrupt */ | ||
3030 | tmp = readl(&dev->regs->irqmsk); | ||
3031 | tmp |= AMD_BIT(UDC_DEVINT_US); | ||
3032 | writel(tmp, &dev->regs->irqmsk); | ||
3033 | DBG(dev, "USB Disconnect (session valid low)\n"); | ||
3034 | /* cleanup on disconnect */ | ||
3035 | usb_disconnect(udc); | ||
3036 | } | ||
3037 | |||
3038 | } | ||
3039 | |||
3040 | return ret_val; | ||
3041 | } | ||
3042 | |||
3043 | /* Interrupt Service Routine, see Linux Kernel Doc for parameters */ | ||
3044 | static irqreturn_t udc_irq(int irq, void *pdev) | ||
3045 | { | ||
3046 | struct udc *dev = pdev; | ||
3047 | u32 reg; | ||
3048 | u16 i; | ||
3049 | u32 ep_irq; | ||
3050 | irqreturn_t ret_val = IRQ_NONE; | ||
3051 | |||
3052 | spin_lock(&dev->lock); | ||
3053 | |||
3054 | /* check for ep irq */ | ||
3055 | reg = readl(&dev->regs->ep_irqsts); | ||
3056 | if (reg) { | ||
3057 | if (reg & AMD_BIT(UDC_EPINT_OUT_EP0)) | ||
3058 | ret_val |= udc_control_out_isr(dev); | ||
3059 | if (reg & AMD_BIT(UDC_EPINT_IN_EP0)) | ||
3060 | ret_val |= udc_control_in_isr(dev); | ||
3061 | |||
3062 | /* | ||
3063 | * data endpoint | ||
3064 | * iterate ep's | ||
3065 | */ | ||
3066 | for (i = 1; i < UDC_EP_NUM; i++) { | ||
3067 | ep_irq = 1 << i; | ||
3068 | if (!(reg & ep_irq) || i == UDC_EPINT_OUT_EP0) | ||
3069 | continue; | ||
3070 | |||
3071 | /* clear irq status */ | ||
3072 | writel(ep_irq, &dev->regs->ep_irqsts); | ||
3073 | |||
3074 | /* irq for out ep ? */ | ||
3075 | if (i > UDC_EPIN_NUM) | ||
3076 | ret_val |= udc_data_out_isr(dev, i); | ||
3077 | else | ||
3078 | ret_val |= udc_data_in_isr(dev, i); | ||
3079 | } | ||
3080 | |||
3081 | } | ||
3082 | |||
3083 | |||
3084 | /* check for dev irq */ | ||
3085 | reg = readl(&dev->regs->irqsts); | ||
3086 | if (reg) { | ||
3087 | /* clear irq */ | ||
3088 | writel(reg, &dev->regs->irqsts); | ||
3089 | ret_val |= udc_dev_isr(dev, reg); | ||
3090 | } | ||
3091 | |||
3092 | |||
3093 | spin_unlock(&dev->lock); | ||
3094 | return ret_val; | ||
3095 | } | ||
3096 | |||
3097 | /* Tears down device */ | ||
3098 | static void gadget_release(struct device *pdev) | ||
3099 | { | ||
3100 | struct amd5536udc *dev = dev_get_drvdata(pdev); | ||
3101 | kfree(dev); | ||
3102 | } | ||
3103 | |||
3104 | /* Cleanup on device remove */ | ||
3105 | static void udc_remove(struct udc *dev) | ||
3106 | { | ||
3107 | /* remove timer */ | ||
3108 | stop_timer++; | ||
3109 | if (timer_pending(&udc_timer)) | ||
3110 | wait_for_completion(&on_exit); | ||
3111 | if (udc_timer.data) | ||
3112 | del_timer_sync(&udc_timer); | ||
3113 | /* remove pollstall timer */ | ||
3114 | stop_pollstall_timer++; | ||
3115 | if (timer_pending(&udc_pollstall_timer)) | ||
3116 | wait_for_completion(&on_pollstall_exit); | ||
3117 | if (udc_pollstall_timer.data) | ||
3118 | del_timer_sync(&udc_pollstall_timer); | ||
3119 | udc = NULL; | ||
3120 | } | ||
3121 | |||
3122 | /* Reset all pci context */ | ||
3123 | static void udc_pci_remove(struct pci_dev *pdev) | ||
3124 | { | ||
3125 | struct udc *dev; | ||
3126 | |||
3127 | dev = pci_get_drvdata(pdev); | ||
3128 | |||
3129 | /* gadget driver must not be registered */ | ||
3130 | BUG_ON(dev->driver != NULL); | ||
3131 | |||
3132 | /* dma pool cleanup */ | ||
3133 | if (dev->data_requests) | ||
3134 | pci_pool_destroy(dev->data_requests); | ||
3135 | |||
3136 | if (dev->stp_requests) { | ||
3137 | /* cleanup DMA desc's for ep0in */ | ||
3138 | pci_pool_free(dev->stp_requests, | ||
3139 | dev->ep[UDC_EP0OUT_IX].td_stp, | ||
3140 | dev->ep[UDC_EP0OUT_IX].td_stp_dma); | ||
3141 | pci_pool_free(dev->stp_requests, | ||
3142 | dev->ep[UDC_EP0OUT_IX].td, | ||
3143 | dev->ep[UDC_EP0OUT_IX].td_phys); | ||
3144 | |||
3145 | pci_pool_destroy(dev->stp_requests); | ||
3146 | } | ||
3147 | |||
3148 | /* reset controller */ | ||
3149 | writel(AMD_BIT(UDC_DEVCFG_SOFTRESET), &dev->regs->cfg); | ||
3150 | if (dev->irq_registered) | ||
3151 | free_irq(pdev->irq, dev); | ||
3152 | if (dev->regs) | ||
3153 | iounmap(dev->regs); | ||
3154 | if (dev->mem_region) | ||
3155 | release_mem_region(pci_resource_start(pdev, 0), | ||
3156 | pci_resource_len(pdev, 0)); | ||
3157 | if (dev->active) | ||
3158 | pci_disable_device(pdev); | ||
3159 | |||
3160 | device_unregister(&dev->gadget.dev); | ||
3161 | pci_set_drvdata(pdev, NULL); | ||
3162 | |||
3163 | udc_remove(dev); | ||
3164 | } | ||
3165 | |||
3166 | /* create dma pools on init */ | ||
3167 | static int init_dma_pools(struct udc *dev) | ||
3168 | { | ||
3169 | struct udc_stp_dma *td_stp; | ||
3170 | struct udc_data_dma *td_data; | ||
3171 | int retval; | ||
3172 | |||
3173 | /* consistent DMA mode setting ? */ | ||
3174 | if (use_dma_ppb) { | ||
3175 | use_dma_bufferfill_mode = 0; | ||
3176 | } else { | ||
3177 | use_dma_ppb_du = 0; | ||
3178 | use_dma_bufferfill_mode = 1; | ||
3179 | } | ||
3180 | |||
3181 | /* DMA setup */ | ||
3182 | dev->data_requests = dma_pool_create("data_requests", NULL, | ||
3183 | sizeof(struct udc_data_dma), 0, 0); | ||
3184 | if (!dev->data_requests) { | ||
3185 | DBG(dev, "can't get request data pool\n"); | ||
3186 | retval = -ENOMEM; | ||
3187 | goto finished; | ||
3188 | } | ||
3189 | |||
3190 | /* EP0 in dma regs = dev control regs */ | ||
3191 | dev->ep[UDC_EP0IN_IX].dma = &dev->regs->ctl; | ||
3192 | |||
3193 | /* dma desc for setup data */ | ||
3194 | dev->stp_requests = dma_pool_create("setup requests", NULL, | ||
3195 | sizeof(struct udc_stp_dma), 0, 0); | ||
3196 | if (!dev->stp_requests) { | ||
3197 | DBG(dev, "can't get stp request pool\n"); | ||
3198 | retval = -ENOMEM; | ||
3199 | goto finished; | ||
3200 | } | ||
3201 | /* setup */ | ||
3202 | td_stp = dma_pool_alloc(dev->stp_requests, GFP_KERNEL, | ||
3203 | &dev->ep[UDC_EP0OUT_IX].td_stp_dma); | ||
3204 | if (td_stp == NULL) { | ||
3205 | retval = -ENOMEM; | ||
3206 | goto finished; | ||
3207 | } | ||
3208 | dev->ep[UDC_EP0OUT_IX].td_stp = td_stp; | ||
3209 | |||
3210 | /* data: 0 packets !? */ | ||
3211 | td_data = dma_pool_alloc(dev->stp_requests, GFP_KERNEL, | ||
3212 | &dev->ep[UDC_EP0OUT_IX].td_phys); | ||
3213 | if (td_data == NULL) { | ||
3214 | retval = -ENOMEM; | ||
3215 | goto finished; | ||
3216 | } | ||
3217 | dev->ep[UDC_EP0OUT_IX].td = td_data; | ||
3218 | return 0; | ||
3219 | |||
3220 | finished: | ||
3221 | return retval; | ||
3222 | } | ||
3223 | |||
3224 | /* Called by pci bus driver to init pci context */ | ||
3225 | static int udc_pci_probe( | ||
3226 | struct pci_dev *pdev, | ||
3227 | const struct pci_device_id *id | ||
3228 | ) | ||
3229 | { | ||
3230 | struct udc *dev; | ||
3231 | unsigned long resource; | ||
3232 | unsigned long len; | ||
3233 | int retval = 0; | ||
3234 | |||
3235 | /* one udc only */ | ||
3236 | if (udc) { | ||
3237 | dev_dbg(&pdev->dev, "already probed\n"); | ||
3238 | return -EBUSY; | ||
3239 | } | ||
3240 | |||
3241 | /* init */ | ||
3242 | dev = kzalloc(sizeof(struct udc), GFP_KERNEL); | ||
3243 | if (!dev) { | ||
3244 | retval = -ENOMEM; | ||
3245 | goto finished; | ||
3246 | } | ||
3247 | |||
3248 | /* pci setup */ | ||
3249 | if (pci_enable_device(pdev) < 0) { | ||
3250 | retval = -ENODEV; | ||
3251 | goto finished; | ||
3252 | } | ||
3253 | dev->active = 1; | ||
3254 | |||
3255 | /* PCI resource allocation */ | ||
3256 | resource = pci_resource_start(pdev, 0); | ||
3257 | len = pci_resource_len(pdev, 0); | ||
3258 | |||
3259 | if (!request_mem_region(resource, len, name)) { | ||
3260 | dev_dbg(&pdev->dev, "pci device used already\n"); | ||
3261 | retval = -EBUSY; | ||
3262 | goto finished; | ||
3263 | } | ||
3264 | dev->mem_region = 1; | ||
3265 | |||
3266 | dev->virt_addr = ioremap_nocache(resource, len); | ||
3267 | if (dev->virt_addr == NULL) { | ||
3268 | dev_dbg(&pdev->dev, "start address cannot be mapped\n"); | ||
3269 | retval = -EFAULT; | ||
3270 | goto finished; | ||
3271 | } | ||
3272 | |||
3273 | if (!pdev->irq) { | ||
3274 | dev_err(&dev->pdev->dev, "irq not set\n"); | ||
3275 | retval = -ENODEV; | ||
3276 | goto finished; | ||
3277 | } | ||
3278 | |||
3279 | if (request_irq(pdev->irq, udc_irq, IRQF_SHARED, name, dev) != 0) { | ||
3280 | dev_dbg(&dev->pdev->dev, "request_irq(%d) fail\n", pdev->irq); | ||
3281 | retval = -EBUSY; | ||
3282 | goto finished; | ||
3283 | } | ||
3284 | dev->irq_registered = 1; | ||
3285 | |||
3286 | pci_set_drvdata(pdev, dev); | ||
3287 | |||
3288 | /* chip revision for Hs AMD5536 */ | ||
3289 | dev->chiprev = pdev->revision; | ||
3290 | |||
3291 | pci_set_master(pdev); | ||
3292 | pci_set_mwi(pdev); | ||
3293 | |||
3294 | /* init dma pools */ | ||
3295 | if (use_dma) { | ||
3296 | retval = init_dma_pools(dev); | ||
3297 | if (retval != 0) | ||
3298 | goto finished; | ||
3299 | } | ||
3300 | |||
3301 | dev->phys_addr = resource; | ||
3302 | dev->irq = pdev->irq; | ||
3303 | dev->pdev = pdev; | ||
3304 | dev->gadget.dev.parent = &pdev->dev; | ||
3305 | dev->gadget.dev.dma_mask = pdev->dev.dma_mask; | ||
3306 | |||
3307 | /* general probing */ | ||
3308 | if (udc_probe(dev) == 0) | ||
3309 | return 0; | ||
3310 | |||
3311 | finished: | ||
3312 | if (dev) | ||
3313 | udc_pci_remove(pdev); | ||
3314 | return retval; | ||
3315 | } | ||
3316 | |||
3317 | /* general probe */ | ||
3318 | static int udc_probe(struct udc *dev) | ||
3319 | { | ||
3320 | char tmp[128]; | ||
3321 | u32 reg; | ||
3322 | int retval; | ||
3323 | |||
3324 | /* mark timer as not initialized */ | ||
3325 | udc_timer.data = 0; | ||
3326 | udc_pollstall_timer.data = 0; | ||
3327 | |||
3328 | /* device struct setup */ | ||
3329 | spin_lock_init(&dev->lock); | ||
3330 | dev->gadget.ops = &udc_ops; | ||
3331 | |||
3332 | strcpy(dev->gadget.dev.bus_id, "gadget"); | ||
3333 | dev->gadget.dev.release = gadget_release; | ||
3334 | dev->gadget.name = name; | ||
3335 | dev->gadget.name = name; | ||
3336 | dev->gadget.is_dualspeed = 1; | ||
3337 | |||
3338 | /* udc csr registers base */ | ||
3339 | dev->csr = dev->virt_addr + UDC_CSR_ADDR; | ||
3340 | /* dev registers base */ | ||
3341 | dev->regs = dev->virt_addr + UDC_DEVCFG_ADDR; | ||
3342 | /* ep registers base */ | ||
3343 | dev->ep_regs = dev->virt_addr + UDC_EPREGS_ADDR; | ||
3344 | /* fifo's base */ | ||
3345 | dev->rxfifo = (u32 __iomem *)(dev->virt_addr + UDC_RXFIFO_ADDR); | ||
3346 | dev->txfifo = (u32 __iomem *)(dev->virt_addr + UDC_TXFIFO_ADDR); | ||
3347 | |||
3348 | /* init registers, interrupts, ... */ | ||
3349 | startup_registers(dev); | ||
3350 | |||
3351 | dev_info(&dev->pdev->dev, "%s\n", mod_desc); | ||
3352 | |||
3353 | snprintf(tmp, sizeof tmp, "%d", dev->irq); | ||
3354 | dev_info(&dev->pdev->dev, | ||
3355 | "irq %s, pci mem %08lx, chip rev %02x(Geode5536 %s)\n", | ||
3356 | tmp, dev->phys_addr, dev->chiprev, | ||
3357 | (dev->chiprev == UDC_HSA0_REV) ? "A0" : "B1"); | ||
3358 | strcpy(tmp, UDC_DRIVER_VERSION_STRING); | ||
3359 | if (dev->chiprev == UDC_HSA0_REV) { | ||
3360 | dev_err(&dev->pdev->dev, "chip revision is A0; too old\n"); | ||
3361 | retval = -ENODEV; | ||
3362 | goto finished; | ||
3363 | } | ||
3364 | dev_info(&dev->pdev->dev, | ||
3365 | "driver version: %s(for Geode5536 B1)\n", tmp); | ||
3366 | udc = dev; | ||
3367 | |||
3368 | retval = device_register(&dev->gadget.dev); | ||
3369 | if (retval) | ||
3370 | goto finished; | ||
3371 | |||
3372 | /* timer init */ | ||
3373 | init_timer(&udc_timer); | ||
3374 | udc_timer.function = udc_timer_function; | ||
3375 | udc_timer.data = 1; | ||
3376 | /* timer pollstall init */ | ||
3377 | init_timer(&udc_pollstall_timer); | ||
3378 | udc_pollstall_timer.function = udc_pollstall_timer_function; | ||
3379 | udc_pollstall_timer.data = 1; | ||
3380 | |||
3381 | /* set SD */ | ||
3382 | reg = readl(&dev->regs->ctl); | ||
3383 | reg |= AMD_BIT(UDC_DEVCTL_SD); | ||
3384 | writel(reg, &dev->regs->ctl); | ||
3385 | |||
3386 | /* print dev register info */ | ||
3387 | print_regs(dev); | ||
3388 | |||
3389 | return 0; | ||
3390 | |||
3391 | finished: | ||
3392 | return retval; | ||
3393 | } | ||
3394 | |||
3395 | /* Initiates a remote wakeup */ | ||
3396 | static int udc_remote_wakeup(struct udc *dev) | ||
3397 | { | ||
3398 | unsigned long flags; | ||
3399 | u32 tmp; | ||
3400 | |||
3401 | DBG(dev, "UDC initiates remote wakeup\n"); | ||
3402 | |||
3403 | spin_lock_irqsave(&dev->lock, flags); | ||
3404 | |||
3405 | tmp = readl(&dev->regs->ctl); | ||
3406 | tmp |= AMD_BIT(UDC_DEVCTL_RES); | ||
3407 | writel(tmp, &dev->regs->ctl); | ||
3408 | tmp &= AMD_CLEAR_BIT(UDC_DEVCTL_RES); | ||
3409 | writel(tmp, &dev->regs->ctl); | ||
3410 | |||
3411 | spin_unlock_irqrestore(&dev->lock, flags); | ||
3412 | return 0; | ||
3413 | } | ||
3414 | |||
3415 | /* PCI device parameters */ | ||
3416 | static const struct pci_device_id pci_id[] = { | ||
3417 | { | ||
3418 | PCI_DEVICE(PCI_VENDOR_ID_AMD, 0x2096), | ||
3419 | .class = (PCI_CLASS_SERIAL_USB << 8) | 0xfe, | ||
3420 | .class_mask = 0xffffffff, | ||
3421 | }, | ||
3422 | {}, | ||
3423 | }; | ||
3424 | MODULE_DEVICE_TABLE(pci, pci_id); | ||
3425 | |||
3426 | /* PCI functions */ | ||
3427 | static struct pci_driver udc_pci_driver = { | ||
3428 | .name = (char *) name, | ||
3429 | .id_table = pci_id, | ||
3430 | .probe = udc_pci_probe, | ||
3431 | .remove = udc_pci_remove, | ||
3432 | }; | ||
3433 | |||
3434 | /* Inits driver */ | ||
3435 | static int __init init(void) | ||
3436 | { | ||
3437 | return pci_register_driver(&udc_pci_driver); | ||
3438 | } | ||
3439 | module_init(init); | ||
3440 | |||
3441 | /* Cleans driver */ | ||
3442 | static void __exit cleanup(void) | ||
3443 | { | ||
3444 | pci_unregister_driver(&udc_pci_driver); | ||
3445 | } | ||
3446 | module_exit(cleanup); | ||
3447 | |||
3448 | MODULE_DESCRIPTION(UDC_MOD_DESCRIPTION); | ||
3449 | MODULE_AUTHOR("Thomas Dahlmann"); | ||
3450 | MODULE_LICENSE("GPL"); | ||
3451 | |||
diff --git a/drivers/usb/gadget/amd5536udc.h b/drivers/usb/gadget/amd5536udc.h new file mode 100644 index 00000000000..4bbabbbfc93 --- /dev/null +++ b/drivers/usb/gadget/amd5536udc.h | |||
@@ -0,0 +1,626 @@ | |||
1 | /* | ||
2 | * amd5536.h -- header for AMD 5536 UDC high/full speed USB device controller | ||
3 | * | ||
4 | * Copyright (C) 2007 AMD (http://www.amd.com) | ||
5 | * Author: Thomas Dahlmann | ||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
20 | */ | ||
21 | |||
22 | #ifndef AMD5536UDC_H | ||
23 | #define AMD5536UDC_H | ||
24 | |||
25 | /* various constants */ | ||
26 | #define UDC_RDE_TIMER_SECONDS 1 | ||
27 | #define UDC_RDE_TIMER_DIV 10 | ||
28 | #define UDC_POLLSTALL_TIMER_USECONDS 500 | ||
29 | |||
30 | /* Hs AMD5536 chip rev. */ | ||
31 | #define UDC_HSA0_REV 1 | ||
32 | #define UDC_HSB1_REV 2 | ||
33 | |||
34 | /* | ||
35 | * SETUP usb commands | ||
36 | * needed, because some SETUP's are handled in hw, but must be passed to | ||
37 | * gadget driver above | ||
38 | * SET_CONFIG | ||
39 | */ | ||
40 | #define UDC_SETCONFIG_DWORD0 0x00000900 | ||
41 | #define UDC_SETCONFIG_DWORD0_VALUE_MASK 0xffff0000 | ||
42 | #define UDC_SETCONFIG_DWORD0_VALUE_OFS 16 | ||
43 | |||
44 | #define UDC_SETCONFIG_DWORD1 0x00000000 | ||
45 | |||
46 | /* SET_INTERFACE */ | ||
47 | #define UDC_SETINTF_DWORD0 0x00000b00 | ||
48 | #define UDC_SETINTF_DWORD0_ALT_MASK 0xffff0000 | ||
49 | #define UDC_SETINTF_DWORD0_ALT_OFS 16 | ||
50 | |||
51 | #define UDC_SETINTF_DWORD1 0x00000000 | ||
52 | #define UDC_SETINTF_DWORD1_INTF_MASK 0x0000ffff | ||
53 | #define UDC_SETINTF_DWORD1_INTF_OFS 0 | ||
54 | |||
55 | /* Mass storage reset */ | ||
56 | #define UDC_MSCRES_DWORD0 0x0000ff21 | ||
57 | #define UDC_MSCRES_DWORD1 0x00000000 | ||
58 | |||
59 | /* Global CSR's -------------------------------------------------------------*/ | ||
60 | #define UDC_CSR_ADDR 0x500 | ||
61 | |||
62 | /* EP NE bits */ | ||
63 | /* EP number */ | ||
64 | #define UDC_CSR_NE_NUM_MASK 0x0000000f | ||
65 | #define UDC_CSR_NE_NUM_OFS 0 | ||
66 | /* EP direction */ | ||
67 | #define UDC_CSR_NE_DIR_MASK 0x00000010 | ||
68 | #define UDC_CSR_NE_DIR_OFS 4 | ||
69 | /* EP type */ | ||
70 | #define UDC_CSR_NE_TYPE_MASK 0x00000060 | ||
71 | #define UDC_CSR_NE_TYPE_OFS 5 | ||
72 | /* EP config number */ | ||
73 | #define UDC_CSR_NE_CFG_MASK 0x00000780 | ||
74 | #define UDC_CSR_NE_CFG_OFS 7 | ||
75 | /* EP interface number */ | ||
76 | #define UDC_CSR_NE_INTF_MASK 0x00007800 | ||
77 | #define UDC_CSR_NE_INTF_OFS 11 | ||
78 | /* EP alt setting */ | ||
79 | #define UDC_CSR_NE_ALT_MASK 0x00078000 | ||
80 | #define UDC_CSR_NE_ALT_OFS 15 | ||
81 | |||
82 | /* max pkt */ | ||
83 | #define UDC_CSR_NE_MAX_PKT_MASK 0x3ff80000 | ||
84 | #define UDC_CSR_NE_MAX_PKT_OFS 19 | ||
85 | |||
86 | /* Device Config Register ---------------------------------------------------*/ | ||
87 | #define UDC_DEVCFG_ADDR 0x400 | ||
88 | |||
89 | #define UDC_DEVCFG_SOFTRESET 31 | ||
90 | #define UDC_DEVCFG_HNPSFEN 30 | ||
91 | #define UDC_DEVCFG_DMARST 29 | ||
92 | #define UDC_DEVCFG_SET_DESC 18 | ||
93 | #define UDC_DEVCFG_CSR_PRG 17 | ||
94 | #define UDC_DEVCFG_STATUS 7 | ||
95 | #define UDC_DEVCFG_DIR 6 | ||
96 | #define UDC_DEVCFG_PI 5 | ||
97 | #define UDC_DEVCFG_SS 4 | ||
98 | #define UDC_DEVCFG_SP 3 | ||
99 | #define UDC_DEVCFG_RWKP 2 | ||
100 | |||
101 | #define UDC_DEVCFG_SPD_MASK 0x3 | ||
102 | #define UDC_DEVCFG_SPD_OFS 0 | ||
103 | #define UDC_DEVCFG_SPD_HS 0x0 | ||
104 | #define UDC_DEVCFG_SPD_FS 0x1 | ||
105 | #define UDC_DEVCFG_SPD_LS 0x2 | ||
106 | /*#define UDC_DEVCFG_SPD_FS 0x3*/ | ||
107 | |||
108 | |||
109 | /* Device Control Register --------------------------------------------------*/ | ||
110 | #define UDC_DEVCTL_ADDR 0x404 | ||
111 | |||
112 | #define UDC_DEVCTL_THLEN_MASK 0xff000000 | ||
113 | #define UDC_DEVCTL_THLEN_OFS 24 | ||
114 | |||
115 | #define UDC_DEVCTL_BRLEN_MASK 0x00ff0000 | ||
116 | #define UDC_DEVCTL_BRLEN_OFS 16 | ||
117 | |||
118 | #define UDC_DEVCTL_CSR_DONE 13 | ||
119 | #define UDC_DEVCTL_DEVNAK 12 | ||
120 | #define UDC_DEVCTL_SD 10 | ||
121 | #define UDC_DEVCTL_MODE 9 | ||
122 | #define UDC_DEVCTL_BREN 8 | ||
123 | #define UDC_DEVCTL_THE 7 | ||
124 | #define UDC_DEVCTL_BF 6 | ||
125 | #define UDC_DEVCTL_BE 5 | ||
126 | #define UDC_DEVCTL_DU 4 | ||
127 | #define UDC_DEVCTL_TDE 3 | ||
128 | #define UDC_DEVCTL_RDE 2 | ||
129 | #define UDC_DEVCTL_RES 0 | ||
130 | |||
131 | |||
132 | /* Device Status Register ---------------------------------------------------*/ | ||
133 | #define UDC_DEVSTS_ADDR 0x408 | ||
134 | |||
135 | #define UDC_DEVSTS_TS_MASK 0xfffc0000 | ||
136 | #define UDC_DEVSTS_TS_OFS 18 | ||
137 | |||
138 | #define UDC_DEVSTS_SESSVLD 17 | ||
139 | #define UDC_DEVSTS_PHY_ERROR 16 | ||
140 | #define UDC_DEVSTS_RXFIFO_EMPTY 15 | ||
141 | |||
142 | #define UDC_DEVSTS_ENUM_SPEED_MASK 0x00006000 | ||
143 | #define UDC_DEVSTS_ENUM_SPEED_OFS 13 | ||
144 | #define UDC_DEVSTS_ENUM_SPEED_FULL 1 | ||
145 | #define UDC_DEVSTS_ENUM_SPEED_HIGH 0 | ||
146 | |||
147 | #define UDC_DEVSTS_SUSP 12 | ||
148 | |||
149 | #define UDC_DEVSTS_ALT_MASK 0x00000f00 | ||
150 | #define UDC_DEVSTS_ALT_OFS 8 | ||
151 | |||
152 | #define UDC_DEVSTS_INTF_MASK 0x000000f0 | ||
153 | #define UDC_DEVSTS_INTF_OFS 4 | ||
154 | |||
155 | #define UDC_DEVSTS_CFG_MASK 0x0000000f | ||
156 | #define UDC_DEVSTS_CFG_OFS 0 | ||
157 | |||
158 | |||
159 | /* Device Interrupt Register ------------------------------------------------*/ | ||
160 | #define UDC_DEVINT_ADDR 0x40c | ||
161 | |||
162 | #define UDC_DEVINT_SVC 7 | ||
163 | #define UDC_DEVINT_ENUM 6 | ||
164 | #define UDC_DEVINT_SOF 5 | ||
165 | #define UDC_DEVINT_US 4 | ||
166 | #define UDC_DEVINT_UR 3 | ||
167 | #define UDC_DEVINT_ES 2 | ||
168 | #define UDC_DEVINT_SI 1 | ||
169 | #define UDC_DEVINT_SC 0 | ||
170 | |||
171 | /* Device Interrupt Mask Register -------------------------------------------*/ | ||
172 | #define UDC_DEVINT_MSK_ADDR 0x410 | ||
173 | |||
174 | #define UDC_DEVINT_MSK 0x7f | ||
175 | |||
176 | /* Endpoint Interrupt Register ----------------------------------------------*/ | ||
177 | #define UDC_EPINT_ADDR 0x414 | ||
178 | |||
179 | #define UDC_EPINT_OUT_MASK 0xffff0000 | ||
180 | #define UDC_EPINT_OUT_OFS 16 | ||
181 | #define UDC_EPINT_IN_MASK 0x0000ffff | ||
182 | #define UDC_EPINT_IN_OFS 0 | ||
183 | |||
184 | #define UDC_EPINT_IN_EP0 0 | ||
185 | #define UDC_EPINT_IN_EP1 1 | ||
186 | #define UDC_EPINT_IN_EP2 2 | ||
187 | #define UDC_EPINT_IN_EP3 3 | ||
188 | #define UDC_EPINT_OUT_EP0 16 | ||
189 | #define UDC_EPINT_OUT_EP1 17 | ||
190 | #define UDC_EPINT_OUT_EP2 18 | ||
191 | #define UDC_EPINT_OUT_EP3 19 | ||
192 | |||
193 | #define UDC_EPINT_EP0_ENABLE_MSK 0x001e001e | ||
194 | |||
195 | /* Endpoint Interrupt Mask Register -----------------------------------------*/ | ||
196 | #define UDC_EPINT_MSK_ADDR 0x418 | ||
197 | |||
198 | #define UDC_EPINT_OUT_MSK_MASK 0xffff0000 | ||
199 | #define UDC_EPINT_OUT_MSK_OFS 16 | ||
200 | #define UDC_EPINT_IN_MSK_MASK 0x0000ffff | ||
201 | #define UDC_EPINT_IN_MSK_OFS 0 | ||
202 | |||
203 | #define UDC_EPINT_MSK_DISABLE_ALL 0xffffffff | ||
204 | /* mask non-EP0 endpoints */ | ||
205 | #define UDC_EPDATAINT_MSK_DISABLE 0xfffefffe | ||
206 | /* mask all dev interrupts */ | ||
207 | #define UDC_DEV_MSK_DISABLE 0x7f | ||
208 | |||
209 | /* Endpoint-specific CSR's --------------------------------------------------*/ | ||
210 | #define UDC_EPREGS_ADDR 0x0 | ||
211 | #define UDC_EPIN_REGS_ADDR 0x0 | ||
212 | #define UDC_EPOUT_REGS_ADDR 0x200 | ||
213 | |||
214 | #define UDC_EPCTL_ADDR 0x0 | ||
215 | |||
216 | #define UDC_EPCTL_RRDY 9 | ||
217 | #define UDC_EPCTL_CNAK 8 | ||
218 | #define UDC_EPCTL_SNAK 7 | ||
219 | #define UDC_EPCTL_NAK 6 | ||
220 | |||
221 | #define UDC_EPCTL_ET_MASK 0x00000030 | ||
222 | #define UDC_EPCTL_ET_OFS 4 | ||
223 | #define UDC_EPCTL_ET_CONTROL 0 | ||
224 | #define UDC_EPCTL_ET_ISO 1 | ||
225 | #define UDC_EPCTL_ET_BULK 2 | ||
226 | #define UDC_EPCTL_ET_INTERRUPT 3 | ||
227 | |||
228 | #define UDC_EPCTL_P 3 | ||
229 | #define UDC_EPCTL_SN 2 | ||
230 | #define UDC_EPCTL_F 1 | ||
231 | #define UDC_EPCTL_S 0 | ||
232 | |||
233 | /* Endpoint Status Registers ------------------------------------------------*/ | ||
234 | #define UDC_EPSTS_ADDR 0x4 | ||
235 | |||
236 | #define UDC_EPSTS_RX_PKT_SIZE_MASK 0x007ff800 | ||
237 | #define UDC_EPSTS_RX_PKT_SIZE_OFS 11 | ||
238 | |||
239 | #define UDC_EPSTS_TDC 10 | ||
240 | #define UDC_EPSTS_HE 9 | ||
241 | #define UDC_EPSTS_BNA 7 | ||
242 | #define UDC_EPSTS_IN 6 | ||
243 | |||
244 | #define UDC_EPSTS_OUT_MASK 0x00000030 | ||
245 | #define UDC_EPSTS_OUT_OFS 4 | ||
246 | #define UDC_EPSTS_OUT_DATA 1 | ||
247 | #define UDC_EPSTS_OUT_DATA_CLEAR 0x10 | ||
248 | #define UDC_EPSTS_OUT_SETUP 2 | ||
249 | #define UDC_EPSTS_OUT_SETUP_CLEAR 0x20 | ||
250 | #define UDC_EPSTS_OUT_CLEAR 0x30 | ||
251 | |||
252 | /* Endpoint Buffer Size IN/ Receive Packet Frame Number OUT Registers ------*/ | ||
253 | #define UDC_EPIN_BUFF_SIZE_ADDR 0x8 | ||
254 | #define UDC_EPOUT_FRAME_NUMBER_ADDR 0x8 | ||
255 | |||
256 | #define UDC_EPIN_BUFF_SIZE_MASK 0x0000ffff | ||
257 | #define UDC_EPIN_BUFF_SIZE_OFS 0 | ||
258 | /* EP0in txfifo = 128 bytes*/ | ||
259 | #define UDC_EPIN0_BUFF_SIZE 32 | ||
260 | /* EP0in fullspeed txfifo = 128 bytes*/ | ||
261 | #define UDC_FS_EPIN0_BUFF_SIZE 32 | ||
262 | |||
263 | /* fifo size mult = fifo size / max packet */ | ||
264 | #define UDC_EPIN_BUFF_SIZE_MULT 2 | ||
265 | |||
266 | /* EPin data fifo size = 1024 bytes DOUBLE BUFFERING */ | ||
267 | #define UDC_EPIN_BUFF_SIZE 256 | ||
268 | /* EPin small INT data fifo size = 128 bytes */ | ||
269 | #define UDC_EPIN_SMALLINT_BUFF_SIZE 32 | ||
270 | |||
271 | /* EPin fullspeed data fifo size = 128 bytes DOUBLE BUFFERING */ | ||
272 | #define UDC_FS_EPIN_BUFF_SIZE 32 | ||
273 | |||
274 | #define UDC_EPOUT_FRAME_NUMBER_MASK 0x0000ffff | ||
275 | #define UDC_EPOUT_FRAME_NUMBER_OFS 0 | ||
276 | |||
277 | /* Endpoint Buffer Size OUT/Max Packet Size Registers -----------------------*/ | ||
278 | #define UDC_EPOUT_BUFF_SIZE_ADDR 0x0c | ||
279 | #define UDC_EP_MAX_PKT_SIZE_ADDR 0x0c | ||
280 | |||
281 | #define UDC_EPOUT_BUFF_SIZE_MASK 0xffff0000 | ||
282 | #define UDC_EPOUT_BUFF_SIZE_OFS 16 | ||
283 | #define UDC_EP_MAX_PKT_SIZE_MASK 0x0000ffff | ||
284 | #define UDC_EP_MAX_PKT_SIZE_OFS 0 | ||
285 | /* EP0in max packet size = 64 bytes */ | ||
286 | #define UDC_EP0IN_MAX_PKT_SIZE 64 | ||
287 | /* EP0out max packet size = 64 bytes */ | ||
288 | #define UDC_EP0OUT_MAX_PKT_SIZE 64 | ||
289 | /* EP0in fullspeed max packet size = 64 bytes */ | ||
290 | #define UDC_FS_EP0IN_MAX_PKT_SIZE 64 | ||
291 | /* EP0out fullspeed max packet size = 64 bytes */ | ||
292 | #define UDC_FS_EP0OUT_MAX_PKT_SIZE 64 | ||
293 | |||
294 | /* | ||
295 | * Endpoint dma descriptors ------------------------------------------------ | ||
296 | * | ||
297 | * Setup data, Status dword | ||
298 | */ | ||
299 | #define UDC_DMA_STP_STS_CFG_MASK 0x0fff0000 | ||
300 | #define UDC_DMA_STP_STS_CFG_OFS 16 | ||
301 | #define UDC_DMA_STP_STS_CFG_ALT_MASK 0x000f0000 | ||
302 | #define UDC_DMA_STP_STS_CFG_ALT_OFS 16 | ||
303 | #define UDC_DMA_STP_STS_CFG_INTF_MASK 0x00f00000 | ||
304 | #define UDC_DMA_STP_STS_CFG_INTF_OFS 20 | ||
305 | #define UDC_DMA_STP_STS_CFG_NUM_MASK 0x0f000000 | ||
306 | #define UDC_DMA_STP_STS_CFG_NUM_OFS 24 | ||
307 | #define UDC_DMA_STP_STS_RX_MASK 0x30000000 | ||
308 | #define UDC_DMA_STP_STS_RX_OFS 28 | ||
309 | #define UDC_DMA_STP_STS_BS_MASK 0xc0000000 | ||
310 | #define UDC_DMA_STP_STS_BS_OFS 30 | ||
311 | #define UDC_DMA_STP_STS_BS_HOST_READY 0 | ||
312 | #define UDC_DMA_STP_STS_BS_DMA_BUSY 1 | ||
313 | #define UDC_DMA_STP_STS_BS_DMA_DONE 2 | ||
314 | #define UDC_DMA_STP_STS_BS_HOST_BUSY 3 | ||
315 | /* IN data, Status dword */ | ||
316 | #define UDC_DMA_IN_STS_TXBYTES_MASK 0x0000ffff | ||
317 | #define UDC_DMA_IN_STS_TXBYTES_OFS 0 | ||
318 | #define UDC_DMA_IN_STS_FRAMENUM_MASK 0x07ff0000 | ||
319 | #define UDC_DMA_IN_STS_FRAMENUM_OFS 0 | ||
320 | #define UDC_DMA_IN_STS_L 27 | ||
321 | #define UDC_DMA_IN_STS_TX_MASK 0x30000000 | ||
322 | #define UDC_DMA_IN_STS_TX_OFS 28 | ||
323 | #define UDC_DMA_IN_STS_BS_MASK 0xc0000000 | ||
324 | #define UDC_DMA_IN_STS_BS_OFS 30 | ||
325 | #define UDC_DMA_IN_STS_BS_HOST_READY 0 | ||
326 | #define UDC_DMA_IN_STS_BS_DMA_BUSY 1 | ||
327 | #define UDC_DMA_IN_STS_BS_DMA_DONE 2 | ||
328 | #define UDC_DMA_IN_STS_BS_HOST_BUSY 3 | ||
329 | /* OUT data, Status dword */ | ||
330 | #define UDC_DMA_OUT_STS_RXBYTES_MASK 0x0000ffff | ||
331 | #define UDC_DMA_OUT_STS_RXBYTES_OFS 0 | ||
332 | #define UDC_DMA_OUT_STS_FRAMENUM_MASK 0x07ff0000 | ||
333 | #define UDC_DMA_OUT_STS_FRAMENUM_OFS 0 | ||
334 | #define UDC_DMA_OUT_STS_L 27 | ||
335 | #define UDC_DMA_OUT_STS_RX_MASK 0x30000000 | ||
336 | #define UDC_DMA_OUT_STS_RX_OFS 28 | ||
337 | #define UDC_DMA_OUT_STS_BS_MASK 0xc0000000 | ||
338 | #define UDC_DMA_OUT_STS_BS_OFS 30 | ||
339 | #define UDC_DMA_OUT_STS_BS_HOST_READY 0 | ||
340 | #define UDC_DMA_OUT_STS_BS_DMA_BUSY 1 | ||
341 | #define UDC_DMA_OUT_STS_BS_DMA_DONE 2 | ||
342 | #define UDC_DMA_OUT_STS_BS_HOST_BUSY 3 | ||
343 | /* max ep0in packet */ | ||
344 | #define UDC_EP0IN_MAXPACKET 1000 | ||
345 | /* max dma packet */ | ||
346 | #define UDC_DMA_MAXPACKET 65536 | ||
347 | |||
348 | /* un-usable DMA address */ | ||
349 | #define DMA_DONT_USE (~(dma_addr_t) 0 ) | ||
350 | |||
351 | /* other Endpoint register addresses and values-----------------------------*/ | ||
352 | #define UDC_EP_SUBPTR_ADDR 0x10 | ||
353 | #define UDC_EP_DESPTR_ADDR 0x14 | ||
354 | #define UDC_EP_WRITE_CONFIRM_ADDR 0x1c | ||
355 | |||
356 | /* EP number as layouted in AHB space */ | ||
357 | #define UDC_EP_NUM 32 | ||
358 | #define UDC_EPIN_NUM 16 | ||
359 | #define UDC_EPIN_NUM_USED 5 | ||
360 | #define UDC_EPOUT_NUM 16 | ||
361 | /* EP number of EP's really used = EP0 + 8 data EP's */ | ||
362 | #define UDC_USED_EP_NUM 9 | ||
363 | /* UDC CSR regs are aligned but AHB regs not - offset for OUT EP's */ | ||
364 | #define UDC_CSR_EP_OUT_IX_OFS 12 | ||
365 | |||
366 | #define UDC_EP0OUT_IX 16 | ||
367 | #define UDC_EP0IN_IX 0 | ||
368 | |||
369 | /* Rx fifo address and size = 1k -------------------------------------------*/ | ||
370 | #define UDC_RXFIFO_ADDR 0x800 | ||
371 | #define UDC_RXFIFO_SIZE 0x400 | ||
372 | |||
373 | /* Tx fifo address and size = 1.5k -----------------------------------------*/ | ||
374 | #define UDC_TXFIFO_ADDR 0xc00 | ||
375 | #define UDC_TXFIFO_SIZE 0x600 | ||
376 | |||
377 | /* default data endpoints --------------------------------------------------*/ | ||
378 | #define UDC_EPIN_STATUS_IX 1 | ||
379 | #define UDC_EPIN_IX 2 | ||
380 | #define UDC_EPOUT_IX 18 | ||
381 | |||
382 | /* general constants -------------------------------------------------------*/ | ||
383 | #define UDC_DWORD_BYTES 4 | ||
384 | #define UDC_BITS_PER_BYTE_SHIFT 3 | ||
385 | #define UDC_BYTE_MASK 0xff | ||
386 | #define UDC_BITS_PER_BYTE 8 | ||
387 | |||
388 | /*---------------------------------------------------------------------------*/ | ||
389 | /* UDC CSR's */ | ||
390 | struct udc_csrs { | ||
391 | |||
392 | /* sca - setup command address */ | ||
393 | u32 sca; | ||
394 | |||
395 | /* ep ne's */ | ||
396 | u32 ne[UDC_USED_EP_NUM]; | ||
397 | } __attribute__ ((packed)); | ||
398 | |||
399 | /* AHB subsystem CSR registers */ | ||
400 | struct udc_regs { | ||
401 | |||
402 | /* device configuration */ | ||
403 | u32 cfg; | ||
404 | |||
405 | /* device control */ | ||
406 | u32 ctl; | ||
407 | |||
408 | /* device status */ | ||
409 | u32 sts; | ||
410 | |||
411 | /* device interrupt */ | ||
412 | u32 irqsts; | ||
413 | |||
414 | /* device interrupt mask */ | ||
415 | u32 irqmsk; | ||
416 | |||
417 | /* endpoint interrupt */ | ||
418 | u32 ep_irqsts; | ||
419 | |||
420 | /* endpoint interrupt mask */ | ||
421 | u32 ep_irqmsk; | ||
422 | } __attribute__ ((packed)); | ||
423 | |||
424 | /* endpoint specific registers */ | ||
425 | struct udc_ep_regs { | ||
426 | |||
427 | /* endpoint control */ | ||
428 | u32 ctl; | ||
429 | |||
430 | /* endpoint status */ | ||
431 | u32 sts; | ||
432 | |||
433 | /* endpoint buffer size in/ receive packet frame number out */ | ||
434 | u32 bufin_framenum; | ||
435 | |||
436 | /* endpoint buffer size out/max packet size */ | ||
437 | u32 bufout_maxpkt; | ||
438 | |||
439 | /* endpoint setup buffer pointer */ | ||
440 | u32 subptr; | ||
441 | |||
442 | /* endpoint data descriptor pointer */ | ||
443 | u32 desptr; | ||
444 | |||
445 | /* reserverd */ | ||
446 | u32 reserved; | ||
447 | |||
448 | /* write/read confirmation */ | ||
449 | u32 confirm; | ||
450 | |||
451 | } __attribute__ ((packed)); | ||
452 | |||
453 | /* control data DMA desc */ | ||
454 | struct udc_stp_dma { | ||
455 | /* status quadlet */ | ||
456 | u32 status; | ||
457 | /* reserved */ | ||
458 | u32 _reserved; | ||
459 | /* first setup word */ | ||
460 | u32 data12; | ||
461 | /* second setup word */ | ||
462 | u32 data34; | ||
463 | } __attribute__ ((aligned (16))); | ||
464 | |||
465 | /* normal data DMA desc */ | ||
466 | struct udc_data_dma { | ||
467 | /* status quadlet */ | ||
468 | u32 status; | ||
469 | /* reserved */ | ||
470 | u32 _reserved; | ||
471 | /* buffer pointer */ | ||
472 | u32 bufptr; | ||
473 | /* next descriptor pointer */ | ||
474 | u32 next; | ||
475 | } __attribute__ ((aligned (16))); | ||
476 | |||
477 | /* request packet */ | ||
478 | struct udc_request { | ||
479 | /* embedded gadget ep */ | ||
480 | struct usb_request req; | ||
481 | |||
482 | /* flags */ | ||
483 | unsigned dma_going : 1, | ||
484 | dma_mapping : 1, | ||
485 | dma_done : 1; | ||
486 | /* phys. address */ | ||
487 | dma_addr_t td_phys; | ||
488 | /* first dma desc. of chain */ | ||
489 | struct udc_data_dma *td_data; | ||
490 | /* last dma desc. of chain */ | ||
491 | struct udc_data_dma *td_data_last; | ||
492 | struct list_head queue; | ||
493 | |||
494 | /* chain length */ | ||
495 | unsigned chain_len; | ||
496 | |||
497 | }; | ||
498 | |||
499 | /* UDC specific endpoint parameters */ | ||
500 | struct udc_ep { | ||
501 | struct usb_ep ep; | ||
502 | struct udc_ep_regs __iomem *regs; | ||
503 | u32 __iomem *txfifo; | ||
504 | u32 __iomem *dma; | ||
505 | dma_addr_t td_phys; | ||
506 | dma_addr_t td_stp_dma; | ||
507 | struct udc_stp_dma *td_stp; | ||
508 | struct udc_data_dma *td; | ||
509 | /* temp request */ | ||
510 | struct udc_request *req; | ||
511 | unsigned req_used; | ||
512 | unsigned req_completed; | ||
513 | /* dummy DMA desc for BNA dummy */ | ||
514 | struct udc_request *bna_dummy_req; | ||
515 | unsigned bna_occurred; | ||
516 | |||
517 | /* NAK state */ | ||
518 | unsigned naking; | ||
519 | |||
520 | struct udc *dev; | ||
521 | |||
522 | /* queue for requests */ | ||
523 | struct list_head queue; | ||
524 | const struct usb_endpoint_descriptor *desc; | ||
525 | unsigned halted; | ||
526 | unsigned cancel_transfer; | ||
527 | unsigned num : 5, | ||
528 | fifo_depth : 14, | ||
529 | in : 1; | ||
530 | }; | ||
531 | |||
532 | /* device struct */ | ||
533 | struct udc { | ||
534 | struct usb_gadget gadget; | ||
535 | spinlock_t lock; /* protects all state */ | ||
536 | /* all endpoints */ | ||
537 | struct udc_ep ep[UDC_EP_NUM]; | ||
538 | struct usb_gadget_driver *driver; | ||
539 | /* operational flags */ | ||
540 | unsigned active : 1, | ||
541 | stall_ep0in : 1, | ||
542 | waiting_zlp_ack_ep0in : 1, | ||
543 | set_cfg_not_acked : 1, | ||
544 | irq_registered : 1, | ||
545 | data_ep_enabled : 1, | ||
546 | data_ep_queued : 1, | ||
547 | mem_region : 1, | ||
548 | sys_suspended : 1, | ||
549 | connected; | ||
550 | |||
551 | u16 chiprev; | ||
552 | |||
553 | /* registers */ | ||
554 | struct pci_dev *pdev; | ||
555 | struct udc_csrs __iomem *csr; | ||
556 | struct udc_regs __iomem *regs; | ||
557 | struct udc_ep_regs __iomem *ep_regs; | ||
558 | u32 __iomem *rxfifo; | ||
559 | u32 __iomem *txfifo; | ||
560 | |||
561 | /* DMA desc pools */ | ||
562 | struct pci_pool *data_requests; | ||
563 | struct pci_pool *stp_requests; | ||
564 | |||
565 | /* device data */ | ||
566 | unsigned long phys_addr; | ||
567 | void __iomem *virt_addr; | ||
568 | unsigned irq; | ||
569 | |||
570 | /* states */ | ||
571 | u16 cur_config; | ||
572 | u16 cur_intf; | ||
573 | u16 cur_alt; | ||
574 | }; | ||
575 | |||
576 | /* setup request data */ | ||
577 | union udc_setup_data { | ||
578 | u32 data[2]; | ||
579 | struct usb_ctrlrequest request; | ||
580 | }; | ||
581 | |||
582 | /* | ||
583 | *--------------------------------------------------------------------------- | ||
584 | * SET and GET bitfields in u32 values | ||
585 | * via constants for mask/offset: | ||
586 | * <bit_field_stub_name> is the text between | ||
587 | * UDC_ and _MASK|_OFS of appropiate | ||
588 | * constant | ||
589 | * | ||
590 | * set bitfield value in u32 u32Val | ||
591 | */ | ||
592 | #define AMD_ADDBITS(u32Val, bitfield_val, bitfield_stub_name) \ | ||
593 | (((u32Val) & (((u32) ~((u32) bitfield_stub_name##_MASK)))) \ | ||
594 | | (((bitfield_val) << ((u32) bitfield_stub_name##_OFS)) \ | ||
595 | & ((u32) bitfield_stub_name##_MASK))) | ||
596 | |||
597 | /* | ||
598 | * set bitfield value in zero-initialized u32 u32Val | ||
599 | * => bitfield bits in u32Val are all zero | ||
600 | */ | ||
601 | #define AMD_INIT_SETBITS(u32Val, bitfield_val, bitfield_stub_name) \ | ||
602 | ((u32Val) \ | ||
603 | | (((bitfield_val) << ((u32) bitfield_stub_name##_OFS)) \ | ||
604 | & ((u32) bitfield_stub_name##_MASK))) | ||
605 | |||
606 | /* get bitfield value from u32 u32Val */ | ||
607 | #define AMD_GETBITS(u32Val, bitfield_stub_name) \ | ||
608 | ((u32Val & ((u32) bitfield_stub_name##_MASK)) \ | ||
609 | >> ((u32) bitfield_stub_name##_OFS)) | ||
610 | |||
611 | /* SET and GET bits in u32 values ------------------------------------------*/ | ||
612 | #define AMD_BIT(bit_stub_name) (1 << bit_stub_name) | ||
613 | #define AMD_UNMASK_BIT(bit_stub_name) (~AMD_BIT(bit_stub_name)) | ||
614 | #define AMD_CLEAR_BIT(bit_stub_name) (~AMD_BIT(bit_stub_name)) | ||
615 | |||
616 | /* debug macros ------------------------------------------------------------*/ | ||
617 | |||
618 | #define DBG(udc , args...) dev_dbg(&(udc)->pdev->dev, args) | ||
619 | |||
620 | #ifdef UDC_VERBOSE | ||
621 | #define VDBG DBG | ||
622 | #else | ||
623 | #define VDBG(udc , args...) do {} while (0) | ||
624 | #endif | ||
625 | |||
626 | #endif /* #ifdef AMD5536UDC_H */ | ||
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index 63d7d656869..a6adf7e0f6f 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include <linux/proc_fs.h> | 38 | #include <linux/proc_fs.h> |
39 | #include <linux/clk.h> | 39 | #include <linux/clk.h> |
40 | #include <linux/usb/ch9.h> | 40 | #include <linux/usb/ch9.h> |
41 | #include <linux/usb_gadget.h> | 41 | #include <linux/usb/gadget.h> |
42 | 42 | ||
43 | #include <asm/byteorder.h> | 43 | #include <asm/byteorder.h> |
44 | #include <asm/hardware.h> | 44 | #include <asm/hardware.h> |
diff --git a/drivers/usb/gadget/atmel_usba_udc.c b/drivers/usb/gadget/atmel_usba_udc.c new file mode 100644 index 00000000000..4fb5ff46957 --- /dev/null +++ b/drivers/usb/gadget/atmel_usba_udc.c | |||
@@ -0,0 +1,2077 @@ | |||
1 | /* | ||
2 | * Driver for the Atmel USBA high speed USB device controller | ||
3 | * | ||
4 | * Copyright (C) 2005-2007 Atmel Corporation | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #include <linux/clk.h> | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/init.h> | ||
13 | #include <linux/interrupt.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/device.h> | ||
16 | #include <linux/dma-mapping.h> | ||
17 | #include <linux/list.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/usb/ch9.h> | ||
20 | #include <linux/usb/gadget.h> | ||
21 | #include <linux/delay.h> | ||
22 | |||
23 | #include <asm/gpio.h> | ||
24 | #include <asm/arch/board.h> | ||
25 | |||
26 | #include "atmel_usba_udc.h" | ||
27 | |||
28 | |||
29 | static struct usba_udc the_udc; | ||
30 | |||
31 | #ifdef CONFIG_USB_GADGET_DEBUG_FS | ||
32 | #include <linux/debugfs.h> | ||
33 | #include <linux/uaccess.h> | ||
34 | |||
35 | static int queue_dbg_open(struct inode *inode, struct file *file) | ||
36 | { | ||
37 | struct usba_ep *ep = inode->i_private; | ||
38 | struct usba_request *req, *req_copy; | ||
39 | struct list_head *queue_data; | ||
40 | |||
41 | queue_data = kmalloc(sizeof(*queue_data), GFP_KERNEL); | ||
42 | if (!queue_data) | ||
43 | return -ENOMEM; | ||
44 | INIT_LIST_HEAD(queue_data); | ||
45 | |||
46 | spin_lock_irq(&ep->udc->lock); | ||
47 | list_for_each_entry(req, &ep->queue, queue) { | ||
48 | req_copy = kmalloc(sizeof(*req_copy), GFP_ATOMIC); | ||
49 | if (!req_copy) | ||
50 | goto fail; | ||
51 | memcpy(req_copy, req, sizeof(*req_copy)); | ||
52 | list_add_tail(&req_copy->queue, queue_data); | ||
53 | } | ||
54 | spin_unlock_irq(&ep->udc->lock); | ||
55 | |||
56 | file->private_data = queue_data; | ||
57 | return 0; | ||
58 | |||
59 | fail: | ||
60 | spin_unlock_irq(&ep->udc->lock); | ||
61 | list_for_each_entry_safe(req, req_copy, queue_data, queue) { | ||
62 | list_del(&req->queue); | ||
63 | kfree(req); | ||
64 | } | ||
65 | kfree(queue_data); | ||
66 | return -ENOMEM; | ||
67 | } | ||
68 | |||
69 | /* | ||
70 | * bbbbbbbb llllllll IZS sssss nnnn FDL\n\0 | ||
71 | * | ||
72 | * b: buffer address | ||
73 | * l: buffer length | ||
74 | * I/i: interrupt/no interrupt | ||
75 | * Z/z: zero/no zero | ||
76 | * S/s: short ok/short not ok | ||
77 | * s: status | ||
78 | * n: nr_packets | ||
79 | * F/f: submitted/not submitted to FIFO | ||
80 | * D/d: using/not using DMA | ||
81 | * L/l: last transaction/not last transaction | ||
82 | */ | ||
83 | static ssize_t queue_dbg_read(struct file *file, char __user *buf, | ||
84 | size_t nbytes, loff_t *ppos) | ||
85 | { | ||
86 | struct list_head *queue = file->private_data; | ||
87 | struct usba_request *req, *tmp_req; | ||
88 | size_t len, remaining, actual = 0; | ||
89 | char tmpbuf[38]; | ||
90 | |||
91 | if (!access_ok(VERIFY_WRITE, buf, nbytes)) | ||
92 | return -EFAULT; | ||
93 | |||
94 | mutex_lock(&file->f_dentry->d_inode->i_mutex); | ||
95 | list_for_each_entry_safe(req, tmp_req, queue, queue) { | ||
96 | len = snprintf(tmpbuf, sizeof(tmpbuf), | ||
97 | "%8p %08x %c%c%c %5d %c%c%c\n", | ||
98 | req->req.buf, req->req.length, | ||
99 | req->req.no_interrupt ? 'i' : 'I', | ||
100 | req->req.zero ? 'Z' : 'z', | ||
101 | req->req.short_not_ok ? 's' : 'S', | ||
102 | req->req.status, | ||
103 | req->submitted ? 'F' : 'f', | ||
104 | req->using_dma ? 'D' : 'd', | ||
105 | req->last_transaction ? 'L' : 'l'); | ||
106 | len = min(len, sizeof(tmpbuf)); | ||
107 | if (len > nbytes) | ||
108 | break; | ||
109 | |||
110 | list_del(&req->queue); | ||
111 | kfree(req); | ||
112 | |||
113 | remaining = __copy_to_user(buf, tmpbuf, len); | ||
114 | actual += len - remaining; | ||
115 | if (remaining) | ||
116 | break; | ||
117 | |||
118 | nbytes -= len; | ||
119 | buf += len; | ||
120 | } | ||
121 | mutex_unlock(&file->f_dentry->d_inode->i_mutex); | ||
122 | |||
123 | return actual; | ||
124 | } | ||
125 | |||
126 | static int queue_dbg_release(struct inode *inode, struct file *file) | ||
127 | { | ||
128 | struct list_head *queue_data = file->private_data; | ||
129 | struct usba_request *req, *tmp_req; | ||
130 | |||
131 | list_for_each_entry_safe(req, tmp_req, queue_data, queue) { | ||
132 | list_del(&req->queue); | ||
133 | kfree(req); | ||
134 | } | ||
135 | kfree(queue_data); | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | static int regs_dbg_open(struct inode *inode, struct file *file) | ||
140 | { | ||
141 | struct usba_udc *udc; | ||
142 | unsigned int i; | ||
143 | u32 *data; | ||
144 | int ret = -ENOMEM; | ||
145 | |||
146 | mutex_lock(&inode->i_mutex); | ||
147 | udc = inode->i_private; | ||
148 | data = kmalloc(inode->i_size, GFP_KERNEL); | ||
149 | if (!data) | ||
150 | goto out; | ||
151 | |||
152 | spin_lock_irq(&udc->lock); | ||
153 | for (i = 0; i < inode->i_size / 4; i++) | ||
154 | data[i] = __raw_readl(udc->regs + i * 4); | ||
155 | spin_unlock_irq(&udc->lock); | ||
156 | |||
157 | file->private_data = data; | ||
158 | ret = 0; | ||
159 | |||
160 | out: | ||
161 | mutex_unlock(&inode->i_mutex); | ||
162 | |||
163 | return ret; | ||
164 | } | ||
165 | |||
166 | static ssize_t regs_dbg_read(struct file *file, char __user *buf, | ||
167 | size_t nbytes, loff_t *ppos) | ||
168 | { | ||
169 | struct inode *inode = file->f_dentry->d_inode; | ||
170 | int ret; | ||
171 | |||
172 | mutex_lock(&inode->i_mutex); | ||
173 | ret = simple_read_from_buffer(buf, nbytes, ppos, | ||
174 | file->private_data, | ||
175 | file->f_dentry->d_inode->i_size); | ||
176 | mutex_unlock(&inode->i_mutex); | ||
177 | |||
178 | return ret; | ||
179 | } | ||
180 | |||
181 | static int regs_dbg_release(struct inode *inode, struct file *file) | ||
182 | { | ||
183 | kfree(file->private_data); | ||
184 | return 0; | ||
185 | } | ||
186 | |||
187 | const struct file_operations queue_dbg_fops = { | ||
188 | .owner = THIS_MODULE, | ||
189 | .open = queue_dbg_open, | ||
190 | .llseek = no_llseek, | ||
191 | .read = queue_dbg_read, | ||
192 | .release = queue_dbg_release, | ||
193 | }; | ||
194 | |||
195 | const struct file_operations regs_dbg_fops = { | ||
196 | .owner = THIS_MODULE, | ||
197 | .open = regs_dbg_open, | ||
198 | .llseek = generic_file_llseek, | ||
199 | .read = regs_dbg_read, | ||
200 | .release = regs_dbg_release, | ||
201 | }; | ||
202 | |||
203 | static void usba_ep_init_debugfs(struct usba_udc *udc, | ||
204 | struct usba_ep *ep) | ||
205 | { | ||
206 | struct dentry *ep_root; | ||
207 | |||
208 | ep_root = debugfs_create_dir(ep->ep.name, udc->debugfs_root); | ||
209 | if (!ep_root) | ||
210 | goto err_root; | ||
211 | ep->debugfs_dir = ep_root; | ||
212 | |||
213 | ep->debugfs_queue = debugfs_create_file("queue", 0400, ep_root, | ||
214 | ep, &queue_dbg_fops); | ||
215 | if (!ep->debugfs_queue) | ||
216 | goto err_queue; | ||
217 | |||
218 | if (ep->can_dma) { | ||
219 | ep->debugfs_dma_status | ||
220 | = debugfs_create_u32("dma_status", 0400, ep_root, | ||
221 | &ep->last_dma_status); | ||
222 | if (!ep->debugfs_dma_status) | ||
223 | goto err_dma_status; | ||
224 | } | ||
225 | if (ep_is_control(ep)) { | ||
226 | ep->debugfs_state | ||
227 | = debugfs_create_u32("state", 0400, ep_root, | ||
228 | &ep->state); | ||
229 | if (!ep->debugfs_state) | ||
230 | goto err_state; | ||
231 | } | ||
232 | |||
233 | return; | ||
234 | |||
235 | err_state: | ||
236 | if (ep->can_dma) | ||
237 | debugfs_remove(ep->debugfs_dma_status); | ||
238 | err_dma_status: | ||
239 | debugfs_remove(ep->debugfs_queue); | ||
240 | err_queue: | ||
241 | debugfs_remove(ep_root); | ||
242 | err_root: | ||
243 | dev_err(&ep->udc->pdev->dev, | ||
244 | "failed to create debugfs directory for %s\n", ep->ep.name); | ||
245 | } | ||
246 | |||
247 | static void usba_ep_cleanup_debugfs(struct usba_ep *ep) | ||
248 | { | ||
249 | debugfs_remove(ep->debugfs_queue); | ||
250 | debugfs_remove(ep->debugfs_dma_status); | ||
251 | debugfs_remove(ep->debugfs_state); | ||
252 | debugfs_remove(ep->debugfs_dir); | ||
253 | ep->debugfs_dma_status = NULL; | ||
254 | ep->debugfs_dir = NULL; | ||
255 | } | ||
256 | |||
257 | static void usba_init_debugfs(struct usba_udc *udc) | ||
258 | { | ||
259 | struct dentry *root, *regs; | ||
260 | struct resource *regs_resource; | ||
261 | |||
262 | root = debugfs_create_dir(udc->gadget.name, NULL); | ||
263 | if (IS_ERR(root) || !root) | ||
264 | goto err_root; | ||
265 | udc->debugfs_root = root; | ||
266 | |||
267 | regs = debugfs_create_file("regs", 0400, root, udc, ®s_dbg_fops); | ||
268 | if (!regs) | ||
269 | goto err_regs; | ||
270 | |||
271 | regs_resource = platform_get_resource(udc->pdev, IORESOURCE_MEM, | ||
272 | CTRL_IOMEM_ID); | ||
273 | regs->d_inode->i_size = regs_resource->end - regs_resource->start + 1; | ||
274 | udc->debugfs_regs = regs; | ||
275 | |||
276 | usba_ep_init_debugfs(udc, to_usba_ep(udc->gadget.ep0)); | ||
277 | |||
278 | return; | ||
279 | |||
280 | err_regs: | ||
281 | debugfs_remove(root); | ||
282 | err_root: | ||
283 | udc->debugfs_root = NULL; | ||
284 | dev_err(&udc->pdev->dev, "debugfs is not available\n"); | ||
285 | } | ||
286 | |||
287 | static void usba_cleanup_debugfs(struct usba_udc *udc) | ||
288 | { | ||
289 | usba_ep_cleanup_debugfs(to_usba_ep(udc->gadget.ep0)); | ||
290 | debugfs_remove(udc->debugfs_regs); | ||
291 | debugfs_remove(udc->debugfs_root); | ||
292 | udc->debugfs_regs = NULL; | ||
293 | udc->debugfs_root = NULL; | ||
294 | } | ||
295 | #else | ||
296 | static inline void usba_ep_init_debugfs(struct usba_udc *udc, | ||
297 | struct usba_ep *ep) | ||
298 | { | ||
299 | |||
300 | } | ||
301 | |||
302 | static inline void usba_ep_cleanup_debugfs(struct usba_ep *ep) | ||
303 | { | ||
304 | |||
305 | } | ||
306 | |||
307 | static inline void usba_init_debugfs(struct usba_udc *udc) | ||
308 | { | ||
309 | |||
310 | } | ||
311 | |||
312 | static inline void usba_cleanup_debugfs(struct usba_udc *udc) | ||
313 | { | ||
314 | |||
315 | } | ||
316 | #endif | ||
317 | |||
318 | static int vbus_is_present(struct usba_udc *udc) | ||
319 | { | ||
320 | if (udc->vbus_pin != -1) | ||
321 | return gpio_get_value(udc->vbus_pin); | ||
322 | |||
323 | /* No Vbus detection: Assume always present */ | ||
324 | return 1; | ||
325 | } | ||
326 | |||
327 | static void copy_to_fifo(void __iomem *fifo, const void *buf, int len) | ||
328 | { | ||
329 | unsigned long tmp; | ||
330 | |||
331 | DBG(DBG_FIFO, "copy to FIFO (len %d):\n", len); | ||
332 | for (; len > 0; len -= 4, buf += 4, fifo += 4) { | ||
333 | tmp = *(unsigned long *)buf; | ||
334 | if (len >= 4) { | ||
335 | DBG(DBG_FIFO, " -> %08lx\n", tmp); | ||
336 | __raw_writel(tmp, fifo); | ||
337 | } else { | ||
338 | do { | ||
339 | DBG(DBG_FIFO, " -> %02lx\n", tmp >> 24); | ||
340 | __raw_writeb(tmp >> 24, fifo); | ||
341 | fifo++; | ||
342 | tmp <<= 8; | ||
343 | } while (--len); | ||
344 | break; | ||
345 | } | ||
346 | } | ||
347 | } | ||
348 | |||
349 | static void copy_from_fifo(void *buf, void __iomem *fifo, int len) | ||
350 | { | ||
351 | union { | ||
352 | unsigned long *w; | ||
353 | unsigned char *b; | ||
354 | } p; | ||
355 | unsigned long tmp; | ||
356 | |||
357 | DBG(DBG_FIFO, "copy from FIFO (len %d):\n", len); | ||
358 | for (p.w = buf; len > 0; len -= 4, p.w++, fifo += 4) { | ||
359 | if (len >= 4) { | ||
360 | tmp = __raw_readl(fifo); | ||
361 | *p.w = tmp; | ||
362 | DBG(DBG_FIFO, " -> %08lx\n", tmp); | ||
363 | } else { | ||
364 | do { | ||
365 | tmp = __raw_readb(fifo); | ||
366 | *p.b = tmp; | ||
367 | DBG(DBG_FIFO, " -> %02lx\n", tmp); | ||
368 | fifo++, p.b++; | ||
369 | } while (--len); | ||
370 | } | ||
371 | } | ||
372 | } | ||
373 | |||
374 | static void next_fifo_transaction(struct usba_ep *ep, struct usba_request *req) | ||
375 | { | ||
376 | unsigned int transaction_len; | ||
377 | |||
378 | transaction_len = req->req.length - req->req.actual; | ||
379 | req->last_transaction = 1; | ||
380 | if (transaction_len > ep->ep.maxpacket) { | ||
381 | transaction_len = ep->ep.maxpacket; | ||
382 | req->last_transaction = 0; | ||
383 | } else if (transaction_len == ep->ep.maxpacket && req->req.zero) | ||
384 | req->last_transaction = 0; | ||
385 | |||
386 | DBG(DBG_QUEUE, "%s: submit_transaction, req %p (length %d)%s\n", | ||
387 | ep->ep.name, req, transaction_len, | ||
388 | req->last_transaction ? ", done" : ""); | ||
389 | |||
390 | copy_to_fifo(ep->fifo, req->req.buf + req->req.actual, transaction_len); | ||
391 | usba_ep_writel(ep, SET_STA, USBA_TX_PK_RDY); | ||
392 | req->req.actual += transaction_len; | ||
393 | } | ||
394 | |||
395 | static void submit_request(struct usba_ep *ep, struct usba_request *req) | ||
396 | { | ||
397 | DBG(DBG_QUEUE, "%s: submit_request: req %p (length %d)\n", | ||
398 | ep->ep.name, req, req->req.length); | ||
399 | |||
400 | req->req.actual = 0; | ||
401 | req->submitted = 1; | ||
402 | |||
403 | if (req->using_dma) { | ||
404 | if (req->req.length == 0) { | ||
405 | usba_ep_writel(ep, CTL_ENB, USBA_TX_PK_RDY); | ||
406 | return; | ||
407 | } | ||
408 | |||
409 | if (req->req.zero) | ||
410 | usba_ep_writel(ep, CTL_ENB, USBA_SHORT_PACKET); | ||
411 | else | ||
412 | usba_ep_writel(ep, CTL_DIS, USBA_SHORT_PACKET); | ||
413 | |||
414 | usba_dma_writel(ep, ADDRESS, req->req.dma); | ||
415 | usba_dma_writel(ep, CONTROL, req->ctrl); | ||
416 | } else { | ||
417 | next_fifo_transaction(ep, req); | ||
418 | if (req->last_transaction) { | ||
419 | usba_ep_writel(ep, CTL_DIS, USBA_TX_PK_RDY); | ||
420 | usba_ep_writel(ep, CTL_ENB, USBA_TX_COMPLETE); | ||
421 | } else { | ||
422 | usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE); | ||
423 | usba_ep_writel(ep, CTL_ENB, USBA_TX_PK_RDY); | ||
424 | } | ||
425 | } | ||
426 | } | ||
427 | |||
428 | static void submit_next_request(struct usba_ep *ep) | ||
429 | { | ||
430 | struct usba_request *req; | ||
431 | |||
432 | if (list_empty(&ep->queue)) { | ||
433 | usba_ep_writel(ep, CTL_DIS, USBA_TX_PK_RDY | USBA_RX_BK_RDY); | ||
434 | return; | ||
435 | } | ||
436 | |||
437 | req = list_entry(ep->queue.next, struct usba_request, queue); | ||
438 | if (!req->submitted) | ||
439 | submit_request(ep, req); | ||
440 | } | ||
441 | |||
442 | static void send_status(struct usba_udc *udc, struct usba_ep *ep) | ||
443 | { | ||
444 | ep->state = STATUS_STAGE_IN; | ||
445 | usba_ep_writel(ep, SET_STA, USBA_TX_PK_RDY); | ||
446 | usba_ep_writel(ep, CTL_ENB, USBA_TX_COMPLETE); | ||
447 | } | ||
448 | |||
449 | static void receive_data(struct usba_ep *ep) | ||
450 | { | ||
451 | struct usba_udc *udc = ep->udc; | ||
452 | struct usba_request *req; | ||
453 | unsigned long status; | ||
454 | unsigned int bytecount, nr_busy; | ||
455 | int is_complete = 0; | ||
456 | |||
457 | status = usba_ep_readl(ep, STA); | ||
458 | nr_busy = USBA_BFEXT(BUSY_BANKS, status); | ||
459 | |||
460 | DBG(DBG_QUEUE, "receive data: nr_busy=%u\n", nr_busy); | ||
461 | |||
462 | while (nr_busy > 0) { | ||
463 | if (list_empty(&ep->queue)) { | ||
464 | usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY); | ||
465 | break; | ||
466 | } | ||
467 | req = list_entry(ep->queue.next, | ||
468 | struct usba_request, queue); | ||
469 | |||
470 | bytecount = USBA_BFEXT(BYTE_COUNT, status); | ||
471 | |||
472 | if (status & (1 << 31)) | ||
473 | is_complete = 1; | ||
474 | if (req->req.actual + bytecount >= req->req.length) { | ||
475 | is_complete = 1; | ||
476 | bytecount = req->req.length - req->req.actual; | ||
477 | } | ||
478 | |||
479 | copy_from_fifo(req->req.buf + req->req.actual, | ||
480 | ep->fifo, bytecount); | ||
481 | req->req.actual += bytecount; | ||
482 | |||
483 | usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY); | ||
484 | |||
485 | if (is_complete) { | ||
486 | DBG(DBG_QUEUE, "%s: request done\n", ep->ep.name); | ||
487 | req->req.status = 0; | ||
488 | list_del_init(&req->queue); | ||
489 | usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY); | ||
490 | spin_unlock(&udc->lock); | ||
491 | req->req.complete(&ep->ep, &req->req); | ||
492 | spin_lock(&udc->lock); | ||
493 | } | ||
494 | |||
495 | status = usba_ep_readl(ep, STA); | ||
496 | nr_busy = USBA_BFEXT(BUSY_BANKS, status); | ||
497 | |||
498 | if (is_complete && ep_is_control(ep)) { | ||
499 | send_status(udc, ep); | ||
500 | break; | ||
501 | } | ||
502 | } | ||
503 | } | ||
504 | |||
505 | static void | ||
506 | request_complete(struct usba_ep *ep, struct usba_request *req, int status) | ||
507 | { | ||
508 | struct usba_udc *udc = ep->udc; | ||
509 | |||
510 | WARN_ON(!list_empty(&req->queue)); | ||
511 | |||
512 | if (req->req.status == -EINPROGRESS) | ||
513 | req->req.status = status; | ||
514 | |||
515 | if (req->mapped) { | ||
516 | dma_unmap_single( | ||
517 | &udc->pdev->dev, req->req.dma, req->req.length, | ||
518 | ep->is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
519 | req->req.dma = DMA_ADDR_INVALID; | ||
520 | req->mapped = 0; | ||
521 | } | ||
522 | |||
523 | DBG(DBG_GADGET | DBG_REQ, | ||
524 | "%s: req %p complete: status %d, actual %u\n", | ||
525 | ep->ep.name, req, req->req.status, req->req.actual); | ||
526 | |||
527 | spin_unlock(&udc->lock); | ||
528 | req->req.complete(&ep->ep, &req->req); | ||
529 | spin_lock(&udc->lock); | ||
530 | } | ||
531 | |||
532 | static void | ||
533 | request_complete_list(struct usba_ep *ep, struct list_head *list, int status) | ||
534 | { | ||
535 | struct usba_request *req, *tmp_req; | ||
536 | |||
537 | list_for_each_entry_safe(req, tmp_req, list, queue) { | ||
538 | list_del_init(&req->queue); | ||
539 | request_complete(ep, req, status); | ||
540 | } | ||
541 | } | ||
542 | |||
543 | static int | ||
544 | usba_ep_enable(struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc) | ||
545 | { | ||
546 | struct usba_ep *ep = to_usba_ep(_ep); | ||
547 | struct usba_udc *udc = ep->udc; | ||
548 | unsigned long flags, ept_cfg, maxpacket; | ||
549 | unsigned int nr_trans; | ||
550 | |||
551 | DBG(DBG_GADGET, "%s: ep_enable: desc=%p\n", ep->ep.name, desc); | ||
552 | |||
553 | maxpacket = le16_to_cpu(desc->wMaxPacketSize) & 0x7ff; | ||
554 | |||
555 | if (((desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) != ep->index) | ||
556 | || ep->index == 0 | ||
557 | || desc->bDescriptorType != USB_DT_ENDPOINT | ||
558 | || maxpacket == 0 | ||
559 | || maxpacket > ep->fifo_size) { | ||
560 | DBG(DBG_ERR, "ep_enable: Invalid argument"); | ||
561 | return -EINVAL; | ||
562 | } | ||
563 | |||
564 | ep->is_isoc = 0; | ||
565 | ep->is_in = 0; | ||
566 | |||
567 | if (maxpacket <= 8) | ||
568 | ept_cfg = USBA_BF(EPT_SIZE, USBA_EPT_SIZE_8); | ||
569 | else | ||
570 | /* LSB is bit 1, not 0 */ | ||
571 | ept_cfg = USBA_BF(EPT_SIZE, fls(maxpacket - 1) - 3); | ||
572 | |||
573 | DBG(DBG_HW, "%s: EPT_SIZE = %lu (maxpacket = %lu)\n", | ||
574 | ep->ep.name, ept_cfg, maxpacket); | ||
575 | |||
576 | if ((desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN) { | ||
577 | ep->is_in = 1; | ||
578 | ept_cfg |= USBA_EPT_DIR_IN; | ||
579 | } | ||
580 | |||
581 | switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | ||
582 | case USB_ENDPOINT_XFER_CONTROL: | ||
583 | ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_CONTROL); | ||
584 | ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_ONE); | ||
585 | break; | ||
586 | case USB_ENDPOINT_XFER_ISOC: | ||
587 | if (!ep->can_isoc) { | ||
588 | DBG(DBG_ERR, "ep_enable: %s is not isoc capable\n", | ||
589 | ep->ep.name); | ||
590 | return -EINVAL; | ||
591 | } | ||
592 | |||
593 | /* | ||
594 | * Bits 11:12 specify number of _additional_ | ||
595 | * transactions per microframe. | ||
596 | */ | ||
597 | nr_trans = ((le16_to_cpu(desc->wMaxPacketSize) >> 11) & 3) + 1; | ||
598 | if (nr_trans > 3) | ||
599 | return -EINVAL; | ||
600 | |||
601 | ep->is_isoc = 1; | ||
602 | ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_ISO); | ||
603 | |||
604 | /* | ||
605 | * Do triple-buffering on high-bandwidth iso endpoints. | ||
606 | */ | ||
607 | if (nr_trans > 1 && ep->nr_banks == 3) | ||
608 | ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_TRIPLE); | ||
609 | else | ||
610 | ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_DOUBLE); | ||
611 | ept_cfg |= USBA_BF(NB_TRANS, nr_trans); | ||
612 | break; | ||
613 | case USB_ENDPOINT_XFER_BULK: | ||
614 | ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_BULK); | ||
615 | ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_DOUBLE); | ||
616 | break; | ||
617 | case USB_ENDPOINT_XFER_INT: | ||
618 | ept_cfg |= USBA_BF(EPT_TYPE, USBA_EPT_TYPE_INT); | ||
619 | ept_cfg |= USBA_BF(BK_NUMBER, USBA_BK_NUMBER_DOUBLE); | ||
620 | break; | ||
621 | } | ||
622 | |||
623 | spin_lock_irqsave(&ep->udc->lock, flags); | ||
624 | |||
625 | if (ep->desc) { | ||
626 | spin_unlock_irqrestore(&ep->udc->lock, flags); | ||
627 | DBG(DBG_ERR, "ep%d already enabled\n", ep->index); | ||
628 | return -EBUSY; | ||
629 | } | ||
630 | |||
631 | ep->desc = desc; | ||
632 | ep->ep.maxpacket = maxpacket; | ||
633 | |||
634 | usba_ep_writel(ep, CFG, ept_cfg); | ||
635 | usba_ep_writel(ep, CTL_ENB, USBA_EPT_ENABLE); | ||
636 | |||
637 | if (ep->can_dma) { | ||
638 | u32 ctrl; | ||
639 | |||
640 | usba_writel(udc, INT_ENB, | ||
641 | (usba_readl(udc, INT_ENB) | ||
642 | | USBA_BF(EPT_INT, 1 << ep->index) | ||
643 | | USBA_BF(DMA_INT, 1 << ep->index))); | ||
644 | ctrl = USBA_AUTO_VALID | USBA_INTDIS_DMA; | ||
645 | usba_ep_writel(ep, CTL_ENB, ctrl); | ||
646 | } else { | ||
647 | usba_writel(udc, INT_ENB, | ||
648 | (usba_readl(udc, INT_ENB) | ||
649 | | USBA_BF(EPT_INT, 1 << ep->index))); | ||
650 | } | ||
651 | |||
652 | spin_unlock_irqrestore(&udc->lock, flags); | ||
653 | |||
654 | DBG(DBG_HW, "EPT_CFG%d after init: %#08lx\n", ep->index, | ||
655 | (unsigned long)usba_ep_readl(ep, CFG)); | ||
656 | DBG(DBG_HW, "INT_ENB after init: %#08lx\n", | ||
657 | (unsigned long)usba_readl(udc, INT_ENB)); | ||
658 | |||
659 | return 0; | ||
660 | } | ||
661 | |||
662 | static int usba_ep_disable(struct usb_ep *_ep) | ||
663 | { | ||
664 | struct usba_ep *ep = to_usba_ep(_ep); | ||
665 | struct usba_udc *udc = ep->udc; | ||
666 | LIST_HEAD(req_list); | ||
667 | unsigned long flags; | ||
668 | |||
669 | DBG(DBG_GADGET, "ep_disable: %s\n", ep->ep.name); | ||
670 | |||
671 | spin_lock_irqsave(&udc->lock, flags); | ||
672 | |||
673 | if (!ep->desc) { | ||
674 | spin_unlock_irqrestore(&udc->lock, flags); | ||
675 | DBG(DBG_ERR, "ep_disable: %s not enabled\n", ep->ep.name); | ||
676 | return -EINVAL; | ||
677 | } | ||
678 | ep->desc = NULL; | ||
679 | |||
680 | list_splice_init(&ep->queue, &req_list); | ||
681 | if (ep->can_dma) { | ||
682 | usba_dma_writel(ep, CONTROL, 0); | ||
683 | usba_dma_writel(ep, ADDRESS, 0); | ||
684 | usba_dma_readl(ep, STATUS); | ||
685 | } | ||
686 | usba_ep_writel(ep, CTL_DIS, USBA_EPT_ENABLE); | ||
687 | usba_writel(udc, INT_ENB, | ||
688 | usba_readl(udc, INT_ENB) | ||
689 | & ~USBA_BF(EPT_INT, 1 << ep->index)); | ||
690 | |||
691 | request_complete_list(ep, &req_list, -ESHUTDOWN); | ||
692 | |||
693 | spin_unlock_irqrestore(&udc->lock, flags); | ||
694 | |||
695 | return 0; | ||
696 | } | ||
697 | |||
698 | static struct usb_request * | ||
699 | usba_ep_alloc_request(struct usb_ep *_ep, gfp_t gfp_flags) | ||
700 | { | ||
701 | struct usba_request *req; | ||
702 | |||
703 | DBG(DBG_GADGET, "ep_alloc_request: %p, 0x%x\n", _ep, gfp_flags); | ||
704 | |||
705 | req = kzalloc(sizeof(*req), gfp_flags); | ||
706 | if (!req) | ||
707 | return NULL; | ||
708 | |||
709 | INIT_LIST_HEAD(&req->queue); | ||
710 | req->req.dma = DMA_ADDR_INVALID; | ||
711 | |||
712 | return &req->req; | ||
713 | } | ||
714 | |||
715 | static void | ||
716 | usba_ep_free_request(struct usb_ep *_ep, struct usb_request *_req) | ||
717 | { | ||
718 | struct usba_request *req = to_usba_req(_req); | ||
719 | |||
720 | DBG(DBG_GADGET, "ep_free_request: %p, %p\n", _ep, _req); | ||
721 | |||
722 | kfree(req); | ||
723 | } | ||
724 | |||
725 | static int queue_dma(struct usba_udc *udc, struct usba_ep *ep, | ||
726 | struct usba_request *req, gfp_t gfp_flags) | ||
727 | { | ||
728 | unsigned long flags; | ||
729 | int ret; | ||
730 | |||
731 | DBG(DBG_DMA, "%s: req l/%u d/%08x %c%c%c\n", | ||
732 | ep->ep.name, req->req.length, req->req.dma, | ||
733 | req->req.zero ? 'Z' : 'z', | ||
734 | req->req.short_not_ok ? 'S' : 's', | ||
735 | req->req.no_interrupt ? 'I' : 'i'); | ||
736 | |||
737 | if (req->req.length > 0x10000) { | ||
738 | /* Lengths from 0 to 65536 (inclusive) are supported */ | ||
739 | DBG(DBG_ERR, "invalid request length %u\n", req->req.length); | ||
740 | return -EINVAL; | ||
741 | } | ||
742 | |||
743 | req->using_dma = 1; | ||
744 | |||
745 | if (req->req.dma == DMA_ADDR_INVALID) { | ||
746 | req->req.dma = dma_map_single( | ||
747 | &udc->pdev->dev, req->req.buf, req->req.length, | ||
748 | ep->is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
749 | req->mapped = 1; | ||
750 | } else { | ||
751 | dma_sync_single_for_device( | ||
752 | &udc->pdev->dev, req->req.dma, req->req.length, | ||
753 | ep->is_in ? DMA_TO_DEVICE : DMA_FROM_DEVICE); | ||
754 | req->mapped = 0; | ||
755 | } | ||
756 | |||
757 | req->ctrl = USBA_BF(DMA_BUF_LEN, req->req.length) | ||
758 | | USBA_DMA_CH_EN | USBA_DMA_END_BUF_IE | ||
759 | | USBA_DMA_END_TR_EN | USBA_DMA_END_TR_IE; | ||
760 | |||
761 | if (ep->is_in) | ||
762 | req->ctrl |= USBA_DMA_END_BUF_EN; | ||
763 | |||
764 | /* | ||
765 | * Add this request to the queue and submit for DMA if | ||
766 | * possible. Check if we're still alive first -- we may have | ||
767 | * received a reset since last time we checked. | ||
768 | */ | ||
769 | ret = -ESHUTDOWN; | ||
770 | spin_lock_irqsave(&udc->lock, flags); | ||
771 | if (ep->desc) { | ||
772 | if (list_empty(&ep->queue)) | ||
773 | submit_request(ep, req); | ||
774 | |||
775 | list_add_tail(&req->queue, &ep->queue); | ||
776 | ret = 0; | ||
777 | } | ||
778 | spin_unlock_irqrestore(&udc->lock, flags); | ||
779 | |||
780 | return ret; | ||
781 | } | ||
782 | |||
783 | static int | ||
784 | usba_ep_queue(struct usb_ep *_ep, struct usb_request *_req, gfp_t gfp_flags) | ||
785 | { | ||
786 | struct usba_request *req = to_usba_req(_req); | ||
787 | struct usba_ep *ep = to_usba_ep(_ep); | ||
788 | struct usba_udc *udc = ep->udc; | ||
789 | unsigned long flags; | ||
790 | int ret; | ||
791 | |||
792 | DBG(DBG_GADGET | DBG_QUEUE | DBG_REQ, "%s: queue req %p, len %u\n", | ||
793 | ep->ep.name, req, _req->length); | ||
794 | |||
795 | if (!udc->driver || udc->gadget.speed == USB_SPEED_UNKNOWN || !ep->desc) | ||
796 | return -ESHUTDOWN; | ||
797 | |||
798 | req->submitted = 0; | ||
799 | req->using_dma = 0; | ||
800 | req->last_transaction = 0; | ||
801 | |||
802 | _req->status = -EINPROGRESS; | ||
803 | _req->actual = 0; | ||
804 | |||
805 | if (ep->can_dma) | ||
806 | return queue_dma(udc, ep, req, gfp_flags); | ||
807 | |||
808 | /* May have received a reset since last time we checked */ | ||
809 | ret = -ESHUTDOWN; | ||
810 | spin_lock_irqsave(&udc->lock, flags); | ||
811 | if (ep->desc) { | ||
812 | list_add_tail(&req->queue, &ep->queue); | ||
813 | |||
814 | if (ep->is_in || (ep_is_control(ep) | ||
815 | && (ep->state == DATA_STAGE_IN | ||
816 | || ep->state == STATUS_STAGE_IN))) | ||
817 | usba_ep_writel(ep, CTL_ENB, USBA_TX_PK_RDY); | ||
818 | else | ||
819 | usba_ep_writel(ep, CTL_ENB, USBA_RX_BK_RDY); | ||
820 | ret = 0; | ||
821 | } | ||
822 | spin_unlock_irqrestore(&udc->lock, flags); | ||
823 | |||
824 | return ret; | ||
825 | } | ||
826 | |||
827 | static void | ||
828 | usba_update_req(struct usba_ep *ep, struct usba_request *req, u32 status) | ||
829 | { | ||
830 | req->req.actual = req->req.length - USBA_BFEXT(DMA_BUF_LEN, status); | ||
831 | } | ||
832 | |||
833 | static int stop_dma(struct usba_ep *ep, u32 *pstatus) | ||
834 | { | ||
835 | unsigned int timeout; | ||
836 | u32 status; | ||
837 | |||
838 | /* | ||
839 | * Stop the DMA controller. When writing both CH_EN | ||
840 | * and LINK to 0, the other bits are not affected. | ||
841 | */ | ||
842 | usba_dma_writel(ep, CONTROL, 0); | ||
843 | |||
844 | /* Wait for the FIFO to empty */ | ||
845 | for (timeout = 40; timeout; --timeout) { | ||
846 | status = usba_dma_readl(ep, STATUS); | ||
847 | if (!(status & USBA_DMA_CH_EN)) | ||
848 | break; | ||
849 | udelay(1); | ||
850 | } | ||
851 | |||
852 | if (pstatus) | ||
853 | *pstatus = status; | ||
854 | |||
855 | if (timeout == 0) { | ||
856 | dev_err(&ep->udc->pdev->dev, | ||
857 | "%s: timed out waiting for DMA FIFO to empty\n", | ||
858 | ep->ep.name); | ||
859 | return -ETIMEDOUT; | ||
860 | } | ||
861 | |||
862 | return 0; | ||
863 | } | ||
864 | |||
865 | static int usba_ep_dequeue(struct usb_ep *_ep, struct usb_request *_req) | ||
866 | { | ||
867 | struct usba_ep *ep = to_usba_ep(_ep); | ||
868 | struct usba_udc *udc = ep->udc; | ||
869 | struct usba_request *req = to_usba_req(_req); | ||
870 | unsigned long flags; | ||
871 | u32 status; | ||
872 | |||
873 | DBG(DBG_GADGET | DBG_QUEUE, "ep_dequeue: %s, req %p\n", | ||
874 | ep->ep.name, req); | ||
875 | |||
876 | spin_lock_irqsave(&udc->lock, flags); | ||
877 | |||
878 | if (req->using_dma) { | ||
879 | /* | ||
880 | * If this request is currently being transferred, | ||
881 | * stop the DMA controller and reset the FIFO. | ||
882 | */ | ||
883 | if (ep->queue.next == &req->queue) { | ||
884 | status = usba_dma_readl(ep, STATUS); | ||
885 | if (status & USBA_DMA_CH_EN) | ||
886 | stop_dma(ep, &status); | ||
887 | |||
888 | #ifdef CONFIG_USB_GADGET_DEBUG_FS | ||
889 | ep->last_dma_status = status; | ||
890 | #endif | ||
891 | |||
892 | usba_writel(udc, EPT_RST, 1 << ep->index); | ||
893 | |||
894 | usba_update_req(ep, req, status); | ||
895 | } | ||
896 | } | ||
897 | |||
898 | /* | ||
899 | * Errors should stop the queue from advancing until the | ||
900 | * completion function returns. | ||
901 | */ | ||
902 | list_del_init(&req->queue); | ||
903 | |||
904 | request_complete(ep, req, -ECONNRESET); | ||
905 | |||
906 | /* Process the next request if any */ | ||
907 | submit_next_request(ep); | ||
908 | spin_unlock_irqrestore(&udc->lock, flags); | ||
909 | |||
910 | return 0; | ||
911 | } | ||
912 | |||
913 | static int usba_ep_set_halt(struct usb_ep *_ep, int value) | ||
914 | { | ||
915 | struct usba_ep *ep = to_usba_ep(_ep); | ||
916 | struct usba_udc *udc = ep->udc; | ||
917 | unsigned long flags; | ||
918 | int ret = 0; | ||
919 | |||
920 | DBG(DBG_GADGET, "endpoint %s: %s HALT\n", ep->ep.name, | ||
921 | value ? "set" : "clear"); | ||
922 | |||
923 | if (!ep->desc) { | ||
924 | DBG(DBG_ERR, "Attempted to halt uninitialized ep %s\n", | ||
925 | ep->ep.name); | ||
926 | return -ENODEV; | ||
927 | } | ||
928 | if (ep->is_isoc) { | ||
929 | DBG(DBG_ERR, "Attempted to halt isochronous ep %s\n", | ||
930 | ep->ep.name); | ||
931 | return -ENOTTY; | ||
932 | } | ||
933 | |||
934 | spin_lock_irqsave(&udc->lock, flags); | ||
935 | |||
936 | /* | ||
937 | * We can't halt IN endpoints while there are still data to be | ||
938 | * transferred | ||
939 | */ | ||
940 | if (!list_empty(&ep->queue) | ||
941 | || ((value && ep->is_in && (usba_ep_readl(ep, STA) | ||
942 | & USBA_BF(BUSY_BANKS, -1L))))) { | ||
943 | ret = -EAGAIN; | ||
944 | } else { | ||
945 | if (value) | ||
946 | usba_ep_writel(ep, SET_STA, USBA_FORCE_STALL); | ||
947 | else | ||
948 | usba_ep_writel(ep, CLR_STA, | ||
949 | USBA_FORCE_STALL | USBA_TOGGLE_CLR); | ||
950 | usba_ep_readl(ep, STA); | ||
951 | } | ||
952 | |||
953 | spin_unlock_irqrestore(&udc->lock, flags); | ||
954 | |||
955 | return ret; | ||
956 | } | ||
957 | |||
958 | static int usba_ep_fifo_status(struct usb_ep *_ep) | ||
959 | { | ||
960 | struct usba_ep *ep = to_usba_ep(_ep); | ||
961 | |||
962 | return USBA_BFEXT(BYTE_COUNT, usba_ep_readl(ep, STA)); | ||
963 | } | ||
964 | |||
965 | static void usba_ep_fifo_flush(struct usb_ep *_ep) | ||
966 | { | ||
967 | struct usba_ep *ep = to_usba_ep(_ep); | ||
968 | struct usba_udc *udc = ep->udc; | ||
969 | |||
970 | usba_writel(udc, EPT_RST, 1 << ep->index); | ||
971 | } | ||
972 | |||
973 | static const struct usb_ep_ops usba_ep_ops = { | ||
974 | .enable = usba_ep_enable, | ||
975 | .disable = usba_ep_disable, | ||
976 | .alloc_request = usba_ep_alloc_request, | ||
977 | .free_request = usba_ep_free_request, | ||
978 | .queue = usba_ep_queue, | ||
979 | .dequeue = usba_ep_dequeue, | ||
980 | .set_halt = usba_ep_set_halt, | ||
981 | .fifo_status = usba_ep_fifo_status, | ||
982 | .fifo_flush = usba_ep_fifo_flush, | ||
983 | }; | ||
984 | |||
985 | static int usba_udc_get_frame(struct usb_gadget *gadget) | ||
986 | { | ||
987 | struct usba_udc *udc = to_usba_udc(gadget); | ||
988 | |||
989 | return USBA_BFEXT(FRAME_NUMBER, usba_readl(udc, FNUM)); | ||
990 | } | ||
991 | |||
992 | static int usba_udc_wakeup(struct usb_gadget *gadget) | ||
993 | { | ||
994 | struct usba_udc *udc = to_usba_udc(gadget); | ||
995 | unsigned long flags; | ||
996 | u32 ctrl; | ||
997 | int ret = -EINVAL; | ||
998 | |||
999 | spin_lock_irqsave(&udc->lock, flags); | ||
1000 | if (udc->devstatus & (1 << USB_DEVICE_REMOTE_WAKEUP)) { | ||
1001 | ctrl = usba_readl(udc, CTRL); | ||
1002 | usba_writel(udc, CTRL, ctrl | USBA_REMOTE_WAKE_UP); | ||
1003 | ret = 0; | ||
1004 | } | ||
1005 | spin_unlock_irqrestore(&udc->lock, flags); | ||
1006 | |||
1007 | return ret; | ||
1008 | } | ||
1009 | |||
1010 | static int | ||
1011 | usba_udc_set_selfpowered(struct usb_gadget *gadget, int is_selfpowered) | ||
1012 | { | ||
1013 | struct usba_udc *udc = to_usba_udc(gadget); | ||
1014 | unsigned long flags; | ||
1015 | |||
1016 | spin_lock_irqsave(&udc->lock, flags); | ||
1017 | if (is_selfpowered) | ||
1018 | udc->devstatus |= 1 << USB_DEVICE_SELF_POWERED; | ||
1019 | else | ||
1020 | udc->devstatus &= ~(1 << USB_DEVICE_SELF_POWERED); | ||
1021 | spin_unlock_irqrestore(&udc->lock, flags); | ||
1022 | |||
1023 | return 0; | ||
1024 | } | ||
1025 | |||
1026 | static const struct usb_gadget_ops usba_udc_ops = { | ||
1027 | .get_frame = usba_udc_get_frame, | ||
1028 | .wakeup = usba_udc_wakeup, | ||
1029 | .set_selfpowered = usba_udc_set_selfpowered, | ||
1030 | }; | ||
1031 | |||
1032 | #define EP(nam, idx, maxpkt, maxbk, dma, isoc) \ | ||
1033 | { \ | ||
1034 | .ep = { \ | ||
1035 | .ops = &usba_ep_ops, \ | ||
1036 | .name = nam, \ | ||
1037 | .maxpacket = maxpkt, \ | ||
1038 | }, \ | ||
1039 | .udc = &the_udc, \ | ||
1040 | .queue = LIST_HEAD_INIT(usba_ep[idx].queue), \ | ||
1041 | .fifo_size = maxpkt, \ | ||
1042 | .nr_banks = maxbk, \ | ||
1043 | .index = idx, \ | ||
1044 | .can_dma = dma, \ | ||
1045 | .can_isoc = isoc, \ | ||
1046 | } | ||
1047 | |||
1048 | static struct usba_ep usba_ep[] = { | ||
1049 | EP("ep0", 0, 64, 1, 0, 0), | ||
1050 | EP("ep1in-bulk", 1, 512, 2, 1, 1), | ||
1051 | EP("ep2out-bulk", 2, 512, 2, 1, 1), | ||
1052 | EP("ep3in-int", 3, 64, 3, 1, 0), | ||
1053 | EP("ep4out-int", 4, 64, 3, 1, 0), | ||
1054 | EP("ep5in-iso", 5, 1024, 3, 1, 1), | ||
1055 | EP("ep6out-iso", 6, 1024, 3, 1, 1), | ||
1056 | }; | ||
1057 | #undef EP | ||
1058 | |||
1059 | static struct usb_endpoint_descriptor usba_ep0_desc = { | ||
1060 | .bLength = USB_DT_ENDPOINT_SIZE, | ||
1061 | .bDescriptorType = USB_DT_ENDPOINT, | ||
1062 | .bEndpointAddress = 0, | ||
1063 | .bmAttributes = USB_ENDPOINT_XFER_CONTROL, | ||
1064 | .wMaxPacketSize = __constant_cpu_to_le16(64), | ||
1065 | /* FIXME: I have no idea what to put here */ | ||
1066 | .bInterval = 1, | ||
1067 | }; | ||
1068 | |||
1069 | static void nop_release(struct device *dev) | ||
1070 | { | ||
1071 | |||
1072 | } | ||
1073 | |||
1074 | static struct usba_udc the_udc = { | ||
1075 | .gadget = { | ||
1076 | .ops = &usba_udc_ops, | ||
1077 | .ep0 = &usba_ep[0].ep, | ||
1078 | .ep_list = LIST_HEAD_INIT(the_udc.gadget.ep_list), | ||
1079 | .is_dualspeed = 1, | ||
1080 | .name = "atmel_usba_udc", | ||
1081 | .dev = { | ||
1082 | .bus_id = "gadget", | ||
1083 | .release = nop_release, | ||
1084 | }, | ||
1085 | }, | ||
1086 | |||
1087 | .lock = SPIN_LOCK_UNLOCKED, | ||
1088 | }; | ||
1089 | |||
1090 | /* | ||
1091 | * Called with interrupts disabled and udc->lock held. | ||
1092 | */ | ||
1093 | static void reset_all_endpoints(struct usba_udc *udc) | ||
1094 | { | ||
1095 | struct usba_ep *ep; | ||
1096 | struct usba_request *req, *tmp_req; | ||
1097 | |||
1098 | usba_writel(udc, EPT_RST, ~0UL); | ||
1099 | |||
1100 | ep = to_usba_ep(udc->gadget.ep0); | ||
1101 | list_for_each_entry_safe(req, tmp_req, &ep->queue, queue) { | ||
1102 | list_del_init(&req->queue); | ||
1103 | request_complete(ep, req, -ECONNRESET); | ||
1104 | } | ||
1105 | |||
1106 | list_for_each_entry(ep, &udc->gadget.ep_list, ep.ep_list) { | ||
1107 | if (ep->desc) { | ||
1108 | spin_unlock(&udc->lock); | ||
1109 | usba_ep_disable(&ep->ep); | ||
1110 | spin_lock(&udc->lock); | ||
1111 | } | ||
1112 | } | ||
1113 | } | ||
1114 | |||
1115 | static struct usba_ep *get_ep_by_addr(struct usba_udc *udc, u16 wIndex) | ||
1116 | { | ||
1117 | struct usba_ep *ep; | ||
1118 | |||
1119 | if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0) | ||
1120 | return to_usba_ep(udc->gadget.ep0); | ||
1121 | |||
1122 | list_for_each_entry (ep, &udc->gadget.ep_list, ep.ep_list) { | ||
1123 | u8 bEndpointAddress; | ||
1124 | |||
1125 | if (!ep->desc) | ||
1126 | continue; | ||
1127 | bEndpointAddress = ep->desc->bEndpointAddress; | ||
1128 | if ((wIndex ^ bEndpointAddress) & USB_DIR_IN) | ||
1129 | continue; | ||
1130 | if ((bEndpointAddress & USB_ENDPOINT_NUMBER_MASK) | ||
1131 | == (wIndex & USB_ENDPOINT_NUMBER_MASK)) | ||
1132 | return ep; | ||
1133 | } | ||
1134 | |||
1135 | return NULL; | ||
1136 | } | ||
1137 | |||
1138 | /* Called with interrupts disabled and udc->lock held */ | ||
1139 | static inline void set_protocol_stall(struct usba_udc *udc, struct usba_ep *ep) | ||
1140 | { | ||
1141 | usba_ep_writel(ep, SET_STA, USBA_FORCE_STALL); | ||
1142 | ep->state = WAIT_FOR_SETUP; | ||
1143 | } | ||
1144 | |||
1145 | static inline int is_stalled(struct usba_udc *udc, struct usba_ep *ep) | ||
1146 | { | ||
1147 | if (usba_ep_readl(ep, STA) & USBA_FORCE_STALL) | ||
1148 | return 1; | ||
1149 | return 0; | ||
1150 | } | ||
1151 | |||
1152 | static inline void set_address(struct usba_udc *udc, unsigned int addr) | ||
1153 | { | ||
1154 | u32 regval; | ||
1155 | |||
1156 | DBG(DBG_BUS, "setting address %u...\n", addr); | ||
1157 | regval = usba_readl(udc, CTRL); | ||
1158 | regval = USBA_BFINS(DEV_ADDR, addr, regval); | ||
1159 | usba_writel(udc, CTRL, regval); | ||
1160 | } | ||
1161 | |||
1162 | static int do_test_mode(struct usba_udc *udc) | ||
1163 | { | ||
1164 | static const char test_packet_buffer[] = { | ||
1165 | /* JKJKJKJK * 9 */ | ||
1166 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
1167 | /* JJKKJJKK * 8 */ | ||
1168 | 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, | ||
1169 | /* JJKKJJKK * 8 */ | ||
1170 | 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, | ||
1171 | /* JJJJJJJKKKKKKK * 8 */ | ||
1172 | 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
1173 | 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | ||
1174 | /* JJJJJJJK * 8 */ | ||
1175 | 0x7F, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, | ||
1176 | /* {JKKKKKKK * 10}, JK */ | ||
1177 | 0xFC, 0x7E, 0xBF, 0xDF, 0xEF, 0xF7, 0xFB, 0xFD, 0x7E | ||
1178 | }; | ||
1179 | struct usba_ep *ep; | ||
1180 | struct device *dev = &udc->pdev->dev; | ||
1181 | int test_mode; | ||
1182 | |||
1183 | test_mode = udc->test_mode; | ||
1184 | |||
1185 | /* Start from a clean slate */ | ||
1186 | reset_all_endpoints(udc); | ||
1187 | |||
1188 | switch (test_mode) { | ||
1189 | case 0x0100: | ||
1190 | /* Test_J */ | ||
1191 | usba_writel(udc, TST, USBA_TST_J_MODE); | ||
1192 | dev_info(dev, "Entering Test_J mode...\n"); | ||
1193 | break; | ||
1194 | case 0x0200: | ||
1195 | /* Test_K */ | ||
1196 | usba_writel(udc, TST, USBA_TST_K_MODE); | ||
1197 | dev_info(dev, "Entering Test_K mode...\n"); | ||
1198 | break; | ||
1199 | case 0x0300: | ||
1200 | /* | ||
1201 | * Test_SE0_NAK: Force high-speed mode and set up ep0 | ||
1202 | * for Bulk IN transfers | ||
1203 | */ | ||
1204 | ep = &usba_ep[0]; | ||
1205 | usba_writel(udc, TST, | ||
1206 | USBA_BF(SPEED_CFG, USBA_SPEED_CFG_FORCE_HIGH)); | ||
1207 | usba_ep_writel(ep, CFG, | ||
1208 | USBA_BF(EPT_SIZE, USBA_EPT_SIZE_64) | ||
1209 | | USBA_EPT_DIR_IN | ||
1210 | | USBA_BF(EPT_TYPE, USBA_EPT_TYPE_BULK) | ||
1211 | | USBA_BF(BK_NUMBER, 1)); | ||
1212 | if (!(usba_ep_readl(ep, CFG) & USBA_EPT_MAPPED)) { | ||
1213 | set_protocol_stall(udc, ep); | ||
1214 | dev_err(dev, "Test_SE0_NAK: ep0 not mapped\n"); | ||
1215 | } else { | ||
1216 | usba_ep_writel(ep, CTL_ENB, USBA_EPT_ENABLE); | ||
1217 | dev_info(dev, "Entering Test_SE0_NAK mode...\n"); | ||
1218 | } | ||
1219 | break; | ||
1220 | case 0x0400: | ||
1221 | /* Test_Packet */ | ||
1222 | ep = &usba_ep[0]; | ||
1223 | usba_ep_writel(ep, CFG, | ||
1224 | USBA_BF(EPT_SIZE, USBA_EPT_SIZE_64) | ||
1225 | | USBA_EPT_DIR_IN | ||
1226 | | USBA_BF(EPT_TYPE, USBA_EPT_TYPE_BULK) | ||
1227 | | USBA_BF(BK_NUMBER, 1)); | ||
1228 | if (!(usba_ep_readl(ep, CFG) & USBA_EPT_MAPPED)) { | ||
1229 | set_protocol_stall(udc, ep); | ||
1230 | dev_err(dev, "Test_Packet: ep0 not mapped\n"); | ||
1231 | } else { | ||
1232 | usba_ep_writel(ep, CTL_ENB, USBA_EPT_ENABLE); | ||
1233 | usba_writel(udc, TST, USBA_TST_PKT_MODE); | ||
1234 | copy_to_fifo(ep->fifo, test_packet_buffer, | ||
1235 | sizeof(test_packet_buffer)); | ||
1236 | usba_ep_writel(ep, SET_STA, USBA_TX_PK_RDY); | ||
1237 | dev_info(dev, "Entering Test_Packet mode...\n"); | ||
1238 | } | ||
1239 | break; | ||
1240 | default: | ||
1241 | dev_err(dev, "Invalid test mode: 0x%04x\n", test_mode); | ||
1242 | return -EINVAL; | ||
1243 | } | ||
1244 | |||
1245 | return 0; | ||
1246 | } | ||
1247 | |||
1248 | /* Avoid overly long expressions */ | ||
1249 | static inline bool feature_is_dev_remote_wakeup(struct usb_ctrlrequest *crq) | ||
1250 | { | ||
1251 | if (crq->wValue == __constant_cpu_to_le16(USB_DEVICE_REMOTE_WAKEUP)) | ||
1252 | return true; | ||
1253 | return false; | ||
1254 | } | ||
1255 | |||
1256 | static inline bool feature_is_dev_test_mode(struct usb_ctrlrequest *crq) | ||
1257 | { | ||
1258 | if (crq->wValue == __constant_cpu_to_le16(USB_DEVICE_TEST_MODE)) | ||
1259 | return true; | ||
1260 | return false; | ||
1261 | } | ||
1262 | |||
1263 | static inline bool feature_is_ep_halt(struct usb_ctrlrequest *crq) | ||
1264 | { | ||
1265 | if (crq->wValue == __constant_cpu_to_le16(USB_ENDPOINT_HALT)) | ||
1266 | return true; | ||
1267 | return false; | ||
1268 | } | ||
1269 | |||
1270 | static int handle_ep0_setup(struct usba_udc *udc, struct usba_ep *ep, | ||
1271 | struct usb_ctrlrequest *crq) | ||
1272 | { | ||
1273 | int retval = 0;; | ||
1274 | |||
1275 | switch (crq->bRequest) { | ||
1276 | case USB_REQ_GET_STATUS: { | ||
1277 | u16 status; | ||
1278 | |||
1279 | if (crq->bRequestType == (USB_DIR_IN | USB_RECIP_DEVICE)) { | ||
1280 | status = cpu_to_le16(udc->devstatus); | ||
1281 | } else if (crq->bRequestType | ||
1282 | == (USB_DIR_IN | USB_RECIP_INTERFACE)) { | ||
1283 | status = __constant_cpu_to_le16(0); | ||
1284 | } else if (crq->bRequestType | ||
1285 | == (USB_DIR_IN | USB_RECIP_ENDPOINT)) { | ||
1286 | struct usba_ep *target; | ||
1287 | |||
1288 | target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex)); | ||
1289 | if (!target) | ||
1290 | goto stall; | ||
1291 | |||
1292 | status = 0; | ||
1293 | if (is_stalled(udc, target)) | ||
1294 | status |= __constant_cpu_to_le16(1); | ||
1295 | } else | ||
1296 | goto delegate; | ||
1297 | |||
1298 | /* Write directly to the FIFO. No queueing is done. */ | ||
1299 | if (crq->wLength != __constant_cpu_to_le16(sizeof(status))) | ||
1300 | goto stall; | ||
1301 | ep->state = DATA_STAGE_IN; | ||
1302 | __raw_writew(status, ep->fifo); | ||
1303 | usba_ep_writel(ep, SET_STA, USBA_TX_PK_RDY); | ||
1304 | break; | ||
1305 | } | ||
1306 | |||
1307 | case USB_REQ_CLEAR_FEATURE: { | ||
1308 | if (crq->bRequestType == USB_RECIP_DEVICE) { | ||
1309 | if (feature_is_dev_remote_wakeup(crq)) | ||
1310 | udc->devstatus | ||
1311 | &= ~(1 << USB_DEVICE_REMOTE_WAKEUP); | ||
1312 | else | ||
1313 | /* Can't CLEAR_FEATURE TEST_MODE */ | ||
1314 | goto stall; | ||
1315 | } else if (crq->bRequestType == USB_RECIP_ENDPOINT) { | ||
1316 | struct usba_ep *target; | ||
1317 | |||
1318 | if (crq->wLength != __constant_cpu_to_le16(0) | ||
1319 | || !feature_is_ep_halt(crq)) | ||
1320 | goto stall; | ||
1321 | target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex)); | ||
1322 | if (!target) | ||
1323 | goto stall; | ||
1324 | |||
1325 | usba_ep_writel(target, CLR_STA, USBA_FORCE_STALL); | ||
1326 | if (target->index != 0) | ||
1327 | usba_ep_writel(target, CLR_STA, | ||
1328 | USBA_TOGGLE_CLR); | ||
1329 | } else { | ||
1330 | goto delegate; | ||
1331 | } | ||
1332 | |||
1333 | send_status(udc, ep); | ||
1334 | break; | ||
1335 | } | ||
1336 | |||
1337 | case USB_REQ_SET_FEATURE: { | ||
1338 | if (crq->bRequestType == USB_RECIP_DEVICE) { | ||
1339 | if (feature_is_dev_test_mode(crq)) { | ||
1340 | send_status(udc, ep); | ||
1341 | ep->state = STATUS_STAGE_TEST; | ||
1342 | udc->test_mode = le16_to_cpu(crq->wIndex); | ||
1343 | return 0; | ||
1344 | } else if (feature_is_dev_remote_wakeup(crq)) { | ||
1345 | udc->devstatus |= 1 << USB_DEVICE_REMOTE_WAKEUP; | ||
1346 | } else { | ||
1347 | goto stall; | ||
1348 | } | ||
1349 | } else if (crq->bRequestType == USB_RECIP_ENDPOINT) { | ||
1350 | struct usba_ep *target; | ||
1351 | |||
1352 | if (crq->wLength != __constant_cpu_to_le16(0) | ||
1353 | || !feature_is_ep_halt(crq)) | ||
1354 | goto stall; | ||
1355 | |||
1356 | target = get_ep_by_addr(udc, le16_to_cpu(crq->wIndex)); | ||
1357 | if (!target) | ||
1358 | goto stall; | ||
1359 | |||
1360 | usba_ep_writel(target, SET_STA, USBA_FORCE_STALL); | ||
1361 | } else | ||
1362 | goto delegate; | ||
1363 | |||
1364 | send_status(udc, ep); | ||
1365 | break; | ||
1366 | } | ||
1367 | |||
1368 | case USB_REQ_SET_ADDRESS: | ||
1369 | if (crq->bRequestType != (USB_DIR_OUT | USB_RECIP_DEVICE)) | ||
1370 | goto delegate; | ||
1371 | |||
1372 | set_address(udc, le16_to_cpu(crq->wValue)); | ||
1373 | send_status(udc, ep); | ||
1374 | ep->state = STATUS_STAGE_ADDR; | ||
1375 | break; | ||
1376 | |||
1377 | default: | ||
1378 | delegate: | ||
1379 | spin_unlock(&udc->lock); | ||
1380 | retval = udc->driver->setup(&udc->gadget, crq); | ||
1381 | spin_lock(&udc->lock); | ||
1382 | } | ||
1383 | |||
1384 | return retval; | ||
1385 | |||
1386 | stall: | ||
1387 | printk(KERN_ERR | ||
1388 | "udc: %s: Invalid setup request: %02x.%02x v%04x i%04x l%d, " | ||
1389 | "halting endpoint...\n", | ||
1390 | ep->ep.name, crq->bRequestType, crq->bRequest, | ||
1391 | le16_to_cpu(crq->wValue), le16_to_cpu(crq->wIndex), | ||
1392 | le16_to_cpu(crq->wLength)); | ||
1393 | set_protocol_stall(udc, ep); | ||
1394 | return -1; | ||
1395 | } | ||
1396 | |||
1397 | static void usba_control_irq(struct usba_udc *udc, struct usba_ep *ep) | ||
1398 | { | ||
1399 | struct usba_request *req; | ||
1400 | u32 epstatus; | ||
1401 | u32 epctrl; | ||
1402 | |||
1403 | restart: | ||
1404 | epstatus = usba_ep_readl(ep, STA); | ||
1405 | epctrl = usba_ep_readl(ep, CTL); | ||
1406 | |||
1407 | DBG(DBG_INT, "%s [%d]: s/%08x c/%08x\n", | ||
1408 | ep->ep.name, ep->state, epstatus, epctrl); | ||
1409 | |||
1410 | req = NULL; | ||
1411 | if (!list_empty(&ep->queue)) | ||
1412 | req = list_entry(ep->queue.next, | ||
1413 | struct usba_request, queue); | ||
1414 | |||
1415 | if ((epctrl & USBA_TX_PK_RDY) && !(epstatus & USBA_TX_PK_RDY)) { | ||
1416 | if (req->submitted) | ||
1417 | next_fifo_transaction(ep, req); | ||
1418 | else | ||
1419 | submit_request(ep, req); | ||
1420 | |||
1421 | if (req->last_transaction) { | ||
1422 | usba_ep_writel(ep, CTL_DIS, USBA_TX_PK_RDY); | ||
1423 | usba_ep_writel(ep, CTL_ENB, USBA_TX_COMPLETE); | ||
1424 | } | ||
1425 | goto restart; | ||
1426 | } | ||
1427 | if ((epstatus & epctrl) & USBA_TX_COMPLETE) { | ||
1428 | usba_ep_writel(ep, CLR_STA, USBA_TX_COMPLETE); | ||
1429 | |||
1430 | switch (ep->state) { | ||
1431 | case DATA_STAGE_IN: | ||
1432 | usba_ep_writel(ep, CTL_ENB, USBA_RX_BK_RDY); | ||
1433 | usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE); | ||
1434 | ep->state = STATUS_STAGE_OUT; | ||
1435 | break; | ||
1436 | case STATUS_STAGE_ADDR: | ||
1437 | /* Activate our new address */ | ||
1438 | usba_writel(udc, CTRL, (usba_readl(udc, CTRL) | ||
1439 | | USBA_FADDR_EN)); | ||
1440 | usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE); | ||
1441 | ep->state = WAIT_FOR_SETUP; | ||
1442 | break; | ||
1443 | case STATUS_STAGE_IN: | ||
1444 | if (req) { | ||
1445 | list_del_init(&req->queue); | ||
1446 | request_complete(ep, req, 0); | ||
1447 | submit_next_request(ep); | ||
1448 | } | ||
1449 | usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE); | ||
1450 | ep->state = WAIT_FOR_SETUP; | ||
1451 | break; | ||
1452 | case STATUS_STAGE_TEST: | ||
1453 | usba_ep_writel(ep, CTL_DIS, USBA_TX_COMPLETE); | ||
1454 | ep->state = WAIT_FOR_SETUP; | ||
1455 | if (do_test_mode(udc)) | ||
1456 | set_protocol_stall(udc, ep); | ||
1457 | break; | ||
1458 | default: | ||
1459 | printk(KERN_ERR | ||
1460 | "udc: %s: TXCOMP: Invalid endpoint state %d, " | ||
1461 | "halting endpoint...\n", | ||
1462 | ep->ep.name, ep->state); | ||
1463 | set_protocol_stall(udc, ep); | ||
1464 | break; | ||
1465 | } | ||
1466 | |||
1467 | goto restart; | ||
1468 | } | ||
1469 | if ((epstatus & epctrl) & USBA_RX_BK_RDY) { | ||
1470 | switch (ep->state) { | ||
1471 | case STATUS_STAGE_OUT: | ||
1472 | usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY); | ||
1473 | usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY); | ||
1474 | |||
1475 | if (req) { | ||
1476 | list_del_init(&req->queue); | ||
1477 | request_complete(ep, req, 0); | ||
1478 | } | ||
1479 | ep->state = WAIT_FOR_SETUP; | ||
1480 | break; | ||
1481 | |||
1482 | case DATA_STAGE_OUT: | ||
1483 | receive_data(ep); | ||
1484 | break; | ||
1485 | |||
1486 | default: | ||
1487 | usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY); | ||
1488 | usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY); | ||
1489 | printk(KERN_ERR | ||
1490 | "udc: %s: RXRDY: Invalid endpoint state %d, " | ||
1491 | "halting endpoint...\n", | ||
1492 | ep->ep.name, ep->state); | ||
1493 | set_protocol_stall(udc, ep); | ||
1494 | break; | ||
1495 | } | ||
1496 | |||
1497 | goto restart; | ||
1498 | } | ||
1499 | if (epstatus & USBA_RX_SETUP) { | ||
1500 | union { | ||
1501 | struct usb_ctrlrequest crq; | ||
1502 | unsigned long data[2]; | ||
1503 | } crq; | ||
1504 | unsigned int pkt_len; | ||
1505 | int ret; | ||
1506 | |||
1507 | if (ep->state != WAIT_FOR_SETUP) { | ||
1508 | /* | ||
1509 | * Didn't expect a SETUP packet at this | ||
1510 | * point. Clean up any pending requests (which | ||
1511 | * may be successful). | ||
1512 | */ | ||
1513 | int status = -EPROTO; | ||
1514 | |||
1515 | /* | ||
1516 | * RXRDY and TXCOMP are dropped when SETUP | ||
1517 | * packets arrive. Just pretend we received | ||
1518 | * the status packet. | ||
1519 | */ | ||
1520 | if (ep->state == STATUS_STAGE_OUT | ||
1521 | || ep->state == STATUS_STAGE_IN) { | ||
1522 | usba_ep_writel(ep, CTL_DIS, USBA_RX_BK_RDY); | ||
1523 | status = 0; | ||
1524 | } | ||
1525 | |||
1526 | if (req) { | ||
1527 | list_del_init(&req->queue); | ||
1528 | request_complete(ep, req, status); | ||
1529 | } | ||
1530 | } | ||
1531 | |||
1532 | pkt_len = USBA_BFEXT(BYTE_COUNT, usba_ep_readl(ep, STA)); | ||
1533 | DBG(DBG_HW, "Packet length: %u\n", pkt_len); | ||
1534 | if (pkt_len != sizeof(crq)) { | ||
1535 | printk(KERN_WARNING "udc: Invalid packet length %u " | ||
1536 | "(expected %lu)\n", pkt_len, sizeof(crq)); | ||
1537 | set_protocol_stall(udc, ep); | ||
1538 | return; | ||
1539 | } | ||
1540 | |||
1541 | DBG(DBG_FIFO, "Copying ctrl request from 0x%p:\n", ep->fifo); | ||
1542 | copy_from_fifo(crq.data, ep->fifo, sizeof(crq)); | ||
1543 | |||
1544 | /* Free up one bank in the FIFO so that we can | ||
1545 | * generate or receive a reply right away. */ | ||
1546 | usba_ep_writel(ep, CLR_STA, USBA_RX_SETUP); | ||
1547 | |||
1548 | /* printk(KERN_DEBUG "setup: %d: %02x.%02x\n", | ||
1549 | ep->state, crq.crq.bRequestType, | ||
1550 | crq.crq.bRequest); */ | ||
1551 | |||
1552 | if (crq.crq.bRequestType & USB_DIR_IN) { | ||
1553 | /* | ||
1554 | * The USB 2.0 spec states that "if wLength is | ||
1555 | * zero, there is no data transfer phase." | ||
1556 | * However, testusb #14 seems to actually | ||
1557 | * expect a data phase even if wLength = 0... | ||
1558 | */ | ||
1559 | ep->state = DATA_STAGE_IN; | ||
1560 | } else { | ||
1561 | if (crq.crq.wLength != __constant_cpu_to_le16(0)) | ||
1562 | ep->state = DATA_STAGE_OUT; | ||
1563 | else | ||
1564 | ep->state = STATUS_STAGE_IN; | ||
1565 | } | ||
1566 | |||
1567 | ret = -1; | ||
1568 | if (ep->index == 0) | ||
1569 | ret = handle_ep0_setup(udc, ep, &crq.crq); | ||
1570 | else { | ||
1571 | spin_unlock(&udc->lock); | ||
1572 | ret = udc->driver->setup(&udc->gadget, &crq.crq); | ||
1573 | spin_lock(&udc->lock); | ||
1574 | } | ||
1575 | |||
1576 | DBG(DBG_BUS, "req %02x.%02x, length %d, state %d, ret %d\n", | ||
1577 | crq.crq.bRequestType, crq.crq.bRequest, | ||
1578 | le16_to_cpu(crq.crq.wLength), ep->state, ret); | ||
1579 | |||
1580 | if (ret < 0) { | ||
1581 | /* Let the host know that we failed */ | ||
1582 | set_protocol_stall(udc, ep); | ||
1583 | } | ||
1584 | } | ||
1585 | } | ||
1586 | |||
1587 | static void usba_ep_irq(struct usba_udc *udc, struct usba_ep *ep) | ||
1588 | { | ||
1589 | struct usba_request *req; | ||
1590 | u32 epstatus; | ||
1591 | u32 epctrl; | ||
1592 | |||
1593 | epstatus = usba_ep_readl(ep, STA); | ||
1594 | epctrl = usba_ep_readl(ep, CTL); | ||
1595 | |||
1596 | DBG(DBG_INT, "%s: interrupt, status: 0x%08x\n", ep->ep.name, epstatus); | ||
1597 | |||
1598 | while ((epctrl & USBA_TX_PK_RDY) && !(epstatus & USBA_TX_PK_RDY)) { | ||
1599 | DBG(DBG_BUS, "%s: TX PK ready\n", ep->ep.name); | ||
1600 | |||
1601 | if (list_empty(&ep->queue)) { | ||
1602 | dev_warn(&udc->pdev->dev, "ep_irq: queue empty\n"); | ||
1603 | usba_ep_writel(ep, CTL_DIS, USBA_TX_PK_RDY); | ||
1604 | return; | ||
1605 | } | ||
1606 | |||
1607 | req = list_entry(ep->queue.next, struct usba_request, queue); | ||
1608 | |||
1609 | if (req->using_dma) { | ||
1610 | /* Send a zero-length packet */ | ||
1611 | usba_ep_writel(ep, SET_STA, | ||
1612 | USBA_TX_PK_RDY); | ||
1613 | usba_ep_writel(ep, CTL_DIS, | ||
1614 | USBA_TX_PK_RDY); | ||
1615 | list_del_init(&req->queue); | ||
1616 | submit_next_request(ep); | ||
1617 | request_complete(ep, req, 0); | ||
1618 | } else { | ||
1619 | if (req->submitted) | ||
1620 | next_fifo_transaction(ep, req); | ||
1621 | else | ||
1622 | submit_request(ep, req); | ||
1623 | |||
1624 | if (req->last_transaction) { | ||
1625 | list_del_init(&req->queue); | ||
1626 | submit_next_request(ep); | ||
1627 | request_complete(ep, req, 0); | ||
1628 | } | ||
1629 | } | ||
1630 | |||
1631 | epstatus = usba_ep_readl(ep, STA); | ||
1632 | epctrl = usba_ep_readl(ep, CTL); | ||
1633 | } | ||
1634 | if ((epstatus & epctrl) & USBA_RX_BK_RDY) { | ||
1635 | DBG(DBG_BUS, "%s: RX data ready\n", ep->ep.name); | ||
1636 | receive_data(ep); | ||
1637 | usba_ep_writel(ep, CLR_STA, USBA_RX_BK_RDY); | ||
1638 | } | ||
1639 | } | ||
1640 | |||
1641 | static void usba_dma_irq(struct usba_udc *udc, struct usba_ep *ep) | ||
1642 | { | ||
1643 | struct usba_request *req; | ||
1644 | u32 status, control, pending; | ||
1645 | |||
1646 | status = usba_dma_readl(ep, STATUS); | ||
1647 | control = usba_dma_readl(ep, CONTROL); | ||
1648 | #ifdef CONFIG_USB_GADGET_DEBUG_FS | ||
1649 | ep->last_dma_status = status; | ||
1650 | #endif | ||
1651 | pending = status & control; | ||
1652 | DBG(DBG_INT | DBG_DMA, "dma irq, s/%#08x, c/%#08x\n", status, control); | ||
1653 | |||
1654 | if (status & USBA_DMA_CH_EN) { | ||
1655 | dev_err(&udc->pdev->dev, | ||
1656 | "DMA_CH_EN is set after transfer is finished!\n"); | ||
1657 | dev_err(&udc->pdev->dev, | ||
1658 | "status=%#08x, pending=%#08x, control=%#08x\n", | ||
1659 | status, pending, control); | ||
1660 | |||
1661 | /* | ||
1662 | * try to pretend nothing happened. We might have to | ||
1663 | * do something here... | ||
1664 | */ | ||
1665 | } | ||
1666 | |||
1667 | if (list_empty(&ep->queue)) | ||
1668 | /* Might happen if a reset comes along at the right moment */ | ||
1669 | return; | ||
1670 | |||
1671 | if (pending & (USBA_DMA_END_TR_ST | USBA_DMA_END_BUF_ST)) { | ||
1672 | req = list_entry(ep->queue.next, struct usba_request, queue); | ||
1673 | usba_update_req(ep, req, status); | ||
1674 | |||
1675 | list_del_init(&req->queue); | ||
1676 | submit_next_request(ep); | ||
1677 | request_complete(ep, req, 0); | ||
1678 | } | ||
1679 | } | ||
1680 | |||
1681 | static irqreturn_t usba_udc_irq(int irq, void *devid) | ||
1682 | { | ||
1683 | struct usba_udc *udc = devid; | ||
1684 | u32 status; | ||
1685 | u32 dma_status; | ||
1686 | u32 ep_status; | ||
1687 | |||
1688 | spin_lock(&udc->lock); | ||
1689 | |||
1690 | status = usba_readl(udc, INT_STA); | ||
1691 | DBG(DBG_INT, "irq, status=%#08x\n", status); | ||
1692 | |||
1693 | if (status & USBA_DET_SUSPEND) { | ||
1694 | usba_writel(udc, INT_CLR, USBA_DET_SUSPEND); | ||
1695 | DBG(DBG_BUS, "Suspend detected\n"); | ||
1696 | if (udc->gadget.speed != USB_SPEED_UNKNOWN | ||
1697 | && udc->driver && udc->driver->suspend) { | ||
1698 | spin_unlock(&udc->lock); | ||
1699 | udc->driver->suspend(&udc->gadget); | ||
1700 | spin_lock(&udc->lock); | ||
1701 | } | ||
1702 | } | ||
1703 | |||
1704 | if (status & USBA_WAKE_UP) { | ||
1705 | usba_writel(udc, INT_CLR, USBA_WAKE_UP); | ||
1706 | DBG(DBG_BUS, "Wake Up CPU detected\n"); | ||
1707 | } | ||
1708 | |||
1709 | if (status & USBA_END_OF_RESUME) { | ||
1710 | usba_writel(udc, INT_CLR, USBA_END_OF_RESUME); | ||
1711 | DBG(DBG_BUS, "Resume detected\n"); | ||
1712 | if (udc->gadget.speed != USB_SPEED_UNKNOWN | ||
1713 | && udc->driver && udc->driver->resume) { | ||
1714 | spin_unlock(&udc->lock); | ||
1715 | udc->driver->resume(&udc->gadget); | ||
1716 | spin_lock(&udc->lock); | ||
1717 | } | ||
1718 | } | ||
1719 | |||
1720 | dma_status = USBA_BFEXT(DMA_INT, status); | ||
1721 | if (dma_status) { | ||
1722 | int i; | ||
1723 | |||
1724 | for (i = 1; i < USBA_NR_ENDPOINTS; i++) | ||
1725 | if (dma_status & (1 << i)) | ||
1726 | usba_dma_irq(udc, &usba_ep[i]); | ||
1727 | } | ||
1728 | |||
1729 | ep_status = USBA_BFEXT(EPT_INT, status); | ||
1730 | if (ep_status) { | ||
1731 | int i; | ||
1732 | |||
1733 | for (i = 0; i < USBA_NR_ENDPOINTS; i++) | ||
1734 | if (ep_status & (1 << i)) { | ||
1735 | if (ep_is_control(&usba_ep[i])) | ||
1736 | usba_control_irq(udc, &usba_ep[i]); | ||
1737 | else | ||
1738 | usba_ep_irq(udc, &usba_ep[i]); | ||
1739 | } | ||
1740 | } | ||
1741 | |||
1742 | if (status & USBA_END_OF_RESET) { | ||
1743 | struct usba_ep *ep0; | ||
1744 | |||
1745 | usba_writel(udc, INT_CLR, USBA_END_OF_RESET); | ||
1746 | reset_all_endpoints(udc); | ||
1747 | |||
1748 | if (status & USBA_HIGH_SPEED) { | ||
1749 | DBG(DBG_BUS, "High-speed bus reset detected\n"); | ||
1750 | udc->gadget.speed = USB_SPEED_HIGH; | ||
1751 | } else { | ||
1752 | DBG(DBG_BUS, "Full-speed bus reset detected\n"); | ||
1753 | udc->gadget.speed = USB_SPEED_FULL; | ||
1754 | } | ||
1755 | |||
1756 | ep0 = &usba_ep[0]; | ||
1757 | ep0->desc = &usba_ep0_desc; | ||
1758 | ep0->state = WAIT_FOR_SETUP; | ||
1759 | usba_ep_writel(ep0, CFG, | ||
1760 | (USBA_BF(EPT_SIZE, EP0_EPT_SIZE) | ||
1761 | | USBA_BF(EPT_TYPE, USBA_EPT_TYPE_CONTROL) | ||
1762 | | USBA_BF(BK_NUMBER, USBA_BK_NUMBER_ONE))); | ||
1763 | usba_ep_writel(ep0, CTL_ENB, | ||
1764 | USBA_EPT_ENABLE | USBA_RX_SETUP); | ||
1765 | usba_writel(udc, INT_ENB, | ||
1766 | (usba_readl(udc, INT_ENB) | ||
1767 | | USBA_BF(EPT_INT, 1) | ||
1768 | | USBA_DET_SUSPEND | ||
1769 | | USBA_END_OF_RESUME)); | ||
1770 | |||
1771 | if (!(usba_ep_readl(ep0, CFG) & USBA_EPT_MAPPED)) | ||
1772 | dev_warn(&udc->pdev->dev, | ||
1773 | "WARNING: EP0 configuration is invalid!\n"); | ||
1774 | } | ||
1775 | |||
1776 | spin_unlock(&udc->lock); | ||
1777 | |||
1778 | return IRQ_HANDLED; | ||
1779 | } | ||
1780 | |||
1781 | static irqreturn_t usba_vbus_irq(int irq, void *devid) | ||
1782 | { | ||
1783 | struct usba_udc *udc = devid; | ||
1784 | int vbus; | ||
1785 | |||
1786 | /* debounce */ | ||
1787 | udelay(10); | ||
1788 | |||
1789 | spin_lock(&udc->lock); | ||
1790 | |||
1791 | /* May happen if Vbus pin toggles during probe() */ | ||
1792 | if (!udc->driver) | ||
1793 | goto out; | ||
1794 | |||
1795 | vbus = gpio_get_value(udc->vbus_pin); | ||
1796 | if (vbus != udc->vbus_prev) { | ||
1797 | if (vbus) { | ||
1798 | usba_writel(udc, CTRL, USBA_EN_USBA); | ||
1799 | usba_writel(udc, INT_ENB, USBA_END_OF_RESET); | ||
1800 | } else { | ||
1801 | udc->gadget.speed = USB_SPEED_UNKNOWN; | ||
1802 | reset_all_endpoints(udc); | ||
1803 | usba_writel(udc, CTRL, 0); | ||
1804 | spin_unlock(&udc->lock); | ||
1805 | udc->driver->disconnect(&udc->gadget); | ||
1806 | spin_lock(&udc->lock); | ||
1807 | } | ||
1808 | udc->vbus_prev = vbus; | ||
1809 | } | ||
1810 | |||
1811 | out: | ||
1812 | spin_unlock(&udc->lock); | ||
1813 | |||
1814 | return IRQ_HANDLED; | ||
1815 | } | ||
1816 | |||
1817 | int usb_gadget_register_driver(struct usb_gadget_driver *driver) | ||
1818 | { | ||
1819 | struct usba_udc *udc = &the_udc; | ||
1820 | unsigned long flags; | ||
1821 | int ret; | ||
1822 | |||
1823 | if (!udc->pdev) | ||
1824 | return -ENODEV; | ||
1825 | |||
1826 | spin_lock_irqsave(&udc->lock, flags); | ||
1827 | if (udc->driver) { | ||
1828 | spin_unlock_irqrestore(&udc->lock, flags); | ||
1829 | return -EBUSY; | ||
1830 | } | ||
1831 | |||
1832 | udc->devstatus = 1 << USB_DEVICE_SELF_POWERED; | ||
1833 | udc->driver = driver; | ||
1834 | udc->gadget.dev.driver = &driver->driver; | ||
1835 | spin_unlock_irqrestore(&udc->lock, flags); | ||
1836 | |||
1837 | clk_enable(udc->pclk); | ||
1838 | clk_enable(udc->hclk); | ||
1839 | |||
1840 | ret = driver->bind(&udc->gadget); | ||
1841 | if (ret) { | ||
1842 | DBG(DBG_ERR, "Could not bind to driver %s: error %d\n", | ||
1843 | driver->driver.name, ret); | ||
1844 | goto err_driver_bind; | ||
1845 | } | ||
1846 | |||
1847 | DBG(DBG_GADGET, "registered driver `%s'\n", driver->driver.name); | ||
1848 | |||
1849 | udc->vbus_prev = 0; | ||
1850 | if (udc->vbus_pin != -1) | ||
1851 | enable_irq(gpio_to_irq(udc->vbus_pin)); | ||
1852 | |||
1853 | /* If Vbus is present, enable the controller and wait for reset */ | ||
1854 | spin_lock_irqsave(&udc->lock, flags); | ||
1855 | if (vbus_is_present(udc) && udc->vbus_prev == 0) { | ||
1856 | usba_writel(udc, CTRL, USBA_EN_USBA); | ||
1857 | usba_writel(udc, INT_ENB, USBA_END_OF_RESET); | ||
1858 | } | ||
1859 | spin_unlock_irqrestore(&udc->lock, flags); | ||
1860 | |||
1861 | return 0; | ||
1862 | |||
1863 | err_driver_bind: | ||
1864 | udc->driver = NULL; | ||
1865 | udc->gadget.dev.driver = NULL; | ||
1866 | return ret; | ||
1867 | } | ||
1868 | EXPORT_SYMBOL(usb_gadget_register_driver); | ||
1869 | |||
1870 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | ||
1871 | { | ||
1872 | struct usba_udc *udc = &the_udc; | ||
1873 | unsigned long flags; | ||
1874 | |||
1875 | if (!udc->pdev) | ||
1876 | return -ENODEV; | ||
1877 | if (driver != udc->driver) | ||
1878 | return -EINVAL; | ||
1879 | |||
1880 | if (udc->vbus_pin != -1) | ||
1881 | disable_irq(gpio_to_irq(udc->vbus_pin)); | ||
1882 | |||
1883 | spin_lock_irqsave(&udc->lock, flags); | ||
1884 | udc->gadget.speed = USB_SPEED_UNKNOWN; | ||
1885 | reset_all_endpoints(udc); | ||
1886 | spin_unlock_irqrestore(&udc->lock, flags); | ||
1887 | |||
1888 | /* This will also disable the DP pullup */ | ||
1889 | usba_writel(udc, CTRL, 0); | ||
1890 | |||
1891 | driver->unbind(&udc->gadget); | ||
1892 | udc->gadget.dev.driver = NULL; | ||
1893 | udc->driver = NULL; | ||
1894 | |||
1895 | clk_disable(udc->hclk); | ||
1896 | clk_disable(udc->pclk); | ||
1897 | |||
1898 | DBG(DBG_GADGET, "unregistered driver `%s'\n", driver->driver.name); | ||
1899 | |||
1900 | return 0; | ||
1901 | } | ||
1902 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | ||
1903 | |||
1904 | static int __init usba_udc_probe(struct platform_device *pdev) | ||
1905 | { | ||
1906 | struct usba_platform_data *pdata = pdev->dev.platform_data; | ||
1907 | struct resource *regs, *fifo; | ||
1908 | struct clk *pclk, *hclk; | ||
1909 | struct usba_udc *udc = &the_udc; | ||
1910 | int irq, ret, i; | ||
1911 | |||
1912 | regs = platform_get_resource(pdev, IORESOURCE_MEM, CTRL_IOMEM_ID); | ||
1913 | fifo = platform_get_resource(pdev, IORESOURCE_MEM, FIFO_IOMEM_ID); | ||
1914 | if (!regs || !fifo) | ||
1915 | return -ENXIO; | ||
1916 | |||
1917 | irq = platform_get_irq(pdev, 0); | ||
1918 | if (irq < 0) | ||
1919 | return irq; | ||
1920 | |||
1921 | pclk = clk_get(&pdev->dev, "pclk"); | ||
1922 | if (IS_ERR(pclk)) | ||
1923 | return PTR_ERR(pclk); | ||
1924 | hclk = clk_get(&pdev->dev, "hclk"); | ||
1925 | if (IS_ERR(hclk)) { | ||
1926 | ret = PTR_ERR(hclk); | ||
1927 | goto err_get_hclk; | ||
1928 | } | ||
1929 | |||
1930 | udc->pdev = pdev; | ||
1931 | udc->pclk = pclk; | ||
1932 | udc->hclk = hclk; | ||
1933 | udc->vbus_pin = -1; | ||
1934 | |||
1935 | ret = -ENOMEM; | ||
1936 | udc->regs = ioremap(regs->start, regs->end - regs->start + 1); | ||
1937 | if (!udc->regs) { | ||
1938 | dev_err(&pdev->dev, "Unable to map I/O memory, aborting.\n"); | ||
1939 | goto err_map_regs; | ||
1940 | } | ||
1941 | dev_info(&pdev->dev, "MMIO registers at 0x%08lx mapped at %p\n", | ||
1942 | (unsigned long)regs->start, udc->regs); | ||
1943 | udc->fifo = ioremap(fifo->start, fifo->end - fifo->start + 1); | ||
1944 | if (!udc->fifo) { | ||
1945 | dev_err(&pdev->dev, "Unable to map FIFO, aborting.\n"); | ||
1946 | goto err_map_fifo; | ||
1947 | } | ||
1948 | dev_info(&pdev->dev, "FIFO at 0x%08lx mapped at %p\n", | ||
1949 | (unsigned long)fifo->start, udc->fifo); | ||
1950 | |||
1951 | device_initialize(&udc->gadget.dev); | ||
1952 | udc->gadget.dev.parent = &pdev->dev; | ||
1953 | udc->gadget.dev.dma_mask = pdev->dev.dma_mask; | ||
1954 | |||
1955 | platform_set_drvdata(pdev, udc); | ||
1956 | |||
1957 | /* Make sure we start from a clean slate */ | ||
1958 | clk_enable(pclk); | ||
1959 | usba_writel(udc, CTRL, 0); | ||
1960 | clk_disable(pclk); | ||
1961 | |||
1962 | INIT_LIST_HEAD(&usba_ep[0].ep.ep_list); | ||
1963 | usba_ep[0].ep_regs = udc->regs + USBA_EPT_BASE(0); | ||
1964 | usba_ep[0].dma_regs = udc->regs + USBA_DMA_BASE(0); | ||
1965 | usba_ep[0].fifo = udc->fifo + USBA_FIFO_BASE(0); | ||
1966 | for (i = 1; i < ARRAY_SIZE(usba_ep); i++) { | ||
1967 | struct usba_ep *ep = &usba_ep[i]; | ||
1968 | |||
1969 | ep->ep_regs = udc->regs + USBA_EPT_BASE(i); | ||
1970 | ep->dma_regs = udc->regs + USBA_DMA_BASE(i); | ||
1971 | ep->fifo = udc->fifo + USBA_FIFO_BASE(i); | ||
1972 | |||
1973 | list_add_tail(&ep->ep.ep_list, &udc->gadget.ep_list); | ||
1974 | } | ||
1975 | |||
1976 | ret = request_irq(irq, usba_udc_irq, 0, "atmel_usba_udc", udc); | ||
1977 | if (ret) { | ||
1978 | dev_err(&pdev->dev, "Cannot request irq %d (error %d)\n", | ||
1979 | irq, ret); | ||
1980 | goto err_request_irq; | ||
1981 | } | ||
1982 | udc->irq = irq; | ||
1983 | |||
1984 | ret = device_add(&udc->gadget.dev); | ||
1985 | if (ret) { | ||
1986 | dev_dbg(&pdev->dev, "Could not add gadget: %d\n", ret); | ||
1987 | goto err_device_add; | ||
1988 | } | ||
1989 | |||
1990 | if (pdata && pdata->vbus_pin != GPIO_PIN_NONE) { | ||
1991 | if (!gpio_request(pdata->vbus_pin, "atmel_usba_udc")) { | ||
1992 | udc->vbus_pin = pdata->vbus_pin; | ||
1993 | |||
1994 | ret = request_irq(gpio_to_irq(udc->vbus_pin), | ||
1995 | usba_vbus_irq, 0, | ||
1996 | "atmel_usba_udc", udc); | ||
1997 | if (ret) { | ||
1998 | gpio_free(udc->vbus_pin); | ||
1999 | udc->vbus_pin = -1; | ||
2000 | dev_warn(&udc->pdev->dev, | ||
2001 | "failed to request vbus irq; " | ||
2002 | "assuming always on\n"); | ||
2003 | } else { | ||
2004 | disable_irq(gpio_to_irq(udc->vbus_pin)); | ||
2005 | } | ||
2006 | } | ||
2007 | } | ||
2008 | |||
2009 | usba_init_debugfs(udc); | ||
2010 | for (i = 1; i < ARRAY_SIZE(usba_ep); i++) | ||
2011 | usba_ep_init_debugfs(udc, &usba_ep[i]); | ||
2012 | |||
2013 | return 0; | ||
2014 | |||
2015 | err_device_add: | ||
2016 | free_irq(irq, udc); | ||
2017 | err_request_irq: | ||
2018 | iounmap(udc->fifo); | ||
2019 | err_map_fifo: | ||
2020 | iounmap(udc->regs); | ||
2021 | err_map_regs: | ||
2022 | clk_put(hclk); | ||
2023 | err_get_hclk: | ||
2024 | clk_put(pclk); | ||
2025 | |||
2026 | platform_set_drvdata(pdev, NULL); | ||
2027 | |||
2028 | return ret; | ||
2029 | } | ||
2030 | |||
2031 | static int __exit usba_udc_remove(struct platform_device *pdev) | ||
2032 | { | ||
2033 | struct usba_udc *udc; | ||
2034 | int i; | ||
2035 | |||
2036 | udc = platform_get_drvdata(pdev); | ||
2037 | |||
2038 | for (i = 1; i < ARRAY_SIZE(usba_ep); i++) | ||
2039 | usba_ep_cleanup_debugfs(&usba_ep[i]); | ||
2040 | usba_cleanup_debugfs(udc); | ||
2041 | |||
2042 | if (udc->vbus_pin != -1) | ||
2043 | gpio_free(udc->vbus_pin); | ||
2044 | |||
2045 | free_irq(udc->irq, udc); | ||
2046 | iounmap(udc->fifo); | ||
2047 | iounmap(udc->regs); | ||
2048 | clk_put(udc->hclk); | ||
2049 | clk_put(udc->pclk); | ||
2050 | |||
2051 | device_unregister(&udc->gadget.dev); | ||
2052 | |||
2053 | return 0; | ||
2054 | } | ||
2055 | |||
2056 | static struct platform_driver udc_driver = { | ||
2057 | .remove = __exit_p(usba_udc_remove), | ||
2058 | .driver = { | ||
2059 | .name = "atmel_usba_udc", | ||
2060 | }, | ||
2061 | }; | ||
2062 | |||
2063 | static int __init udc_init(void) | ||
2064 | { | ||
2065 | return platform_driver_probe(&udc_driver, usba_udc_probe); | ||
2066 | } | ||
2067 | module_init(udc_init); | ||
2068 | |||
2069 | static void __exit udc_exit(void) | ||
2070 | { | ||
2071 | platform_driver_unregister(&udc_driver); | ||
2072 | } | ||
2073 | module_exit(udc_exit); | ||
2074 | |||
2075 | MODULE_DESCRIPTION("Atmel USBA UDC driver"); | ||
2076 | MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>"); | ||
2077 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/usb/gadget/atmel_usba_udc.h b/drivers/usb/gadget/atmel_usba_udc.h new file mode 100644 index 00000000000..a68304e31a6 --- /dev/null +++ b/drivers/usb/gadget/atmel_usba_udc.h | |||
@@ -0,0 +1,352 @@ | |||
1 | /* | ||
2 | * Driver for the Atmel USBA high speed USB device controller | ||
3 | * | ||
4 | * Copyright (C) 2005-2007 Atmel Corporation | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #ifndef __LINUX_USB_GADGET_USBA_UDC_H__ | ||
11 | #define __LINUX_USB_GADGET_USBA_UDC_H__ | ||
12 | |||
13 | /* USB register offsets */ | ||
14 | #define USBA_CTRL 0x0000 | ||
15 | #define USBA_FNUM 0x0004 | ||
16 | #define USBA_INT_ENB 0x0010 | ||
17 | #define USBA_INT_STA 0x0014 | ||
18 | #define USBA_INT_CLR 0x0018 | ||
19 | #define USBA_EPT_RST 0x001c | ||
20 | #define USBA_TST 0x00e0 | ||
21 | |||
22 | /* USB endpoint register offsets */ | ||
23 | #define USBA_EPT_CFG 0x0000 | ||
24 | #define USBA_EPT_CTL_ENB 0x0004 | ||
25 | #define USBA_EPT_CTL_DIS 0x0008 | ||
26 | #define USBA_EPT_CTL 0x000c | ||
27 | #define USBA_EPT_SET_STA 0x0014 | ||
28 | #define USBA_EPT_CLR_STA 0x0018 | ||
29 | #define USBA_EPT_STA 0x001c | ||
30 | |||
31 | /* USB DMA register offsets */ | ||
32 | #define USBA_DMA_NXT_DSC 0x0000 | ||
33 | #define USBA_DMA_ADDRESS 0x0004 | ||
34 | #define USBA_DMA_CONTROL 0x0008 | ||
35 | #define USBA_DMA_STATUS 0x000c | ||
36 | |||
37 | /* Bitfields in CTRL */ | ||
38 | #define USBA_DEV_ADDR_OFFSET 0 | ||
39 | #define USBA_DEV_ADDR_SIZE 7 | ||
40 | #define USBA_FADDR_EN (1 << 7) | ||
41 | #define USBA_EN_USBA (1 << 8) | ||
42 | #define USBA_DETACH (1 << 9) | ||
43 | #define USBA_REMOTE_WAKE_UP (1 << 10) | ||
44 | |||
45 | /* Bitfields in FNUM */ | ||
46 | #define USBA_MICRO_FRAME_NUM_OFFSET 0 | ||
47 | #define USBA_MICRO_FRAME_NUM_SIZE 3 | ||
48 | #define USBA_FRAME_NUMBER_OFFSET 3 | ||
49 | #define USBA_FRAME_NUMBER_SIZE 11 | ||
50 | #define USBA_FRAME_NUM_ERROR (1 << 31) | ||
51 | |||
52 | /* Bitfields in INT_ENB/INT_STA/INT_CLR */ | ||
53 | #define USBA_HIGH_SPEED (1 << 0) | ||
54 | #define USBA_DET_SUSPEND (1 << 1) | ||
55 | #define USBA_MICRO_SOF (1 << 2) | ||
56 | #define USBA_SOF (1 << 3) | ||
57 | #define USBA_END_OF_RESET (1 << 4) | ||
58 | #define USBA_WAKE_UP (1 << 5) | ||
59 | #define USBA_END_OF_RESUME (1 << 6) | ||
60 | #define USBA_UPSTREAM_RESUME (1 << 7) | ||
61 | #define USBA_EPT_INT_OFFSET 8 | ||
62 | #define USBA_EPT_INT_SIZE 16 | ||
63 | #define USBA_DMA_INT_OFFSET 24 | ||
64 | #define USBA_DMA_INT_SIZE 8 | ||
65 | |||
66 | /* Bitfields in EPT_RST */ | ||
67 | #define USBA_RST_OFFSET 0 | ||
68 | #define USBA_RST_SIZE 16 | ||
69 | |||
70 | /* Bitfields in USBA_TST */ | ||
71 | #define USBA_SPEED_CFG_OFFSET 0 | ||
72 | #define USBA_SPEED_CFG_SIZE 2 | ||
73 | #define USBA_TST_J_MODE (1 << 2) | ||
74 | #define USBA_TST_K_MODE (1 << 3) | ||
75 | #define USBA_TST_PKT_MODE (1 << 4) | ||
76 | #define USBA_OPMODE2 (1 << 5) | ||
77 | |||
78 | /* Bitfields in EPT_CFG */ | ||
79 | #define USBA_EPT_SIZE_OFFSET 0 | ||
80 | #define USBA_EPT_SIZE_SIZE 3 | ||
81 | #define USBA_EPT_DIR_IN (1 << 3) | ||
82 | #define USBA_EPT_TYPE_OFFSET 4 | ||
83 | #define USBA_EPT_TYPE_SIZE 2 | ||
84 | #define USBA_BK_NUMBER_OFFSET 6 | ||
85 | #define USBA_BK_NUMBER_SIZE 2 | ||
86 | #define USBA_NB_TRANS_OFFSET 8 | ||
87 | #define USBA_NB_TRANS_SIZE 2 | ||
88 | #define USBA_EPT_MAPPED (1 << 31) | ||
89 | |||
90 | /* Bitfields in EPT_CTL/EPT_CTL_ENB/EPT_CTL_DIS */ | ||
91 | #define USBA_EPT_ENABLE (1 << 0) | ||
92 | #define USBA_AUTO_VALID (1 << 1) | ||
93 | #define USBA_INTDIS_DMA (1 << 3) | ||
94 | #define USBA_NYET_DIS (1 << 4) | ||
95 | #define USBA_DATAX_RX (1 << 6) | ||
96 | #define USBA_MDATA_RX (1 << 7) | ||
97 | /* Bits 8-15 and 31 enable interrupts for respective bits in EPT_STA */ | ||
98 | #define USBA_BUSY_BANK_IE (1 << 18) | ||
99 | |||
100 | /* Bitfields in EPT_SET_STA/EPT_CLR_STA/EPT_STA */ | ||
101 | #define USBA_FORCE_STALL (1 << 5) | ||
102 | #define USBA_TOGGLE_CLR (1 << 6) | ||
103 | #define USBA_TOGGLE_SEQ_OFFSET 6 | ||
104 | #define USBA_TOGGLE_SEQ_SIZE 2 | ||
105 | #define USBA_ERR_OVFLW (1 << 8) | ||
106 | #define USBA_RX_BK_RDY (1 << 9) | ||
107 | #define USBA_KILL_BANK (1 << 9) | ||
108 | #define USBA_TX_COMPLETE (1 << 10) | ||
109 | #define USBA_TX_PK_RDY (1 << 11) | ||
110 | #define USBA_ISO_ERR_TRANS (1 << 11) | ||
111 | #define USBA_RX_SETUP (1 << 12) | ||
112 | #define USBA_ISO_ERR_FLOW (1 << 12) | ||
113 | #define USBA_STALL_SENT (1 << 13) | ||
114 | #define USBA_ISO_ERR_CRC (1 << 13) | ||
115 | #define USBA_ISO_ERR_NBTRANS (1 << 13) | ||
116 | #define USBA_NAK_IN (1 << 14) | ||
117 | #define USBA_ISO_ERR_FLUSH (1 << 14) | ||
118 | #define USBA_NAK_OUT (1 << 15) | ||
119 | #define USBA_CURRENT_BANK_OFFSET 16 | ||
120 | #define USBA_CURRENT_BANK_SIZE 2 | ||
121 | #define USBA_BUSY_BANKS_OFFSET 18 | ||
122 | #define USBA_BUSY_BANKS_SIZE 2 | ||
123 | #define USBA_BYTE_COUNT_OFFSET 20 | ||
124 | #define USBA_BYTE_COUNT_SIZE 11 | ||
125 | #define USBA_SHORT_PACKET (1 << 31) | ||
126 | |||
127 | /* Bitfields in DMA_CONTROL */ | ||
128 | #define USBA_DMA_CH_EN (1 << 0) | ||
129 | #define USBA_DMA_LINK (1 << 1) | ||
130 | #define USBA_DMA_END_TR_EN (1 << 2) | ||
131 | #define USBA_DMA_END_BUF_EN (1 << 3) | ||
132 | #define USBA_DMA_END_TR_IE (1 << 4) | ||
133 | #define USBA_DMA_END_BUF_IE (1 << 5) | ||
134 | #define USBA_DMA_DESC_LOAD_IE (1 << 6) | ||
135 | #define USBA_DMA_BURST_LOCK (1 << 7) | ||
136 | #define USBA_DMA_BUF_LEN_OFFSET 16 | ||
137 | #define USBA_DMA_BUF_LEN_SIZE 16 | ||
138 | |||
139 | /* Bitfields in DMA_STATUS */ | ||
140 | #define USBA_DMA_CH_ACTIVE (1 << 1) | ||
141 | #define USBA_DMA_END_TR_ST (1 << 4) | ||
142 | #define USBA_DMA_END_BUF_ST (1 << 5) | ||
143 | #define USBA_DMA_DESC_LOAD_ST (1 << 6) | ||
144 | |||
145 | /* Constants for SPEED_CFG */ | ||
146 | #define USBA_SPEED_CFG_NORMAL 0 | ||
147 | #define USBA_SPEED_CFG_FORCE_HIGH 2 | ||
148 | #define USBA_SPEED_CFG_FORCE_FULL 3 | ||
149 | |||
150 | /* Constants for EPT_SIZE */ | ||
151 | #define USBA_EPT_SIZE_8 0 | ||
152 | #define USBA_EPT_SIZE_16 1 | ||
153 | #define USBA_EPT_SIZE_32 2 | ||
154 | #define USBA_EPT_SIZE_64 3 | ||
155 | #define USBA_EPT_SIZE_128 4 | ||
156 | #define USBA_EPT_SIZE_256 5 | ||
157 | #define USBA_EPT_SIZE_512 6 | ||
158 | #define USBA_EPT_SIZE_1024 7 | ||
159 | |||
160 | /* Constants for EPT_TYPE */ | ||
161 | #define USBA_EPT_TYPE_CONTROL 0 | ||
162 | #define USBA_EPT_TYPE_ISO 1 | ||
163 | #define USBA_EPT_TYPE_BULK 2 | ||
164 | #define USBA_EPT_TYPE_INT 3 | ||
165 | |||
166 | /* Constants for BK_NUMBER */ | ||
167 | #define USBA_BK_NUMBER_ZERO 0 | ||
168 | #define USBA_BK_NUMBER_ONE 1 | ||
169 | #define USBA_BK_NUMBER_DOUBLE 2 | ||
170 | #define USBA_BK_NUMBER_TRIPLE 3 | ||
171 | |||
172 | /* Bit manipulation macros */ | ||
173 | #define USBA_BF(name, value) \ | ||
174 | (((value) & ((1 << USBA_##name##_SIZE) - 1)) \ | ||
175 | << USBA_##name##_OFFSET) | ||
176 | #define USBA_BFEXT(name, value) \ | ||
177 | (((value) >> USBA_##name##_OFFSET) \ | ||
178 | & ((1 << USBA_##name##_SIZE) - 1)) | ||
179 | #define USBA_BFINS(name, value, old) \ | ||
180 | (((old) & ~(((1 << USBA_##name##_SIZE) - 1) \ | ||
181 | << USBA_##name##_OFFSET)) \ | ||
182 | | USBA_BF(name, value)) | ||
183 | |||
184 | /* Register access macros */ | ||
185 | #define usba_readl(udc, reg) \ | ||
186 | __raw_readl((udc)->regs + USBA_##reg) | ||
187 | #define usba_writel(udc, reg, value) \ | ||
188 | __raw_writel((value), (udc)->regs + USBA_##reg) | ||
189 | #define usba_ep_readl(ep, reg) \ | ||
190 | __raw_readl((ep)->ep_regs + USBA_EPT_##reg) | ||
191 | #define usba_ep_writel(ep, reg, value) \ | ||
192 | __raw_writel((value), (ep)->ep_regs + USBA_EPT_##reg) | ||
193 | #define usba_dma_readl(ep, reg) \ | ||
194 | __raw_readl((ep)->dma_regs + USBA_DMA_##reg) | ||
195 | #define usba_dma_writel(ep, reg, value) \ | ||
196 | __raw_writel((value), (ep)->dma_regs + USBA_DMA_##reg) | ||
197 | |||
198 | /* Calculate base address for a given endpoint or DMA controller */ | ||
199 | #define USBA_EPT_BASE(x) (0x100 + (x) * 0x20) | ||
200 | #define USBA_DMA_BASE(x) (0x300 + (x) * 0x10) | ||
201 | #define USBA_FIFO_BASE(x) ((x) << 16) | ||
202 | |||
203 | /* Synth parameters */ | ||
204 | #define USBA_NR_ENDPOINTS 7 | ||
205 | |||
206 | #define EP0_FIFO_SIZE 64 | ||
207 | #define EP0_EPT_SIZE USBA_EPT_SIZE_64 | ||
208 | #define EP0_NR_BANKS 1 | ||
209 | |||
210 | /* | ||
211 | * REVISIT: Try to eliminate this value. Can we rely on req->mapped to | ||
212 | * provide this information? | ||
213 | */ | ||
214 | #define DMA_ADDR_INVALID (~(dma_addr_t)0) | ||
215 | |||
216 | #define FIFO_IOMEM_ID 0 | ||
217 | #define CTRL_IOMEM_ID 1 | ||
218 | |||
219 | #ifdef DEBUG | ||
220 | #define DBG_ERR 0x0001 /* report all error returns */ | ||
221 | #define DBG_HW 0x0002 /* debug hardware initialization */ | ||
222 | #define DBG_GADGET 0x0004 /* calls to/from gadget driver */ | ||
223 | #define DBG_INT 0x0008 /* interrupts */ | ||
224 | #define DBG_BUS 0x0010 /* report changes in bus state */ | ||
225 | #define DBG_QUEUE 0x0020 /* debug request queue processing */ | ||
226 | #define DBG_FIFO 0x0040 /* debug FIFO contents */ | ||
227 | #define DBG_DMA 0x0080 /* debug DMA handling */ | ||
228 | #define DBG_REQ 0x0100 /* print out queued request length */ | ||
229 | #define DBG_ALL 0xffff | ||
230 | #define DBG_NONE 0x0000 | ||
231 | |||
232 | #define DEBUG_LEVEL (DBG_ERR) | ||
233 | #define DBG(level, fmt, ...) \ | ||
234 | do { \ | ||
235 | if ((level) & DEBUG_LEVEL) \ | ||
236 | printk(KERN_DEBUG "udc: " fmt, ## __VA_ARGS__); \ | ||
237 | } while (0) | ||
238 | #else | ||
239 | #define DBG(level, fmt...) | ||
240 | #endif | ||
241 | |||
242 | enum usba_ctrl_state { | ||
243 | WAIT_FOR_SETUP, | ||
244 | DATA_STAGE_IN, | ||
245 | DATA_STAGE_OUT, | ||
246 | STATUS_STAGE_IN, | ||
247 | STATUS_STAGE_OUT, | ||
248 | STATUS_STAGE_ADDR, | ||
249 | STATUS_STAGE_TEST, | ||
250 | }; | ||
251 | /* | ||
252 | EP_STATE_IDLE, | ||
253 | EP_STATE_SETUP, | ||
254 | EP_STATE_IN_DATA, | ||
255 | EP_STATE_OUT_DATA, | ||
256 | EP_STATE_SET_ADDR_STATUS, | ||
257 | EP_STATE_RX_STATUS, | ||
258 | EP_STATE_TX_STATUS, | ||
259 | EP_STATE_HALT, | ||
260 | */ | ||
261 | |||
262 | struct usba_dma_desc { | ||
263 | dma_addr_t next; | ||
264 | dma_addr_t addr; | ||
265 | u32 ctrl; | ||
266 | }; | ||
267 | |||
268 | struct usba_ep { | ||
269 | int state; | ||
270 | void __iomem *ep_regs; | ||
271 | void __iomem *dma_regs; | ||
272 | void __iomem *fifo; | ||
273 | struct usb_ep ep; | ||
274 | struct usba_udc *udc; | ||
275 | |||
276 | struct list_head queue; | ||
277 | const struct usb_endpoint_descriptor *desc; | ||
278 | |||
279 | u16 fifo_size; | ||
280 | u8 nr_banks; | ||
281 | u8 index; | ||
282 | unsigned int can_dma:1; | ||
283 | unsigned int can_isoc:1; | ||
284 | unsigned int is_isoc:1; | ||
285 | unsigned int is_in:1; | ||
286 | |||
287 | #ifdef CONFIG_USB_GADGET_DEBUG_FS | ||
288 | u32 last_dma_status; | ||
289 | struct dentry *debugfs_dir; | ||
290 | struct dentry *debugfs_queue; | ||
291 | struct dentry *debugfs_dma_status; | ||
292 | struct dentry *debugfs_state; | ||
293 | #endif | ||
294 | }; | ||
295 | |||
296 | struct usba_request { | ||
297 | struct usb_request req; | ||
298 | struct list_head queue; | ||
299 | |||
300 | u32 ctrl; | ||
301 | |||
302 | unsigned int submitted:1; | ||
303 | unsigned int last_transaction:1; | ||
304 | unsigned int using_dma:1; | ||
305 | unsigned int mapped:1; | ||
306 | }; | ||
307 | |||
308 | struct usba_udc { | ||
309 | /* Protect hw registers from concurrent modifications */ | ||
310 | spinlock_t lock; | ||
311 | |||
312 | void __iomem *regs; | ||
313 | void __iomem *fifo; | ||
314 | |||
315 | struct usb_gadget gadget; | ||
316 | struct usb_gadget_driver *driver; | ||
317 | struct platform_device *pdev; | ||
318 | int irq; | ||
319 | int vbus_pin; | ||
320 | struct clk *pclk; | ||
321 | struct clk *hclk; | ||
322 | |||
323 | u16 devstatus; | ||
324 | |||
325 | u16 test_mode; | ||
326 | int vbus_prev; | ||
327 | |||
328 | #ifdef CONFIG_USB_GADGET_DEBUG_FS | ||
329 | struct dentry *debugfs_root; | ||
330 | struct dentry *debugfs_regs; | ||
331 | #endif | ||
332 | }; | ||
333 | |||
334 | static inline struct usba_ep *to_usba_ep(struct usb_ep *ep) | ||
335 | { | ||
336 | return container_of(ep, struct usba_ep, ep); | ||
337 | } | ||
338 | |||
339 | static inline struct usba_request *to_usba_req(struct usb_request *req) | ||
340 | { | ||
341 | return container_of(req, struct usba_request, req); | ||
342 | } | ||
343 | |||
344 | static inline struct usba_udc *to_usba_udc(struct usb_gadget *gadget) | ||
345 | { | ||
346 | return container_of(gadget, struct usba_udc, gadget); | ||
347 | } | ||
348 | |||
349 | #define ep_is_control(ep) ((ep)->index == 0) | ||
350 | #define ep_is_idle(ep) ((ep)->state == EP_STATE_IDLE) | ||
351 | |||
352 | #endif /* __LINUX_USB_GADGET_USBA_UDC_H */ | ||
diff --git a/drivers/usb/gadget/config.c b/drivers/usb/gadget/config.c index d18901b92cd..a4e54b2743f 100644 --- a/drivers/usb/gadget/config.c +++ b/drivers/usb/gadget/config.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <linux/device.h> | 25 | #include <linux/device.h> |
26 | 26 | ||
27 | #include <linux/usb/ch9.h> | 27 | #include <linux/usb/ch9.h> |
28 | #include <linux/usb_gadget.h> | 28 | #include <linux/usb/gadget.h> |
29 | 29 | ||
30 | 30 | ||
31 | /** | 31 | /** |
@@ -50,7 +50,7 @@ usb_descriptor_fillbuf(void *buf, unsigned buflen, | |||
50 | return -EINVAL; | 50 | return -EINVAL; |
51 | 51 | ||
52 | /* fill buffer from src[] until null descriptor ptr */ | 52 | /* fill buffer from src[] until null descriptor ptr */ |
53 | for (; 0 != *src; src++) { | 53 | for (; NULL != *src; src++) { |
54 | unsigned len = (*src)->bLength; | 54 | unsigned len = (*src)->bLength; |
55 | 55 | ||
56 | if (len > buflen) | 56 | if (len > buflen) |
diff --git a/drivers/usb/gadget/dummy_hcd.c b/drivers/usb/gadget/dummy_hcd.c index f2fbdc7fe37..9db2482bdfa 100644 --- a/drivers/usb/gadget/dummy_hcd.c +++ b/drivers/usb/gadget/dummy_hcd.c | |||
@@ -34,8 +34,6 @@ | |||
34 | * bypassing some hardware (and driver) issues. UML could help too. | 34 | * bypassing some hardware (and driver) issues. UML could help too. |
35 | */ | 35 | */ |
36 | 36 | ||
37 | #define DEBUG | ||
38 | |||
39 | #include <linux/module.h> | 37 | #include <linux/module.h> |
40 | #include <linux/kernel.h> | 38 | #include <linux/kernel.h> |
41 | #include <linux/delay.h> | 39 | #include <linux/delay.h> |
@@ -48,7 +46,7 @@ | |||
48 | #include <linux/interrupt.h> | 46 | #include <linux/interrupt.h> |
49 | #include <linux/platform_device.h> | 47 | #include <linux/platform_device.h> |
50 | #include <linux/usb.h> | 48 | #include <linux/usb.h> |
51 | #include <linux/usb_gadget.h> | 49 | #include <linux/usb/gadget.h> |
52 | 50 | ||
53 | #include <asm/byteorder.h> | 51 | #include <asm/byteorder.h> |
54 | #include <asm/io.h> | 52 | #include <asm/io.h> |
@@ -964,13 +962,13 @@ static struct platform_driver dummy_udc_driver = { | |||
964 | 962 | ||
965 | static int dummy_urb_enqueue ( | 963 | static int dummy_urb_enqueue ( |
966 | struct usb_hcd *hcd, | 964 | struct usb_hcd *hcd, |
967 | struct usb_host_endpoint *ep, | ||
968 | struct urb *urb, | 965 | struct urb *urb, |
969 | gfp_t mem_flags | 966 | gfp_t mem_flags |
970 | ) { | 967 | ) { |
971 | struct dummy *dum; | 968 | struct dummy *dum; |
972 | struct urbp *urbp; | 969 | struct urbp *urbp; |
973 | unsigned long flags; | 970 | unsigned long flags; |
971 | int rc; | ||
974 | 972 | ||
975 | if (!urb->transfer_buffer && urb->transfer_buffer_length) | 973 | if (!urb->transfer_buffer && urb->transfer_buffer_length) |
976 | return -EINVAL; | 974 | return -EINVAL; |
@@ -982,6 +980,11 @@ static int dummy_urb_enqueue ( | |||
982 | 980 | ||
983 | dum = hcd_to_dummy (hcd); | 981 | dum = hcd_to_dummy (hcd); |
984 | spin_lock_irqsave (&dum->lock, flags); | 982 | spin_lock_irqsave (&dum->lock, flags); |
983 | rc = usb_hcd_link_urb_to_ep(hcd, urb); | ||
984 | if (rc) { | ||
985 | kfree(urbp); | ||
986 | goto done; | ||
987 | } | ||
985 | 988 | ||
986 | if (!dum->udev) { | 989 | if (!dum->udev) { |
987 | dum->udev = urb->dev; | 990 | dum->udev = urb->dev; |
@@ -998,36 +1001,35 @@ static int dummy_urb_enqueue ( | |||
998 | if (!timer_pending (&dum->timer)) | 1001 | if (!timer_pending (&dum->timer)) |
999 | mod_timer (&dum->timer, jiffies + 1); | 1002 | mod_timer (&dum->timer, jiffies + 1); |
1000 | 1003 | ||
1001 | spin_unlock_irqrestore (&dum->lock, flags); | 1004 | done: |
1002 | return 0; | 1005 | spin_unlock_irqrestore(&dum->lock, flags); |
1006 | return rc; | ||
1003 | } | 1007 | } |
1004 | 1008 | ||
1005 | static int dummy_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) | 1009 | static int dummy_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) |
1006 | { | 1010 | { |
1007 | struct dummy *dum; | 1011 | struct dummy *dum; |
1008 | unsigned long flags; | 1012 | unsigned long flags; |
1013 | int rc; | ||
1009 | 1014 | ||
1010 | /* giveback happens automatically in timer callback, | 1015 | /* giveback happens automatically in timer callback, |
1011 | * so make sure the callback happens */ | 1016 | * so make sure the callback happens */ |
1012 | dum = hcd_to_dummy (hcd); | 1017 | dum = hcd_to_dummy (hcd); |
1013 | spin_lock_irqsave (&dum->lock, flags); | 1018 | spin_lock_irqsave (&dum->lock, flags); |
1014 | if (dum->rh_state != DUMMY_RH_RUNNING && !list_empty(&dum->urbp_list)) | 1019 | |
1020 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); | ||
1021 | if (!rc && dum->rh_state != DUMMY_RH_RUNNING && | ||
1022 | !list_empty(&dum->urbp_list)) | ||
1015 | mod_timer (&dum->timer, jiffies); | 1023 | mod_timer (&dum->timer, jiffies); |
1016 | spin_unlock_irqrestore (&dum->lock, flags); | ||
1017 | return 0; | ||
1018 | } | ||
1019 | 1024 | ||
1020 | static void maybe_set_status (struct urb *urb, int status) | 1025 | spin_unlock_irqrestore (&dum->lock, flags); |
1021 | { | 1026 | return rc; |
1022 | spin_lock (&urb->lock); | ||
1023 | if (urb->status == -EINPROGRESS) | ||
1024 | urb->status = status; | ||
1025 | spin_unlock (&urb->lock); | ||
1026 | } | 1027 | } |
1027 | 1028 | ||
1028 | /* transfer up to a frame's worth; caller must own lock */ | 1029 | /* transfer up to a frame's worth; caller must own lock */ |
1029 | static int | 1030 | static int |
1030 | transfer (struct dummy *dum, struct urb *urb, struct dummy_ep *ep, int limit) | 1031 | transfer(struct dummy *dum, struct urb *urb, struct dummy_ep *ep, int limit, |
1032 | int *status) | ||
1031 | { | 1033 | { |
1032 | struct dummy_request *req; | 1034 | struct dummy_request *req; |
1033 | 1035 | ||
@@ -1090,24 +1092,20 @@ top: | |||
1090 | * | 1092 | * |
1091 | * partially filling a buffer optionally blocks queue advances | 1093 | * partially filling a buffer optionally blocks queue advances |
1092 | * (so completion handlers can clean up the queue) but we don't | 1094 | * (so completion handlers can clean up the queue) but we don't |
1093 | * need to emulate such data-in-flight. so we only show part | 1095 | * need to emulate such data-in-flight. |
1094 | * of the URB_SHORT_NOT_OK effect: completion status. | ||
1095 | */ | 1096 | */ |
1096 | if (is_short) { | 1097 | if (is_short) { |
1097 | if (host_len == dev_len) { | 1098 | if (host_len == dev_len) { |
1098 | req->req.status = 0; | 1099 | req->req.status = 0; |
1099 | maybe_set_status (urb, 0); | 1100 | *status = 0; |
1100 | } else if (to_host) { | 1101 | } else if (to_host) { |
1101 | req->req.status = 0; | 1102 | req->req.status = 0; |
1102 | if (dev_len > host_len) | 1103 | if (dev_len > host_len) |
1103 | maybe_set_status (urb, -EOVERFLOW); | 1104 | *status = -EOVERFLOW; |
1104 | else | 1105 | else |
1105 | maybe_set_status (urb, | 1106 | *status = 0; |
1106 | (urb->transfer_flags | ||
1107 | & URB_SHORT_NOT_OK) | ||
1108 | ? -EREMOTEIO : 0); | ||
1109 | } else if (!to_host) { | 1107 | } else if (!to_host) { |
1110 | maybe_set_status (urb, 0); | 1108 | *status = 0; |
1111 | if (host_len > dev_len) | 1109 | if (host_len > dev_len) |
1112 | req->req.status = -EOVERFLOW; | 1110 | req->req.status = -EOVERFLOW; |
1113 | else | 1111 | else |
@@ -1121,9 +1119,8 @@ top: | |||
1121 | req->req.status = 0; | 1119 | req->req.status = 0; |
1122 | if (urb->transfer_buffer_length == urb->actual_length | 1120 | if (urb->transfer_buffer_length == urb->actual_length |
1123 | && !(urb->transfer_flags | 1121 | && !(urb->transfer_flags |
1124 | & URB_ZERO_PACKET)) { | 1122 | & URB_ZERO_PACKET)) |
1125 | maybe_set_status (urb, 0); | 1123 | *status = 0; |
1126 | } | ||
1127 | } | 1124 | } |
1128 | 1125 | ||
1129 | /* device side completion --> continuable */ | 1126 | /* device side completion --> continuable */ |
@@ -1139,7 +1136,7 @@ top: | |||
1139 | } | 1136 | } |
1140 | 1137 | ||
1141 | /* host side completion --> terminate */ | 1138 | /* host side completion --> terminate */ |
1142 | if (urb->status != -EINPROGRESS) | 1139 | if (*status != -EINPROGRESS) |
1143 | break; | 1140 | break; |
1144 | 1141 | ||
1145 | /* rescan to continue with any other queued i/o */ | 1142 | /* rescan to continue with any other queued i/o */ |
@@ -1250,12 +1247,12 @@ restart: | |||
1250 | u8 address; | 1247 | u8 address; |
1251 | struct dummy_ep *ep = NULL; | 1248 | struct dummy_ep *ep = NULL; |
1252 | int type; | 1249 | int type; |
1250 | int status = -EINPROGRESS; | ||
1253 | 1251 | ||
1254 | urb = urbp->urb; | 1252 | urb = urbp->urb; |
1255 | if (urb->status != -EINPROGRESS) { | 1253 | if (urb->unlinked) |
1256 | /* likely it was just unlinked */ | ||
1257 | goto return_urb; | 1254 | goto return_urb; |
1258 | } else if (dum->rh_state != DUMMY_RH_RUNNING) | 1255 | else if (dum->rh_state != DUMMY_RH_RUNNING) |
1259 | continue; | 1256 | continue; |
1260 | type = usb_pipetype (urb->pipe); | 1257 | type = usb_pipetype (urb->pipe); |
1261 | 1258 | ||
@@ -1276,7 +1273,7 @@ restart: | |||
1276 | dev_dbg (dummy_dev(dum), | 1273 | dev_dbg (dummy_dev(dum), |
1277 | "no ep configured for urb %p\n", | 1274 | "no ep configured for urb %p\n", |
1278 | urb); | 1275 | urb); |
1279 | maybe_set_status (urb, -EPROTO); | 1276 | status = -EPROTO; |
1280 | goto return_urb; | 1277 | goto return_urb; |
1281 | } | 1278 | } |
1282 | 1279 | ||
@@ -1291,7 +1288,7 @@ restart: | |||
1291 | /* NOTE: must not be iso! */ | 1288 | /* NOTE: must not be iso! */ |
1292 | dev_dbg (dummy_dev(dum), "ep %s halted, urb %p\n", | 1289 | dev_dbg (dummy_dev(dum), "ep %s halted, urb %p\n", |
1293 | ep->ep.name, urb); | 1290 | ep->ep.name, urb); |
1294 | maybe_set_status (urb, -EPIPE); | 1291 | status = -EPIPE; |
1295 | goto return_urb; | 1292 | goto return_urb; |
1296 | } | 1293 | } |
1297 | /* FIXME make sure both ends agree on maxpacket */ | 1294 | /* FIXME make sure both ends agree on maxpacket */ |
@@ -1309,7 +1306,7 @@ restart: | |||
1309 | w_value = le16_to_cpu(setup.wValue); | 1306 | w_value = le16_to_cpu(setup.wValue); |
1310 | if (le16_to_cpu(setup.wLength) != | 1307 | if (le16_to_cpu(setup.wLength) != |
1311 | urb->transfer_buffer_length) { | 1308 | urb->transfer_buffer_length) { |
1312 | maybe_set_status (urb, -EOVERFLOW); | 1309 | status = -EOVERFLOW; |
1313 | goto return_urb; | 1310 | goto return_urb; |
1314 | } | 1311 | } |
1315 | 1312 | ||
@@ -1339,7 +1336,7 @@ restart: | |||
1339 | if (setup.bRequestType != Dev_Request) | 1336 | if (setup.bRequestType != Dev_Request) |
1340 | break; | 1337 | break; |
1341 | dum->address = w_value; | 1338 | dum->address = w_value; |
1342 | maybe_set_status (urb, 0); | 1339 | status = 0; |
1343 | dev_dbg (udc_dev(dum), "set_address = %d\n", | 1340 | dev_dbg (udc_dev(dum), "set_address = %d\n", |
1344 | w_value); | 1341 | w_value); |
1345 | value = 0; | 1342 | value = 0; |
@@ -1366,7 +1363,7 @@ restart: | |||
1366 | if (value == 0) { | 1363 | if (value == 0) { |
1367 | dum->devstatus |= | 1364 | dum->devstatus |= |
1368 | (1 << w_value); | 1365 | (1 << w_value); |
1369 | maybe_set_status (urb, 0); | 1366 | status = 0; |
1370 | } | 1367 | } |
1371 | 1368 | ||
1372 | } else if (setup.bRequestType == Ep_Request) { | 1369 | } else if (setup.bRequestType == Ep_Request) { |
@@ -1378,7 +1375,7 @@ restart: | |||
1378 | } | 1375 | } |
1379 | ep2->halted = 1; | 1376 | ep2->halted = 1; |
1380 | value = 0; | 1377 | value = 0; |
1381 | maybe_set_status (urb, 0); | 1378 | status = 0; |
1382 | } | 1379 | } |
1383 | break; | 1380 | break; |
1384 | case USB_REQ_CLEAR_FEATURE: | 1381 | case USB_REQ_CLEAR_FEATURE: |
@@ -1388,7 +1385,7 @@ restart: | |||
1388 | dum->devstatus &= ~(1 << | 1385 | dum->devstatus &= ~(1 << |
1389 | USB_DEVICE_REMOTE_WAKEUP); | 1386 | USB_DEVICE_REMOTE_WAKEUP); |
1390 | value = 0; | 1387 | value = 0; |
1391 | maybe_set_status (urb, 0); | 1388 | status = 0; |
1392 | break; | 1389 | break; |
1393 | default: | 1390 | default: |
1394 | value = -EOPNOTSUPP; | 1391 | value = -EOPNOTSUPP; |
@@ -1403,7 +1400,7 @@ restart: | |||
1403 | } | 1400 | } |
1404 | ep2->halted = 0; | 1401 | ep2->halted = 0; |
1405 | value = 0; | 1402 | value = 0; |
1406 | maybe_set_status (urb, 0); | 1403 | status = 0; |
1407 | } | 1404 | } |
1408 | break; | 1405 | break; |
1409 | case USB_REQ_GET_STATUS: | 1406 | case USB_REQ_GET_STATUS: |
@@ -1440,7 +1437,7 @@ restart: | |||
1440 | urb->actual_length = min (2, | 1437 | urb->actual_length = min (2, |
1441 | urb->transfer_buffer_length); | 1438 | urb->transfer_buffer_length); |
1442 | value = 0; | 1439 | value = 0; |
1443 | maybe_set_status (urb, 0); | 1440 | status = 0; |
1444 | } | 1441 | } |
1445 | break; | 1442 | break; |
1446 | } | 1443 | } |
@@ -1467,7 +1464,7 @@ restart: | |||
1467 | dev_dbg (udc_dev(dum), | 1464 | dev_dbg (udc_dev(dum), |
1468 | "setup --> %d\n", | 1465 | "setup --> %d\n", |
1469 | value); | 1466 | value); |
1470 | maybe_set_status (urb, -EPIPE); | 1467 | status = -EPIPE; |
1471 | urb->actual_length = 0; | 1468 | urb->actual_length = 0; |
1472 | } | 1469 | } |
1473 | 1470 | ||
@@ -1484,7 +1481,7 @@ restart: | |||
1484 | * report random errors, to debug drivers. | 1481 | * report random errors, to debug drivers. |
1485 | */ | 1482 | */ |
1486 | limit = max (limit, periodic_bytes (dum, ep)); | 1483 | limit = max (limit, periodic_bytes (dum, ep)); |
1487 | maybe_set_status (urb, -ENOSYS); | 1484 | status = -ENOSYS; |
1488 | break; | 1485 | break; |
1489 | 1486 | ||
1490 | case PIPE_INTERRUPT: | 1487 | case PIPE_INTERRUPT: |
@@ -1498,23 +1495,23 @@ restart: | |||
1498 | default: | 1495 | default: |
1499 | treat_control_like_bulk: | 1496 | treat_control_like_bulk: |
1500 | ep->last_io = jiffies; | 1497 | ep->last_io = jiffies; |
1501 | total = transfer (dum, urb, ep, limit); | 1498 | total = transfer(dum, urb, ep, limit, &status); |
1502 | break; | 1499 | break; |
1503 | } | 1500 | } |
1504 | 1501 | ||
1505 | /* incomplete transfer? */ | 1502 | /* incomplete transfer? */ |
1506 | if (urb->status == -EINPROGRESS) | 1503 | if (status == -EINPROGRESS) |
1507 | continue; | 1504 | continue; |
1508 | 1505 | ||
1509 | return_urb: | 1506 | return_urb: |
1510 | urb->hcpriv = NULL; | ||
1511 | list_del (&urbp->urbp_list); | 1507 | list_del (&urbp->urbp_list); |
1512 | kfree (urbp); | 1508 | kfree (urbp); |
1513 | if (ep) | 1509 | if (ep) |
1514 | ep->already_seen = ep->setup_stage = 0; | 1510 | ep->already_seen = ep->setup_stage = 0; |
1515 | 1511 | ||
1512 | usb_hcd_unlink_urb_from_ep(dummy_to_hcd(dum), urb); | ||
1516 | spin_unlock (&dum->lock); | 1513 | spin_unlock (&dum->lock); |
1517 | usb_hcd_giveback_urb (dummy_to_hcd(dum), urb); | 1514 | usb_hcd_giveback_urb(dummy_to_hcd(dum), urb, status); |
1518 | spin_lock (&dum->lock); | 1515 | spin_lock (&dum->lock); |
1519 | 1516 | ||
1520 | goto restart; | 1517 | goto restart; |
diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c index 6042364402b..f9d07108bc3 100644 --- a/drivers/usb/gadget/epautoconf.c +++ b/drivers/usb/gadget/epautoconf.c | |||
@@ -28,7 +28,7 @@ | |||
28 | #include <linux/string.h> | 28 | #include <linux/string.h> |
29 | 29 | ||
30 | #include <linux/usb/ch9.h> | 30 | #include <linux/usb/ch9.h> |
31 | #include <linux/usb_gadget.h> | 31 | #include <linux/usb/gadget.h> |
32 | 32 | ||
33 | #include "gadget_chips.h" | 33 | #include "gadget_chips.h" |
34 | 34 | ||
@@ -71,7 +71,7 @@ ep_matches ( | |||
71 | u16 max; | 71 | u16 max; |
72 | 72 | ||
73 | /* endpoint already claimed? */ | 73 | /* endpoint already claimed? */ |
74 | if (0 != ep->driver_data) | 74 | if (NULL != ep->driver_data) |
75 | return 0; | 75 | return 0; |
76 | 76 | ||
77 | /* only support ep0 for portable CONTROL traffic */ | 77 | /* only support ep0 for portable CONTROL traffic */ |
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index dbaf867436d..9e732bff9df 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c | |||
@@ -19,40 +19,18 @@ | |||
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 20 | */ |
21 | 21 | ||
22 | /* #define VERBOSE_DEBUG */ | ||
22 | 23 | ||
23 | // #define DEBUG 1 | ||
24 | // #define VERBOSE | ||
25 | |||
26 | #include <linux/module.h> | ||
27 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
28 | #include <linux/delay.h> | ||
29 | #include <linux/ioport.h> | ||
30 | #include <linux/slab.h> | ||
31 | #include <linux/errno.h> | ||
32 | #include <linux/init.h> | ||
33 | #include <linux/timer.h> | ||
34 | #include <linux/list.h> | ||
35 | #include <linux/interrupt.h> | ||
36 | #include <linux/utsname.h> | 25 | #include <linux/utsname.h> |
37 | #include <linux/device.h> | 26 | #include <linux/device.h> |
38 | #include <linux/moduleparam.h> | ||
39 | #include <linux/ctype.h> | 27 | #include <linux/ctype.h> |
40 | 28 | #include <linux/etherdevice.h> | |
41 | #include <asm/byteorder.h> | 29 | #include <linux/ethtool.h> |
42 | #include <asm/io.h> | ||
43 | #include <asm/irq.h> | ||
44 | #include <asm/system.h> | ||
45 | #include <asm/uaccess.h> | ||
46 | #include <asm/unaligned.h> | ||
47 | 30 | ||
48 | #include <linux/usb/ch9.h> | 31 | #include <linux/usb/ch9.h> |
49 | #include <linux/usb/cdc.h> | 32 | #include <linux/usb/cdc.h> |
50 | #include <linux/usb_gadget.h> | 33 | #include <linux/usb/gadget.h> |
51 | |||
52 | #include <linux/random.h> | ||
53 | #include <linux/netdevice.h> | ||
54 | #include <linux/etherdevice.h> | ||
55 | #include <linux/ethtool.h> | ||
56 | 34 | ||
57 | #include "gadget_chips.h" | 35 | #include "gadget_chips.h" |
58 | 36 | ||
@@ -305,6 +283,10 @@ MODULE_PARM_DESC(host_addr, "Host Ethernet Address"); | |||
305 | #define DEV_CONFIG_CDC | 283 | #define DEV_CONFIG_CDC |
306 | #endif | 284 | #endif |
307 | 285 | ||
286 | #ifdef CONFIG_USB_GADGET_AMD5536UDC | ||
287 | #define DEV_CONFIG_CDC | ||
288 | #endif | ||
289 | |||
308 | 290 | ||
309 | /*-------------------------------------------------------------------------*/ | 291 | /*-------------------------------------------------------------------------*/ |
310 | 292 | ||
@@ -352,15 +334,15 @@ module_param (qmult, uint, S_IRUGO|S_IWUSR); | |||
352 | #define qlen(gadget) \ | 334 | #define qlen(gadget) \ |
353 | (DEFAULT_QLEN*((gadget->speed == USB_SPEED_HIGH) ? qmult : 1)) | 335 | (DEFAULT_QLEN*((gadget->speed == USB_SPEED_HIGH) ? qmult : 1)) |
354 | 336 | ||
355 | /* also defer IRQs on highspeed TX */ | ||
356 | #define TX_DELAY qmult | ||
357 | |||
358 | static inline int BITRATE(struct usb_gadget *g) | 337 | static inline int BITRATE(struct usb_gadget *g) |
359 | { | 338 | { |
360 | return (g->speed == USB_SPEED_HIGH) ? HS_BPS : FS_BPS; | 339 | return (g->speed == USB_SPEED_HIGH) ? HS_BPS : FS_BPS; |
361 | } | 340 | } |
362 | 341 | ||
363 | #else /* full speed (low speed doesn't do bulk) */ | 342 | #else /* full speed (low speed doesn't do bulk) */ |
343 | |||
344 | #define qmult 1 | ||
345 | |||
364 | #define DEVSPEED USB_SPEED_FULL | 346 | #define DEVSPEED USB_SPEED_FULL |
365 | 347 | ||
366 | #define qlen(gadget) DEFAULT_QLEN | 348 | #define qlen(gadget) DEFAULT_QLEN |
@@ -386,7 +368,7 @@ static inline int BITRATE(struct usb_gadget *g) | |||
386 | do { } while (0) | 368 | do { } while (0) |
387 | #endif /* DEBUG */ | 369 | #endif /* DEBUG */ |
388 | 370 | ||
389 | #ifdef VERBOSE | 371 | #ifdef VERBOSE_DEBUG |
390 | #define VDEBUG DEBUG | 372 | #define VDEBUG DEBUG |
391 | #else | 373 | #else |
392 | #define VDEBUG(dev,fmt,args...) \ | 374 | #define VDEBUG(dev,fmt,args...) \ |
@@ -826,8 +808,6 @@ static const struct usb_descriptor_header *fs_rndis_function [] = { | |||
826 | }; | 808 | }; |
827 | #endif | 809 | #endif |
828 | 810 | ||
829 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
830 | |||
831 | /* | 811 | /* |
832 | * usb 2.0 devices need to expose both high speed and full speed | 812 | * usb 2.0 devices need to expose both high speed and full speed |
833 | * descriptors, unless they only run at full speed. | 813 | * descriptors, unless they only run at full speed. |
@@ -930,18 +910,15 @@ static const struct usb_descriptor_header *hs_rndis_function [] = { | |||
930 | 910 | ||
931 | 911 | ||
932 | /* maxpacket and other transfer characteristics vary by speed. */ | 912 | /* maxpacket and other transfer characteristics vary by speed. */ |
933 | #define ep_desc(g,hs,fs) (((g)->speed==USB_SPEED_HIGH)?(hs):(fs)) | 913 | static inline struct usb_endpoint_descriptor * |
934 | 914 | ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *hs, | |
935 | #else | 915 | struct usb_endpoint_descriptor *fs) |
936 | |||
937 | /* if there's no high speed support, maxpacket doesn't change. */ | ||
938 | #define ep_desc(g,hs,fs) (((void)(g)), (fs)) | ||
939 | |||
940 | static inline void __init hs_subset_descriptors(void) | ||
941 | { | 916 | { |
917 | if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) | ||
918 | return hs; | ||
919 | return fs; | ||
942 | } | 920 | } |
943 | 921 | ||
944 | #endif /* !CONFIG_USB_GADGET_DUALSPEED */ | ||
945 | 922 | ||
946 | /*-------------------------------------------------------------------------*/ | 923 | /*-------------------------------------------------------------------------*/ |
947 | 924 | ||
@@ -985,22 +962,19 @@ static struct usb_gadget_strings stringtab = { | |||
985 | * complications: class descriptors, and an altsetting. | 962 | * complications: class descriptors, and an altsetting. |
986 | */ | 963 | */ |
987 | static int | 964 | static int |
988 | config_buf (enum usb_device_speed speed, | 965 | config_buf(struct usb_gadget *g, u8 *buf, u8 type, unsigned index, int is_otg) |
989 | u8 *buf, u8 type, | ||
990 | unsigned index, int is_otg) | ||
991 | { | 966 | { |
992 | int len; | 967 | int len; |
993 | const struct usb_config_descriptor *config; | 968 | const struct usb_config_descriptor *config; |
994 | const struct usb_descriptor_header **function; | 969 | const struct usb_descriptor_header **function; |
995 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 970 | int hs = 0; |
996 | int hs = (speed == USB_SPEED_HIGH); | ||
997 | 971 | ||
998 | if (type == USB_DT_OTHER_SPEED_CONFIG) | 972 | if (gadget_is_dualspeed(g)) { |
999 | hs = !hs; | 973 | hs = (g->speed == USB_SPEED_HIGH); |
974 | if (type == USB_DT_OTHER_SPEED_CONFIG) | ||
975 | hs = !hs; | ||
976 | } | ||
1000 | #define which_fn(t) (hs ? hs_ ## t ## _function : fs_ ## t ## _function) | 977 | #define which_fn(t) (hs ? hs_ ## t ## _function : fs_ ## t ## _function) |
1001 | #else | ||
1002 | #define which_fn(t) (fs_ ## t ## _function) | ||
1003 | #endif | ||
1004 | 978 | ||
1005 | if (index >= device_desc.bNumConfigurations) | 979 | if (index >= device_desc.bNumConfigurations) |
1006 | return -EINVAL; | 980 | return -EINVAL; |
@@ -1213,7 +1187,7 @@ eth_set_config (struct eth_dev *dev, unsigned number, gfp_t gfp_flags) | |||
1213 | if (number) | 1187 | if (number) |
1214 | eth_reset_config (dev); | 1188 | eth_reset_config (dev); |
1215 | usb_gadget_vbus_draw(dev->gadget, | 1189 | usb_gadget_vbus_draw(dev->gadget, |
1216 | dev->gadget->is_otg ? 8 : 100); | 1190 | gadget_is_otg(dev->gadget) ? 8 : 100); |
1217 | } else { | 1191 | } else { |
1218 | char *speed; | 1192 | char *speed; |
1219 | unsigned power; | 1193 | unsigned power; |
@@ -1395,24 +1369,22 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1395 | value = min (wLength, (u16) sizeof device_desc); | 1369 | value = min (wLength, (u16) sizeof device_desc); |
1396 | memcpy (req->buf, &device_desc, value); | 1370 | memcpy (req->buf, &device_desc, value); |
1397 | break; | 1371 | break; |
1398 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
1399 | case USB_DT_DEVICE_QUALIFIER: | 1372 | case USB_DT_DEVICE_QUALIFIER: |
1400 | if (!gadget->is_dualspeed) | 1373 | if (!gadget_is_dualspeed(gadget)) |
1401 | break; | 1374 | break; |
1402 | value = min (wLength, (u16) sizeof dev_qualifier); | 1375 | value = min (wLength, (u16) sizeof dev_qualifier); |
1403 | memcpy (req->buf, &dev_qualifier, value); | 1376 | memcpy (req->buf, &dev_qualifier, value); |
1404 | break; | 1377 | break; |
1405 | 1378 | ||
1406 | case USB_DT_OTHER_SPEED_CONFIG: | 1379 | case USB_DT_OTHER_SPEED_CONFIG: |
1407 | if (!gadget->is_dualspeed) | 1380 | if (!gadget_is_dualspeed(gadget)) |
1408 | break; | 1381 | break; |
1409 | // FALLTHROUGH | 1382 | // FALLTHROUGH |
1410 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | ||
1411 | case USB_DT_CONFIG: | 1383 | case USB_DT_CONFIG: |
1412 | value = config_buf (gadget->speed, req->buf, | 1384 | value = config_buf(gadget, req->buf, |
1413 | wValue >> 8, | 1385 | wValue >> 8, |
1414 | wValue & 0xff, | 1386 | wValue & 0xff, |
1415 | gadget->is_otg); | 1387 | gadget_is_otg(gadget)); |
1416 | if (value >= 0) | 1388 | if (value >= 0) |
1417 | value = min (wLength, (u16) value); | 1389 | value = min (wLength, (u16) value); |
1418 | break; | 1390 | break; |
@@ -1581,12 +1553,12 @@ done_set_intf: | |||
1581 | && rndis_control_intf.bInterfaceNumber | 1553 | && rndis_control_intf.bInterfaceNumber |
1582 | == wIndex) { | 1554 | == wIndex) { |
1583 | u8 *buf; | 1555 | u8 *buf; |
1556 | u32 n; | ||
1584 | 1557 | ||
1585 | /* return the result */ | 1558 | /* return the result */ |
1586 | buf = rndis_get_next_response (dev->rndis_config, | 1559 | buf = rndis_get_next_response(dev->rndis_config, &n); |
1587 | &value); | ||
1588 | if (buf) { | 1560 | if (buf) { |
1589 | memcpy (req->buf, buf, value); | 1561 | memcpy(req->buf, buf, n); |
1590 | req->complete = rndis_response_complete; | 1562 | req->complete = rndis_response_complete; |
1591 | rndis_free_response(dev->rndis_config, buf); | 1563 | rndis_free_response(dev->rndis_config, buf); |
1592 | } | 1564 | } |
@@ -1719,7 +1691,8 @@ rx_submit (struct eth_dev *dev, struct usb_request *req, gfp_t gfp_flags) | |||
1719 | size += sizeof (struct rndis_packet_msg_type); | 1691 | size += sizeof (struct rndis_packet_msg_type); |
1720 | size -= size % dev->out_ep->maxpacket; | 1692 | size -= size % dev->out_ep->maxpacket; |
1721 | 1693 | ||
1722 | if ((skb = alloc_skb (size + NET_IP_ALIGN, gfp_flags)) == 0) { | 1694 | skb = alloc_skb(size + NET_IP_ALIGN, gfp_flags); |
1695 | if (skb == NULL) { | ||
1723 | DEBUG (dev, "no rx skb\n"); | 1696 | DEBUG (dev, "no rx skb\n"); |
1724 | goto enomem; | 1697 | goto enomem; |
1725 | } | 1698 | } |
@@ -1984,8 +1957,20 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net) | |||
1984 | } | 1957 | } |
1985 | 1958 | ||
1986 | spin_lock_irqsave(&dev->req_lock, flags); | 1959 | spin_lock_irqsave(&dev->req_lock, flags); |
1960 | /* | ||
1961 | * this freelist can be empty if an interrupt triggered disconnect() | ||
1962 | * and reconfigured the gadget (shutting down this queue) after the | ||
1963 | * network stack decided to xmit but before we got the spinlock. | ||
1964 | */ | ||
1965 | if (list_empty(&dev->tx_reqs)) { | ||
1966 | spin_unlock_irqrestore(&dev->req_lock, flags); | ||
1967 | return 1; | ||
1968 | } | ||
1969 | |||
1987 | req = container_of (dev->tx_reqs.next, struct usb_request, list); | 1970 | req = container_of (dev->tx_reqs.next, struct usb_request, list); |
1988 | list_del (&req->list); | 1971 | list_del (&req->list); |
1972 | |||
1973 | /* temporarily stop TX queue when the freelist empties */ | ||
1989 | if (list_empty (&dev->tx_reqs)) | 1974 | if (list_empty (&dev->tx_reqs)) |
1990 | netif_stop_queue (net); | 1975 | netif_stop_queue (net); |
1991 | spin_unlock_irqrestore(&dev->req_lock, flags); | 1976 | spin_unlock_irqrestore(&dev->req_lock, flags); |
@@ -2021,12 +2006,11 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net) | |||
2021 | 2006 | ||
2022 | req->length = length; | 2007 | req->length = length; |
2023 | 2008 | ||
2024 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
2025 | /* throttle highspeed IRQ rate back slightly */ | 2009 | /* throttle highspeed IRQ rate back slightly */ |
2026 | req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH) | 2010 | if (gadget_is_dualspeed(dev->gadget)) |
2027 | ? ((atomic_read (&dev->tx_qlen) % TX_DELAY) != 0) | 2011 | req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH) |
2028 | : 0; | 2012 | ? ((atomic_read(&dev->tx_qlen) % qmult) != 0) |
2029 | #endif | 2013 | : 0; |
2030 | 2014 | ||
2031 | retval = usb_ep_queue (dev->in_ep, req, GFP_ATOMIC); | 2015 | retval = usb_ep_queue (dev->in_ep, req, GFP_ATOMIC); |
2032 | switch (retval) { | 2016 | switch (retval) { |
@@ -2183,8 +2167,7 @@ static int eth_stop (struct net_device *net) | |||
2183 | } | 2167 | } |
2184 | 2168 | ||
2185 | if (rndis_active(dev)) { | 2169 | if (rndis_active(dev)) { |
2186 | rndis_set_param_medium (dev->rndis_config, | 2170 | rndis_set_param_medium(dev->rndis_config, NDIS_MEDIUM_802_3, 0); |
2187 | NDIS_MEDIUM_802_3, 0); | ||
2188 | (void) rndis_signal_disconnect (dev->rndis_config); | 2171 | (void) rndis_signal_disconnect (dev->rndis_config); |
2189 | } | 2172 | } |
2190 | 2173 | ||
@@ -2438,26 +2421,28 @@ autoconf_fail: | |||
2438 | if (rndis) | 2421 | if (rndis) |
2439 | device_desc.bNumConfigurations = 2; | 2422 | device_desc.bNumConfigurations = 2; |
2440 | 2423 | ||
2441 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 2424 | if (gadget_is_dualspeed(gadget)) { |
2442 | if (rndis) | 2425 | if (rndis) |
2443 | dev_qualifier.bNumConfigurations = 2; | 2426 | dev_qualifier.bNumConfigurations = 2; |
2444 | else if (!cdc) | 2427 | else if (!cdc) |
2445 | dev_qualifier.bDeviceClass = USB_CLASS_VENDOR_SPEC; | 2428 | dev_qualifier.bDeviceClass = USB_CLASS_VENDOR_SPEC; |
2446 | 2429 | ||
2447 | /* assumes ep0 uses the same value for both speeds ... */ | 2430 | /* assumes ep0 uses the same value for both speeds ... */ |
2448 | dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0; | 2431 | dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0; |
2449 | 2432 | ||
2450 | /* and that all endpoints are dual-speed */ | 2433 | /* and that all endpoints are dual-speed */ |
2451 | hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress; | 2434 | hs_source_desc.bEndpointAddress = |
2452 | hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress; | 2435 | fs_source_desc.bEndpointAddress; |
2436 | hs_sink_desc.bEndpointAddress = | ||
2437 | fs_sink_desc.bEndpointAddress; | ||
2453 | #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) | 2438 | #if defined(DEV_CONFIG_CDC) || defined(CONFIG_USB_ETH_RNDIS) |
2454 | if (status_ep) | 2439 | if (status_ep) |
2455 | hs_status_desc.bEndpointAddress = | 2440 | hs_status_desc.bEndpointAddress = |
2456 | fs_status_desc.bEndpointAddress; | 2441 | fs_status_desc.bEndpointAddress; |
2457 | #endif | 2442 | #endif |
2458 | #endif /* DUALSPEED */ | 2443 | } |
2459 | 2444 | ||
2460 | if (gadget->is_otg) { | 2445 | if (gadget_is_otg(gadget)) { |
2461 | otg_descriptor.bmAttributes |= USB_OTG_HNP, | 2446 | otg_descriptor.bmAttributes |= USB_OTG_HNP, |
2462 | eth_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 2447 | eth_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
2463 | eth_config.bMaxPower = 4; | 2448 | eth_config.bMaxPower = 4; |
@@ -2479,7 +2464,6 @@ autoconf_fail: | |||
2479 | 2464 | ||
2480 | /* network device setup */ | 2465 | /* network device setup */ |
2481 | dev->net = net; | 2466 | dev->net = net; |
2482 | SET_MODULE_OWNER (net); | ||
2483 | strcpy (net->name, "usb%d"); | 2467 | strcpy (net->name, "usb%d"); |
2484 | dev->cdc = cdc; | 2468 | dev->cdc = cdc; |
2485 | dev->zlp = zlp; | 2469 | dev->zlp = zlp; |
@@ -2594,12 +2578,11 @@ fail0: | |||
2594 | if (rndis_set_param_dev (dev->rndis_config, dev->net, | 2578 | if (rndis_set_param_dev (dev->rndis_config, dev->net, |
2595 | &dev->stats, &dev->cdc_filter)) | 2579 | &dev->stats, &dev->cdc_filter)) |
2596 | goto fail0; | 2580 | goto fail0; |
2597 | if (rndis_set_param_vendor (dev->rndis_config, vendorID, | 2581 | if (rndis_set_param_vendor(dev->rndis_config, vendorID, |
2598 | manufacturer)) | 2582 | manufacturer)) |
2599 | goto fail0; | 2583 | goto fail0; |
2600 | if (rndis_set_param_medium (dev->rndis_config, | 2584 | if (rndis_set_param_medium(dev->rndis_config, |
2601 | NDIS_MEDIUM_802_3, | 2585 | NDIS_MEDIUM_802_3, 0)) |
2602 | 0)) | ||
2603 | goto fail0; | 2586 | goto fail0; |
2604 | INFO (dev, "RNDIS ready\n"); | 2587 | INFO (dev, "RNDIS ready\n"); |
2605 | } | 2588 | } |
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c index be7a1bd2823..73726c570a6 100644 --- a/drivers/usb/gadget/file_storage.c +++ b/drivers/usb/gadget/file_storage.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * file_storage.c -- File-backed USB Storage Gadget, for USB development | 2 | * file_storage.c -- File-backed USB Storage Gadget, for USB development |
3 | * | 3 | * |
4 | * Copyright (C) 2003-2005 Alan Stern | 4 | * Copyright (C) 2003-2007 Alan Stern |
5 | * All rights reserved. | 5 | * All rights reserved. |
6 | * | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * Redistribution and use in source and binary forms, with or without |
@@ -217,17 +217,11 @@ | |||
217 | */ | 217 | */ |
218 | 218 | ||
219 | 219 | ||
220 | #undef DEBUG | 220 | /* #define VERBOSE_DEBUG */ |
221 | #undef VERBOSE | 221 | /* #define DUMP_MSGS */ |
222 | #undef DUMP_MSGS | ||
223 | |||
224 | 222 | ||
225 | #include <asm/system.h> | ||
226 | #include <asm/uaccess.h> | ||
227 | 223 | ||
228 | #include <linux/bitops.h> | ||
229 | #include <linux/blkdev.h> | 224 | #include <linux/blkdev.h> |
230 | #include <linux/compiler.h> | ||
231 | #include <linux/completion.h> | 225 | #include <linux/completion.h> |
232 | #include <linux/dcache.h> | 226 | #include <linux/dcache.h> |
233 | #include <linux/delay.h> | 227 | #include <linux/delay.h> |
@@ -235,18 +229,10 @@ | |||
235 | #include <linux/fcntl.h> | 229 | #include <linux/fcntl.h> |
236 | #include <linux/file.h> | 230 | #include <linux/file.h> |
237 | #include <linux/fs.h> | 231 | #include <linux/fs.h> |
238 | #include <linux/init.h> | ||
239 | #include <linux/kernel.h> | ||
240 | #include <linux/kref.h> | 232 | #include <linux/kref.h> |
241 | #include <linux/kthread.h> | 233 | #include <linux/kthread.h> |
242 | #include <linux/limits.h> | 234 | #include <linux/limits.h> |
243 | #include <linux/list.h> | ||
244 | #include <linux/module.h> | ||
245 | #include <linux/moduleparam.h> | ||
246 | #include <linux/pagemap.h> | ||
247 | #include <linux/rwsem.h> | 235 | #include <linux/rwsem.h> |
248 | #include <linux/sched.h> | ||
249 | #include <linux/signal.h> | ||
250 | #include <linux/slab.h> | 236 | #include <linux/slab.h> |
251 | #include <linux/spinlock.h> | 237 | #include <linux/spinlock.h> |
252 | #include <linux/string.h> | 238 | #include <linux/string.h> |
@@ -254,7 +240,7 @@ | |||
254 | #include <linux/utsname.h> | 240 | #include <linux/utsname.h> |
255 | 241 | ||
256 | #include <linux/usb/ch9.h> | 242 | #include <linux/usb/ch9.h> |
257 | #include <linux/usb_gadget.h> | 243 | #include <linux/usb/gadget.h> |
258 | 244 | ||
259 | #include "gadget_chips.h" | 245 | #include "gadget_chips.h" |
260 | 246 | ||
@@ -263,7 +249,7 @@ | |||
263 | 249 | ||
264 | #define DRIVER_DESC "File-backed Storage Gadget" | 250 | #define DRIVER_DESC "File-backed Storage Gadget" |
265 | #define DRIVER_NAME "g_file_storage" | 251 | #define DRIVER_NAME "g_file_storage" |
266 | #define DRIVER_VERSION "28 November 2005" | 252 | #define DRIVER_VERSION "7 August 2007" |
267 | 253 | ||
268 | static const char longname[] = DRIVER_DESC; | 254 | static const char longname[] = DRIVER_DESC; |
269 | static const char shortname[] = DRIVER_NAME; | 255 | static const char shortname[] = DRIVER_NAME; |
@@ -289,57 +275,48 @@ MODULE_LICENSE("Dual BSD/GPL"); | |||
289 | 275 | ||
290 | /*-------------------------------------------------------------------------*/ | 276 | /*-------------------------------------------------------------------------*/ |
291 | 277 | ||
292 | #define xprintk(f,level,fmt,args...) \ | ||
293 | dev_printk(level , &(f)->gadget->dev , fmt , ## args) | ||
294 | #define yprintk(l,level,fmt,args...) \ | ||
295 | dev_printk(level , &(l)->dev , fmt , ## args) | ||
296 | |||
297 | #ifdef DEBUG | 278 | #ifdef DEBUG |
298 | #define DBG(fsg,fmt,args...) \ | ||
299 | xprintk(fsg , KERN_DEBUG , fmt , ## args) | ||
300 | #define LDBG(lun,fmt,args...) \ | 279 | #define LDBG(lun,fmt,args...) \ |
301 | yprintk(lun , KERN_DEBUG , fmt , ## args) | 280 | dev_dbg(&(lun)->dev , fmt , ## args) |
302 | #define MDBG(fmt,args...) \ | 281 | #define MDBG(fmt,args...) \ |
303 | printk(KERN_DEBUG DRIVER_NAME ": " fmt , ## args) | 282 | printk(KERN_DEBUG DRIVER_NAME ": " fmt , ## args) |
304 | #else | 283 | #else |
305 | #define DBG(fsg,fmt,args...) \ | ||
306 | do { } while (0) | ||
307 | #define LDBG(lun,fmt,args...) \ | 284 | #define LDBG(lun,fmt,args...) \ |
308 | do { } while (0) | 285 | do { } while (0) |
309 | #define MDBG(fmt,args...) \ | 286 | #define MDBG(fmt,args...) \ |
310 | do { } while (0) | 287 | do { } while (0) |
311 | #undef VERBOSE | 288 | #undef VERBOSE_DEBUG |
312 | #undef DUMP_MSGS | 289 | #undef DUMP_MSGS |
313 | #endif /* DEBUG */ | 290 | #endif /* DEBUG */ |
314 | 291 | ||
315 | #ifdef VERBOSE | 292 | #ifdef VERBOSE_DEBUG |
316 | #define VDBG DBG | ||
317 | #define VLDBG LDBG | 293 | #define VLDBG LDBG |
318 | #else | 294 | #else |
319 | #define VDBG(fsg,fmt,args...) \ | ||
320 | do { } while (0) | ||
321 | #define VLDBG(lun,fmt,args...) \ | 295 | #define VLDBG(lun,fmt,args...) \ |
322 | do { } while (0) | 296 | do { } while (0) |
323 | #endif /* VERBOSE */ | 297 | #endif /* VERBOSE_DEBUG */ |
324 | 298 | ||
325 | #define ERROR(fsg,fmt,args...) \ | ||
326 | xprintk(fsg , KERN_ERR , fmt , ## args) | ||
327 | #define LERROR(lun,fmt,args...) \ | 299 | #define LERROR(lun,fmt,args...) \ |
328 | yprintk(lun , KERN_ERR , fmt , ## args) | 300 | dev_err(&(lun)->dev , fmt , ## args) |
329 | |||
330 | #define WARN(fsg,fmt,args...) \ | ||
331 | xprintk(fsg , KERN_WARNING , fmt , ## args) | ||
332 | #define LWARN(lun,fmt,args...) \ | 301 | #define LWARN(lun,fmt,args...) \ |
333 | yprintk(lun , KERN_WARNING , fmt , ## args) | 302 | dev_warn(&(lun)->dev , fmt , ## args) |
334 | |||
335 | #define INFO(fsg,fmt,args...) \ | ||
336 | xprintk(fsg , KERN_INFO , fmt , ## args) | ||
337 | #define LINFO(lun,fmt,args...) \ | 303 | #define LINFO(lun,fmt,args...) \ |
338 | yprintk(lun , KERN_INFO , fmt , ## args) | 304 | dev_info(&(lun)->dev , fmt , ## args) |
339 | 305 | ||
340 | #define MINFO(fmt,args...) \ | 306 | #define MINFO(fmt,args...) \ |
341 | printk(KERN_INFO DRIVER_NAME ": " fmt , ## args) | 307 | printk(KERN_INFO DRIVER_NAME ": " fmt , ## args) |
342 | 308 | ||
309 | #define DBG(d, fmt, args...) \ | ||
310 | dev_dbg(&(d)->gadget->dev , fmt , ## args) | ||
311 | #define VDBG(d, fmt, args...) \ | ||
312 | dev_vdbg(&(d)->gadget->dev , fmt , ## args) | ||
313 | #define ERROR(d, fmt, args...) \ | ||
314 | dev_err(&(d)->gadget->dev , fmt , ## args) | ||
315 | #define WARN(d, fmt, args...) \ | ||
316 | dev_warn(&(d)->gadget->dev , fmt , ## args) | ||
317 | #define INFO(d, fmt, args...) \ | ||
318 | dev_info(&(d)->gadget->dev , fmt , ## args) | ||
319 | |||
343 | 320 | ||
344 | /*-------------------------------------------------------------------------*/ | 321 | /*-------------------------------------------------------------------------*/ |
345 | 322 | ||
@@ -350,8 +327,8 @@ MODULE_LICENSE("Dual BSD/GPL"); | |||
350 | static struct { | 327 | static struct { |
351 | char *file[MAX_LUNS]; | 328 | char *file[MAX_LUNS]; |
352 | int ro[MAX_LUNS]; | 329 | int ro[MAX_LUNS]; |
353 | int num_filenames; | 330 | unsigned int num_filenames; |
354 | int num_ros; | 331 | unsigned int num_ros; |
355 | unsigned int nluns; | 332 | unsigned int nluns; |
356 | 333 | ||
357 | int removable; | 334 | int removable; |
@@ -578,7 +555,7 @@ struct lun { | |||
578 | 555 | ||
579 | #define backing_file_is_open(curlun) ((curlun)->filp != NULL) | 556 | #define backing_file_is_open(curlun) ((curlun)->filp != NULL) |
580 | 557 | ||
581 | static inline struct lun *dev_to_lun(struct device *dev) | 558 | static struct lun *dev_to_lun(struct device *dev) |
582 | { | 559 | { |
583 | return container_of(dev, struct lun, dev); | 560 | return container_of(dev, struct lun, dev); |
584 | } | 561 | } |
@@ -599,7 +576,6 @@ enum fsg_buffer_state { | |||
599 | 576 | ||
600 | struct fsg_buffhd { | 577 | struct fsg_buffhd { |
601 | void *buf; | 578 | void *buf; |
602 | dma_addr_t dma; | ||
603 | enum fsg_buffer_state state; | 579 | enum fsg_buffer_state state; |
604 | struct fsg_buffhd *next; | 580 | struct fsg_buffhd *next; |
605 | 581 | ||
@@ -712,13 +688,13 @@ struct fsg_dev { | |||
712 | 688 | ||
713 | typedef void (*fsg_routine_t)(struct fsg_dev *); | 689 | typedef void (*fsg_routine_t)(struct fsg_dev *); |
714 | 690 | ||
715 | static int inline exception_in_progress(struct fsg_dev *fsg) | 691 | static int exception_in_progress(struct fsg_dev *fsg) |
716 | { | 692 | { |
717 | return (fsg->state > FSG_STATE_IDLE); | 693 | return (fsg->state > FSG_STATE_IDLE); |
718 | } | 694 | } |
719 | 695 | ||
720 | /* Make bulk-out requests be divisible by the maxpacket size */ | 696 | /* Make bulk-out requests be divisible by the maxpacket size */ |
721 | static void inline set_bulk_out_req_length(struct fsg_dev *fsg, | 697 | static void set_bulk_out_req_length(struct fsg_dev *fsg, |
722 | struct fsg_buffhd *bh, unsigned int length) | 698 | struct fsg_buffhd *bh, unsigned int length) |
723 | { | 699 | { |
724 | unsigned int rem; | 700 | unsigned int rem; |
@@ -744,50 +720,36 @@ static void close_all_backing_files(struct fsg_dev *fsg); | |||
744 | static void dump_msg(struct fsg_dev *fsg, const char *label, | 720 | static void dump_msg(struct fsg_dev *fsg, const char *label, |
745 | const u8 *buf, unsigned int length) | 721 | const u8 *buf, unsigned int length) |
746 | { | 722 | { |
747 | unsigned int start, num, i; | 723 | if (length < 512) { |
748 | char line[52], *p; | 724 | DBG(fsg, "%s, length %u:\n", label, length); |
749 | 725 | print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, | |
750 | if (length >= 512) | 726 | 16, 1, buf, length, 0); |
751 | return; | ||
752 | DBG(fsg, "%s, length %u:\n", label, length); | ||
753 | |||
754 | start = 0; | ||
755 | while (length > 0) { | ||
756 | num = min(length, 16u); | ||
757 | p = line; | ||
758 | for (i = 0; i < num; ++i) { | ||
759 | if (i == 8) | ||
760 | *p++ = ' '; | ||
761 | sprintf(p, " %02x", buf[i]); | ||
762 | p += 3; | ||
763 | } | ||
764 | *p = 0; | ||
765 | printk(KERN_DEBUG "%6x: %s\n", start, line); | ||
766 | buf += num; | ||
767 | start += num; | ||
768 | length -= num; | ||
769 | } | 727 | } |
770 | } | 728 | } |
771 | 729 | ||
772 | static void inline dump_cdb(struct fsg_dev *fsg) | 730 | static void dump_cdb(struct fsg_dev *fsg) |
773 | {} | 731 | {} |
774 | 732 | ||
775 | #else | 733 | #else |
776 | 734 | ||
777 | static void inline dump_msg(struct fsg_dev *fsg, const char *label, | 735 | static void dump_msg(struct fsg_dev *fsg, const char *label, |
778 | const u8 *buf, unsigned int length) | 736 | const u8 *buf, unsigned int length) |
779 | {} | 737 | {} |
780 | 738 | ||
781 | static void inline dump_cdb(struct fsg_dev *fsg) | 739 | #ifdef VERBOSE_DEBUG |
782 | { | ||
783 | int i; | ||
784 | char cmdbuf[3*MAX_COMMAND_SIZE + 1]; | ||
785 | 740 | ||
786 | for (i = 0; i < fsg->cmnd_size; ++i) | 741 | static void dump_cdb(struct fsg_dev *fsg) |
787 | sprintf(cmdbuf + i*3, " %02x", fsg->cmnd[i]); | 742 | { |
788 | VDBG(fsg, "SCSI CDB: %s\n", cmdbuf); | 743 | print_hex_dump(KERN_DEBUG, "SCSI CDB: ", DUMP_PREFIX_NONE, |
744 | 16, 1, fsg->cmnd, fsg->cmnd_size, 0); | ||
789 | } | 745 | } |
790 | 746 | ||
747 | #else | ||
748 | |||
749 | static void dump_cdb(struct fsg_dev *fsg) | ||
750 | {} | ||
751 | |||
752 | #endif /* VERBOSE_DEBUG */ | ||
791 | #endif /* DUMP_MSGS */ | 753 | #endif /* DUMP_MSGS */ |
792 | 754 | ||
793 | 755 | ||
@@ -810,24 +772,24 @@ static int fsg_set_halt(struct fsg_dev *fsg, struct usb_ep *ep) | |||
810 | 772 | ||
811 | /* Routines for unaligned data access */ | 773 | /* Routines for unaligned data access */ |
812 | 774 | ||
813 | static u16 inline get_be16(u8 *buf) | 775 | static u16 get_be16(u8 *buf) |
814 | { | 776 | { |
815 | return ((u16) buf[0] << 8) | ((u16) buf[1]); | 777 | return ((u16) buf[0] << 8) | ((u16) buf[1]); |
816 | } | 778 | } |
817 | 779 | ||
818 | static u32 inline get_be32(u8 *buf) | 780 | static u32 get_be32(u8 *buf) |
819 | { | 781 | { |
820 | return ((u32) buf[0] << 24) | ((u32) buf[1] << 16) | | 782 | return ((u32) buf[0] << 24) | ((u32) buf[1] << 16) | |
821 | ((u32) buf[2] << 8) | ((u32) buf[3]); | 783 | ((u32) buf[2] << 8) | ((u32) buf[3]); |
822 | } | 784 | } |
823 | 785 | ||
824 | static void inline put_be16(u8 *buf, u16 val) | 786 | static void put_be16(u8 *buf, u16 val) |
825 | { | 787 | { |
826 | buf[0] = val >> 8; | 788 | buf[0] = val >> 8; |
827 | buf[1] = val; | 789 | buf[1] = val; |
828 | } | 790 | } |
829 | 791 | ||
830 | static void inline put_be32(u8 *buf, u32 val) | 792 | static void put_be32(u8 *buf, u32 val) |
831 | { | 793 | { |
832 | buf[0] = val >> 24; | 794 | buf[0] = val >> 24; |
833 | buf[1] = val >> 16; | 795 | buf[1] = val >> 16; |
@@ -951,8 +913,6 @@ static const struct usb_descriptor_header *fs_function[] = { | |||
951 | #define FS_FUNCTION_PRE_EP_ENTRIES 2 | 913 | #define FS_FUNCTION_PRE_EP_ENTRIES 2 |
952 | 914 | ||
953 | 915 | ||
954 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
955 | |||
956 | /* | 916 | /* |
957 | * USB 2.0 devices need to expose both high speed and full speed | 917 | * USB 2.0 devices need to expose both high speed and full speed |
958 | * descriptors, unless they only run at full speed. | 918 | * descriptors, unless they only run at full speed. |
@@ -1015,14 +975,14 @@ static const struct usb_descriptor_header *hs_function[] = { | |||
1015 | #define HS_FUNCTION_PRE_EP_ENTRIES 2 | 975 | #define HS_FUNCTION_PRE_EP_ENTRIES 2 |
1016 | 976 | ||
1017 | /* Maxpacket and other transfer characteristics vary by speed. */ | 977 | /* Maxpacket and other transfer characteristics vary by speed. */ |
1018 | #define ep_desc(g,fs,hs) (((g)->speed==USB_SPEED_HIGH) ? (hs) : (fs)) | 978 | static struct usb_endpoint_descriptor * |
1019 | 979 | ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs, | |
1020 | #else | 980 | struct usb_endpoint_descriptor *hs) |
1021 | 981 | { | |
1022 | /* If there's no high speed support, always use the full-speed descriptor. */ | 982 | if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) |
1023 | #define ep_desc(g,fs,hs) fs | 983 | return hs; |
1024 | 984 | return fs; | |
1025 | #endif /* !CONFIG_USB_GADGET_DUALSPEED */ | 985 | } |
1026 | 986 | ||
1027 | 987 | ||
1028 | /* The CBI specification limits the serial string to 12 uppercase hexadecimal | 988 | /* The CBI specification limits the serial string to 12 uppercase hexadecimal |
@@ -1054,26 +1014,22 @@ static struct usb_gadget_strings stringtab = { | |||
1054 | static int populate_config_buf(struct usb_gadget *gadget, | 1014 | static int populate_config_buf(struct usb_gadget *gadget, |
1055 | u8 *buf, u8 type, unsigned index) | 1015 | u8 *buf, u8 type, unsigned index) |
1056 | { | 1016 | { |
1057 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
1058 | enum usb_device_speed speed = gadget->speed; | 1017 | enum usb_device_speed speed = gadget->speed; |
1059 | #endif | ||
1060 | int len; | 1018 | int len; |
1061 | const struct usb_descriptor_header **function; | 1019 | const struct usb_descriptor_header **function; |
1062 | 1020 | ||
1063 | if (index > 0) | 1021 | if (index > 0) |
1064 | return -EINVAL; | 1022 | return -EINVAL; |
1065 | 1023 | ||
1066 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1024 | if (gadget_is_dualspeed(gadget) && type == USB_DT_OTHER_SPEED_CONFIG) |
1067 | if (type == USB_DT_OTHER_SPEED_CONFIG) | ||
1068 | speed = (USB_SPEED_FULL + USB_SPEED_HIGH) - speed; | 1025 | speed = (USB_SPEED_FULL + USB_SPEED_HIGH) - speed; |
1069 | if (speed == USB_SPEED_HIGH) | 1026 | if (gadget_is_dualspeed(gadget) && speed == USB_SPEED_HIGH) |
1070 | function = hs_function; | 1027 | function = hs_function; |
1071 | else | 1028 | else |
1072 | #endif | ||
1073 | function = fs_function; | 1029 | function = fs_function; |
1074 | 1030 | ||
1075 | /* for now, don't advertise srp-only devices */ | 1031 | /* for now, don't advertise srp-only devices */ |
1076 | if (!gadget->is_otg) | 1032 | if (!gadget_is_otg(gadget)) |
1077 | function++; | 1033 | function++; |
1078 | 1034 | ||
1079 | len = usb_gadget_config_buf(&config_desc, buf, EP0_BUFSIZE, function); | 1035 | len = usb_gadget_config_buf(&config_desc, buf, EP0_BUFSIZE, function); |
@@ -1295,6 +1251,7 @@ static int class_setup_req(struct fsg_dev *fsg, | |||
1295 | struct usb_request *req = fsg->ep0req; | 1251 | struct usb_request *req = fsg->ep0req; |
1296 | int value = -EOPNOTSUPP; | 1252 | int value = -EOPNOTSUPP; |
1297 | u16 w_index = le16_to_cpu(ctrl->wIndex); | 1253 | u16 w_index = le16_to_cpu(ctrl->wIndex); |
1254 | u16 w_value = le16_to_cpu(ctrl->wValue); | ||
1298 | u16 w_length = le16_to_cpu(ctrl->wLength); | 1255 | u16 w_length = le16_to_cpu(ctrl->wLength); |
1299 | 1256 | ||
1300 | if (!fsg->config) | 1257 | if (!fsg->config) |
@@ -1308,7 +1265,7 @@ static int class_setup_req(struct fsg_dev *fsg, | |||
1308 | if (ctrl->bRequestType != (USB_DIR_OUT | | 1265 | if (ctrl->bRequestType != (USB_DIR_OUT | |
1309 | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) | 1266 | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) |
1310 | break; | 1267 | break; |
1311 | if (w_index != 0) { | 1268 | if (w_index != 0 || w_value != 0) { |
1312 | value = -EDOM; | 1269 | value = -EDOM; |
1313 | break; | 1270 | break; |
1314 | } | 1271 | } |
@@ -1324,7 +1281,7 @@ static int class_setup_req(struct fsg_dev *fsg, | |||
1324 | if (ctrl->bRequestType != (USB_DIR_IN | | 1281 | if (ctrl->bRequestType != (USB_DIR_IN | |
1325 | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) | 1282 | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) |
1326 | break; | 1283 | break; |
1327 | if (w_index != 0) { | 1284 | if (w_index != 0 || w_value != 0) { |
1328 | value = -EDOM; | 1285 | value = -EDOM; |
1329 | break; | 1286 | break; |
1330 | } | 1287 | } |
@@ -1343,7 +1300,7 @@ static int class_setup_req(struct fsg_dev *fsg, | |||
1343 | if (ctrl->bRequestType != (USB_DIR_OUT | | 1300 | if (ctrl->bRequestType != (USB_DIR_OUT | |
1344 | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) | 1301 | USB_TYPE_CLASS | USB_RECIP_INTERFACE)) |
1345 | break; | 1302 | break; |
1346 | if (w_index != 0) { | 1303 | if (w_index != 0 || w_value != 0) { |
1347 | value = -EDOM; | 1304 | value = -EDOM; |
1348 | break; | 1305 | break; |
1349 | } | 1306 | } |
@@ -1394,10 +1351,9 @@ static int standard_setup_req(struct fsg_dev *fsg, | |||
1394 | value = sizeof device_desc; | 1351 | value = sizeof device_desc; |
1395 | memcpy(req->buf, &device_desc, value); | 1352 | memcpy(req->buf, &device_desc, value); |
1396 | break; | 1353 | break; |
1397 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
1398 | case USB_DT_DEVICE_QUALIFIER: | 1354 | case USB_DT_DEVICE_QUALIFIER: |
1399 | VDBG(fsg, "get device qualifier\n"); | 1355 | VDBG(fsg, "get device qualifier\n"); |
1400 | if (!fsg->gadget->is_dualspeed) | 1356 | if (!gadget_is_dualspeed(fsg->gadget)) |
1401 | break; | 1357 | break; |
1402 | value = sizeof dev_qualifier; | 1358 | value = sizeof dev_qualifier; |
1403 | memcpy(req->buf, &dev_qualifier, value); | 1359 | memcpy(req->buf, &dev_qualifier, value); |
@@ -1405,15 +1361,12 @@ static int standard_setup_req(struct fsg_dev *fsg, | |||
1405 | 1361 | ||
1406 | case USB_DT_OTHER_SPEED_CONFIG: | 1362 | case USB_DT_OTHER_SPEED_CONFIG: |
1407 | VDBG(fsg, "get other-speed config descriptor\n"); | 1363 | VDBG(fsg, "get other-speed config descriptor\n"); |
1408 | if (!fsg->gadget->is_dualspeed) | 1364 | if (!gadget_is_dualspeed(fsg->gadget)) |
1409 | break; | 1365 | break; |
1410 | goto get_config; | 1366 | goto get_config; |
1411 | #endif | ||
1412 | case USB_DT_CONFIG: | 1367 | case USB_DT_CONFIG: |
1413 | VDBG(fsg, "get configuration descriptor\n"); | 1368 | VDBG(fsg, "get configuration descriptor\n"); |
1414 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1369 | get_config: |
1415 | get_config: | ||
1416 | #endif | ||
1417 | value = populate_config_buf(fsg->gadget, | 1370 | value = populate_config_buf(fsg->gadget, |
1418 | req->buf, | 1371 | req->buf, |
1419 | w_value >> 8, | 1372 | w_value >> 8, |
@@ -1646,7 +1599,8 @@ static int do_read(struct fsg_dev *fsg) | |||
1646 | /* Wait for the next buffer to become available */ | 1599 | /* Wait for the next buffer to become available */ |
1647 | bh = fsg->next_buffhd_to_fill; | 1600 | bh = fsg->next_buffhd_to_fill; |
1648 | while (bh->state != BUF_STATE_EMPTY) { | 1601 | while (bh->state != BUF_STATE_EMPTY) { |
1649 | if ((rc = sleep_thread(fsg)) != 0) | 1602 | rc = sleep_thread(fsg); |
1603 | if (rc) | ||
1650 | return rc; | 1604 | return rc; |
1651 | } | 1605 | } |
1652 | 1606 | ||
@@ -1885,7 +1839,8 @@ static int do_write(struct fsg_dev *fsg) | |||
1885 | } | 1839 | } |
1886 | 1840 | ||
1887 | /* Wait for something to happen */ | 1841 | /* Wait for something to happen */ |
1888 | if ((rc = sleep_thread(fsg)) != 0) | 1842 | rc = sleep_thread(fsg); |
1843 | if (rc) | ||
1889 | return rc; | 1844 | return rc; |
1890 | } | 1845 | } |
1891 | 1846 | ||
@@ -2369,7 +2324,8 @@ static int pad_with_zeros(struct fsg_dev *fsg) | |||
2369 | 2324 | ||
2370 | /* Wait for the next buffer to be free */ | 2325 | /* Wait for the next buffer to be free */ |
2371 | while (bh->state != BUF_STATE_EMPTY) { | 2326 | while (bh->state != BUF_STATE_EMPTY) { |
2372 | if ((rc = sleep_thread(fsg)) != 0) | 2327 | rc = sleep_thread(fsg); |
2328 | if (rc) | ||
2373 | return rc; | 2329 | return rc; |
2374 | } | 2330 | } |
2375 | 2331 | ||
@@ -2429,7 +2385,8 @@ static int throw_away_data(struct fsg_dev *fsg) | |||
2429 | } | 2385 | } |
2430 | 2386 | ||
2431 | /* Otherwise wait for something to happen */ | 2387 | /* Otherwise wait for something to happen */ |
2432 | if ((rc = sleep_thread(fsg)) != 0) | 2388 | rc = sleep_thread(fsg); |
2389 | if (rc) | ||
2433 | return rc; | 2390 | return rc; |
2434 | } | 2391 | } |
2435 | return 0; | 2392 | return 0; |
@@ -2551,7 +2508,8 @@ static int send_status(struct fsg_dev *fsg) | |||
2551 | /* Wait for the next buffer to become available */ | 2508 | /* Wait for the next buffer to become available */ |
2552 | bh = fsg->next_buffhd_to_fill; | 2509 | bh = fsg->next_buffhd_to_fill; |
2553 | while (bh->state != BUF_STATE_EMPTY) { | 2510 | while (bh->state != BUF_STATE_EMPTY) { |
2554 | if ((rc = sleep_thread(fsg)) != 0) | 2511 | rc = sleep_thread(fsg); |
2512 | if (rc) | ||
2555 | return rc; | 2513 | return rc; |
2556 | } | 2514 | } |
2557 | 2515 | ||
@@ -2611,7 +2569,6 @@ static int send_status(struct fsg_dev *fsg) | |||
2611 | 2569 | ||
2612 | fsg->intr_buffhd = bh; // Point to the right buffhd | 2570 | fsg->intr_buffhd = bh; // Point to the right buffhd |
2613 | fsg->intreq->buf = bh->inreq->buf; | 2571 | fsg->intreq->buf = bh->inreq->buf; |
2614 | fsg->intreq->dma = bh->inreq->dma; | ||
2615 | fsg->intreq->context = bh; | 2572 | fsg->intreq->context = bh; |
2616 | start_transfer(fsg, fsg->intr_in, fsg->intreq, | 2573 | start_transfer(fsg, fsg->intr_in, fsg->intreq, |
2617 | &fsg->intreq_busy, &bh->state); | 2574 | &fsg->intreq_busy, &bh->state); |
@@ -2772,9 +2729,10 @@ static int do_scsi_command(struct fsg_dev *fsg) | |||
2772 | /* Wait for the next buffer to become available for data or status */ | 2729 | /* Wait for the next buffer to become available for data or status */ |
2773 | bh = fsg->next_buffhd_to_drain = fsg->next_buffhd_to_fill; | 2730 | bh = fsg->next_buffhd_to_drain = fsg->next_buffhd_to_fill; |
2774 | while (bh->state != BUF_STATE_EMPTY) { | 2731 | while (bh->state != BUF_STATE_EMPTY) { |
2775 | if ((rc = sleep_thread(fsg)) != 0) | 2732 | rc = sleep_thread(fsg); |
2733 | if (rc) | ||
2776 | return rc; | 2734 | return rc; |
2777 | } | 2735 | } |
2778 | fsg->phase_error = 0; | 2736 | fsg->phase_error = 0; |
2779 | fsg->short_packet_received = 0; | 2737 | fsg->short_packet_received = 0; |
2780 | 2738 | ||
@@ -3006,7 +2964,7 @@ static int received_cbw(struct fsg_dev *fsg, struct fsg_buffhd *bh) | |||
3006 | 2964 | ||
3007 | /* Is the CBW meaningful? */ | 2965 | /* Is the CBW meaningful? */ |
3008 | if (cbw->Lun >= MAX_LUNS || cbw->Flags & ~USB_BULK_IN_FLAG || | 2966 | if (cbw->Lun >= MAX_LUNS || cbw->Flags & ~USB_BULK_IN_FLAG || |
3009 | cbw->Length < 6 || cbw->Length > MAX_COMMAND_SIZE) { | 2967 | cbw->Length <= 0 || cbw->Length > MAX_COMMAND_SIZE) { |
3010 | DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, " | 2968 | DBG(fsg, "non-meaningful CBW: lun = %u, flags = 0x%x, " |
3011 | "cmdlen %u\n", | 2969 | "cmdlen %u\n", |
3012 | cbw->Lun, cbw->Flags, cbw->Length); | 2970 | cbw->Lun, cbw->Flags, cbw->Length); |
@@ -3046,9 +3004,10 @@ static int get_next_command(struct fsg_dev *fsg) | |||
3046 | /* Wait for the next buffer to become available */ | 3004 | /* Wait for the next buffer to become available */ |
3047 | bh = fsg->next_buffhd_to_fill; | 3005 | bh = fsg->next_buffhd_to_fill; |
3048 | while (bh->state != BUF_STATE_EMPTY) { | 3006 | while (bh->state != BUF_STATE_EMPTY) { |
3049 | if ((rc = sleep_thread(fsg)) != 0) | 3007 | rc = sleep_thread(fsg); |
3008 | if (rc) | ||
3050 | return rc; | 3009 | return rc; |
3051 | } | 3010 | } |
3052 | 3011 | ||
3053 | /* Queue a request to read a Bulk-only CBW */ | 3012 | /* Queue a request to read a Bulk-only CBW */ |
3054 | set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN); | 3013 | set_bulk_out_req_length(fsg, bh, USB_BULK_CB_WRAP_LEN); |
@@ -3062,9 +3021,10 @@ static int get_next_command(struct fsg_dev *fsg) | |||
3062 | 3021 | ||
3063 | /* Wait for the CBW to arrive */ | 3022 | /* Wait for the CBW to arrive */ |
3064 | while (bh->state != BUF_STATE_FULL) { | 3023 | while (bh->state != BUF_STATE_FULL) { |
3065 | if ((rc = sleep_thread(fsg)) != 0) | 3024 | rc = sleep_thread(fsg); |
3025 | if (rc) | ||
3066 | return rc; | 3026 | return rc; |
3067 | } | 3027 | } |
3068 | smp_rmb(); | 3028 | smp_rmb(); |
3069 | rc = received_cbw(fsg, bh); | 3029 | rc = received_cbw(fsg, bh); |
3070 | bh->state = BUF_STATE_EMPTY; | 3030 | bh->state = BUF_STATE_EMPTY; |
@@ -3073,9 +3033,10 @@ static int get_next_command(struct fsg_dev *fsg) | |||
3073 | 3033 | ||
3074 | /* Wait for the next command to arrive */ | 3034 | /* Wait for the next command to arrive */ |
3075 | while (fsg->cbbuf_cmnd_size == 0) { | 3035 | while (fsg->cbbuf_cmnd_size == 0) { |
3076 | if ((rc = sleep_thread(fsg)) != 0) | 3036 | rc = sleep_thread(fsg); |
3037 | if (rc) | ||
3077 | return rc; | 3038 | return rc; |
3078 | } | 3039 | } |
3079 | 3040 | ||
3080 | /* Is the previous status interrupt request still busy? | 3041 | /* Is the previous status interrupt request still busy? |
3081 | * The host is allowed to skip reading the status, | 3042 | * The host is allowed to skip reading the status, |
@@ -3200,7 +3161,6 @@ reset: | |||
3200 | if ((rc = alloc_request(fsg, fsg->bulk_out, &bh->outreq)) != 0) | 3161 | if ((rc = alloc_request(fsg, fsg->bulk_out, &bh->outreq)) != 0) |
3201 | goto reset; | 3162 | goto reset; |
3202 | bh->inreq->buf = bh->outreq->buf = bh->buf; | 3163 | bh->inreq->buf = bh->outreq->buf = bh->buf; |
3203 | bh->inreq->dma = bh->outreq->dma = bh->dma; | ||
3204 | bh->inreq->context = bh->outreq->context = bh; | 3164 | bh->inreq->context = bh->outreq->context = bh; |
3205 | bh->inreq->complete = bulk_in_complete; | 3165 | bh->inreq->complete = bulk_in_complete; |
3206 | bh->outreq->complete = bulk_out_complete; | 3166 | bh->outreq->complete = bulk_out_complete; |
@@ -3597,7 +3557,8 @@ static ssize_t show_ro(struct device *dev, struct device_attribute *attr, char * | |||
3597 | return sprintf(buf, "%d\n", curlun->ro); | 3557 | return sprintf(buf, "%d\n", curlun->ro); |
3598 | } | 3558 | } |
3599 | 3559 | ||
3600 | static ssize_t show_file(struct device *dev, struct device_attribute *attr, char *buf) | 3560 | static ssize_t show_file(struct device *dev, struct device_attribute *attr, |
3561 | char *buf) | ||
3601 | { | 3562 | { |
3602 | struct lun *curlun = dev_to_lun(dev); | 3563 | struct lun *curlun = dev_to_lun(dev); |
3603 | struct fsg_dev *fsg = dev_get_drvdata(dev); | 3564 | struct fsg_dev *fsg = dev_get_drvdata(dev); |
@@ -3606,8 +3567,8 @@ static ssize_t show_file(struct device *dev, struct device_attribute *attr, char | |||
3606 | 3567 | ||
3607 | down_read(&fsg->filesem); | 3568 | down_read(&fsg->filesem); |
3608 | if (backing_file_is_open(curlun)) { // Get the complete pathname | 3569 | if (backing_file_is_open(curlun)) { // Get the complete pathname |
3609 | p = d_path(curlun->filp->f_path.dentry, curlun->filp->f_path.mnt, | 3570 | p = d_path(curlun->filp->f_path.dentry, |
3610 | buf, PAGE_SIZE - 1); | 3571 | curlun->filp->f_path.mnt, buf, PAGE_SIZE - 1); |
3611 | if (IS_ERR(p)) | 3572 | if (IS_ERR(p)) |
3612 | rc = PTR_ERR(p); | 3573 | rc = PTR_ERR(p); |
3613 | else { | 3574 | else { |
@@ -3625,7 +3586,8 @@ static ssize_t show_file(struct device *dev, struct device_attribute *attr, char | |||
3625 | } | 3586 | } |
3626 | 3587 | ||
3627 | 3588 | ||
3628 | static ssize_t store_ro(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 3589 | static ssize_t store_ro(struct device *dev, struct device_attribute *attr, |
3590 | const char *buf, size_t count) | ||
3629 | { | 3591 | { |
3630 | ssize_t rc = count; | 3592 | ssize_t rc = count; |
3631 | struct lun *curlun = dev_to_lun(dev); | 3593 | struct lun *curlun = dev_to_lun(dev); |
@@ -3649,7 +3611,8 @@ static ssize_t store_ro(struct device *dev, struct device_attribute *attr, const | |||
3649 | return rc; | 3611 | return rc; |
3650 | } | 3612 | } |
3651 | 3613 | ||
3652 | static ssize_t store_file(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 3614 | static ssize_t store_file(struct device *dev, struct device_attribute *attr, |
3615 | const char *buf, size_t count) | ||
3653 | { | 3616 | { |
3654 | struct lun *curlun = dev_to_lun(dev); | 3617 | struct lun *curlun = dev_to_lun(dev); |
3655 | struct fsg_dev *fsg = dev_get_drvdata(dev); | 3618 | struct fsg_dev *fsg = dev_get_drvdata(dev); |
@@ -3861,7 +3824,7 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3861 | /* Find out how many LUNs there should be */ | 3824 | /* Find out how many LUNs there should be */ |
3862 | i = mod_data.nluns; | 3825 | i = mod_data.nluns; |
3863 | if (i == 0) | 3826 | if (i == 0) |
3864 | i = max(mod_data.num_filenames, 1); | 3827 | i = max(mod_data.num_filenames, 1u); |
3865 | if (i > MAX_LUNS) { | 3828 | if (i > MAX_LUNS) { |
3866 | ERROR(fsg, "invalid number of LUNs: %d\n", i); | 3829 | ERROR(fsg, "invalid number of LUNs: %d\n", i); |
3867 | rc = -EINVAL; | 3830 | rc = -EINVAL; |
@@ -3946,21 +3909,23 @@ static int __init fsg_bind(struct usb_gadget *gadget) | |||
3946 | intf_desc.bInterfaceProtocol = mod_data.transport_type; | 3909 | intf_desc.bInterfaceProtocol = mod_data.transport_type; |
3947 | fs_function[i + FS_FUNCTION_PRE_EP_ENTRIES] = NULL; | 3910 | fs_function[i + FS_FUNCTION_PRE_EP_ENTRIES] = NULL; |
3948 | 3911 | ||
3949 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 3912 | if (gadget_is_dualspeed(gadget)) { |
3950 | hs_function[i + HS_FUNCTION_PRE_EP_ENTRIES] = NULL; | 3913 | hs_function[i + HS_FUNCTION_PRE_EP_ENTRIES] = NULL; |
3951 | 3914 | ||
3952 | /* Assume ep0 uses the same maxpacket value for both speeds */ | 3915 | /* Assume ep0 uses the same maxpacket value for both speeds */ |
3953 | dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket; | 3916 | dev_qualifier.bMaxPacketSize0 = fsg->ep0->maxpacket; |
3954 | 3917 | ||
3955 | /* Assume that all endpoint addresses are the same for both speeds */ | 3918 | /* Assume endpoint addresses are the same for both speeds */ |
3956 | hs_bulk_in_desc.bEndpointAddress = fs_bulk_in_desc.bEndpointAddress; | 3919 | hs_bulk_in_desc.bEndpointAddress = |
3957 | hs_bulk_out_desc.bEndpointAddress = fs_bulk_out_desc.bEndpointAddress; | 3920 | fs_bulk_in_desc.bEndpointAddress; |
3958 | hs_intr_in_desc.bEndpointAddress = fs_intr_in_desc.bEndpointAddress; | 3921 | hs_bulk_out_desc.bEndpointAddress = |
3959 | #endif | 3922 | fs_bulk_out_desc.bEndpointAddress; |
3923 | hs_intr_in_desc.bEndpointAddress = | ||
3924 | fs_intr_in_desc.bEndpointAddress; | ||
3925 | } | ||
3960 | 3926 | ||
3961 | if (gadget->is_otg) { | 3927 | if (gadget_is_otg(gadget)) |
3962 | otg_desc.bmAttributes |= USB_OTG_HNP; | 3928 | otg_desc.bmAttributes |= USB_OTG_HNP; |
3963 | } | ||
3964 | 3929 | ||
3965 | rc = -ENOMEM; | 3930 | rc = -ENOMEM; |
3966 | 3931 | ||
diff --git a/drivers/usb/gadget/fsl_usb2_udc.c b/drivers/usb/gadget/fsl_usb2_udc.c index 10b2b33b869..9bb7f64a85c 100644 --- a/drivers/usb/gadget/fsl_usb2_udc.c +++ b/drivers/usb/gadget/fsl_usb2_udc.c | |||
@@ -35,7 +35,7 @@ | |||
35 | #include <linux/moduleparam.h> | 35 | #include <linux/moduleparam.h> |
36 | #include <linux/device.h> | 36 | #include <linux/device.h> |
37 | #include <linux/usb/ch9.h> | 37 | #include <linux/usb/ch9.h> |
38 | #include <linux/usb_gadget.h> | 38 | #include <linux/usb/gadget.h> |
39 | #include <linux/usb/otg.h> | 39 | #include <linux/usb/otg.h> |
40 | #include <linux/dma-mapping.h> | 40 | #include <linux/dma-mapping.h> |
41 | #include <linux/platform_device.h> | 41 | #include <linux/platform_device.h> |
@@ -1090,14 +1090,11 @@ static int fsl_vbus_session(struct usb_gadget *gadget, int is_active) | |||
1090 | */ | 1090 | */ |
1091 | static int fsl_vbus_draw(struct usb_gadget *gadget, unsigned mA) | 1091 | static int fsl_vbus_draw(struct usb_gadget *gadget, unsigned mA) |
1092 | { | 1092 | { |
1093 | #ifdef CONFIG_USB_OTG | ||
1094 | struct fsl_udc *udc; | 1093 | struct fsl_udc *udc; |
1095 | 1094 | ||
1096 | udc = container_of(gadget, struct fsl_udc, gadget); | 1095 | udc = container_of(gadget, struct fsl_udc, gadget); |
1097 | |||
1098 | if (udc->transceiver) | 1096 | if (udc->transceiver) |
1099 | return otg_set_power(udc->transceiver, mA); | 1097 | return otg_set_power(udc->transceiver, mA); |
1100 | #endif | ||
1101 | return -ENOTSUPP; | 1098 | return -ENOTSUPP; |
1102 | } | 1099 | } |
1103 | 1100 | ||
@@ -1120,7 +1117,7 @@ static int fsl_pullup(struct usb_gadget *gadget, int is_on) | |||
1120 | return 0; | 1117 | return 0; |
1121 | } | 1118 | } |
1122 | 1119 | ||
1123 | /* defined in usb_gadget.h */ | 1120 | /* defined in gadget.h */ |
1124 | static struct usb_gadget_ops fsl_gadget_ops = { | 1121 | static struct usb_gadget_ops fsl_gadget_ops = { |
1125 | .get_frame = fsl_get_frame, | 1122 | .get_frame = fsl_get_frame, |
1126 | .wakeup = fsl_wakeup, | 1123 | .wakeup = fsl_wakeup, |
@@ -1277,31 +1274,32 @@ static void setup_received_irq(struct fsl_udc *udc, | |||
1277 | 1274 | ||
1278 | udc_reset_ep_queue(udc, 0); | 1275 | udc_reset_ep_queue(udc, 0); |
1279 | 1276 | ||
1277 | /* We process some stardard setup requests here */ | ||
1280 | switch (setup->bRequest) { | 1278 | switch (setup->bRequest) { |
1281 | /* Request that need Data+Status phase from udc */ | ||
1282 | case USB_REQ_GET_STATUS: | 1279 | case USB_REQ_GET_STATUS: |
1283 | if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_STANDARD)) | 1280 | /* Data+Status phase from udc */ |
1281 | if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK)) | ||
1284 | != (USB_DIR_IN | USB_TYPE_STANDARD)) | 1282 | != (USB_DIR_IN | USB_TYPE_STANDARD)) |
1285 | break; | 1283 | break; |
1286 | ch9getstatus(udc, setup->bRequestType, wValue, wIndex, wLength); | 1284 | ch9getstatus(udc, setup->bRequestType, wValue, wIndex, wLength); |
1287 | break; | 1285 | return; |
1288 | 1286 | ||
1289 | /* Requests that need Status phase from udc */ | ||
1290 | case USB_REQ_SET_ADDRESS: | 1287 | case USB_REQ_SET_ADDRESS: |
1288 | /* Status phase from udc */ | ||
1291 | if (setup->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD | 1289 | if (setup->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD |
1292 | | USB_RECIP_DEVICE)) | 1290 | | USB_RECIP_DEVICE)) |
1293 | break; | 1291 | break; |
1294 | ch9setaddress(udc, wValue, wIndex, wLength); | 1292 | ch9setaddress(udc, wValue, wIndex, wLength); |
1295 | break; | 1293 | return; |
1296 | 1294 | ||
1297 | /* Handled by udc, no data, status by udc */ | ||
1298 | case USB_REQ_CLEAR_FEATURE: | 1295 | case USB_REQ_CLEAR_FEATURE: |
1299 | case USB_REQ_SET_FEATURE: | 1296 | case USB_REQ_SET_FEATURE: |
1300 | { /* status transaction */ | 1297 | /* Status phase from udc */ |
1298 | { | ||
1301 | int rc = -EOPNOTSUPP; | 1299 | int rc = -EOPNOTSUPP; |
1302 | 1300 | ||
1303 | if ((setup->bRequestType & USB_RECIP_MASK) | 1301 | if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK)) |
1304 | == USB_RECIP_ENDPOINT) { | 1302 | == (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD)) { |
1305 | int pipe = get_pipe_by_windex(wIndex); | 1303 | int pipe = get_pipe_by_windex(wIndex); |
1306 | struct fsl_ep *ep; | 1304 | struct fsl_ep *ep; |
1307 | 1305 | ||
@@ -1315,11 +1313,12 @@ static void setup_received_irq(struct fsl_udc *udc, | |||
1315 | ? 1 : 0); | 1313 | ? 1 : 0); |
1316 | spin_lock(&udc->lock); | 1314 | spin_lock(&udc->lock); |
1317 | 1315 | ||
1318 | } else if ((setup->bRequestType & USB_RECIP_MASK) | 1316 | } else if ((setup->bRequestType & (USB_RECIP_MASK |
1319 | == USB_RECIP_DEVICE) { | 1317 | | USB_TYPE_MASK)) == (USB_RECIP_DEVICE |
1318 | | USB_TYPE_STANDARD)) { | ||
1320 | /* Note: The driver has not include OTG support yet. | 1319 | /* Note: The driver has not include OTG support yet. |
1321 | * This will be set when OTG support is added */ | 1320 | * This will be set when OTG support is added */ |
1322 | if (!udc->gadget.is_otg) | 1321 | if (!gadget_is_otg(udc->gadget)) |
1323 | break; | 1322 | break; |
1324 | else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE) | 1323 | else if (setup->bRequest == USB_DEVICE_B_HNP_ENABLE) |
1325 | udc->gadget.b_hnp_enable = 1; | 1324 | udc->gadget.b_hnp_enable = 1; |
@@ -1328,40 +1327,45 @@ static void setup_received_irq(struct fsl_udc *udc, | |||
1328 | else if (setup->bRequest == | 1327 | else if (setup->bRequest == |
1329 | USB_DEVICE_A_ALT_HNP_SUPPORT) | 1328 | USB_DEVICE_A_ALT_HNP_SUPPORT) |
1330 | udc->gadget.a_alt_hnp_support = 1; | 1329 | udc->gadget.a_alt_hnp_support = 1; |
1330 | else | ||
1331 | break; | ||
1331 | rc = 0; | 1332 | rc = 0; |
1332 | } | 1333 | } else |
1334 | break; | ||
1335 | |||
1333 | if (rc == 0) { | 1336 | if (rc == 0) { |
1334 | if (ep0_prime_status(udc, EP_DIR_IN)) | 1337 | if (ep0_prime_status(udc, EP_DIR_IN)) |
1335 | ep0stall(udc); | 1338 | ep0stall(udc); |
1336 | } | 1339 | } |
1337 | break; | 1340 | return; |
1338 | } | 1341 | } |
1339 | /* Requests handled by gadget */ | ||
1340 | default: | ||
1341 | if (wLength) { | ||
1342 | /* Data phase from gadget, status phase from udc */ | ||
1343 | udc->ep0_dir = (setup->bRequestType & USB_DIR_IN) | ||
1344 | ? USB_DIR_IN : USB_DIR_OUT; | ||
1345 | spin_unlock(&udc->lock); | ||
1346 | if (udc->driver->setup(&udc->gadget, | ||
1347 | &udc->local_setup_buff) < 0) | ||
1348 | ep0stall(udc); | ||
1349 | spin_lock(&udc->lock); | ||
1350 | udc->ep0_state = (setup->bRequestType & USB_DIR_IN) | ||
1351 | ? DATA_STATE_XMIT : DATA_STATE_RECV; | ||
1352 | 1342 | ||
1353 | } else { | 1343 | default: |
1354 | /* No data phase, IN status from gadget */ | ||
1355 | udc->ep0_dir = USB_DIR_IN; | ||
1356 | spin_unlock(&udc->lock); | ||
1357 | if (udc->driver->setup(&udc->gadget, | ||
1358 | &udc->local_setup_buff) < 0) | ||
1359 | ep0stall(udc); | ||
1360 | spin_lock(&udc->lock); | ||
1361 | udc->ep0_state = WAIT_FOR_OUT_STATUS; | ||
1362 | } | ||
1363 | break; | 1344 | break; |
1364 | } | 1345 | } |
1346 | |||
1347 | /* Requests handled by gadget */ | ||
1348 | if (wLength) { | ||
1349 | /* Data phase from gadget, status phase from udc */ | ||
1350 | udc->ep0_dir = (setup->bRequestType & USB_DIR_IN) | ||
1351 | ? USB_DIR_IN : USB_DIR_OUT; | ||
1352 | spin_unlock(&udc->lock); | ||
1353 | if (udc->driver->setup(&udc->gadget, | ||
1354 | &udc->local_setup_buff) < 0) | ||
1355 | ep0stall(udc); | ||
1356 | spin_lock(&udc->lock); | ||
1357 | udc->ep0_state = (setup->bRequestType & USB_DIR_IN) | ||
1358 | ? DATA_STATE_XMIT : DATA_STATE_RECV; | ||
1359 | } else { | ||
1360 | /* No data phase, IN status from gadget */ | ||
1361 | udc->ep0_dir = USB_DIR_IN; | ||
1362 | spin_unlock(&udc->lock); | ||
1363 | if (udc->driver->setup(&udc->gadget, | ||
1364 | &udc->local_setup_buff) < 0) | ||
1365 | ep0stall(udc); | ||
1366 | spin_lock(&udc->lock); | ||
1367 | udc->ep0_state = WAIT_FOR_OUT_STATUS; | ||
1368 | } | ||
1365 | } | 1369 | } |
1366 | 1370 | ||
1367 | /* Process request for Data or Status phase of ep0 | 1371 | /* Process request for Data or Status phase of ep0 |
@@ -1835,10 +1839,8 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1835 | if (!driver || driver != udc_controller->driver || !driver->unbind) | 1839 | if (!driver || driver != udc_controller->driver || !driver->unbind) |
1836 | return -EINVAL; | 1840 | return -EINVAL; |
1837 | 1841 | ||
1838 | #ifdef CONFIG_USB_OTG | ||
1839 | if (udc_controller->transceiver) | 1842 | if (udc_controller->transceiver) |
1840 | (void)otg_set_peripheral(udc_controller->transceiver, 0); | 1843 | (void)otg_set_peripheral(udc_controller->transceiver, 0); |
1841 | #endif | ||
1842 | 1844 | ||
1843 | /* stop DR, disable intr */ | 1845 | /* stop DR, disable intr */ |
1844 | dr_controller_stop(udc_controller); | 1846 | dr_controller_stop(udc_controller); |
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index 53e9139ba38..f7f159c1002 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h | |||
@@ -17,6 +17,12 @@ | |||
17 | #define gadget_is_net2280(g) 0 | 17 | #define gadget_is_net2280(g) 0 |
18 | #endif | 18 | #endif |
19 | 19 | ||
20 | #ifdef CONFIG_USB_GADGET_AMD5536UDC | ||
21 | #define gadget_is_amd5536udc(g) !strcmp("amd5536udc", (g)->name) | ||
22 | #else | ||
23 | #define gadget_is_amd5536udc(g) 0 | ||
24 | #endif | ||
25 | |||
20 | #ifdef CONFIG_USB_GADGET_DUMMY_HCD | 26 | #ifdef CONFIG_USB_GADGET_DUMMY_HCD |
21 | #define gadget_is_dummy(g) !strcmp("dummy_udc", (g)->name) | 27 | #define gadget_is_dummy(g) !strcmp("dummy_udc", (g)->name) |
22 | #else | 28 | #else |
@@ -202,7 +208,9 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) | |||
202 | return 0x18; | 208 | return 0x18; |
203 | else if (gadget_is_fsl_usb2(gadget)) | 209 | else if (gadget_is_fsl_usb2(gadget)) |
204 | return 0x19; | 210 | return 0x19; |
205 | else if (gadget_is_m66592(gadget)) | 211 | else if (gadget_is_amd5536udc(gadget)) |
206 | return 0x20; | 212 | return 0x20; |
213 | else if (gadget_is_m66592(gadget)) | ||
214 | return 0x21; | ||
207 | return -ENOENT; | 215 | return -ENOENT; |
208 | } | 216 | } |
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c index 1c5aa49d743..0689189550b 100644 --- a/drivers/usb/gadget/gmidi.c +++ b/drivers/usb/gadget/gmidi.c | |||
@@ -18,17 +18,11 @@ | |||
18 | * http://www.usb.org/developers/devclass_docs/midi10.pdf | 18 | * http://www.usb.org/developers/devclass_docs/midi10.pdf |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #define DEBUG 1 | 21 | /* #define VERBOSE_DEBUG */ |
22 | // #define VERBOSE | ||
23 | 22 | ||
24 | #include <linux/module.h> | ||
25 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
26 | #include <linux/delay.h> | ||
27 | #include <linux/errno.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/utsname.h> | 24 | #include <linux/utsname.h> |
30 | #include <linux/device.h> | 25 | #include <linux/device.h> |
31 | #include <linux/moduleparam.h> | ||
32 | 26 | ||
33 | #include <sound/driver.h> | 27 | #include <sound/driver.h> |
34 | #include <sound/core.h> | 28 | #include <sound/core.h> |
@@ -36,7 +30,7 @@ | |||
36 | #include <sound/rawmidi.h> | 30 | #include <sound/rawmidi.h> |
37 | 31 | ||
38 | #include <linux/usb/ch9.h> | 32 | #include <linux/usb/ch9.h> |
39 | #include <linux/usb_gadget.h> | 33 | #include <linux/usb/gadget.h> |
40 | #include <linux/usb/audio.h> | 34 | #include <linux/usb/audio.h> |
41 | #include <linux/usb/midi.h> | 35 | #include <linux/usb/midi.h> |
42 | 36 | ||
@@ -139,30 +133,16 @@ struct gmidi_device { | |||
139 | static void gmidi_transmit(struct gmidi_device* dev, struct usb_request* req); | 133 | static void gmidi_transmit(struct gmidi_device* dev, struct usb_request* req); |
140 | 134 | ||
141 | 135 | ||
142 | #define xprintk(d,level,fmt,args...) \ | 136 | #define DBG(d, fmt, args...) \ |
143 | dev_printk(level , &(d)->gadget->dev , fmt , ## args) | 137 | dev_dbg(&(d)->gadget->dev , fmt , ## args) |
144 | 138 | #define VDBG(d, fmt, args...) \ | |
145 | #ifdef DEBUG | 139 | dev_vdbg(&(d)->gadget->dev , fmt , ## args) |
146 | #define DBG(dev,fmt,args...) \ | 140 | #define ERROR(d, fmt, args...) \ |
147 | xprintk(dev , KERN_DEBUG , fmt , ## args) | 141 | dev_err(&(d)->gadget->dev , fmt , ## args) |
148 | #else | 142 | #define WARN(d, fmt, args...) \ |
149 | #define DBG(dev,fmt,args...) \ | 143 | dev_warn(&(d)->gadget->dev , fmt , ## args) |
150 | do { } while (0) | 144 | #define INFO(d, fmt, args...) \ |
151 | #endif /* DEBUG */ | 145 | dev_info(&(d)->gadget->dev , fmt , ## args) |
152 | |||
153 | #ifdef VERBOSE | ||
154 | #define VDBG DBG | ||
155 | #else | ||
156 | #define VDBG(dev,fmt,args...) \ | ||
157 | do { } while (0) | ||
158 | #endif /* VERBOSE */ | ||
159 | |||
160 | #define ERROR(dev,fmt,args...) \ | ||
161 | xprintk(dev , KERN_ERR , fmt , ## args) | ||
162 | #define WARN(dev,fmt,args...) \ | ||
163 | xprintk(dev , KERN_WARNING , fmt , ## args) | ||
164 | #define INFO(dev,fmt,args...) \ | ||
165 | xprintk(dev , KERN_INFO , fmt , ## args) | ||
166 | 146 | ||
167 | 147 | ||
168 | static unsigned buflen = 256; | 148 | static unsigned buflen = 256; |
@@ -425,7 +405,7 @@ static int config_buf(struct usb_gadget *gadget, | |||
425 | return len; | 405 | return len; |
426 | } | 406 | } |
427 | 407 | ||
428 | static struct usb_request* alloc_ep_req(struct usb_ep *ep, unsigned length) | 408 | static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length) |
429 | { | 409 | { |
430 | struct usb_request *req; | 410 | struct usb_request *req; |
431 | 411 | ||
@@ -455,7 +435,7 @@ static const uint8_t gmidi_cin_length[] = { | |||
455 | * Receives a chunk of MIDI data. | 435 | * Receives a chunk of MIDI data. |
456 | */ | 436 | */ |
457 | static void gmidi_read_data(struct usb_ep *ep, int cable, | 437 | static void gmidi_read_data(struct usb_ep *ep, int cable, |
458 | uint8_t* data, int length) | 438 | uint8_t *data, int length) |
459 | { | 439 | { |
460 | struct gmidi_device *dev = ep->driver_data; | 440 | struct gmidi_device *dev = ep->driver_data; |
461 | /* cable is ignored, because for now we only have one. */ | 441 | /* cable is ignored, because for now we only have one. */ |
@@ -541,7 +521,7 @@ static int set_gmidi_config(struct gmidi_device *dev, gfp_t gfp_flags) | |||
541 | { | 521 | { |
542 | int err = 0; | 522 | int err = 0; |
543 | struct usb_request *req; | 523 | struct usb_request *req; |
544 | struct usb_ep* ep; | 524 | struct usb_ep *ep; |
545 | unsigned i; | 525 | unsigned i; |
546 | 526 | ||
547 | err = usb_ep_enable(dev->in_ep, &bulk_in_desc); | 527 | err = usb_ep_enable(dev->in_ep, &bulk_in_desc); |
@@ -628,7 +608,7 @@ gmidi_set_config(struct gmidi_device *dev, unsigned number, gfp_t gfp_flags) | |||
628 | 608 | ||
629 | if (gadget_is_sa1100(gadget) && dev->config) { | 609 | if (gadget_is_sa1100(gadget) && dev->config) { |
630 | /* tx fifo is full, but we can't clear it...*/ | 610 | /* tx fifo is full, but we can't clear it...*/ |
631 | INFO(dev, "can't change configurations\n"); | 611 | ERROR(dev, "can't change configurations\n"); |
632 | return -ESPIPE; | 612 | return -ESPIPE; |
633 | } | 613 | } |
634 | gmidi_reset_config(dev); | 614 | gmidi_reset_config(dev); |
@@ -843,7 +823,7 @@ static void gmidi_disconnect(struct usb_gadget *gadget) | |||
843 | static void /* __init_or_exit */ gmidi_unbind(struct usb_gadget *gadget) | 823 | static void /* __init_or_exit */ gmidi_unbind(struct usb_gadget *gadget) |
844 | { | 824 | { |
845 | struct gmidi_device *dev = get_gadget_data(gadget); | 825 | struct gmidi_device *dev = get_gadget_data(gadget); |
846 | struct snd_card* card; | 826 | struct snd_card *card; |
847 | 827 | ||
848 | DBG(dev, "unbind\n"); | 828 | DBG(dev, "unbind\n"); |
849 | 829 | ||
@@ -867,12 +847,12 @@ static int gmidi_snd_free(struct snd_device *device) | |||
867 | return 0; | 847 | return 0; |
868 | } | 848 | } |
869 | 849 | ||
870 | static void gmidi_transmit_packet(struct usb_request* req, uint8_t p0, | 850 | static void gmidi_transmit_packet(struct usb_request *req, uint8_t p0, |
871 | uint8_t p1, uint8_t p2, uint8_t p3) | 851 | uint8_t p1, uint8_t p2, uint8_t p3) |
872 | { | 852 | { |
873 | unsigned length = req->length; | 853 | unsigned length = req->length; |
854 | u8 *buf = (u8 *)req->buf + length; | ||
874 | 855 | ||
875 | uint8_t* buf = (uint8_t*)req->buf + length; | ||
876 | buf[0] = p0; | 856 | buf[0] = p0; |
877 | buf[1] = p1; | 857 | buf[1] = p1; |
878 | buf[2] = p2; | 858 | buf[2] = p2; |
@@ -883,8 +863,8 @@ static void gmidi_transmit_packet(struct usb_request* req, uint8_t p0, | |||
883 | /* | 863 | /* |
884 | * Converts MIDI commands to USB MIDI packets. | 864 | * Converts MIDI commands to USB MIDI packets. |
885 | */ | 865 | */ |
886 | static void gmidi_transmit_byte(struct usb_request* req, | 866 | static void gmidi_transmit_byte(struct usb_request *req, |
887 | struct gmidi_in_port* port, uint8_t b) | 867 | struct gmidi_in_port *port, uint8_t b) |
888 | { | 868 | { |
889 | uint8_t p0 = port->cable; | 869 | uint8_t p0 = port->cable; |
890 | 870 | ||
@@ -981,10 +961,10 @@ static void gmidi_transmit_byte(struct usb_request* req, | |||
981 | } | 961 | } |
982 | } | 962 | } |
983 | 963 | ||
984 | static void gmidi_transmit(struct gmidi_device* dev, struct usb_request* req) | 964 | static void gmidi_transmit(struct gmidi_device *dev, struct usb_request *req) |
985 | { | 965 | { |
986 | struct usb_ep* ep = dev->in_ep; | 966 | struct usb_ep *ep = dev->in_ep; |
987 | struct gmidi_in_port* port = &dev->in_port; | 967 | struct gmidi_in_port *port = &dev->in_port; |
988 | 968 | ||
989 | if (!ep) { | 969 | if (!ep) { |
990 | return; | 970 | return; |
@@ -1020,14 +1000,14 @@ static void gmidi_transmit(struct gmidi_device* dev, struct usb_request* req) | |||
1020 | 1000 | ||
1021 | static void gmidi_in_tasklet(unsigned long data) | 1001 | static void gmidi_in_tasklet(unsigned long data) |
1022 | { | 1002 | { |
1023 | struct gmidi_device* dev = (struct gmidi_device*)data; | 1003 | struct gmidi_device *dev = (struct gmidi_device *)data; |
1024 | 1004 | ||
1025 | gmidi_transmit(dev, NULL); | 1005 | gmidi_transmit(dev, NULL); |
1026 | } | 1006 | } |
1027 | 1007 | ||
1028 | static int gmidi_in_open(struct snd_rawmidi_substream *substream) | 1008 | static int gmidi_in_open(struct snd_rawmidi_substream *substream) |
1029 | { | 1009 | { |
1030 | struct gmidi_device* dev = substream->rmidi->private_data; | 1010 | struct gmidi_device *dev = substream->rmidi->private_data; |
1031 | 1011 | ||
1032 | VDBG(dev, "gmidi_in_open\n"); | 1012 | VDBG(dev, "gmidi_in_open\n"); |
1033 | dev->in_substream = substream; | 1013 | dev->in_substream = substream; |
@@ -1037,13 +1017,15 @@ static int gmidi_in_open(struct snd_rawmidi_substream *substream) | |||
1037 | 1017 | ||
1038 | static int gmidi_in_close(struct snd_rawmidi_substream *substream) | 1018 | static int gmidi_in_close(struct snd_rawmidi_substream *substream) |
1039 | { | 1019 | { |
1020 | struct gmidi_device *dev = substream->rmidi->private_data; | ||
1021 | |||
1040 | VDBG(dev, "gmidi_in_close\n"); | 1022 | VDBG(dev, "gmidi_in_close\n"); |
1041 | return 0; | 1023 | return 0; |
1042 | } | 1024 | } |
1043 | 1025 | ||
1044 | static void gmidi_in_trigger(struct snd_rawmidi_substream *substream, int up) | 1026 | static void gmidi_in_trigger(struct snd_rawmidi_substream *substream, int up) |
1045 | { | 1027 | { |
1046 | struct gmidi_device* dev = substream->rmidi->private_data; | 1028 | struct gmidi_device *dev = substream->rmidi->private_data; |
1047 | 1029 | ||
1048 | VDBG(dev, "gmidi_in_trigger %d\n", up); | 1030 | VDBG(dev, "gmidi_in_trigger %d\n", up); |
1049 | dev->in_port.active = up; | 1031 | dev->in_port.active = up; |
@@ -1054,7 +1036,7 @@ static void gmidi_in_trigger(struct snd_rawmidi_substream *substream, int up) | |||
1054 | 1036 | ||
1055 | static int gmidi_out_open(struct snd_rawmidi_substream *substream) | 1037 | static int gmidi_out_open(struct snd_rawmidi_substream *substream) |
1056 | { | 1038 | { |
1057 | struct gmidi_device* dev = substream->rmidi->private_data; | 1039 | struct gmidi_device *dev = substream->rmidi->private_data; |
1058 | 1040 | ||
1059 | VDBG(dev, "gmidi_out_open\n"); | 1041 | VDBG(dev, "gmidi_out_open\n"); |
1060 | dev->out_substream = substream; | 1042 | dev->out_substream = substream; |
@@ -1063,13 +1045,15 @@ static int gmidi_out_open(struct snd_rawmidi_substream *substream) | |||
1063 | 1045 | ||
1064 | static int gmidi_out_close(struct snd_rawmidi_substream *substream) | 1046 | static int gmidi_out_close(struct snd_rawmidi_substream *substream) |
1065 | { | 1047 | { |
1048 | struct gmidi_device *dev = substream->rmidi->private_data; | ||
1049 | |||
1066 | VDBG(dev, "gmidi_out_close\n"); | 1050 | VDBG(dev, "gmidi_out_close\n"); |
1067 | return 0; | 1051 | return 0; |
1068 | } | 1052 | } |
1069 | 1053 | ||
1070 | static void gmidi_out_trigger(struct snd_rawmidi_substream *substream, int up) | 1054 | static void gmidi_out_trigger(struct snd_rawmidi_substream *substream, int up) |
1071 | { | 1055 | { |
1072 | struct gmidi_device* dev = substream->rmidi->private_data; | 1056 | struct gmidi_device *dev = substream->rmidi->private_data; |
1073 | 1057 | ||
1074 | VDBG(dev, "gmidi_out_trigger %d\n", up); | 1058 | VDBG(dev, "gmidi_out_trigger %d\n", up); |
1075 | if (up) { | 1059 | if (up) { |
diff --git a/drivers/usb/gadget/goku_udc.c b/drivers/usb/gadget/goku_udc.c index d6c5f1150ae..2ec9d196a8c 100644 --- a/drivers/usb/gadget/goku_udc.c +++ b/drivers/usb/gadget/goku_udc.c | |||
@@ -37,7 +37,7 @@ | |||
37 | #include <linux/proc_fs.h> | 37 | #include <linux/proc_fs.h> |
38 | #include <linux/device.h> | 38 | #include <linux/device.h> |
39 | #include <linux/usb/ch9.h> | 39 | #include <linux/usb/ch9.h> |
40 | #include <linux/usb_gadget.h> | 40 | #include <linux/usb/gadget.h> |
41 | 41 | ||
42 | #include <asm/byteorder.h> | 42 | #include <asm/byteorder.h> |
43 | #include <asm/io.h> | 43 | #include <asm/io.h> |
@@ -1777,14 +1777,13 @@ static int goku_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1777 | } | 1777 | } |
1778 | 1778 | ||
1779 | /* alloc, and start init */ | 1779 | /* alloc, and start init */ |
1780 | dev = kmalloc (sizeof *dev, GFP_KERNEL); | 1780 | dev = kzalloc (sizeof *dev, GFP_KERNEL); |
1781 | if (dev == NULL){ | 1781 | if (dev == NULL){ |
1782 | pr_debug("enomem %s\n", pci_name(pdev)); | 1782 | pr_debug("enomem %s\n", pci_name(pdev)); |
1783 | retval = -ENOMEM; | 1783 | retval = -ENOMEM; |
1784 | goto done; | 1784 | goto done; |
1785 | } | 1785 | } |
1786 | 1786 | ||
1787 | memset(dev, 0, sizeof *dev); | ||
1788 | spin_lock_init(&dev->lock); | 1787 | spin_lock_init(&dev->lock); |
1789 | dev->pdev = pdev; | 1788 | dev->pdev = pdev; |
1790 | dev->gadget.ops = &goku_ops; | 1789 | dev->gadget.ops = &goku_ops; |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index e60745ffaf8..47ef8bd58a0 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
@@ -20,8 +20,7 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | 22 | ||
23 | // #define DEBUG /* data to help fault diagnosis */ | 23 | /* #define VERBOSE_DEBUG */ |
24 | // #define VERBOSE /* extra debug messages (success too) */ | ||
25 | 24 | ||
26 | #include <linux/init.h> | 25 | #include <linux/init.h> |
27 | #include <linux/module.h> | 26 | #include <linux/module.h> |
@@ -38,7 +37,7 @@ | |||
38 | #include <linux/moduleparam.h> | 37 | #include <linux/moduleparam.h> |
39 | 38 | ||
40 | #include <linux/usb/gadgetfs.h> | 39 | #include <linux/usb/gadgetfs.h> |
41 | #include <linux/usb_gadget.h> | 40 | #include <linux/usb/gadget.h> |
42 | 41 | ||
43 | 42 | ||
44 | /* | 43 | /* |
@@ -253,7 +252,7 @@ static const char *CHIP; | |||
253 | do { } while (0) | 252 | do { } while (0) |
254 | #endif /* DEBUG */ | 253 | #endif /* DEBUG */ |
255 | 254 | ||
256 | #ifdef VERBOSE | 255 | #ifdef VERBOSE_DEBUG |
257 | #define VDEBUG DBG | 256 | #define VDEBUG DBG |
258 | #else | 257 | #else |
259 | #define VDEBUG(dev,fmt,args...) \ | 258 | #define VDEBUG(dev,fmt,args...) \ |
@@ -964,7 +963,7 @@ static int setup_req (struct usb_ep *ep, struct usb_request *req, u16 len) | |||
964 | } | 963 | } |
965 | if (len > sizeof (dev->rbuf)) | 964 | if (len > sizeof (dev->rbuf)) |
966 | req->buf = kmalloc(len, GFP_ATOMIC); | 965 | req->buf = kmalloc(len, GFP_ATOMIC); |
967 | if (req->buf == 0) { | 966 | if (req->buf == NULL) { |
968 | req->buf = dev->rbuf; | 967 | req->buf = dev->rbuf; |
969 | return -ENOMEM; | 968 | return -ENOMEM; |
970 | } | 969 | } |
@@ -1010,11 +1009,12 @@ ep0_read (struct file *fd, char __user *buf, size_t len, loff_t *ptr) | |||
1010 | /* assume that was SET_CONFIGURATION */ | 1009 | /* assume that was SET_CONFIGURATION */ |
1011 | if (dev->current_config) { | 1010 | if (dev->current_config) { |
1012 | unsigned power; | 1011 | unsigned power; |
1013 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1012 | |
1014 | if (dev->gadget->speed == USB_SPEED_HIGH) | 1013 | if (gadget_is_dualspeed(dev->gadget) |
1014 | && (dev->gadget->speed | ||
1015 | == USB_SPEED_HIGH)) | ||
1015 | power = dev->hs_config->bMaxPower; | 1016 | power = dev->hs_config->bMaxPower; |
1016 | else | 1017 | else |
1017 | #endif | ||
1018 | power = dev->config->bMaxPower; | 1018 | power = dev->config->bMaxPower; |
1019 | usb_gadget_vbus_draw(dev->gadget, 2 * power); | 1019 | usb_gadget_vbus_draw(dev->gadget, 2 * power); |
1020 | } | 1020 | } |
@@ -1355,24 +1355,21 @@ static int | |||
1355 | config_buf (struct dev_data *dev, u8 type, unsigned index) | 1355 | config_buf (struct dev_data *dev, u8 type, unsigned index) |
1356 | { | 1356 | { |
1357 | int len; | 1357 | int len; |
1358 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1358 | int hs = 0; |
1359 | int hs; | ||
1360 | #endif | ||
1361 | 1359 | ||
1362 | /* only one configuration */ | 1360 | /* only one configuration */ |
1363 | if (index > 0) | 1361 | if (index > 0) |
1364 | return -EINVAL; | 1362 | return -EINVAL; |
1365 | 1363 | ||
1366 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1364 | if (gadget_is_dualspeed(dev->gadget)) { |
1367 | hs = (dev->gadget->speed == USB_SPEED_HIGH); | 1365 | hs = (dev->gadget->speed == USB_SPEED_HIGH); |
1368 | if (type == USB_DT_OTHER_SPEED_CONFIG) | 1366 | if (type == USB_DT_OTHER_SPEED_CONFIG) |
1369 | hs = !hs; | 1367 | hs = !hs; |
1368 | } | ||
1370 | if (hs) { | 1369 | if (hs) { |
1371 | dev->req->buf = dev->hs_config; | 1370 | dev->req->buf = dev->hs_config; |
1372 | len = le16_to_cpu(dev->hs_config->wTotalLength); | 1371 | len = le16_to_cpu(dev->hs_config->wTotalLength); |
1373 | } else | 1372 | } else { |
1374 | #endif | ||
1375 | { | ||
1376 | dev->req->buf = dev->config; | 1373 | dev->req->buf = dev->config; |
1377 | len = le16_to_cpu(dev->config->wTotalLength); | 1374 | len = le16_to_cpu(dev->config->wTotalLength); |
1378 | } | 1375 | } |
@@ -1393,13 +1390,13 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1393 | spin_lock (&dev->lock); | 1390 | spin_lock (&dev->lock); |
1394 | dev->setup_abort = 0; | 1391 | dev->setup_abort = 0; |
1395 | if (dev->state == STATE_DEV_UNCONNECTED) { | 1392 | if (dev->state == STATE_DEV_UNCONNECTED) { |
1396 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1393 | if (gadget_is_dualspeed(gadget) |
1397 | if (gadget->speed == USB_SPEED_HIGH && dev->hs_config == 0) { | 1394 | && gadget->speed == USB_SPEED_HIGH |
1395 | && dev->hs_config == NULL) { | ||
1398 | spin_unlock(&dev->lock); | 1396 | spin_unlock(&dev->lock); |
1399 | ERROR (dev, "no high speed config??\n"); | 1397 | ERROR (dev, "no high speed config??\n"); |
1400 | return -EINVAL; | 1398 | return -EINVAL; |
1401 | } | 1399 | } |
1402 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | ||
1403 | 1400 | ||
1404 | dev->state = STATE_DEV_CONNECTED; | 1401 | dev->state = STATE_DEV_CONNECTED; |
1405 | dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket; | 1402 | dev->dev->bMaxPacketSize0 = gadget->ep0->maxpacket; |
@@ -1469,13 +1466,12 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1469 | // user mode expected to disable endpoints | 1466 | // user mode expected to disable endpoints |
1470 | } else { | 1467 | } else { |
1471 | u8 config, power; | 1468 | u8 config, power; |
1472 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1469 | |
1473 | if (gadget->speed == USB_SPEED_HIGH) { | 1470 | if (gadget_is_dualspeed(gadget) |
1471 | && gadget->speed == USB_SPEED_HIGH) { | ||
1474 | config = dev->hs_config->bConfigurationValue; | 1472 | config = dev->hs_config->bConfigurationValue; |
1475 | power = dev->hs_config->bMaxPower; | 1473 | power = dev->hs_config->bMaxPower; |
1476 | } else | 1474 | } else { |
1477 | #endif | ||
1478 | { | ||
1479 | config = dev->config->bConfigurationValue; | 1475 | config = dev->config->bConfigurationValue; |
1480 | power = dev->config->bMaxPower; | 1476 | power = dev->config->bMaxPower; |
1481 | } | 1477 | } |
diff --git a/drivers/usb/gadget/lh7a40x_udc.h b/drivers/usb/gadget/lh7a40x_udc.h index b3fe197e1ee..1ecfd6366b9 100644 --- a/drivers/usb/gadget/lh7a40x_udc.h +++ b/drivers/usb/gadget/lh7a40x_udc.h | |||
@@ -50,7 +50,7 @@ | |||
50 | #include <asm/hardware.h> | 50 | #include <asm/hardware.h> |
51 | 51 | ||
52 | #include <linux/usb/ch9.h> | 52 | #include <linux/usb/ch9.h> |
53 | #include <linux/usb_gadget.h> | 53 | #include <linux/usb/gadget.h> |
54 | 54 | ||
55 | /* | 55 | /* |
56 | * Memory map | 56 | * Memory map |
diff --git a/drivers/usb/gadget/m66592-udc.c b/drivers/usb/gadget/m66592-udc.c index 0174a322e00..ebc5536aa27 100644 --- a/drivers/usb/gadget/m66592-udc.c +++ b/drivers/usb/gadget/m66592-udc.c | |||
@@ -21,26 +21,18 @@ | |||
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/kernel.h> | ||
25 | #include <linux/sched.h> | ||
26 | #include <linux/smp_lock.h> | ||
27 | #include <linux/errno.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/timer.h> | ||
30 | #include <linux/delay.h> | ||
31 | #include <linux/list.h> | ||
32 | #include <linux/interrupt.h> | 24 | #include <linux/interrupt.h> |
25 | #include <linux/delay.h> | ||
26 | #include <linux/io.h> | ||
33 | #include <linux/platform_device.h> | 27 | #include <linux/platform_device.h> |
34 | #include <linux/usb/ch9.h> | ||
35 | #include <linux/usb_gadget.h> | ||
36 | 28 | ||
37 | #include <asm/io.h> | 29 | #include <linux/usb/ch9.h> |
38 | #include <asm/irq.h> | 30 | #include <linux/usb/gadget.h> |
39 | #include <asm/system.h> | ||
40 | 31 | ||
41 | #include "m66592-udc.h" | 32 | #include "m66592-udc.h" |
42 | 33 | ||
43 | MODULE_DESCRIPTION("M66592 USB gadget driiver"); | 34 | |
35 | MODULE_DESCRIPTION("M66592 USB gadget driver"); | ||
44 | MODULE_LICENSE("GPL"); | 36 | MODULE_LICENSE("GPL"); |
45 | MODULE_AUTHOR("Yoshihiro Shimoda"); | 37 | MODULE_AUTHOR("Yoshihiro Shimoda"); |
46 | 38 | ||
@@ -49,16 +41,21 @@ MODULE_AUTHOR("Yoshihiro Shimoda"); | |||
49 | /* module parameters */ | 41 | /* module parameters */ |
50 | static unsigned short clock = M66592_XTAL24; | 42 | static unsigned short clock = M66592_XTAL24; |
51 | module_param(clock, ushort, 0644); | 43 | module_param(clock, ushort, 0644); |
52 | MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0(default=16384)"); | 44 | MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 " |
45 | "(default=16384)"); | ||
46 | |||
53 | static unsigned short vif = M66592_LDRV; | 47 | static unsigned short vif = M66592_LDRV; |
54 | module_param(vif, ushort, 0644); | 48 | module_param(vif, ushort, 0644); |
55 | MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0(default=32768)"); | 49 | MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0 (default=32768)"); |
56 | static unsigned short endian = 0; | 50 | |
51 | static unsigned short endian; | ||
57 | module_param(endian, ushort, 0644); | 52 | module_param(endian, ushort, 0644); |
58 | MODULE_PARM_DESC(endian, "data endian: big=256, little=0(default=0)"); | 53 | MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)"); |
54 | |||
59 | static unsigned short irq_sense = M66592_INTL; | 55 | static unsigned short irq_sense = M66592_INTL; |
60 | module_param(irq_sense, ushort, 0644); | 56 | module_param(irq_sense, ushort, 0644); |
61 | MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0(default=2)"); | 57 | MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=2, falling edge=0 " |
58 | "(default=2)"); | ||
62 | 59 | ||
63 | static const char udc_name[] = "m66592_udc"; | 60 | static const char udc_name[] = "m66592_udc"; |
64 | static const char *m66592_ep_name[] = { | 61 | static const char *m66592_ep_name[] = { |
@@ -72,8 +69,8 @@ static int m66592_queue(struct usb_ep *_ep, struct usb_request *_req, | |||
72 | gfp_t gfp_flags); | 69 | gfp_t gfp_flags); |
73 | 70 | ||
74 | static void transfer_complete(struct m66592_ep *ep, | 71 | static void transfer_complete(struct m66592_ep *ep, |
75 | struct m66592_request *req, | 72 | struct m66592_request *req, int status); |
76 | int status); | 73 | |
77 | /*-------------------------------------------------------------------------*/ | 74 | /*-------------------------------------------------------------------------*/ |
78 | static inline u16 get_usb_speed(struct m66592 *m66592) | 75 | static inline u16 get_usb_speed(struct m66592 *m66592) |
79 | { | 76 | { |
@@ -81,25 +78,25 @@ static inline u16 get_usb_speed(struct m66592 *m66592) | |||
81 | } | 78 | } |
82 | 79 | ||
83 | static void enable_pipe_irq(struct m66592 *m66592, u16 pipenum, | 80 | static void enable_pipe_irq(struct m66592 *m66592, u16 pipenum, |
84 | unsigned long reg) | 81 | unsigned long reg) |
85 | { | 82 | { |
86 | u16 tmp; | 83 | u16 tmp; |
87 | 84 | ||
88 | tmp = m66592_read(m66592, M66592_INTENB0); | 85 | tmp = m66592_read(m66592, M66592_INTENB0); |
89 | m66592_bclr(m66592, M66592_BEMPE | M66592_NRDYE | M66592_BRDYE, | 86 | m66592_bclr(m66592, M66592_BEMPE | M66592_NRDYE | M66592_BRDYE, |
90 | M66592_INTENB0); | 87 | M66592_INTENB0); |
91 | m66592_bset(m66592, (1 << pipenum), reg); | 88 | m66592_bset(m66592, (1 << pipenum), reg); |
92 | m66592_write(m66592, tmp, M66592_INTENB0); | 89 | m66592_write(m66592, tmp, M66592_INTENB0); |
93 | } | 90 | } |
94 | 91 | ||
95 | static void disable_pipe_irq(struct m66592 *m66592, u16 pipenum, | 92 | static void disable_pipe_irq(struct m66592 *m66592, u16 pipenum, |
96 | unsigned long reg) | 93 | unsigned long reg) |
97 | { | 94 | { |
98 | u16 tmp; | 95 | u16 tmp; |
99 | 96 | ||
100 | tmp = m66592_read(m66592, M66592_INTENB0); | 97 | tmp = m66592_read(m66592, M66592_INTENB0); |
101 | m66592_bclr(m66592, M66592_BEMPE | M66592_NRDYE | M66592_BRDYE, | 98 | m66592_bclr(m66592, M66592_BEMPE | M66592_NRDYE | M66592_BRDYE, |
102 | M66592_INTENB0); | 99 | M66592_INTENB0); |
103 | m66592_bclr(m66592, (1 << pipenum), reg); | 100 | m66592_bclr(m66592, (1 << pipenum), reg); |
104 | m66592_write(m66592, tmp, M66592_INTENB0); | 101 | m66592_write(m66592, tmp, M66592_INTENB0); |
105 | } | 102 | } |
@@ -108,17 +105,19 @@ static void m66592_usb_connect(struct m66592 *m66592) | |||
108 | { | 105 | { |
109 | m66592_bset(m66592, M66592_CTRE, M66592_INTENB0); | 106 | m66592_bset(m66592, M66592_CTRE, M66592_INTENB0); |
110 | m66592_bset(m66592, M66592_WDST | M66592_RDST | M66592_CMPL, | 107 | m66592_bset(m66592, M66592_WDST | M66592_RDST | M66592_CMPL, |
111 | M66592_INTENB0); | 108 | M66592_INTENB0); |
112 | m66592_bset(m66592, M66592_BEMPE | M66592_BRDYE, M66592_INTENB0); | 109 | m66592_bset(m66592, M66592_BEMPE | M66592_BRDYE, M66592_INTENB0); |
113 | 110 | ||
114 | m66592_bset(m66592, M66592_DPRPU, M66592_SYSCFG); | 111 | m66592_bset(m66592, M66592_DPRPU, M66592_SYSCFG); |
115 | } | 112 | } |
116 | 113 | ||
117 | static void m66592_usb_disconnect(struct m66592 *m66592) | 114 | static void m66592_usb_disconnect(struct m66592 *m66592) |
115 | __releases(m66592->lock) | ||
116 | __acquires(m66592->lock) | ||
118 | { | 117 | { |
119 | m66592_bclr(m66592, M66592_CTRE, M66592_INTENB0); | 118 | m66592_bclr(m66592, M66592_CTRE, M66592_INTENB0); |
120 | m66592_bclr(m66592, M66592_WDST | M66592_RDST | M66592_CMPL, | 119 | m66592_bclr(m66592, M66592_WDST | M66592_RDST | M66592_CMPL, |
121 | M66592_INTENB0); | 120 | M66592_INTENB0); |
122 | m66592_bclr(m66592, M66592_BEMPE | M66592_BRDYE, M66592_INTENB0); | 121 | m66592_bclr(m66592, M66592_BEMPE | M66592_BRDYE, M66592_INTENB0); |
123 | m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); | 122 | m66592_bclr(m66592, M66592_DPRPU, M66592_SYSCFG); |
124 | 123 | ||
@@ -148,7 +147,7 @@ static inline u16 control_reg_get_pid(struct m66592 *m66592, u16 pipenum) | |||
148 | } | 147 | } |
149 | 148 | ||
150 | static inline void control_reg_set_pid(struct m66592 *m66592, u16 pipenum, | 149 | static inline void control_reg_set_pid(struct m66592 *m66592, u16 pipenum, |
151 | u16 pid) | 150 | u16 pid) |
152 | { | 151 | { |
153 | unsigned long offset; | 152 | unsigned long offset; |
154 | 153 | ||
@@ -250,7 +249,7 @@ static inline void pipe_change(struct m66592 *m66592, u16 pipenum) | |||
250 | } | 249 | } |
251 | 250 | ||
252 | static int pipe_buffer_setting(struct m66592 *m66592, | 251 | static int pipe_buffer_setting(struct m66592 *m66592, |
253 | struct m66592_pipe_info *info) | 252 | struct m66592_pipe_info *info) |
254 | { | 253 | { |
255 | u16 bufnum = 0, buf_bsize = 0; | 254 | u16 bufnum = 0, buf_bsize = 0; |
256 | u16 pipecfg = 0; | 255 | u16 pipecfg = 0; |
@@ -287,7 +286,7 @@ static int pipe_buffer_setting(struct m66592 *m66592, | |||
287 | } | 286 | } |
288 | if (m66592->bi_bufnum > M66592_MAX_BUFNUM) { | 287 | if (m66592->bi_bufnum > M66592_MAX_BUFNUM) { |
289 | printk(KERN_ERR "m66592 pipe memory is insufficient(%d)\n", | 288 | printk(KERN_ERR "m66592 pipe memory is insufficient(%d)\n", |
290 | m66592->bi_bufnum); | 289 | m66592->bi_bufnum); |
291 | return -ENOMEM; | 290 | return -ENOMEM; |
292 | } | 291 | } |
293 | 292 | ||
@@ -328,7 +327,7 @@ static void pipe_buffer_release(struct m66592 *m66592, | |||
328 | m66592->bulk--; | 327 | m66592->bulk--; |
329 | } else | 328 | } else |
330 | printk(KERN_ERR "ep_release: unexpect pipenum (%d)\n", | 329 | printk(KERN_ERR "ep_release: unexpect pipenum (%d)\n", |
331 | info->pipe); | 330 | info->pipe); |
332 | } | 331 | } |
333 | 332 | ||
334 | static void pipe_initialize(struct m66592_ep *ep) | 333 | static void pipe_initialize(struct m66592_ep *ep) |
@@ -350,8 +349,8 @@ static void pipe_initialize(struct m66592_ep *ep) | |||
350 | } | 349 | } |
351 | 350 | ||
352 | static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep, | 351 | static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep, |
353 | const struct usb_endpoint_descriptor *desc, | 352 | const struct usb_endpoint_descriptor *desc, |
354 | u16 pipenum, int dma) | 353 | u16 pipenum, int dma) |
355 | { | 354 | { |
356 | if ((pipenum != 0) && dma) { | 355 | if ((pipenum != 0) && dma) { |
357 | if (m66592->num_dma == 0) { | 356 | if (m66592->num_dma == 0) { |
@@ -385,7 +384,7 @@ static void m66592_ep_setting(struct m66592 *m66592, struct m66592_ep *ep, | |||
385 | 384 | ||
386 | ep->pipectr = get_pipectr_addr(pipenum); | 385 | ep->pipectr = get_pipectr_addr(pipenum); |
387 | ep->pipenum = pipenum; | 386 | ep->pipenum = pipenum; |
388 | ep->ep.maxpacket = desc->wMaxPacketSize; | 387 | ep->ep.maxpacket = le16_to_cpu(desc->wMaxPacketSize); |
389 | m66592->pipenum2ep[pipenum] = ep; | 388 | m66592->pipenum2ep[pipenum] = ep; |
390 | m66592->epaddr2ep[desc->bEndpointAddress&USB_ENDPOINT_NUMBER_MASK] = ep; | 389 | m66592->epaddr2ep[desc->bEndpointAddress&USB_ENDPOINT_NUMBER_MASK] = ep; |
391 | INIT_LIST_HEAD(&ep->queue); | 390 | INIT_LIST_HEAD(&ep->queue); |
@@ -407,7 +406,7 @@ static void m66592_ep_release(struct m66592_ep *ep) | |||
407 | } | 406 | } |
408 | 407 | ||
409 | static int alloc_pipe_config(struct m66592_ep *ep, | 408 | static int alloc_pipe_config(struct m66592_ep *ep, |
410 | const struct usb_endpoint_descriptor *desc) | 409 | const struct usb_endpoint_descriptor *desc) |
411 | { | 410 | { |
412 | struct m66592 *m66592 = ep->m66592; | 411 | struct m66592 *m66592 = ep->m66592; |
413 | struct m66592_pipe_info info; | 412 | struct m66592_pipe_info info; |
@@ -419,15 +418,15 @@ static int alloc_pipe_config(struct m66592_ep *ep, | |||
419 | 418 | ||
420 | BUG_ON(ep->pipenum); | 419 | BUG_ON(ep->pipenum); |
421 | 420 | ||
422 | switch(desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | 421 | switch (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { |
423 | case USB_ENDPOINT_XFER_BULK: | 422 | case USB_ENDPOINT_XFER_BULK: |
424 | if (m66592->bulk >= M66592_MAX_NUM_BULK) { | 423 | if (m66592->bulk >= M66592_MAX_NUM_BULK) { |
425 | if (m66592->isochronous >= M66592_MAX_NUM_ISOC) { | 424 | if (m66592->isochronous >= M66592_MAX_NUM_ISOC) { |
426 | printk(KERN_ERR "bulk pipe is insufficient\n"); | 425 | printk(KERN_ERR "bulk pipe is insufficient\n"); |
427 | return -ENODEV; | 426 | return -ENODEV; |
428 | } else { | 427 | } else { |
429 | info.pipe = M66592_BASE_PIPENUM_ISOC + | 428 | info.pipe = M66592_BASE_PIPENUM_ISOC |
430 | m66592->isochronous; | 429 | + m66592->isochronous; |
431 | counter = &m66592->isochronous; | 430 | counter = &m66592->isochronous; |
432 | } | 431 | } |
433 | } else { | 432 | } else { |
@@ -462,7 +461,7 @@ static int alloc_pipe_config(struct m66592_ep *ep, | |||
462 | ep->type = info.type; | 461 | ep->type = info.type; |
463 | 462 | ||
464 | info.epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; | 463 | info.epnum = desc->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; |
465 | info.maxpacket = desc->wMaxPacketSize; | 464 | info.maxpacket = le16_to_cpu(desc->wMaxPacketSize); |
466 | info.interval = desc->bInterval; | 465 | info.interval = desc->bInterval; |
467 | if (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 466 | if (desc->bEndpointAddress & USB_ENDPOINT_DIR_MASK) |
468 | info.dir_in = 1; | 467 | info.dir_in = 1; |
@@ -525,8 +524,8 @@ static void start_ep0_write(struct m66592_ep *ep, struct m66592_request *req) | |||
525 | 524 | ||
526 | pipe_change(m66592, ep->pipenum); | 525 | pipe_change(m66592, ep->pipenum); |
527 | m66592_mdfy(m66592, M66592_ISEL | M66592_PIPE0, | 526 | m66592_mdfy(m66592, M66592_ISEL | M66592_PIPE0, |
528 | (M66592_ISEL | M66592_CURPIPE), | 527 | (M66592_ISEL | M66592_CURPIPE), |
529 | M66592_CFIFOSEL); | 528 | M66592_CFIFOSEL); |
530 | m66592_write(m66592, M66592_BCLR, ep->fifoctr); | 529 | m66592_write(m66592, M66592_BCLR, ep->fifoctr); |
531 | if (req->req.length == 0) { | 530 | if (req->req.length == 0) { |
532 | m66592_bset(m66592, M66592_BVAL, ep->fifoctr); | 531 | m66592_bset(m66592, M66592_BVAL, ep->fifoctr); |
@@ -561,8 +560,8 @@ static void start_packet_read(struct m66592_ep *ep, struct m66592_request *req) | |||
561 | 560 | ||
562 | if (ep->pipenum == 0) { | 561 | if (ep->pipenum == 0) { |
563 | m66592_mdfy(m66592, M66592_PIPE0, | 562 | m66592_mdfy(m66592, M66592_PIPE0, |
564 | (M66592_ISEL | M66592_CURPIPE), | 563 | (M66592_ISEL | M66592_CURPIPE), |
565 | M66592_CFIFOSEL); | 564 | M66592_CFIFOSEL); |
566 | m66592_write(m66592, M66592_BCLR, ep->fifoctr); | 565 | m66592_write(m66592, M66592_BCLR, ep->fifoctr); |
567 | pipe_start(m66592, pipenum); | 566 | pipe_start(m66592, pipenum); |
568 | pipe_irq_enable(m66592, pipenum); | 567 | pipe_irq_enable(m66592, pipenum); |
@@ -572,8 +571,9 @@ static void start_packet_read(struct m66592_ep *ep, struct m66592_request *req) | |||
572 | pipe_change(m66592, pipenum); | 571 | pipe_change(m66592, pipenum); |
573 | m66592_bset(m66592, M66592_TRENB, ep->fifosel); | 572 | m66592_bset(m66592, M66592_TRENB, ep->fifosel); |
574 | m66592_write(m66592, | 573 | m66592_write(m66592, |
575 | (req->req.length + ep->ep.maxpacket - 1) / | 574 | (req->req.length + ep->ep.maxpacket - 1) |
576 | ep->ep.maxpacket, ep->fifotrn); | 575 | / ep->ep.maxpacket, |
576 | ep->fifotrn); | ||
577 | } | 577 | } |
578 | pipe_start(m66592, pipenum); /* trigger once */ | 578 | pipe_start(m66592, pipenum); /* trigger once */ |
579 | pipe_irq_enable(m66592, pipenum); | 579 | pipe_irq_enable(m66592, pipenum); |
@@ -614,7 +614,7 @@ static void start_ep0(struct m66592_ep *ep, struct m66592_request *req) | |||
614 | static void init_controller(struct m66592 *m66592) | 614 | static void init_controller(struct m66592 *m66592) |
615 | { | 615 | { |
616 | m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND), | 616 | m66592_bset(m66592, (vif & M66592_LDRV) | (endian & M66592_BIGEND), |
617 | M66592_PINCFG); | 617 | M66592_PINCFG); |
618 | m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */ | 618 | m66592_bset(m66592, M66592_HSE, M66592_SYSCFG); /* High spd */ |
619 | m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL, M66592_SYSCFG); | 619 | m66592_mdfy(m66592, clock & M66592_XTAL, M66592_XTAL, M66592_SYSCFG); |
620 | 620 | ||
@@ -634,7 +634,7 @@ static void init_controller(struct m66592 *m66592) | |||
634 | 634 | ||
635 | m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1); | 635 | m66592_bset(m66592, irq_sense & M66592_INTL, M66592_INTENB1); |
636 | m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR, | 636 | m66592_write(m66592, M66592_BURST | M66592_CPU_ADR_RD_WR, |
637 | M66592_DMA0CFG); | 637 | M66592_DMA0CFG); |
638 | } | 638 | } |
639 | 639 | ||
640 | static void disable_controller(struct m66592 *m66592) | 640 | static void disable_controller(struct m66592 *m66592) |
@@ -659,8 +659,9 @@ static void m66592_start_xclock(struct m66592 *m66592) | |||
659 | 659 | ||
660 | /*-------------------------------------------------------------------------*/ | 660 | /*-------------------------------------------------------------------------*/ |
661 | static void transfer_complete(struct m66592_ep *ep, | 661 | static void transfer_complete(struct m66592_ep *ep, |
662 | struct m66592_request *req, | 662 | struct m66592_request *req, int status) |
663 | int status) | 663 | __releases(m66592->lock) |
664 | __acquires(m66592->lock) | ||
664 | { | 665 | { |
665 | int restart = 0; | 666 | int restart = 0; |
666 | 667 | ||
@@ -680,8 +681,9 @@ static void transfer_complete(struct m66592_ep *ep, | |||
680 | if (!list_empty(&ep->queue)) | 681 | if (!list_empty(&ep->queue)) |
681 | restart = 1; | 682 | restart = 1; |
682 | 683 | ||
683 | if (likely(req->req.complete)) | 684 | spin_unlock(&ep->m66592->lock); |
684 | req->req.complete(&ep->ep, &req->req); | 685 | req->req.complete(&ep->ep, &req->req); |
686 | spin_lock(&ep->m66592->lock); | ||
685 | 687 | ||
686 | if (restart) { | 688 | if (restart) { |
687 | req = list_entry(ep->queue.next, struct m66592_request, queue); | 689 | req = list_entry(ep->queue.next, struct m66592_request, queue); |
@@ -693,7 +695,7 @@ static void transfer_complete(struct m66592_ep *ep, | |||
693 | static void irq_ep0_write(struct m66592_ep *ep, struct m66592_request *req) | 695 | static void irq_ep0_write(struct m66592_ep *ep, struct m66592_request *req) |
694 | { | 696 | { |
695 | int i; | 697 | int i; |
696 | volatile u16 tmp; | 698 | u16 tmp; |
697 | unsigned bufsize; | 699 | unsigned bufsize; |
698 | size_t size; | 700 | size_t size; |
699 | void *buf; | 701 | void *buf; |
@@ -731,8 +733,9 @@ static void irq_ep0_write(struct m66592_ep *ep, struct m66592_request *req) | |||
731 | req->req.actual += size; | 733 | req->req.actual += size; |
732 | 734 | ||
733 | /* check transfer finish */ | 735 | /* check transfer finish */ |
734 | if ((!req->req.zero && (req->req.actual == req->req.length)) || | 736 | if ((!req->req.zero && (req->req.actual == req->req.length)) |
735 | (size % ep->ep.maxpacket) || (size == 0)) { | 737 | || (size % ep->ep.maxpacket) |
738 | || (size == 0)) { | ||
736 | disable_irq_ready(m66592, pipenum); | 739 | disable_irq_ready(m66592, pipenum); |
737 | disable_irq_empty(m66592, pipenum); | 740 | disable_irq_empty(m66592, pipenum); |
738 | } else { | 741 | } else { |
@@ -768,16 +771,19 @@ static void irq_packet_write(struct m66592_ep *ep, struct m66592_request *req) | |||
768 | /* write fifo */ | 771 | /* write fifo */ |
769 | if (req->req.buf) { | 772 | if (req->req.buf) { |
770 | m66592_write_fifo(m66592, ep->fifoaddr, buf, size); | 773 | m66592_write_fifo(m66592, ep->fifoaddr, buf, size); |
771 | if ((size == 0) || ((size % ep->ep.maxpacket) != 0) || | 774 | if ((size == 0) |
772 | ((bufsize != ep->ep.maxpacket) && (bufsize > size))) | 775 | || ((size % ep->ep.maxpacket) != 0) |
776 | || ((bufsize != ep->ep.maxpacket) | ||
777 | && (bufsize > size))) | ||
773 | m66592_bset(m66592, M66592_BVAL, ep->fifoctr); | 778 | m66592_bset(m66592, M66592_BVAL, ep->fifoctr); |
774 | } | 779 | } |
775 | 780 | ||
776 | /* update parameters */ | 781 | /* update parameters */ |
777 | req->req.actual += size; | 782 | req->req.actual += size; |
778 | /* check transfer finish */ | 783 | /* check transfer finish */ |
779 | if ((!req->req.zero && (req->req.actual == req->req.length)) || | 784 | if ((!req->req.zero && (req->req.actual == req->req.length)) |
780 | (size % ep->ep.maxpacket) || (size == 0)) { | 785 | || (size % ep->ep.maxpacket) |
786 | || (size == 0)) { | ||
781 | disable_irq_ready(m66592, pipenum); | 787 | disable_irq_ready(m66592, pipenum); |
782 | enable_irq_empty(m66592, pipenum); | 788 | enable_irq_empty(m66592, pipenum); |
783 | } else { | 789 | } else { |
@@ -821,8 +827,9 @@ static void irq_packet_read(struct m66592_ep *ep, struct m66592_request *req) | |||
821 | req->req.actual += size; | 827 | req->req.actual += size; |
822 | 828 | ||
823 | /* check transfer finish */ | 829 | /* check transfer finish */ |
824 | if ((!req->req.zero && (req->req.actual == req->req.length)) || | 830 | if ((!req->req.zero && (req->req.actual == req->req.length)) |
825 | (size % ep->ep.maxpacket) || (size == 0)) { | 831 | || (size % ep->ep.maxpacket) |
832 | || (size == 0)) { | ||
826 | pipe_stop(m66592, pipenum); | 833 | pipe_stop(m66592, pipenum); |
827 | pipe_irq_disable(m66592, pipenum); | 834 | pipe_irq_disable(m66592, pipenum); |
828 | finish = 1; | 835 | finish = 1; |
@@ -850,7 +857,7 @@ static void irq_pipe_ready(struct m66592 *m66592, u16 status, u16 enb) | |||
850 | if ((status & M66592_BRDY0) && (enb & M66592_BRDY0)) { | 857 | if ((status & M66592_BRDY0) && (enb & M66592_BRDY0)) { |
851 | m66592_write(m66592, ~M66592_BRDY0, M66592_BRDYSTS); | 858 | m66592_write(m66592, ~M66592_BRDY0, M66592_BRDYSTS); |
852 | m66592_mdfy(m66592, M66592_PIPE0, M66592_CURPIPE, | 859 | m66592_mdfy(m66592, M66592_PIPE0, M66592_CURPIPE, |
853 | M66592_CFIFOSEL); | 860 | M66592_CFIFOSEL); |
854 | 861 | ||
855 | ep = &m66592->ep[0]; | 862 | ep = &m66592->ep[0]; |
856 | req = list_entry(ep->queue.next, struct m66592_request, queue); | 863 | req = list_entry(ep->queue.next, struct m66592_request, queue); |
@@ -909,23 +916,26 @@ static void irq_pipe_empty(struct m66592 *m66592, u16 status, u16 enb) | |||
909 | } | 916 | } |
910 | 917 | ||
911 | static void get_status(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) | 918 | static void get_status(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) |
919 | __releases(m66592->lock) | ||
920 | __acquires(m66592->lock) | ||
912 | { | 921 | { |
913 | struct m66592_ep *ep; | 922 | struct m66592_ep *ep; |
914 | u16 pid; | 923 | u16 pid; |
915 | u16 status = 0; | 924 | u16 status = 0; |
925 | u16 w_index = le16_to_cpu(ctrl->wIndex); | ||
916 | 926 | ||
917 | switch (ctrl->bRequestType & USB_RECIP_MASK) { | 927 | switch (ctrl->bRequestType & USB_RECIP_MASK) { |
918 | case USB_RECIP_DEVICE: | 928 | case USB_RECIP_DEVICE: |
919 | status = 1; /* selfpower */ | 929 | status = 1 << USB_DEVICE_SELF_POWERED; |
920 | break; | 930 | break; |
921 | case USB_RECIP_INTERFACE: | 931 | case USB_RECIP_INTERFACE: |
922 | status = 0; | 932 | status = 0; |
923 | break; | 933 | break; |
924 | case USB_RECIP_ENDPOINT: | 934 | case USB_RECIP_ENDPOINT: |
925 | ep = m66592->epaddr2ep[ctrl->wIndex&USB_ENDPOINT_NUMBER_MASK]; | 935 | ep = m66592->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK]; |
926 | pid = control_reg_get_pid(m66592, ep->pipenum); | 936 | pid = control_reg_get_pid(m66592, ep->pipenum); |
927 | if (pid == M66592_PID_STALL) | 937 | if (pid == M66592_PID_STALL) |
928 | status = 1; | 938 | status = 1 << USB_ENDPOINT_HALT; |
929 | else | 939 | else |
930 | status = 0; | 940 | status = 0; |
931 | break; | 941 | break; |
@@ -934,11 +944,13 @@ static void get_status(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) | |||
934 | return; /* exit */ | 944 | return; /* exit */ |
935 | } | 945 | } |
936 | 946 | ||
937 | *m66592->ep0_buf = status; | 947 | m66592->ep0_data = cpu_to_le16(status); |
938 | m66592->ep0_req->buf = m66592->ep0_buf; | 948 | m66592->ep0_req->buf = &m66592->ep0_data; |
939 | m66592->ep0_req->length = 2; | 949 | m66592->ep0_req->length = 2; |
940 | /* AV: what happens if we get called again before that gets through? */ | 950 | /* AV: what happens if we get called again before that gets through? */ |
951 | spin_unlock(&m66592->lock); | ||
941 | m66592_queue(m66592->gadget.ep0, m66592->ep0_req, GFP_KERNEL); | 952 | m66592_queue(m66592->gadget.ep0, m66592->ep0_req, GFP_KERNEL); |
953 | spin_lock(&m66592->lock); | ||
942 | } | 954 | } |
943 | 955 | ||
944 | static void clear_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) | 956 | static void clear_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) |
@@ -953,8 +965,9 @@ static void clear_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) | |||
953 | case USB_RECIP_ENDPOINT: { | 965 | case USB_RECIP_ENDPOINT: { |
954 | struct m66592_ep *ep; | 966 | struct m66592_ep *ep; |
955 | struct m66592_request *req; | 967 | struct m66592_request *req; |
968 | u16 w_index = le16_to_cpu(ctrl->wIndex); | ||
956 | 969 | ||
957 | ep = m66592->epaddr2ep[ctrl->wIndex&USB_ENDPOINT_NUMBER_MASK]; | 970 | ep = m66592->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK]; |
958 | pipe_stop(m66592, ep->pipenum); | 971 | pipe_stop(m66592, ep->pipenum); |
959 | control_reg_sqclr(m66592, ep->pipenum); | 972 | control_reg_sqclr(m66592, ep->pipenum); |
960 | 973 | ||
@@ -989,8 +1002,9 @@ static void set_feature(struct m66592 *m66592, struct usb_ctrlrequest *ctrl) | |||
989 | break; | 1002 | break; |
990 | case USB_RECIP_ENDPOINT: { | 1003 | case USB_RECIP_ENDPOINT: { |
991 | struct m66592_ep *ep; | 1004 | struct m66592_ep *ep; |
1005 | u16 w_index = le16_to_cpu(ctrl->wIndex); | ||
992 | 1006 | ||
993 | ep = m66592->epaddr2ep[ctrl->wIndex&USB_ENDPOINT_NUMBER_MASK]; | 1007 | ep = m66592->epaddr2ep[w_index & USB_ENDPOINT_NUMBER_MASK]; |
994 | pipe_stall(m66592, ep->pipenum); | 1008 | pipe_stall(m66592, ep->pipenum); |
995 | 1009 | ||
996 | control_end(m66592, 1); | 1010 | control_end(m66592, 1); |
@@ -1066,14 +1080,16 @@ static void irq_device_state(struct m66592 *m66592) | |||
1066 | } | 1080 | } |
1067 | if (m66592->old_dvsq == M66592_DS_CNFG && dvsq != M66592_DS_CNFG) | 1081 | if (m66592->old_dvsq == M66592_DS_CNFG && dvsq != M66592_DS_CNFG) |
1068 | m66592_update_usb_speed(m66592); | 1082 | m66592_update_usb_speed(m66592); |
1069 | if ((dvsq == M66592_DS_CNFG || dvsq == M66592_DS_ADDS) && | 1083 | if ((dvsq == M66592_DS_CNFG || dvsq == M66592_DS_ADDS) |
1070 | m66592->gadget.speed == USB_SPEED_UNKNOWN) | 1084 | && m66592->gadget.speed == USB_SPEED_UNKNOWN) |
1071 | m66592_update_usb_speed(m66592); | 1085 | m66592_update_usb_speed(m66592); |
1072 | 1086 | ||
1073 | m66592->old_dvsq = dvsq; | 1087 | m66592->old_dvsq = dvsq; |
1074 | } | 1088 | } |
1075 | 1089 | ||
1076 | static void irq_control_stage(struct m66592 *m66592) | 1090 | static void irq_control_stage(struct m66592 *m66592) |
1091 | __releases(m66592->lock) | ||
1092 | __acquires(m66592->lock) | ||
1077 | { | 1093 | { |
1078 | struct usb_ctrlrequest ctrl; | 1094 | struct usb_ctrlrequest ctrl; |
1079 | u16 ctsq; | 1095 | u16 ctsq; |
@@ -1095,8 +1111,10 @@ static void irq_control_stage(struct m66592 *m66592) | |||
1095 | case M66592_CS_WRDS: | 1111 | case M66592_CS_WRDS: |
1096 | case M66592_CS_WRND: | 1112 | case M66592_CS_WRND: |
1097 | if (setup_packet(m66592, &ctrl)) { | 1113 | if (setup_packet(m66592, &ctrl)) { |
1114 | spin_unlock(&m66592->lock); | ||
1098 | if (m66592->driver->setup(&m66592->gadget, &ctrl) < 0) | 1115 | if (m66592->driver->setup(&m66592->gadget, &ctrl) < 0) |
1099 | pipe_stall(m66592, 0); | 1116 | pipe_stall(m66592, 0); |
1117 | spin_lock(&m66592->lock); | ||
1100 | } | 1118 | } |
1101 | break; | 1119 | break; |
1102 | case M66592_CS_RDSS: | 1120 | case M66592_CS_RDSS: |
@@ -1119,6 +1137,8 @@ static irqreturn_t m66592_irq(int irq, void *_m66592) | |||
1119 | u16 savepipe; | 1137 | u16 savepipe; |
1120 | u16 mask0; | 1138 | u16 mask0; |
1121 | 1139 | ||
1140 | spin_lock(&m66592->lock); | ||
1141 | |||
1122 | intsts0 = m66592_read(m66592, M66592_INTSTS0); | 1142 | intsts0 = m66592_read(m66592, M66592_INTSTS0); |
1123 | intenb0 = m66592_read(m66592, M66592_INTENB0); | 1143 | intenb0 = m66592_read(m66592, M66592_INTENB0); |
1124 | 1144 | ||
@@ -1134,27 +1154,27 @@ static irqreturn_t m66592_irq(int irq, void *_m66592) | |||
1134 | bempenb = m66592_read(m66592, M66592_BEMPENB); | 1154 | bempenb = m66592_read(m66592, M66592_BEMPENB); |
1135 | 1155 | ||
1136 | if (mask0 & M66592_VBINT) { | 1156 | if (mask0 & M66592_VBINT) { |
1137 | m66592_write(m66592, (u16)~M66592_VBINT, | 1157 | m66592_write(m66592, 0xffff & ~M66592_VBINT, |
1138 | M66592_INTSTS0); | 1158 | M66592_INTSTS0); |
1139 | m66592_start_xclock(m66592); | 1159 | m66592_start_xclock(m66592); |
1140 | 1160 | ||
1141 | /* start vbus sampling */ | 1161 | /* start vbus sampling */ |
1142 | m66592->old_vbus = m66592_read(m66592, M66592_INTSTS0) | 1162 | m66592->old_vbus = m66592_read(m66592, M66592_INTSTS0) |
1143 | & M66592_VBSTS; | 1163 | & M66592_VBSTS; |
1144 | m66592->scount = M66592_MAX_SAMPLING; | 1164 | m66592->scount = M66592_MAX_SAMPLING; |
1145 | 1165 | ||
1146 | mod_timer(&m66592->timer, | 1166 | mod_timer(&m66592->timer, |
1147 | jiffies + msecs_to_jiffies(50)); | 1167 | jiffies + msecs_to_jiffies(50)); |
1148 | } | 1168 | } |
1149 | if (intsts0 & M66592_DVSQ) | 1169 | if (intsts0 & M66592_DVSQ) |
1150 | irq_device_state(m66592); | 1170 | irq_device_state(m66592); |
1151 | 1171 | ||
1152 | if ((intsts0 & M66592_BRDY) && (intenb0 & M66592_BRDYE) && | 1172 | if ((intsts0 & M66592_BRDY) && (intenb0 & M66592_BRDYE) |
1153 | (brdysts & brdyenb)) { | 1173 | && (brdysts & brdyenb)) { |
1154 | irq_pipe_ready(m66592, brdysts, brdyenb); | 1174 | irq_pipe_ready(m66592, brdysts, brdyenb); |
1155 | } | 1175 | } |
1156 | if ((intsts0 & M66592_BEMP) && (intenb0 & M66592_BEMPE) && | 1176 | if ((intsts0 & M66592_BEMP) && (intenb0 & M66592_BEMPE) |
1157 | (bempsts & bempenb)) { | 1177 | && (bempsts & bempenb)) { |
1158 | irq_pipe_empty(m66592, bempsts, bempenb); | 1178 | irq_pipe_empty(m66592, bempsts, bempenb); |
1159 | } | 1179 | } |
1160 | 1180 | ||
@@ -1164,6 +1184,7 @@ static irqreturn_t m66592_irq(int irq, void *_m66592) | |||
1164 | 1184 | ||
1165 | m66592_write(m66592, savepipe, M66592_CFIFOSEL); | 1185 | m66592_write(m66592, savepipe, M66592_CFIFOSEL); |
1166 | 1186 | ||
1187 | spin_unlock(&m66592->lock); | ||
1167 | return IRQ_HANDLED; | 1188 | return IRQ_HANDLED; |
1168 | } | 1189 | } |
1169 | 1190 | ||
@@ -1191,13 +1212,13 @@ static void m66592_timer(unsigned long _m66592) | |||
1191 | m66592_usb_disconnect(m66592); | 1212 | m66592_usb_disconnect(m66592); |
1192 | } else { | 1213 | } else { |
1193 | mod_timer(&m66592->timer, | 1214 | mod_timer(&m66592->timer, |
1194 | jiffies + msecs_to_jiffies(50)); | 1215 | jiffies + msecs_to_jiffies(50)); |
1195 | } | 1216 | } |
1196 | } else { | 1217 | } else { |
1197 | m66592->scount = M66592_MAX_SAMPLING; | 1218 | m66592->scount = M66592_MAX_SAMPLING; |
1198 | m66592->old_vbus = tmp; | 1219 | m66592->old_vbus = tmp; |
1199 | mod_timer(&m66592->timer, | 1220 | mod_timer(&m66592->timer, |
1200 | jiffies + msecs_to_jiffies(50)); | 1221 | jiffies + msecs_to_jiffies(50)); |
1201 | } | 1222 | } |
1202 | } | 1223 | } |
1203 | spin_unlock_irqrestore(&m66592->lock, flags); | 1224 | spin_unlock_irqrestore(&m66592->lock, flags); |
@@ -1278,7 +1299,7 @@ static int m66592_queue(struct usb_ep *_ep, struct usb_request *_req, | |||
1278 | req->req.actual = 0; | 1299 | req->req.actual = 0; |
1279 | req->req.status = -EINPROGRESS; | 1300 | req->req.status = -EINPROGRESS; |
1280 | 1301 | ||
1281 | if (ep->desc == 0) /* control */ | 1302 | if (ep->desc == NULL) /* control */ |
1282 | start_ep0(ep, req); | 1303 | start_ep0(ep, req); |
1283 | else { | 1304 | else { |
1284 | if (request && !ep->busy) | 1305 | if (request && !ep->busy) |
@@ -1335,11 +1356,6 @@ out: | |||
1335 | return ret; | 1356 | return ret; |
1336 | } | 1357 | } |
1337 | 1358 | ||
1338 | static int m66592_fifo_status(struct usb_ep *_ep) | ||
1339 | { | ||
1340 | return -EOPNOTSUPP; | ||
1341 | } | ||
1342 | |||
1343 | static void m66592_fifo_flush(struct usb_ep *_ep) | 1359 | static void m66592_fifo_flush(struct usb_ep *_ep) |
1344 | { | 1360 | { |
1345 | struct m66592_ep *ep; | 1361 | struct m66592_ep *ep; |
@@ -1365,7 +1381,6 @@ static struct usb_ep_ops m66592_ep_ops = { | |||
1365 | .dequeue = m66592_dequeue, | 1381 | .dequeue = m66592_dequeue, |
1366 | 1382 | ||
1367 | .set_halt = m66592_set_halt, | 1383 | .set_halt = m66592_set_halt, |
1368 | .fifo_status = m66592_fifo_status, | ||
1369 | .fifo_flush = m66592_fifo_flush, | 1384 | .fifo_flush = m66592_fifo_flush, |
1370 | }; | 1385 | }; |
1371 | 1386 | ||
@@ -1377,11 +1392,10 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1377 | struct m66592 *m66592 = the_controller; | 1392 | struct m66592 *m66592 = the_controller; |
1378 | int retval; | 1393 | int retval; |
1379 | 1394 | ||
1380 | if (!driver || | 1395 | if (!driver |
1381 | driver->speed != USB_SPEED_HIGH || | 1396 | || driver->speed != USB_SPEED_HIGH |
1382 | !driver->bind || | 1397 | || !driver->bind |
1383 | !driver->unbind || | 1398 | || !driver->setup) |
1384 | !driver->setup) | ||
1385 | return -EINVAL; | 1399 | return -EINVAL; |
1386 | if (!m66592) | 1400 | if (!m66592) |
1387 | return -ENODEV; | 1401 | return -ENODEV; |
@@ -1413,8 +1427,7 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver) | |||
1413 | m66592->old_vbus = m66592_read(m66592, | 1427 | m66592->old_vbus = m66592_read(m66592, |
1414 | M66592_INTSTS0) & M66592_VBSTS; | 1428 | M66592_INTSTS0) & M66592_VBSTS; |
1415 | m66592->scount = M66592_MAX_SAMPLING; | 1429 | m66592->scount = M66592_MAX_SAMPLING; |
1416 | mod_timer(&m66592->timer, | 1430 | mod_timer(&m66592->timer, jiffies + msecs_to_jiffies(50)); |
1417 | jiffies + msecs_to_jiffies(50)); | ||
1418 | } | 1431 | } |
1419 | 1432 | ||
1420 | return 0; | 1433 | return 0; |
@@ -1432,6 +1445,9 @@ int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | |||
1432 | struct m66592 *m66592 = the_controller; | 1445 | struct m66592 *m66592 = the_controller; |
1433 | unsigned long flags; | 1446 | unsigned long flags; |
1434 | 1447 | ||
1448 | if (driver != m66592->driver || !driver->unbind) | ||
1449 | return -EINVAL; | ||
1450 | |||
1435 | spin_lock_irqsave(&m66592->lock, flags); | 1451 | spin_lock_irqsave(&m66592->lock, flags); |
1436 | if (m66592->gadget.speed != USB_SPEED_UNKNOWN) | 1452 | if (m66592->gadget.speed != USB_SPEED_UNKNOWN) |
1437 | m66592_usb_disconnect(m66592); | 1453 | m66592_usb_disconnect(m66592); |
@@ -1461,46 +1477,35 @@ static struct usb_gadget_ops m66592_gadget_ops = { | |||
1461 | .get_frame = m66592_get_frame, | 1477 | .get_frame = m66592_get_frame, |
1462 | }; | 1478 | }; |
1463 | 1479 | ||
1464 | #if defined(CONFIG_PM) | 1480 | static int __exit m66592_remove(struct platform_device *pdev) |
1465 | static int m66592_suspend(struct platform_device *pdev, pm_message_t state) | ||
1466 | { | ||
1467 | pdev->dev.power.power_state = state; | ||
1468 | return 0; | ||
1469 | } | ||
1470 | |||
1471 | static int m66592_resume(struct platform_device *pdev) | ||
1472 | { | ||
1473 | pdev->dev.power.power_state = PMSG_ON; | ||
1474 | return 0; | ||
1475 | } | ||
1476 | #else /* if defined(CONFIG_PM) */ | ||
1477 | #define m66592_suspend NULL | ||
1478 | #define m66592_resume NULL | ||
1479 | #endif | ||
1480 | |||
1481 | static int __init_or_module m66592_remove(struct platform_device *pdev) | ||
1482 | { | 1481 | { |
1483 | struct m66592 *m66592 = dev_get_drvdata(&pdev->dev); | 1482 | struct m66592 *m66592 = dev_get_drvdata(&pdev->dev); |
1484 | 1483 | ||
1485 | del_timer_sync(&m66592->timer); | 1484 | del_timer_sync(&m66592->timer); |
1486 | iounmap(m66592->reg); | 1485 | iounmap(m66592->reg); |
1487 | free_irq(platform_get_irq(pdev, 0), m66592); | 1486 | free_irq(platform_get_irq(pdev, 0), m66592); |
1487 | m66592_free_request(&m66592->ep[0].ep, m66592->ep0_req); | ||
1488 | kfree(m66592); | 1488 | kfree(m66592); |
1489 | return 0; | 1489 | return 0; |
1490 | } | 1490 | } |
1491 | 1491 | ||
1492 | static void nop_completion(struct usb_ep *ep, struct usb_request *r) | ||
1493 | { | ||
1494 | } | ||
1495 | |||
1492 | #define resource_len(r) (((r)->end - (r)->start) + 1) | 1496 | #define resource_len(r) (((r)->end - (r)->start) + 1) |
1497 | |||
1493 | static int __init m66592_probe(struct platform_device *pdev) | 1498 | static int __init m66592_probe(struct platform_device *pdev) |
1494 | { | 1499 | { |
1495 | struct resource *res = NULL; | 1500 | struct resource *res; |
1496 | int irq = -1; | 1501 | int irq; |
1497 | void __iomem *reg = NULL; | 1502 | void __iomem *reg = NULL; |
1498 | struct m66592 *m66592 = NULL; | 1503 | struct m66592 *m66592 = NULL; |
1499 | int ret = 0; | 1504 | int ret = 0; |
1500 | int i; | 1505 | int i; |
1501 | 1506 | ||
1502 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, | 1507 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, |
1503 | (char *)udc_name); | 1508 | (char *)udc_name); |
1504 | if (!res) { | 1509 | if (!res) { |
1505 | ret = -ENODEV; | 1510 | ret = -ENODEV; |
1506 | printk(KERN_ERR "platform_get_resource_byname error.\n"); | 1511 | printk(KERN_ERR "platform_get_resource_byname error.\n"); |
@@ -1548,7 +1553,7 @@ static int __init m66592_probe(struct platform_device *pdev) | |||
1548 | m66592->bi_bufnum = M66592_BASE_BUFNUM; | 1553 | m66592->bi_bufnum = M66592_BASE_BUFNUM; |
1549 | 1554 | ||
1550 | ret = request_irq(irq, m66592_irq, IRQF_DISABLED | IRQF_SHARED, | 1555 | ret = request_irq(irq, m66592_irq, IRQF_DISABLED | IRQF_SHARED, |
1551 | udc_name, m66592); | 1556 | udc_name, m66592); |
1552 | if (ret < 0) { | 1557 | if (ret < 0) { |
1553 | printk(KERN_ERR "request_irq error (%d)\n", ret); | 1558 | printk(KERN_ERR "request_irq error (%d)\n", ret); |
1554 | goto clean_up; | 1559 | goto clean_up; |
@@ -1563,7 +1568,7 @@ static int __init m66592_probe(struct platform_device *pdev) | |||
1563 | if (i != 0) { | 1568 | if (i != 0) { |
1564 | INIT_LIST_HEAD(&m66592->ep[i].ep.ep_list); | 1569 | INIT_LIST_HEAD(&m66592->ep[i].ep.ep_list); |
1565 | list_add_tail(&m66592->ep[i].ep.ep_list, | 1570 | list_add_tail(&m66592->ep[i].ep.ep_list, |
1566 | &m66592->gadget.ep_list); | 1571 | &m66592->gadget.ep_list); |
1567 | } | 1572 | } |
1568 | ep->m66592 = m66592; | 1573 | ep->m66592 = m66592; |
1569 | INIT_LIST_HEAD(&ep->queue); | 1574 | INIT_LIST_HEAD(&ep->queue); |
@@ -1583,20 +1588,18 @@ static int __init m66592_probe(struct platform_device *pdev) | |||
1583 | 1588 | ||
1584 | the_controller = m66592; | 1589 | the_controller = m66592; |
1585 | 1590 | ||
1586 | /* AV: leaks */ | ||
1587 | m66592->ep0_req = m66592_alloc_request(&m66592->ep[0].ep, GFP_KERNEL); | 1591 | m66592->ep0_req = m66592_alloc_request(&m66592->ep[0].ep, GFP_KERNEL); |
1588 | if (m66592->ep0_req == NULL) | 1592 | if (m66592->ep0_req == NULL) |
1589 | goto clean_up; | 1593 | goto clean_up2; |
1590 | /* AV: leaks, and do we really need it separately allocated? */ | 1594 | m66592->ep0_req->complete = nop_completion; |
1591 | m66592->ep0_buf = kzalloc(2, GFP_KERNEL); | ||
1592 | if (m66592->ep0_buf == NULL) | ||
1593 | goto clean_up; | ||
1594 | 1595 | ||
1595 | init_controller(m66592); | 1596 | init_controller(m66592); |
1596 | 1597 | ||
1597 | printk("driver %s, %s\n", udc_name, DRIVER_VERSION); | 1598 | dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); |
1598 | return 0; | 1599 | return 0; |
1599 | 1600 | ||
1601 | clean_up2: | ||
1602 | free_irq(irq, m66592); | ||
1600 | clean_up: | 1603 | clean_up: |
1601 | if (m66592) { | 1604 | if (m66592) { |
1602 | if (m66592->ep0_req) | 1605 | if (m66592->ep0_req) |
@@ -1611,10 +1614,7 @@ clean_up: | |||
1611 | 1614 | ||
1612 | /*-------------------------------------------------------------------------*/ | 1615 | /*-------------------------------------------------------------------------*/ |
1613 | static struct platform_driver m66592_driver = { | 1616 | static struct platform_driver m66592_driver = { |
1614 | .probe = m66592_probe, | 1617 | .remove = __exit_p(m66592_remove), |
1615 | .remove = m66592_remove, | ||
1616 | .suspend = m66592_suspend, | ||
1617 | .resume = m66592_resume, | ||
1618 | .driver = { | 1618 | .driver = { |
1619 | .name = (char *) udc_name, | 1619 | .name = (char *) udc_name, |
1620 | }, | 1620 | }, |
@@ -1622,7 +1622,7 @@ static struct platform_driver m66592_driver = { | |||
1622 | 1622 | ||
1623 | static int __init m66592_udc_init(void) | 1623 | static int __init m66592_udc_init(void) |
1624 | { | 1624 | { |
1625 | return platform_driver_register(&m66592_driver); | 1625 | return platform_driver_probe(&m66592_driver, m66592_probe); |
1626 | } | 1626 | } |
1627 | module_init(m66592_udc_init); | 1627 | module_init(m66592_udc_init); |
1628 | 1628 | ||
@@ -1631,4 +1631,3 @@ static void __exit m66592_udc_cleanup(void) | |||
1631 | platform_driver_unregister(&m66592_driver); | 1631 | platform_driver_unregister(&m66592_driver); |
1632 | } | 1632 | } |
1633 | module_exit(m66592_udc_cleanup); | 1633 | module_exit(m66592_udc_cleanup); |
1634 | |||
diff --git a/drivers/usb/gadget/m66592-udc.h b/drivers/usb/gadget/m66592-udc.h index 26b54f8b894..bfa0c645f22 100644 --- a/drivers/usb/gadget/m66592-udc.h +++ b/drivers/usb/gadget/m66592-udc.h | |||
@@ -24,73 +24,73 @@ | |||
24 | #define __M66592_UDC_H__ | 24 | #define __M66592_UDC_H__ |
25 | 25 | ||
26 | #define M66592_SYSCFG 0x00 | 26 | #define M66592_SYSCFG 0x00 |
27 | #define M66592_XTAL 0xC000 /* b15-14: Crystal selection */ | 27 | #define M66592_XTAL 0xC000 /* b15-14: Crystal selection */ |
28 | #define M66592_XTAL48 0x8000 /* 48MHz */ | 28 | #define M66592_XTAL48 0x8000 /* 48MHz */ |
29 | #define M66592_XTAL24 0x4000 /* 24MHz */ | 29 | #define M66592_XTAL24 0x4000 /* 24MHz */ |
30 | #define M66592_XTAL12 0x0000 /* 12MHz */ | 30 | #define M66592_XTAL12 0x0000 /* 12MHz */ |
31 | #define M66592_XCKE 0x2000 /* b13: External clock enable */ | 31 | #define M66592_XCKE 0x2000 /* b13: External clock enable */ |
32 | #define M66592_RCKE 0x1000 /* b12: Register clock enable */ | 32 | #define M66592_RCKE 0x1000 /* b12: Register clock enable */ |
33 | #define M66592_PLLC 0x0800 /* b11: PLL control */ | 33 | #define M66592_PLLC 0x0800 /* b11: PLL control */ |
34 | #define M66592_SCKE 0x0400 /* b10: USB clock enable */ | 34 | #define M66592_SCKE 0x0400 /* b10: USB clock enable */ |
35 | #define M66592_ATCKM 0x0100 /* b8: Automatic supply functional enable */ | 35 | #define M66592_ATCKM 0x0100 /* b8: Automatic clock supply */ |
36 | #define M66592_HSE 0x0080 /* b7: Hi-speed enable */ | 36 | #define M66592_HSE 0x0080 /* b7: Hi-speed enable */ |
37 | #define M66592_DCFM 0x0040 /* b6: Controller function select */ | 37 | #define M66592_DCFM 0x0040 /* b6: Controller function select */ |
38 | #define M66592_DMRPD 0x0020 /* b5: D- pull down control */ | 38 | #define M66592_DMRPD 0x0020 /* b5: D- pull down control */ |
39 | #define M66592_DPRPU 0x0010 /* b4: D+ pull up control */ | 39 | #define M66592_DPRPU 0x0010 /* b4: D+ pull up control */ |
40 | #define M66592_FSRPC 0x0004 /* b2: Full-speed receiver enable */ | 40 | #define M66592_FSRPC 0x0004 /* b2: Full-speed receiver enable */ |
41 | #define M66592_PCUT 0x0002 /* b1: Low power sleep enable */ | 41 | #define M66592_PCUT 0x0002 /* b1: Low power sleep enable */ |
42 | #define M66592_USBE 0x0001 /* b0: USB module operation enable */ | 42 | #define M66592_USBE 0x0001 /* b0: USB module operation enable */ |
43 | 43 | ||
44 | #define M66592_SYSSTS 0x02 | 44 | #define M66592_SYSSTS 0x02 |
45 | #define M66592_LNST 0x0003 /* b1-0: D+, D- line status */ | 45 | #define M66592_LNST 0x0003 /* b1-0: D+, D- line status */ |
46 | #define M66592_SE1 0x0003 /* SE1 */ | 46 | #define M66592_SE1 0x0003 /* SE1 */ |
47 | #define M66592_KSTS 0x0002 /* K State */ | 47 | #define M66592_KSTS 0x0002 /* K State */ |
48 | #define M66592_JSTS 0x0001 /* J State */ | 48 | #define M66592_JSTS 0x0001 /* J State */ |
49 | #define M66592_SE0 0x0000 /* SE0 */ | 49 | #define M66592_SE0 0x0000 /* SE0 */ |
50 | 50 | ||
51 | #define M66592_DVSTCTR 0x04 | 51 | #define M66592_DVSTCTR 0x04 |
52 | #define M66592_WKUP 0x0100 /* b8: Remote wakeup */ | 52 | #define M66592_WKUP 0x0100 /* b8: Remote wakeup */ |
53 | #define M66592_RWUPE 0x0080 /* b7: Remote wakeup sense */ | 53 | #define M66592_RWUPE 0x0080 /* b7: Remote wakeup sense */ |
54 | #define M66592_USBRST 0x0040 /* b6: USB reset enable */ | 54 | #define M66592_USBRST 0x0040 /* b6: USB reset enable */ |
55 | #define M66592_RESUME 0x0020 /* b5: Resume enable */ | 55 | #define M66592_RESUME 0x0020 /* b5: Resume enable */ |
56 | #define M66592_UACT 0x0010 /* b4: USB bus enable */ | 56 | #define M66592_UACT 0x0010 /* b4: USB bus enable */ |
57 | #define M66592_RHST 0x0003 /* b1-0: Reset handshake status */ | 57 | #define M66592_RHST 0x0003 /* b1-0: Reset handshake status */ |
58 | #define M66592_HSMODE 0x0003 /* Hi-Speed mode */ | 58 | #define M66592_HSMODE 0x0003 /* Hi-Speed mode */ |
59 | #define M66592_FSMODE 0x0002 /* Full-Speed mode */ | 59 | #define M66592_FSMODE 0x0002 /* Full-Speed mode */ |
60 | #define M66592_HSPROC 0x0001 /* HS handshake is processing */ | 60 | #define M66592_HSPROC 0x0001 /* HS handshake is processing */ |
61 | 61 | ||
62 | #define M66592_TESTMODE 0x06 | 62 | #define M66592_TESTMODE 0x06 |
63 | #define M66592_UTST 0x000F /* b4-0: Test select */ | 63 | #define M66592_UTST 0x000F /* b4-0: Test select */ |
64 | #define M66592_H_TST_PACKET 0x000C /* HOST TEST Packet */ | 64 | #define M66592_H_TST_PACKET 0x000C /* HOST TEST Packet */ |
65 | #define M66592_H_TST_SE0_NAK 0x000B /* HOST TEST SE0 NAK */ | 65 | #define M66592_H_TST_SE0_NAK 0x000B /* HOST TEST SE0 NAK */ |
66 | #define M66592_H_TST_K 0x000A /* HOST TEST K */ | 66 | #define M66592_H_TST_K 0x000A /* HOST TEST K */ |
67 | #define M66592_H_TST_J 0x0009 /* HOST TEST J */ | 67 | #define M66592_H_TST_J 0x0009 /* HOST TEST J */ |
68 | #define M66592_H_TST_NORMAL 0x0000 /* HOST Normal Mode */ | 68 | #define M66592_H_TST_NORMAL 0x0000 /* HOST Normal Mode */ |
69 | #define M66592_P_TST_PACKET 0x0004 /* PERI TEST Packet */ | 69 | #define M66592_P_TST_PACKET 0x0004 /* PERI TEST Packet */ |
70 | #define M66592_P_TST_SE0_NAK 0x0003 /* PERI TEST SE0 NAK */ | 70 | #define M66592_P_TST_SE0_NAK 0x0003 /* PERI TEST SE0 NAK */ |
71 | #define M66592_P_TST_K 0x0002 /* PERI TEST K */ | 71 | #define M66592_P_TST_K 0x0002 /* PERI TEST K */ |
72 | #define M66592_P_TST_J 0x0001 /* PERI TEST J */ | 72 | #define M66592_P_TST_J 0x0001 /* PERI TEST J */ |
73 | #define M66592_P_TST_NORMAL 0x0000 /* PERI Normal Mode */ | 73 | #define M66592_P_TST_NORMAL 0x0000 /* PERI Normal Mode */ |
74 | 74 | ||
75 | #define M66592_PINCFG 0x0A | 75 | #define M66592_PINCFG 0x0A |
76 | #define M66592_LDRV 0x8000 /* b15: Drive Current Adjust */ | 76 | #define M66592_LDRV 0x8000 /* b15: Drive Current Adjust */ |
77 | #define M66592_BIGEND 0x0100 /* b8: Big endian mode */ | 77 | #define M66592_BIGEND 0x0100 /* b8: Big endian mode */ |
78 | 78 | ||
79 | #define M66592_DMA0CFG 0x0C | 79 | #define M66592_DMA0CFG 0x0C |
80 | #define M66592_DMA1CFG 0x0E | 80 | #define M66592_DMA1CFG 0x0E |
81 | #define M66592_DREQA 0x4000 /* b14: Dreq active select */ | 81 | #define M66592_DREQA 0x4000 /* b14: Dreq active select */ |
82 | #define M66592_BURST 0x2000 /* b13: Burst mode */ | 82 | #define M66592_BURST 0x2000 /* b13: Burst mode */ |
83 | #define M66592_DACKA 0x0400 /* b10: Dack active select */ | 83 | #define M66592_DACKA 0x0400 /* b10: Dack active select */ |
84 | #define M66592_DFORM 0x0380 /* b9-7: DMA mode select */ | 84 | #define M66592_DFORM 0x0380 /* b9-7: DMA mode select */ |
85 | #define M66592_CPU_ADR_RD_WR 0x0000 /* Address + RD/WR mode (CPU bus) */ | 85 | #define M66592_CPU_ADR_RD_WR 0x0000 /* Address + RD/WR mode (CPU bus) */ |
86 | #define M66592_CPU_DACK_RD_WR 0x0100 /* DACK + RD/WR mode (CPU bus) */ | 86 | #define M66592_CPU_DACK_RD_WR 0x0100 /* DACK + RD/WR mode (CPU bus) */ |
87 | #define M66592_CPU_DACK_ONLY 0x0180 /* DACK only mode (CPU bus) */ | 87 | #define M66592_CPU_DACK_ONLY 0x0180 /* DACK only mode (CPU bus) */ |
88 | #define M66592_SPLIT_DACK_ONLY 0x0200 /* DACK only mode (SPLIT bus) */ | 88 | #define M66592_SPLIT_DACK_ONLY 0x0200 /* DACK only mode (SPLIT bus) */ |
89 | #define M66592_SPLIT_DACK_DSTB 0x0300 /* DACK + DSTB0 mode (SPLIT bus) */ | 89 | #define M66592_SPLIT_DACK_DSTB 0x0300 /* DACK + DSTB0 mode (SPLIT bus) */ |
90 | #define M66592_DENDA 0x0040 /* b6: Dend active select */ | 90 | #define M66592_DENDA 0x0040 /* b6: Dend active select */ |
91 | #define M66592_PKTM 0x0020 /* b5: Packet mode */ | 91 | #define M66592_PKTM 0x0020 /* b5: Packet mode */ |
92 | #define M66592_DENDE 0x0010 /* b4: Dend enable */ | 92 | #define M66592_DENDE 0x0010 /* b4: Dend enable */ |
93 | #define M66592_OBUS 0x0004 /* b2: OUTbus mode */ | 93 | #define M66592_OBUS 0x0004 /* b2: OUTbus mode */ |
94 | 94 | ||
95 | #define M66592_CFIFO 0x10 | 95 | #define M66592_CFIFO 0x10 |
96 | #define M66592_D0FIFO 0x14 | 96 | #define M66592_D0FIFO 0x14 |
@@ -99,300 +99,300 @@ | |||
99 | #define M66592_CFIFOSEL 0x1E | 99 | #define M66592_CFIFOSEL 0x1E |
100 | #define M66592_D0FIFOSEL 0x24 | 100 | #define M66592_D0FIFOSEL 0x24 |
101 | #define M66592_D1FIFOSEL 0x2A | 101 | #define M66592_D1FIFOSEL 0x2A |
102 | #define M66592_RCNT 0x8000 /* b15: Read count mode */ | 102 | #define M66592_RCNT 0x8000 /* b15: Read count mode */ |
103 | #define M66592_REW 0x4000 /* b14: Buffer rewind */ | 103 | #define M66592_REW 0x4000 /* b14: Buffer rewind */ |
104 | #define M66592_DCLRM 0x2000 /* b13: DMA buffer clear mode */ | 104 | #define M66592_DCLRM 0x2000 /* b13: DMA buffer clear mode */ |
105 | #define M66592_DREQE 0x1000 /* b12: DREQ output enable */ | 105 | #define M66592_DREQE 0x1000 /* b12: DREQ output enable */ |
106 | #define M66592_MBW 0x0400 /* b10: Maximum bit width for FIFO access */ | 106 | #define M66592_MBW 0x0400 /* b10: Maximum bit width for FIFO */ |
107 | #define M66592_MBW_8 0x0000 /* 8bit */ | 107 | #define M66592_MBW_8 0x0000 /* 8bit */ |
108 | #define M66592_MBW_16 0x0400 /* 16bit */ | 108 | #define M66592_MBW_16 0x0400 /* 16bit */ |
109 | #define M66592_TRENB 0x0200 /* b9: Transaction counter enable */ | 109 | #define M66592_TRENB 0x0200 /* b9: Transaction counter enable */ |
110 | #define M66592_TRCLR 0x0100 /* b8: Transaction counter clear */ | 110 | #define M66592_TRCLR 0x0100 /* b8: Transaction counter clear */ |
111 | #define M66592_DEZPM 0x0080 /* b7: Zero-length packet additional mode */ | 111 | #define M66592_DEZPM 0x0080 /* b7: Zero-length packet mode */ |
112 | #define M66592_ISEL 0x0020 /* b5: DCP FIFO port direction select */ | 112 | #define M66592_ISEL 0x0020 /* b5: DCP FIFO port direction select */ |
113 | #define M66592_CURPIPE 0x0007 /* b2-0: PIPE select */ | 113 | #define M66592_CURPIPE 0x0007 /* b2-0: PIPE select */ |
114 | 114 | ||
115 | #define M66592_CFIFOCTR 0x20 | 115 | #define M66592_CFIFOCTR 0x20 |
116 | #define M66592_D0FIFOCTR 0x26 | 116 | #define M66592_D0FIFOCTR 0x26 |
117 | #define M66592_D1FIFOCTR 0x2c | 117 | #define M66592_D1FIFOCTR 0x2c |
118 | #define M66592_BVAL 0x8000 /* b15: Buffer valid flag */ | 118 | #define M66592_BVAL 0x8000 /* b15: Buffer valid flag */ |
119 | #define M66592_BCLR 0x4000 /* b14: Buffer clear */ | 119 | #define M66592_BCLR 0x4000 /* b14: Buffer clear */ |
120 | #define M66592_FRDY 0x2000 /* b13: FIFO ready */ | 120 | #define M66592_FRDY 0x2000 /* b13: FIFO ready */ |
121 | #define M66592_DTLN 0x0FFF /* b11-0: FIFO received data length */ | 121 | #define M66592_DTLN 0x0FFF /* b11-0: FIFO received data length */ |
122 | 122 | ||
123 | #define M66592_CFIFOSIE 0x22 | 123 | #define M66592_CFIFOSIE 0x22 |
124 | #define M66592_TGL 0x8000 /* b15: Buffer toggle */ | 124 | #define M66592_TGL 0x8000 /* b15: Buffer toggle */ |
125 | #define M66592_SCLR 0x4000 /* b14: Buffer clear */ | 125 | #define M66592_SCLR 0x4000 /* b14: Buffer clear */ |
126 | #define M66592_SBUSY 0x2000 /* b13: SIE_FIFO busy */ | 126 | #define M66592_SBUSY 0x2000 /* b13: SIE_FIFO busy */ |
127 | 127 | ||
128 | #define M66592_D0FIFOTRN 0x28 | 128 | #define M66592_D0FIFOTRN 0x28 |
129 | #define M66592_D1FIFOTRN 0x2E | 129 | #define M66592_D1FIFOTRN 0x2E |
130 | #define M66592_TRNCNT 0xFFFF /* b15-0: Transaction counter */ | 130 | #define M66592_TRNCNT 0xFFFF /* b15-0: Transaction counter */ |
131 | 131 | ||
132 | #define M66592_INTENB0 0x30 | 132 | #define M66592_INTENB0 0x30 |
133 | #define M66592_VBSE 0x8000 /* b15: VBUS interrupt */ | 133 | #define M66592_VBSE 0x8000 /* b15: VBUS interrupt */ |
134 | #define M66592_RSME 0x4000 /* b14: Resume interrupt */ | 134 | #define M66592_RSME 0x4000 /* b14: Resume interrupt */ |
135 | #define M66592_SOFE 0x2000 /* b13: Frame update interrupt */ | 135 | #define M66592_SOFE 0x2000 /* b13: Frame update interrupt */ |
136 | #define M66592_DVSE 0x1000 /* b12: Device state transition interrupt */ | 136 | #define M66592_DVSE 0x1000 /* b12: Device state transition interrupt */ |
137 | #define M66592_CTRE 0x0800 /* b11: Control transfer stage transition interrupt */ | 137 | #define M66592_CTRE 0x0800 /* b11: Control transfer stage transition irq */ |
138 | #define M66592_BEMPE 0x0400 /* b10: Buffer empty interrupt */ | 138 | #define M66592_BEMPE 0x0400 /* b10: Buffer empty interrupt */ |
139 | #define M66592_NRDYE 0x0200 /* b9: Buffer not ready interrupt */ | 139 | #define M66592_NRDYE 0x0200 /* b9: Buffer not ready interrupt */ |
140 | #define M66592_BRDYE 0x0100 /* b8: Buffer ready interrupt */ | 140 | #define M66592_BRDYE 0x0100 /* b8: Buffer ready interrupt */ |
141 | #define M66592_URST 0x0080 /* b7: USB reset detected interrupt */ | 141 | #define M66592_URST 0x0080 /* b7: USB reset detected interrupt */ |
142 | #define M66592_SADR 0x0040 /* b6: Set address executed interrupt */ | 142 | #define M66592_SADR 0x0040 /* b6: Set address executed interrupt */ |
143 | #define M66592_SCFG 0x0020 /* b5: Set configuration executed interrupt */ | 143 | #define M66592_SCFG 0x0020 /* b5: Set configuration executed interrupt */ |
144 | #define M66592_SUSP 0x0010 /* b4: Suspend detected interrupt */ | 144 | #define M66592_SUSP 0x0010 /* b4: Suspend detected interrupt */ |
145 | #define M66592_WDST 0x0008 /* b3: Control write data stage completed interrupt */ | 145 | #define M66592_WDST 0x0008 /* b3: Control write data stage completed irq */ |
146 | #define M66592_RDST 0x0004 /* b2: Control read data stage completed interrupt */ | 146 | #define M66592_RDST 0x0004 /* b2: Control read data stage completed irq */ |
147 | #define M66592_CMPL 0x0002 /* b1: Control transfer complete interrupt */ | 147 | #define M66592_CMPL 0x0002 /* b1: Control transfer complete interrupt */ |
148 | #define M66592_SERR 0x0001 /* b0: Sequence error interrupt */ | 148 | #define M66592_SERR 0x0001 /* b0: Sequence error interrupt */ |
149 | 149 | ||
150 | #define M66592_INTENB1 0x32 | 150 | #define M66592_INTENB1 0x32 |
151 | #define M66592_BCHGE 0x4000 /* b14: USB us chenge interrupt */ | 151 | #define M66592_BCHGE 0x4000 /* b14: USB us chenge interrupt */ |
152 | #define M66592_DTCHE 0x1000 /* b12: Detach sense interrupt */ | 152 | #define M66592_DTCHE 0x1000 /* b12: Detach sense interrupt */ |
153 | #define M66592_SIGNE 0x0020 /* b5: SETUP IGNORE interrupt */ | 153 | #define M66592_SIGNE 0x0020 /* b5: SETUP IGNORE interrupt */ |
154 | #define M66592_SACKE 0x0010 /* b4: SETUP ACK interrupt */ | 154 | #define M66592_SACKE 0x0010 /* b4: SETUP ACK interrupt */ |
155 | #define M66592_BRDYM 0x0004 /* b2: BRDY clear timing */ | 155 | #define M66592_BRDYM 0x0004 /* b2: BRDY clear timing */ |
156 | #define M66592_INTL 0x0002 /* b1: Interrupt sense select */ | 156 | #define M66592_INTL 0x0002 /* b1: Interrupt sense select */ |
157 | #define M66592_PCSE 0x0001 /* b0: PCUT enable by CS assert */ | 157 | #define M66592_PCSE 0x0001 /* b0: PCUT enable by CS assert */ |
158 | 158 | ||
159 | #define M66592_BRDYENB 0x36 | 159 | #define M66592_BRDYENB 0x36 |
160 | #define M66592_BRDYSTS 0x46 | 160 | #define M66592_BRDYSTS 0x46 |
161 | #define M66592_BRDY7 0x0080 /* b7: PIPE7 */ | 161 | #define M66592_BRDY7 0x0080 /* b7: PIPE7 */ |
162 | #define M66592_BRDY6 0x0040 /* b6: PIPE6 */ | 162 | #define M66592_BRDY6 0x0040 /* b6: PIPE6 */ |
163 | #define M66592_BRDY5 0x0020 /* b5: PIPE5 */ | 163 | #define M66592_BRDY5 0x0020 /* b5: PIPE5 */ |
164 | #define M66592_BRDY4 0x0010 /* b4: PIPE4 */ | 164 | #define M66592_BRDY4 0x0010 /* b4: PIPE4 */ |
165 | #define M66592_BRDY3 0x0008 /* b3: PIPE3 */ | 165 | #define M66592_BRDY3 0x0008 /* b3: PIPE3 */ |
166 | #define M66592_BRDY2 0x0004 /* b2: PIPE2 */ | 166 | #define M66592_BRDY2 0x0004 /* b2: PIPE2 */ |
167 | #define M66592_BRDY1 0x0002 /* b1: PIPE1 */ | 167 | #define M66592_BRDY1 0x0002 /* b1: PIPE1 */ |
168 | #define M66592_BRDY0 0x0001 /* b1: PIPE0 */ | 168 | #define M66592_BRDY0 0x0001 /* b1: PIPE0 */ |
169 | 169 | ||
170 | #define M66592_NRDYENB 0x38 | 170 | #define M66592_NRDYENB 0x38 |
171 | #define M66592_NRDYSTS 0x48 | 171 | #define M66592_NRDYSTS 0x48 |
172 | #define M66592_NRDY7 0x0080 /* b7: PIPE7 */ | 172 | #define M66592_NRDY7 0x0080 /* b7: PIPE7 */ |
173 | #define M66592_NRDY6 0x0040 /* b6: PIPE6 */ | 173 | #define M66592_NRDY6 0x0040 /* b6: PIPE6 */ |
174 | #define M66592_NRDY5 0x0020 /* b5: PIPE5 */ | 174 | #define M66592_NRDY5 0x0020 /* b5: PIPE5 */ |
175 | #define M66592_NRDY4 0x0010 /* b4: PIPE4 */ | 175 | #define M66592_NRDY4 0x0010 /* b4: PIPE4 */ |
176 | #define M66592_NRDY3 0x0008 /* b3: PIPE3 */ | 176 | #define M66592_NRDY3 0x0008 /* b3: PIPE3 */ |
177 | #define M66592_NRDY2 0x0004 /* b2: PIPE2 */ | 177 | #define M66592_NRDY2 0x0004 /* b2: PIPE2 */ |
178 | #define M66592_NRDY1 0x0002 /* b1: PIPE1 */ | 178 | #define M66592_NRDY1 0x0002 /* b1: PIPE1 */ |
179 | #define M66592_NRDY0 0x0001 /* b1: PIPE0 */ | 179 | #define M66592_NRDY0 0x0001 /* b1: PIPE0 */ |
180 | 180 | ||
181 | #define M66592_BEMPENB 0x3A | 181 | #define M66592_BEMPENB 0x3A |
182 | #define M66592_BEMPSTS 0x4A | 182 | #define M66592_BEMPSTS 0x4A |
183 | #define M66592_BEMP7 0x0080 /* b7: PIPE7 */ | 183 | #define M66592_BEMP7 0x0080 /* b7: PIPE7 */ |
184 | #define M66592_BEMP6 0x0040 /* b6: PIPE6 */ | 184 | #define M66592_BEMP6 0x0040 /* b6: PIPE6 */ |
185 | #define M66592_BEMP5 0x0020 /* b5: PIPE5 */ | 185 | #define M66592_BEMP5 0x0020 /* b5: PIPE5 */ |
186 | #define M66592_BEMP4 0x0010 /* b4: PIPE4 */ | 186 | #define M66592_BEMP4 0x0010 /* b4: PIPE4 */ |
187 | #define M66592_BEMP3 0x0008 /* b3: PIPE3 */ | 187 | #define M66592_BEMP3 0x0008 /* b3: PIPE3 */ |
188 | #define M66592_BEMP2 0x0004 /* b2: PIPE2 */ | 188 | #define M66592_BEMP2 0x0004 /* b2: PIPE2 */ |
189 | #define M66592_BEMP1 0x0002 /* b1: PIPE1 */ | 189 | #define M66592_BEMP1 0x0002 /* b1: PIPE1 */ |
190 | #define M66592_BEMP0 0x0001 /* b0: PIPE0 */ | 190 | #define M66592_BEMP0 0x0001 /* b0: PIPE0 */ |
191 | 191 | ||
192 | #define M66592_SOFCFG 0x3C | 192 | #define M66592_SOFCFG 0x3C |
193 | #define M66592_SOFM 0x000C /* b3-2: SOF palse mode */ | 193 | #define M66592_SOFM 0x000C /* b3-2: SOF palse mode */ |
194 | #define M66592_SOF_125US 0x0008 /* SOF OUT 125us uFrame Signal */ | 194 | #define M66592_SOF_125US 0x0008 /* SOF OUT 125us uFrame Signal */ |
195 | #define M66592_SOF_1MS 0x0004 /* SOF OUT 1ms Frame Signal */ | 195 | #define M66592_SOF_1MS 0x0004 /* SOF OUT 1ms Frame Signal */ |
196 | #define M66592_SOF_DISABLE 0x0000 /* SOF OUT Disable */ | 196 | #define M66592_SOF_DISABLE 0x0000 /* SOF OUT Disable */ |
197 | 197 | ||
198 | #define M66592_INTSTS0 0x40 | 198 | #define M66592_INTSTS0 0x40 |
199 | #define M66592_VBINT 0x8000 /* b15: VBUS interrupt */ | 199 | #define M66592_VBINT 0x8000 /* b15: VBUS interrupt */ |
200 | #define M66592_RESM 0x4000 /* b14: Resume interrupt */ | 200 | #define M66592_RESM 0x4000 /* b14: Resume interrupt */ |
201 | #define M66592_SOFR 0x2000 /* b13: SOF frame update interrupt */ | 201 | #define M66592_SOFR 0x2000 /* b13: SOF frame update interrupt */ |
202 | #define M66592_DVST 0x1000 /* b12: Device state transition interrupt */ | 202 | #define M66592_DVST 0x1000 /* b12: Device state transition */ |
203 | #define M66592_CTRT 0x0800 /* b11: Control transfer stage transition interrupt */ | 203 | #define M66592_CTRT 0x0800 /* b11: Control stage transition */ |
204 | #define M66592_BEMP 0x0400 /* b10: Buffer empty interrupt */ | 204 | #define M66592_BEMP 0x0400 /* b10: Buffer empty interrupt */ |
205 | #define M66592_NRDY 0x0200 /* b9: Buffer not ready interrupt */ | 205 | #define M66592_NRDY 0x0200 /* b9: Buffer not ready interrupt */ |
206 | #define M66592_BRDY 0x0100 /* b8: Buffer ready interrupt */ | 206 | #define M66592_BRDY 0x0100 /* b8: Buffer ready interrupt */ |
207 | #define M66592_VBSTS 0x0080 /* b7: VBUS input port */ | 207 | #define M66592_VBSTS 0x0080 /* b7: VBUS input port */ |
208 | #define M66592_DVSQ 0x0070 /* b6-4: Device state */ | 208 | #define M66592_DVSQ 0x0070 /* b6-4: Device state */ |
209 | #define M66592_DS_SPD_CNFG 0x0070 /* Suspend Configured */ | 209 | #define M66592_DS_SPD_CNFG 0x0070 /* Suspend Configured */ |
210 | #define M66592_DS_SPD_ADDR 0x0060 /* Suspend Address */ | 210 | #define M66592_DS_SPD_ADDR 0x0060 /* Suspend Address */ |
211 | #define M66592_DS_SPD_DFLT 0x0050 /* Suspend Default */ | 211 | #define M66592_DS_SPD_DFLT 0x0050 /* Suspend Default */ |
212 | #define M66592_DS_SPD_POWR 0x0040 /* Suspend Powered */ | 212 | #define M66592_DS_SPD_POWR 0x0040 /* Suspend Powered */ |
213 | #define M66592_DS_SUSP 0x0040 /* Suspend */ | 213 | #define M66592_DS_SUSP 0x0040 /* Suspend */ |
214 | #define M66592_DS_CNFG 0x0030 /* Configured */ | 214 | #define M66592_DS_CNFG 0x0030 /* Configured */ |
215 | #define M66592_DS_ADDS 0x0020 /* Address */ | 215 | #define M66592_DS_ADDS 0x0020 /* Address */ |
216 | #define M66592_DS_DFLT 0x0010 /* Default */ | 216 | #define M66592_DS_DFLT 0x0010 /* Default */ |
217 | #define M66592_DS_POWR 0x0000 /* Powered */ | 217 | #define M66592_DS_POWR 0x0000 /* Powered */ |
218 | #define M66592_DVSQS 0x0030 /* b5-4: Device state */ | 218 | #define M66592_DVSQS 0x0030 /* b5-4: Device state */ |
219 | #define M66592_VALID 0x0008 /* b3: Setup packet detected flag */ | 219 | #define M66592_VALID 0x0008 /* b3: Setup packet detected flag */ |
220 | #define M66592_CTSQ 0x0007 /* b2-0: Control transfer stage */ | 220 | #define M66592_CTSQ 0x0007 /* b2-0: Control transfer stage */ |
221 | #define M66592_CS_SQER 0x0006 /* Sequence error */ | 221 | #define M66592_CS_SQER 0x0006 /* Sequence error */ |
222 | #define M66592_CS_WRND 0x0005 /* Control write nodata status stage */ | 222 | #define M66592_CS_WRND 0x0005 /* Control write nodata status */ |
223 | #define M66592_CS_WRSS 0x0004 /* Control write status stage */ | 223 | #define M66592_CS_WRSS 0x0004 /* Control write status stage */ |
224 | #define M66592_CS_WRDS 0x0003 /* Control write data stage */ | 224 | #define M66592_CS_WRDS 0x0003 /* Control write data stage */ |
225 | #define M66592_CS_RDSS 0x0002 /* Control read status stage */ | 225 | #define M66592_CS_RDSS 0x0002 /* Control read status stage */ |
226 | #define M66592_CS_RDDS 0x0001 /* Control read data stage */ | 226 | #define M66592_CS_RDDS 0x0001 /* Control read data stage */ |
227 | #define M66592_CS_IDST 0x0000 /* Idle or setup stage */ | 227 | #define M66592_CS_IDST 0x0000 /* Idle or setup stage */ |
228 | 228 | ||
229 | #define M66592_INTSTS1 0x42 | 229 | #define M66592_INTSTS1 0x42 |
230 | #define M66592_BCHG 0x4000 /* b14: USB bus chenge interrupt */ | 230 | #define M66592_BCHG 0x4000 /* b14: USB bus chenge interrupt */ |
231 | #define M66592_DTCH 0x1000 /* b12: Detach sense interrupt */ | 231 | #define M66592_DTCH 0x1000 /* b12: Detach sense interrupt */ |
232 | #define M66592_SIGN 0x0020 /* b5: SETUP IGNORE interrupt */ | 232 | #define M66592_SIGN 0x0020 /* b5: SETUP IGNORE interrupt */ |
233 | #define M66592_SACK 0x0010 /* b4: SETUP ACK interrupt */ | 233 | #define M66592_SACK 0x0010 /* b4: SETUP ACK interrupt */ |
234 | 234 | ||
235 | #define M66592_FRMNUM 0x4C | 235 | #define M66592_FRMNUM 0x4C |
236 | #define M66592_OVRN 0x8000 /* b15: Overrun error */ | 236 | #define M66592_OVRN 0x8000 /* b15: Overrun error */ |
237 | #define M66592_CRCE 0x4000 /* b14: Received data error */ | 237 | #define M66592_CRCE 0x4000 /* b14: Received data error */ |
238 | #define M66592_SOFRM 0x0800 /* b11: SOF output mode */ | 238 | #define M66592_SOFRM 0x0800 /* b11: SOF output mode */ |
239 | #define M66592_FRNM 0x07FF /* b10-0: Frame number */ | 239 | #define M66592_FRNM 0x07FF /* b10-0: Frame number */ |
240 | 240 | ||
241 | #define M66592_UFRMNUM 0x4E | 241 | #define M66592_UFRMNUM 0x4E |
242 | #define M66592_UFRNM 0x0007 /* b2-0: Micro frame number */ | 242 | #define M66592_UFRNM 0x0007 /* b2-0: Micro frame number */ |
243 | 243 | ||
244 | #define M66592_RECOVER 0x50 | 244 | #define M66592_RECOVER 0x50 |
245 | #define M66592_STSRECOV 0x0700 /* Status recovery */ | 245 | #define M66592_STSRECOV 0x0700 /* Status recovery */ |
246 | #define M66592_STSR_HI 0x0400 /* FULL(0) or HI(1) Speed */ | 246 | #define M66592_STSR_HI 0x0400 /* FULL(0) or HI(1) Speed */ |
247 | #define M66592_STSR_DEFAULT 0x0100 /* Default state */ | 247 | #define M66592_STSR_DEFAULT 0x0100 /* Default state */ |
248 | #define M66592_STSR_ADDRESS 0x0200 /* Address state */ | 248 | #define M66592_STSR_ADDRESS 0x0200 /* Address state */ |
249 | #define M66592_STSR_CONFIG 0x0300 /* Configured state */ | 249 | #define M66592_STSR_CONFIG 0x0300 /* Configured state */ |
250 | #define M66592_USBADDR 0x007F /* b6-0: USB address */ | 250 | #define M66592_USBADDR 0x007F /* b6-0: USB address */ |
251 | 251 | ||
252 | #define M66592_USBREQ 0x54 | 252 | #define M66592_USBREQ 0x54 |
253 | #define M66592_bRequest 0xFF00 /* b15-8: bRequest */ | 253 | #define M66592_bRequest 0xFF00 /* b15-8: bRequest */ |
254 | #define M66592_GET_STATUS 0x0000 | 254 | #define M66592_GET_STATUS 0x0000 |
255 | #define M66592_CLEAR_FEATURE 0x0100 | 255 | #define M66592_CLEAR_FEATURE 0x0100 |
256 | #define M66592_ReqRESERVED 0x0200 | 256 | #define M66592_ReqRESERVED 0x0200 |
257 | #define M66592_SET_FEATURE 0x0300 | 257 | #define M66592_SET_FEATURE 0x0300 |
258 | #define M66592_ReqRESERVED1 0x0400 | 258 | #define M66592_ReqRESERVED1 0x0400 |
259 | #define M66592_SET_ADDRESS 0x0500 | 259 | #define M66592_SET_ADDRESS 0x0500 |
260 | #define M66592_GET_DESCRIPTOR 0x0600 | 260 | #define M66592_GET_DESCRIPTOR 0x0600 |
261 | #define M66592_SET_DESCRIPTOR 0x0700 | 261 | #define M66592_SET_DESCRIPTOR 0x0700 |
262 | #define M66592_GET_CONFIGURATION 0x0800 | 262 | #define M66592_GET_CONFIGURATION 0x0800 |
263 | #define M66592_SET_CONFIGURATION 0x0900 | 263 | #define M66592_SET_CONFIGURATION 0x0900 |
264 | #define M66592_GET_INTERFACE 0x0A00 | 264 | #define M66592_GET_INTERFACE 0x0A00 |
265 | #define M66592_SET_INTERFACE 0x0B00 | 265 | #define M66592_SET_INTERFACE 0x0B00 |
266 | #define M66592_SYNCH_FRAME 0x0C00 | 266 | #define M66592_SYNCH_FRAME 0x0C00 |
267 | #define M66592_bmRequestType 0x00FF /* b7-0: bmRequestType */ | 267 | #define M66592_bmRequestType 0x00FF /* b7-0: bmRequestType */ |
268 | #define M66592_bmRequestTypeDir 0x0080 /* b7 : Data transfer direction */ | 268 | #define M66592_bmRequestTypeDir 0x0080 /* b7 : Data direction */ |
269 | #define M66592_HOST_TO_DEVICE 0x0000 | 269 | #define M66592_HOST_TO_DEVICE 0x0000 |
270 | #define M66592_DEVICE_TO_HOST 0x0080 | 270 | #define M66592_DEVICE_TO_HOST 0x0080 |
271 | #define M66592_bmRequestTypeType 0x0060 /* b6-5: Type */ | 271 | #define M66592_bmRequestTypeType 0x0060 /* b6-5: Type */ |
272 | #define M66592_STANDARD 0x0000 | 272 | #define M66592_STANDARD 0x0000 |
273 | #define M66592_CLASS 0x0020 | 273 | #define M66592_CLASS 0x0020 |
274 | #define M66592_VENDOR 0x0040 | 274 | #define M66592_VENDOR 0x0040 |
275 | #define M66592_bmRequestTypeRecip 0x001F /* b4-0: Recipient */ | 275 | #define M66592_bmRequestTypeRecip 0x001F /* b4-0: Recipient */ |
276 | #define M66592_DEVICE 0x0000 | 276 | #define M66592_DEVICE 0x0000 |
277 | #define M66592_INTERFACE 0x0001 | 277 | #define M66592_INTERFACE 0x0001 |
278 | #define M66592_ENDPOINT 0x0002 | 278 | #define M66592_ENDPOINT 0x0002 |
279 | 279 | ||
280 | #define M66592_USBVAL 0x56 | 280 | #define M66592_USBVAL 0x56 |
281 | #define M66592_wValue 0xFFFF /* b15-0: wValue */ | 281 | #define M66592_wValue 0xFFFF /* b15-0: wValue */ |
282 | /* Standard Feature Selector */ | 282 | /* Standard Feature Selector */ |
283 | #define M66592_ENDPOINT_HALT 0x0000 | 283 | #define M66592_ENDPOINT_HALT 0x0000 |
284 | #define M66592_DEVICE_REMOTE_WAKEUP 0x0001 | 284 | #define M66592_DEVICE_REMOTE_WAKEUP 0x0001 |
285 | #define M66592_TEST_MODE 0x0002 | 285 | #define M66592_TEST_MODE 0x0002 |
286 | /* Descriptor Types */ | 286 | /* Descriptor Types */ |
287 | #define M66592_DT_TYPE 0xFF00 | 287 | #define M66592_DT_TYPE 0xFF00 |
288 | #define M66592_GET_DT_TYPE(v) (((v) & DT_TYPE) >> 8) | 288 | #define M66592_GET_DT_TYPE(v) (((v) & DT_TYPE) >> 8) |
289 | #define M66592_DT_DEVICE 0x01 | 289 | #define M66592_DT_DEVICE 0x01 |
290 | #define M66592_DT_CONFIGURATION 0x02 | 290 | #define M66592_DT_CONFIGURATION 0x02 |
291 | #define M66592_DT_STRING 0x03 | 291 | #define M66592_DT_STRING 0x03 |
292 | #define M66592_DT_INTERFACE 0x04 | 292 | #define M66592_DT_INTERFACE 0x04 |
293 | #define M66592_DT_ENDPOINT 0x05 | 293 | #define M66592_DT_ENDPOINT 0x05 |
294 | #define M66592_DT_DEVICE_QUALIFIER 0x06 | 294 | #define M66592_DT_DEVICE_QUALIFIER 0x06 |
295 | #define M66592_DT_OTHER_SPEED_CONFIGURATION 0x07 | 295 | #define M66592_DT_OTHER_SPEED_CONFIGURATION 0x07 |
296 | #define M66592_DT_INTERFACE_POWER 0x08 | 296 | #define M66592_DT_INTERFACE_POWER 0x08 |
297 | #define M66592_DT_INDEX 0x00FF | 297 | #define M66592_DT_INDEX 0x00FF |
298 | #define M66592_CONF_NUM 0x00FF | 298 | #define M66592_CONF_NUM 0x00FF |
299 | #define M66592_ALT_SET 0x00FF | 299 | #define M66592_ALT_SET 0x00FF |
300 | 300 | ||
301 | #define M66592_USBINDEX 0x58 | 301 | #define M66592_USBINDEX 0x58 |
302 | #define M66592_wIndex 0xFFFF /* b15-0: wIndex */ | 302 | #define M66592_wIndex 0xFFFF /* b15-0: wIndex */ |
303 | #define M66592_TEST_SELECT 0xFF00 /* b15-b8: Test Mode Selectors */ | 303 | #define M66592_TEST_SELECT 0xFF00 /* b15-b8: Test Mode */ |
304 | #define M66592_TEST_J 0x0100 /* Test_J */ | 304 | #define M66592_TEST_J 0x0100 /* Test_J */ |
305 | #define M66592_TEST_K 0x0200 /* Test_K */ | 305 | #define M66592_TEST_K 0x0200 /* Test_K */ |
306 | #define M66592_TEST_SE0_NAK 0x0300 /* Test_SE0_NAK */ | 306 | #define M66592_TEST_SE0_NAK 0x0300 /* Test_SE0_NAK */ |
307 | #define M66592_TEST_PACKET 0x0400 /* Test_Packet */ | 307 | #define M66592_TEST_PACKET 0x0400 /* Test_Packet */ |
308 | #define M66592_TEST_FORCE_ENABLE 0x0500 /* Test_Force_Enable */ | 308 | #define M66592_TEST_FORCE_ENABLE 0x0500 /* Test_Force_Enable */ |
309 | #define M66592_TEST_STSelectors 0x0600 /* Standard test selectors */ | 309 | #define M66592_TEST_STSelectors 0x0600 /* Standard test selectors */ |
310 | #define M66592_TEST_Reserved 0x4000 /* Reserved */ | 310 | #define M66592_TEST_Reserved 0x4000 /* Reserved */ |
311 | #define M66592_TEST_VSTModes 0xC000 /* Vendor-specific test modes */ | 311 | #define M66592_TEST_VSTModes 0xC000 /* Vendor-specific tests */ |
312 | #define M66592_EP_DIR 0x0080 /* b7: Endpoint Direction */ | 312 | #define M66592_EP_DIR 0x0080 /* b7: Endpoint Direction */ |
313 | #define M66592_EP_DIR_IN 0x0080 | 313 | #define M66592_EP_DIR_IN 0x0080 |
314 | #define M66592_EP_DIR_OUT 0x0000 | 314 | #define M66592_EP_DIR_OUT 0x0000 |
315 | 315 | ||
316 | #define M66592_USBLENG 0x5A | 316 | #define M66592_USBLENG 0x5A |
317 | #define M66592_wLength 0xFFFF /* b15-0: wLength */ | 317 | #define M66592_wLength 0xFFFF /* b15-0: wLength */ |
318 | 318 | ||
319 | #define M66592_DCPCFG 0x5C | 319 | #define M66592_DCPCFG 0x5C |
320 | #define M66592_CNTMD 0x0100 /* b8: Continuous transfer mode select */ | 320 | #define M66592_CNTMD 0x0100 /* b8: Continuous transfer mode */ |
321 | #define M66592_DIR 0x0010 /* b4: Control transfer DIR select */ | 321 | #define M66592_DIR 0x0010 /* b4: Control transfer DIR select */ |
322 | 322 | ||
323 | #define M66592_DCPMAXP 0x5E | 323 | #define M66592_DCPMAXP 0x5E |
324 | #define M66592_DEVSEL 0xC000 /* b15-14: Device address select */ | 324 | #define M66592_DEVSEL 0xC000 /* b15-14: Device address select */ |
325 | #define M66592_DEVICE_0 0x0000 /* Device address 0 */ | 325 | #define M66592_DEVICE_0 0x0000 /* Device address 0 */ |
326 | #define M66592_DEVICE_1 0x4000 /* Device address 1 */ | 326 | #define M66592_DEVICE_1 0x4000 /* Device address 1 */ |
327 | #define M66592_DEVICE_2 0x8000 /* Device address 2 */ | 327 | #define M66592_DEVICE_2 0x8000 /* Device address 2 */ |
328 | #define M66592_DEVICE_3 0xC000 /* Device address 3 */ | 328 | #define M66592_DEVICE_3 0xC000 /* Device address 3 */ |
329 | #define M66592_MAXP 0x007F /* b6-0: Maxpacket size of default control pipe */ | 329 | #define M66592_MAXP 0x007F /* b6-0: Maxpacket size of ep0 */ |
330 | 330 | ||
331 | #define M66592_DCPCTR 0x60 | 331 | #define M66592_DCPCTR 0x60 |
332 | #define M66592_BSTS 0x8000 /* b15: Buffer status */ | 332 | #define M66592_BSTS 0x8000 /* b15: Buffer status */ |
333 | #define M66592_SUREQ 0x4000 /* b14: Send USB request */ | 333 | #define M66592_SUREQ 0x4000 /* b14: Send USB request */ |
334 | #define M66592_SQCLR 0x0100 /* b8: Sequence toggle bit clear */ | 334 | #define M66592_SQCLR 0x0100 /* b8: Sequence toggle bit clear */ |
335 | #define M66592_SQSET 0x0080 /* b7: Sequence toggle bit set */ | 335 | #define M66592_SQSET 0x0080 /* b7: Sequence toggle bit set */ |
336 | #define M66592_SQMON 0x0040 /* b6: Sequence toggle bit monitor */ | 336 | #define M66592_SQMON 0x0040 /* b6: Sequence toggle bit monitor */ |
337 | #define M66592_CCPL 0x0004 /* b2: Enable control transfer complete */ | 337 | #define M66592_CCPL 0x0004 /* b2: control transfer complete */ |
338 | #define M66592_PID 0x0003 /* b1-0: Response PID */ | 338 | #define M66592_PID 0x0003 /* b1-0: Response PID */ |
339 | #define M66592_PID_STALL 0x0002 /* STALL */ | 339 | #define M66592_PID_STALL 0x0002 /* STALL */ |
340 | #define M66592_PID_BUF 0x0001 /* BUF */ | 340 | #define M66592_PID_BUF 0x0001 /* BUF */ |
341 | #define M66592_PID_NAK 0x0000 /* NAK */ | 341 | #define M66592_PID_NAK 0x0000 /* NAK */ |
342 | 342 | ||
343 | #define M66592_PIPESEL 0x64 | 343 | #define M66592_PIPESEL 0x64 |
344 | #define M66592_PIPENM 0x0007 /* b2-0: Pipe select */ | 344 | #define M66592_PIPENM 0x0007 /* b2-0: Pipe select */ |
345 | #define M66592_PIPE0 0x0000 /* PIPE 0 */ | 345 | #define M66592_PIPE0 0x0000 /* PIPE 0 */ |
346 | #define M66592_PIPE1 0x0001 /* PIPE 1 */ | 346 | #define M66592_PIPE1 0x0001 /* PIPE 1 */ |
347 | #define M66592_PIPE2 0x0002 /* PIPE 2 */ | 347 | #define M66592_PIPE2 0x0002 /* PIPE 2 */ |
348 | #define M66592_PIPE3 0x0003 /* PIPE 3 */ | 348 | #define M66592_PIPE3 0x0003 /* PIPE 3 */ |
349 | #define M66592_PIPE4 0x0004 /* PIPE 4 */ | 349 | #define M66592_PIPE4 0x0004 /* PIPE 4 */ |
350 | #define M66592_PIPE5 0x0005 /* PIPE 5 */ | 350 | #define M66592_PIPE5 0x0005 /* PIPE 5 */ |
351 | #define M66592_PIPE6 0x0006 /* PIPE 6 */ | 351 | #define M66592_PIPE6 0x0006 /* PIPE 6 */ |
352 | #define M66592_PIPE7 0x0007 /* PIPE 7 */ | 352 | #define M66592_PIPE7 0x0007 /* PIPE 7 */ |
353 | 353 | ||
354 | #define M66592_PIPECFG 0x66 | 354 | #define M66592_PIPECFG 0x66 |
355 | #define M66592_TYP 0xC000 /* b15-14: Transfer type */ | 355 | #define M66592_TYP 0xC000 /* b15-14: Transfer type */ |
356 | #define M66592_ISO 0xC000 /* Isochronous */ | 356 | #define M66592_ISO 0xC000 /* Isochronous */ |
357 | #define M66592_INT 0x8000 /* Interrupt */ | 357 | #define M66592_INT 0x8000 /* Interrupt */ |
358 | #define M66592_BULK 0x4000 /* Bulk */ | 358 | #define M66592_BULK 0x4000 /* Bulk */ |
359 | #define M66592_BFRE 0x0400 /* b10: Buffer ready interrupt mode select */ | 359 | #define M66592_BFRE 0x0400 /* b10: Buffer ready interrupt mode */ |
360 | #define M66592_DBLB 0x0200 /* b9: Double buffer mode select */ | 360 | #define M66592_DBLB 0x0200 /* b9: Double buffer mode select */ |
361 | #define M66592_CNTMD 0x0100 /* b8: Continuous transfer mode select */ | 361 | #define M66592_CNTMD 0x0100 /* b8: Continuous transfer mode */ |
362 | #define M66592_SHTNAK 0x0080 /* b7: Transfer end NAK */ | 362 | #define M66592_SHTNAK 0x0080 /* b7: Transfer end NAK */ |
363 | #define M66592_DIR 0x0010 /* b4: Transfer direction select */ | 363 | #define M66592_DIR 0x0010 /* b4: Transfer direction select */ |
364 | #define M66592_DIR_H_OUT 0x0010 /* HOST OUT */ | 364 | #define M66592_DIR_H_OUT 0x0010 /* HOST OUT */ |
365 | #define M66592_DIR_P_IN 0x0010 /* PERI IN */ | 365 | #define M66592_DIR_P_IN 0x0010 /* PERI IN */ |
366 | #define M66592_DIR_H_IN 0x0000 /* HOST IN */ | 366 | #define M66592_DIR_H_IN 0x0000 /* HOST IN */ |
367 | #define M66592_DIR_P_OUT 0x0000 /* PERI OUT */ | 367 | #define M66592_DIR_P_OUT 0x0000 /* PERI OUT */ |
368 | #define M66592_EPNUM 0x000F /* b3-0: Eendpoint number select */ | 368 | #define M66592_EPNUM 0x000F /* b3-0: Eendpoint number select */ |
369 | #define M66592_EP1 0x0001 | 369 | #define M66592_EP1 0x0001 |
370 | #define M66592_EP2 0x0002 | 370 | #define M66592_EP2 0x0002 |
371 | #define M66592_EP3 0x0003 | 371 | #define M66592_EP3 0x0003 |
372 | #define M66592_EP4 0x0004 | 372 | #define M66592_EP4 0x0004 |
373 | #define M66592_EP5 0x0005 | 373 | #define M66592_EP5 0x0005 |
374 | #define M66592_EP6 0x0006 | 374 | #define M66592_EP6 0x0006 |
375 | #define M66592_EP7 0x0007 | 375 | #define M66592_EP7 0x0007 |
376 | #define M66592_EP8 0x0008 | 376 | #define M66592_EP8 0x0008 |
377 | #define M66592_EP9 0x0009 | 377 | #define M66592_EP9 0x0009 |
378 | #define M66592_EP10 0x000A | 378 | #define M66592_EP10 0x000A |
379 | #define M66592_EP11 0x000B | 379 | #define M66592_EP11 0x000B |
380 | #define M66592_EP12 0x000C | 380 | #define M66592_EP12 0x000C |
381 | #define M66592_EP13 0x000D | 381 | #define M66592_EP13 0x000D |
382 | #define M66592_EP14 0x000E | 382 | #define M66592_EP14 0x000E |
383 | #define M66592_EP15 0x000F | 383 | #define M66592_EP15 0x000F |
384 | 384 | ||
385 | #define M66592_PIPEBUF 0x68 | 385 | #define M66592_PIPEBUF 0x68 |
386 | #define M66592_BUFSIZE 0x7C00 /* b14-10: Pipe buffer size */ | 386 | #define M66592_BUFSIZE 0x7C00 /* b14-10: Pipe buffer size */ |
387 | #define M66592_BUF_SIZE(x) ((((x) / 64) - 1) << 10) | 387 | #define M66592_BUF_SIZE(x) ((((x) / 64) - 1) << 10) |
388 | #define M66592_BUFNMB 0x00FF /* b7-0: Pipe buffer number */ | 388 | #define M66592_BUFNMB 0x00FF /* b7-0: Pipe buffer number */ |
389 | 389 | ||
390 | #define M66592_PIPEMAXP 0x6A | 390 | #define M66592_PIPEMAXP 0x6A |
391 | #define M66592_MXPS 0x07FF /* b10-0: Maxpacket size */ | 391 | #define M66592_MXPS 0x07FF /* b10-0: Maxpacket size */ |
392 | 392 | ||
393 | #define M66592_PIPEPERI 0x6C | 393 | #define M66592_PIPEPERI 0x6C |
394 | #define M66592_IFIS 0x1000 /* b12: Isochronous in-buffer flush mode select */ | 394 | #define M66592_IFIS 0x1000 /* b12: ISO in-buffer flush mode */ |
395 | #define M66592_IITV 0x0007 /* b2-0: Isochronous interval */ | 395 | #define M66592_IITV 0x0007 /* b2-0: ISO interval */ |
396 | 396 | ||
397 | #define M66592_PIPE1CTR 0x70 | 397 | #define M66592_PIPE1CTR 0x70 |
398 | #define M66592_PIPE2CTR 0x72 | 398 | #define M66592_PIPE2CTR 0x72 |
@@ -401,19 +401,17 @@ | |||
401 | #define M66592_PIPE5CTR 0x78 | 401 | #define M66592_PIPE5CTR 0x78 |
402 | #define M66592_PIPE6CTR 0x7A | 402 | #define M66592_PIPE6CTR 0x7A |
403 | #define M66592_PIPE7CTR 0x7C | 403 | #define M66592_PIPE7CTR 0x7C |
404 | #define M66592_BSTS 0x8000 /* b15: Buffer status */ | 404 | #define M66592_BSTS 0x8000 /* b15: Buffer status */ |
405 | #define M66592_INBUFM 0x4000 /* b14: IN buffer monitor (Only for PIPE1 to 5) */ | 405 | #define M66592_INBUFM 0x4000 /* b14: IN buffer monitor (PIPE 1-5) */ |
406 | #define M66592_ACLRM 0x0200 /* b9: Out buffer auto clear mode */ | 406 | #define M66592_ACLRM 0x0200 /* b9: Out buffer auto clear mode */ |
407 | #define M66592_SQCLR 0x0100 /* b8: Sequence toggle bit clear */ | 407 | #define M66592_SQCLR 0x0100 /* b8: Sequence toggle bit clear */ |
408 | #define M66592_SQSET 0x0080 /* b7: Sequence toggle bit set */ | 408 | #define M66592_SQSET 0x0080 /* b7: Sequence toggle bit set */ |
409 | #define M66592_SQMON 0x0040 /* b6: Sequence toggle bit monitor */ | 409 | #define M66592_SQMON 0x0040 /* b6: Sequence toggle bit monitor */ |
410 | #define M66592_PID 0x0003 /* b1-0: Response PID */ | 410 | #define M66592_PID 0x0003 /* b1-0: Response PID */ |
411 | 411 | ||
412 | #define M66592_INVALID_REG 0x7E | 412 | #define M66592_INVALID_REG 0x7E |
413 | 413 | ||
414 | 414 | ||
415 | #define __iomem | ||
416 | |||
417 | #define get_pipectr_addr(pipenum) (M66592_PIPE1CTR + (pipenum - 1) * 2) | 415 | #define get_pipectr_addr(pipenum) (M66592_PIPE1CTR + (pipenum - 1) * 2) |
418 | 416 | ||
419 | #define M66592_MAX_SAMPLING 10 | 417 | #define M66592_MAX_SAMPLING 10 |
@@ -449,7 +447,7 @@ struct m66592_ep { | |||
449 | struct m66592 *m66592; | 447 | struct m66592 *m66592; |
450 | 448 | ||
451 | struct list_head queue; | 449 | struct list_head queue; |
452 | unsigned busy:1; | 450 | unsigned busy:1; |
453 | unsigned internal_ccpl:1; /* use only control */ | 451 | unsigned internal_ccpl:1; /* use only control */ |
454 | 452 | ||
455 | /* this member can able to after m66592_enable */ | 453 | /* this member can able to after m66592_enable */ |
@@ -477,7 +475,7 @@ struct m66592 { | |||
477 | struct m66592_ep *epaddr2ep[16]; | 475 | struct m66592_ep *epaddr2ep[16]; |
478 | 476 | ||
479 | struct usb_request *ep0_req; /* for internal request */ | 477 | struct usb_request *ep0_req; /* for internal request */ |
480 | u16 *ep0_buf; /* for internal request */ | 478 | u16 ep0_data; /* for internal request */ |
481 | 479 | ||
482 | struct timer_list timer; | 480 | struct timer_list timer; |
483 | 481 | ||
@@ -527,8 +525,8 @@ static inline u16 m66592_read(struct m66592 *m66592, unsigned long offset) | |||
527 | } | 525 | } |
528 | 526 | ||
529 | static inline void m66592_read_fifo(struct m66592 *m66592, | 527 | static inline void m66592_read_fifo(struct m66592 *m66592, |
530 | unsigned long offset, | 528 | unsigned long offset, |
531 | void *buf, unsigned long len) | 529 | void *buf, unsigned long len) |
532 | { | 530 | { |
533 | unsigned long fifoaddr = (unsigned long)m66592->reg + offset; | 531 | unsigned long fifoaddr = (unsigned long)m66592->reg + offset; |
534 | 532 | ||
@@ -543,8 +541,8 @@ static inline void m66592_write(struct m66592 *m66592, u16 val, | |||
543 | } | 541 | } |
544 | 542 | ||
545 | static inline void m66592_write_fifo(struct m66592 *m66592, | 543 | static inline void m66592_write_fifo(struct m66592 *m66592, |
546 | unsigned long offset, | 544 | unsigned long offset, |
547 | void *buf, unsigned long len) | 545 | void *buf, unsigned long len) |
548 | { | 546 | { |
549 | unsigned long fifoaddr = (unsigned long)m66592->reg + offset; | 547 | unsigned long fifoaddr = (unsigned long)m66592->reg + offset; |
550 | unsigned long odd = len & 0x0001; | 548 | unsigned long odd = len & 0x0001; |
@@ -558,7 +556,7 @@ static inline void m66592_write_fifo(struct m66592 *m66592, | |||
558 | } | 556 | } |
559 | 557 | ||
560 | static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat, | 558 | static inline void m66592_mdfy(struct m66592 *m66592, u16 val, u16 pat, |
561 | unsigned long offset) | 559 | unsigned long offset) |
562 | { | 560 | { |
563 | u16 tmp; | 561 | u16 tmp; |
564 | tmp = m66592_read(m66592, offset); | 562 | tmp = m66592_read(m66592, offset); |
diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index c3d364ecd4f..d5d473f8144 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c | |||
@@ -62,7 +62,7 @@ | |||
62 | #include <linux/moduleparam.h> | 62 | #include <linux/moduleparam.h> |
63 | #include <linux/device.h> | 63 | #include <linux/device.h> |
64 | #include <linux/usb/ch9.h> | 64 | #include <linux/usb/ch9.h> |
65 | #include <linux/usb_gadget.h> | 65 | #include <linux/usb/gadget.h> |
66 | 66 | ||
67 | #include <asm/byteorder.h> | 67 | #include <asm/byteorder.h> |
68 | #include <asm/io.h> | 68 | #include <asm/io.h> |
diff --git a/drivers/usb/gadget/omap_udc.c b/drivers/usb/gadget/omap_udc.c index 9b0f0925ddd..87c4f50dfb6 100644 --- a/drivers/usb/gadget/omap_udc.c +++ b/drivers/usb/gadget/omap_udc.c | |||
@@ -38,7 +38,7 @@ | |||
38 | #include <linux/moduleparam.h> | 38 | #include <linux/moduleparam.h> |
39 | #include <linux/platform_device.h> | 39 | #include <linux/platform_device.h> |
40 | #include <linux/usb/ch9.h> | 40 | #include <linux/usb/ch9.h> |
41 | #include <linux/usb_gadget.h> | 41 | #include <linux/usb/gadget.h> |
42 | #include <linux/usb/otg.h> | 42 | #include <linux/usb/otg.h> |
43 | #include <linux/dma-mapping.h> | 43 | #include <linux/dma-mapping.h> |
44 | #include <linux/clk.h> | 44 | #include <linux/clk.h> |
@@ -1241,19 +1241,15 @@ static void pullup_enable(struct omap_udc *udc) | |||
1241 | udc->gadget.dev.parent->power.power_state = PMSG_ON; | 1241 | udc->gadget.dev.parent->power.power_state = PMSG_ON; |
1242 | udc->gadget.dev.power.power_state = PMSG_ON; | 1242 | udc->gadget.dev.power.power_state = PMSG_ON; |
1243 | UDC_SYSCON1_REG |= UDC_PULLUP_EN; | 1243 | UDC_SYSCON1_REG |= UDC_PULLUP_EN; |
1244 | #ifndef CONFIG_USB_OTG | 1244 | if (!gadget_is_otg(udc->gadget) && !cpu_is_omap15xx()) |
1245 | if (!cpu_is_omap15xx()) | ||
1246 | OTG_CTRL_REG |= OTG_BSESSVLD; | 1245 | OTG_CTRL_REG |= OTG_BSESSVLD; |
1247 | #endif | ||
1248 | UDC_IRQ_EN_REG = UDC_DS_CHG_IE; | 1246 | UDC_IRQ_EN_REG = UDC_DS_CHG_IE; |
1249 | } | 1247 | } |
1250 | 1248 | ||
1251 | static void pullup_disable(struct omap_udc *udc) | 1249 | static void pullup_disable(struct omap_udc *udc) |
1252 | { | 1250 | { |
1253 | #ifndef CONFIG_USB_OTG | 1251 | if (!gadget_is_otg(udc->gadget) && !cpu_is_omap15xx()) |
1254 | if (!cpu_is_omap15xx()) | ||
1255 | OTG_CTRL_REG &= ~OTG_BSESSVLD; | 1252 | OTG_CTRL_REG &= ~OTG_BSESSVLD; |
1256 | #endif | ||
1257 | UDC_IRQ_EN_REG = UDC_DS_CHG_IE; | 1253 | UDC_IRQ_EN_REG = UDC_DS_CHG_IE; |
1258 | UDC_SYSCON1_REG &= ~UDC_PULLUP_EN; | 1254 | UDC_SYSCON1_REG &= ~UDC_PULLUP_EN; |
1259 | } | 1255 | } |
@@ -1390,7 +1386,7 @@ static void update_otg(struct omap_udc *udc) | |||
1390 | { | 1386 | { |
1391 | u16 devstat; | 1387 | u16 devstat; |
1392 | 1388 | ||
1393 | if (!udc->gadget.is_otg) | 1389 | if (!gadget_is_otg(udc->gadget)) |
1394 | return; | 1390 | return; |
1395 | 1391 | ||
1396 | if (OTG_CTRL_REG & OTG_ID) | 1392 | if (OTG_CTRL_REG & OTG_ID) |
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 63b9521c132..3e715082de3 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c | |||
@@ -54,7 +54,7 @@ | |||
54 | #include <asm/hardware.h> | 54 | #include <asm/hardware.h> |
55 | 55 | ||
56 | #include <linux/usb/ch9.h> | 56 | #include <linux/usb/ch9.h> |
57 | #include <linux/usb_gadget.h> | 57 | #include <linux/usb/gadget.h> |
58 | 58 | ||
59 | #include <asm/mach/udc_pxa2xx.h> | 59 | #include <asm/mach/udc_pxa2xx.h> |
60 | 60 | ||
@@ -93,8 +93,6 @@ static const char driver_name [] = "pxa2xx_udc"; | |||
93 | static const char ep0name [] = "ep0"; | 93 | static const char ep0name [] = "ep0"; |
94 | 94 | ||
95 | 95 | ||
96 | // #define DISABLE_TEST_MODE | ||
97 | |||
98 | #ifdef CONFIG_ARCH_IXP4XX | 96 | #ifdef CONFIG_ARCH_IXP4XX |
99 | 97 | ||
100 | /* cpu-specific register addresses are compiled in to this code */ | 98 | /* cpu-specific register addresses are compiled in to this code */ |
@@ -113,17 +111,6 @@ static const char ep0name [] = "ep0"; | |||
113 | #define SIZE_STR "" | 111 | #define SIZE_STR "" |
114 | #endif | 112 | #endif |
115 | 113 | ||
116 | #ifdef DISABLE_TEST_MODE | ||
117 | /* (mode == 0) == no undocumented chip tweaks | ||
118 | * (mode & 1) == double buffer bulk IN | ||
119 | * (mode & 2) == double buffer bulk OUT | ||
120 | * ... so mode = 3 (or 7, 15, etc) does it for both | ||
121 | */ | ||
122 | static ushort fifo_mode = 0; | ||
123 | module_param(fifo_mode, ushort, 0); | ||
124 | MODULE_PARM_DESC (fifo_mode, "pxa2xx udc fifo mode"); | ||
125 | #endif | ||
126 | |||
127 | /* --------------------------------------------------------------------------- | 114 | /* --------------------------------------------------------------------------- |
128 | * endpoint related parts of the api to the usb controller hardware, | 115 | * endpoint related parts of the api to the usb controller hardware, |
129 | * used by gadget driver; and the inner talker-to-hardware core. | 116 | * used by gadget driver; and the inner talker-to-hardware core. |
@@ -980,7 +967,7 @@ static int pxa2xx_udc_pullup(struct usb_gadget *_gadget, int is_active) | |||
980 | udc = container_of(_gadget, struct pxa2xx_udc, gadget); | 967 | udc = container_of(_gadget, struct pxa2xx_udc, gadget); |
981 | 968 | ||
982 | /* not all boards support pullup control */ | 969 | /* not all boards support pullup control */ |
983 | if (!udc->mach->udc_command) | 970 | if (!udc->mach->gpio_pullup && !udc->mach->udc_command) |
984 | return -EOPNOTSUPP; | 971 | return -EOPNOTSUPP; |
985 | 972 | ||
986 | is_active = (is_active != 0); | 973 | is_active = (is_active != 0); |
@@ -1252,23 +1239,6 @@ static void udc_enable (struct pxa2xx_udc *dev) | |||
1252 | UDC_RES2 = 0x00; | 1239 | UDC_RES2 = 0x00; |
1253 | } | 1240 | } |
1254 | 1241 | ||
1255 | #ifdef DISABLE_TEST_MODE | ||
1256 | /* "test mode" seems to have become the default in later chip | ||
1257 | * revs, preventing double buffering (and invalidating docs). | ||
1258 | * this EXPERIMENT enables it for bulk endpoints by tweaking | ||
1259 | * undefined/reserved register bits (that other drivers clear). | ||
1260 | * Belcarra code comments noted this usage. | ||
1261 | */ | ||
1262 | if (fifo_mode & 1) { /* IN endpoints */ | ||
1263 | UDC_RES1 |= USIR0_IR1|USIR0_IR6; | ||
1264 | UDC_RES2 |= USIR1_IR11; | ||
1265 | } | ||
1266 | if (fifo_mode & 2) { /* OUT endpoints */ | ||
1267 | UDC_RES1 |= USIR0_IR2|USIR0_IR7; | ||
1268 | UDC_RES2 |= USIR1_IR12; | ||
1269 | } | ||
1270 | #endif | ||
1271 | |||
1272 | /* enable suspend/resume and reset irqs */ | 1242 | /* enable suspend/resume and reset irqs */ |
1273 | udc_clear_mask_UDCCR(UDCCR_SRM | UDCCR_REM); | 1243 | udc_clear_mask_UDCCR(UDCCR_SRM | UDCCR_REM); |
1274 | 1244 | ||
@@ -2339,7 +2309,7 @@ static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state) | |||
2339 | { | 2309 | { |
2340 | struct pxa2xx_udc *udc = platform_get_drvdata(dev); | 2310 | struct pxa2xx_udc *udc = platform_get_drvdata(dev); |
2341 | 2311 | ||
2342 | if (!udc->mach->udc_command) | 2312 | if (!udc->mach->gpio_pullup && !udc->mach->udc_command) |
2343 | WARN("USB host won't detect disconnect!\n"); | 2313 | WARN("USB host won't detect disconnect!\n"); |
2344 | pullup(udc, 0); | 2314 | pullup(udc, 0); |
2345 | 2315 | ||
diff --git a/drivers/usb/gadget/s3c2410_udc.c b/drivers/usb/gadget/s3c2410_udc.c index 0be80c635c4..e3e90f8a75e 100644 --- a/drivers/usb/gadget/s3c2410_udc.c +++ b/drivers/usb/gadget/s3c2410_udc.c | |||
@@ -42,7 +42,7 @@ | |||
42 | #include <linux/seq_file.h> | 42 | #include <linux/seq_file.h> |
43 | 43 | ||
44 | #include <linux/usb.h> | 44 | #include <linux/usb.h> |
45 | #include <linux/usb_gadget.h> | 45 | #include <linux/usb/gadget.h> |
46 | 46 | ||
47 | #include <asm/byteorder.h> | 47 | #include <asm/byteorder.h> |
48 | #include <asm/io.h> | 48 | #include <asm/io.h> |
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c index dd33ff0ae4c..f5738eb8e76 100644 --- a/drivers/usb/gadget/serial.c +++ b/drivers/usb/gadget/serial.c | |||
@@ -17,33 +17,15 @@ | |||
17 | * | 17 | * |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
22 | #include <linux/delay.h> | ||
23 | #include <linux/ioport.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/errno.h> | ||
26 | #include <linux/init.h> | ||
27 | #include <linux/timer.h> | ||
28 | #include <linux/list.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/utsname.h> | 21 | #include <linux/utsname.h> |
31 | #include <linux/wait.h> | ||
32 | #include <linux/proc_fs.h> | ||
33 | #include <linux/device.h> | 22 | #include <linux/device.h> |
34 | #include <linux/tty.h> | 23 | #include <linux/tty.h> |
35 | #include <linux/tty_flip.h> | 24 | #include <linux/tty_flip.h> |
36 | 25 | ||
37 | #include <asm/byteorder.h> | ||
38 | #include <asm/io.h> | ||
39 | #include <asm/irq.h> | ||
40 | #include <asm/system.h> | ||
41 | #include <asm/unaligned.h> | ||
42 | #include <asm/uaccess.h> | ||
43 | |||
44 | #include <linux/usb/ch9.h> | 26 | #include <linux/usb/ch9.h> |
45 | #include <linux/usb/cdc.h> | 27 | #include <linux/usb/cdc.h> |
46 | #include <linux/usb_gadget.h> | 28 | #include <linux/usb/gadget.h> |
47 | 29 | ||
48 | #include "gadget_chips.h" | 30 | #include "gadget_chips.h" |
49 | 31 | ||
@@ -88,30 +70,29 @@ | |||
88 | #define GS_DEFAULT_PARITY USB_CDC_NO_PARITY | 70 | #define GS_DEFAULT_PARITY USB_CDC_NO_PARITY |
89 | #define GS_DEFAULT_CHAR_FORMAT USB_CDC_1_STOP_BITS | 71 | #define GS_DEFAULT_CHAR_FORMAT USB_CDC_1_STOP_BITS |
90 | 72 | ||
91 | /* select highspeed/fullspeed, hiding highspeed if not configured */ | 73 | /* maxpacket and other transfer characteristics vary by speed. */ |
92 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 74 | static inline struct usb_endpoint_descriptor * |
93 | #define GS_SPEED_SELECT(is_hs,hs,fs) ((is_hs) ? (hs) : (fs)) | 75 | choose_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *hs, |
94 | #else | 76 | struct usb_endpoint_descriptor *fs) |
95 | #define GS_SPEED_SELECT(is_hs,hs,fs) (fs) | 77 | { |
96 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | 78 | if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) |
79 | return hs; | ||
80 | return fs; | ||
81 | } | ||
82 | |||
97 | 83 | ||
98 | /* debug settings */ | 84 | /* debug settings */ |
99 | #ifdef GS_DEBUG | 85 | #ifdef DEBUG |
100 | static int debug = 1; | 86 | static int debug = 1; |
87 | #else | ||
88 | #define debug 0 | ||
89 | #endif | ||
101 | 90 | ||
102 | #define gs_debug(format, arg...) \ | 91 | #define gs_debug(format, arg...) \ |
103 | do { if (debug) printk(KERN_DEBUG format, ## arg); } while(0) | 92 | do { if (debug) printk(KERN_DEBUG format, ## arg); } while(0) |
104 | #define gs_debug_level(level, format, arg...) \ | 93 | #define gs_debug_level(level, format, arg...) \ |
105 | do { if (debug>=level) printk(KERN_DEBUG format, ## arg); } while(0) | 94 | do { if (debug>=level) printk(KERN_DEBUG format, ## arg); } while(0) |
106 | 95 | ||
107 | #else | ||
108 | |||
109 | #define gs_debug(format, arg...) \ | ||
110 | do { } while(0) | ||
111 | #define gs_debug_level(level, format, arg...) \ | ||
112 | do { } while(0) | ||
113 | |||
114 | #endif /* GS_DEBUG */ | ||
115 | 96 | ||
116 | /* Thanks to NetChip Technologies for donating this product ID. | 97 | /* Thanks to NetChip Technologies for donating this product ID. |
117 | * | 98 | * |
@@ -146,10 +127,10 @@ struct gs_req_entry { | |||
146 | 127 | ||
147 | /* the port structure holds info for each port, one for each minor number */ | 128 | /* the port structure holds info for each port, one for each minor number */ |
148 | struct gs_port { | 129 | struct gs_port { |
149 | struct gs_dev *port_dev; /* pointer to device struct */ | 130 | struct gs_dev *port_dev; /* pointer to device struct */ |
150 | struct tty_struct *port_tty; /* pointer to tty struct */ | 131 | struct tty_struct *port_tty; /* pointer to tty struct */ |
151 | spinlock_t port_lock; | 132 | spinlock_t port_lock; |
152 | int port_num; | 133 | int port_num; |
153 | int port_open_count; | 134 | int port_open_count; |
154 | int port_in_use; /* open/close in progress */ | 135 | int port_in_use; /* open/close in progress */ |
155 | wait_queue_head_t port_write_wait;/* waiting to write */ | 136 | wait_queue_head_t port_write_wait;/* waiting to write */ |
@@ -187,7 +168,7 @@ static void __exit gs_module_exit(void); | |||
187 | /* tty driver */ | 168 | /* tty driver */ |
188 | static int gs_open(struct tty_struct *tty, struct file *file); | 169 | static int gs_open(struct tty_struct *tty, struct file *file); |
189 | static void gs_close(struct tty_struct *tty, struct file *file); | 170 | static void gs_close(struct tty_struct *tty, struct file *file); |
190 | static int gs_write(struct tty_struct *tty, | 171 | static int gs_write(struct tty_struct *tty, |
191 | const unsigned char *buf, int count); | 172 | const unsigned char *buf, int count); |
192 | static void gs_put_char(struct tty_struct *tty, unsigned char ch); | 173 | static void gs_put_char(struct tty_struct *tty, unsigned char ch); |
193 | static void gs_flush_chars(struct tty_struct *tty); | 174 | static void gs_flush_chars(struct tty_struct *tty); |
@@ -221,7 +202,7 @@ static void gs_setup_complete(struct usb_ep *ep, struct usb_request *req); | |||
221 | static void gs_disconnect(struct usb_gadget *gadget); | 202 | static void gs_disconnect(struct usb_gadget *gadget); |
222 | static int gs_set_config(struct gs_dev *dev, unsigned config); | 203 | static int gs_set_config(struct gs_dev *dev, unsigned config); |
223 | static void gs_reset_config(struct gs_dev *dev); | 204 | static void gs_reset_config(struct gs_dev *dev); |
224 | static int gs_build_config_buf(u8 *buf, enum usb_device_speed speed, | 205 | static int gs_build_config_buf(u8 *buf, struct usb_gadget *g, |
225 | u8 type, unsigned int index, int is_otg); | 206 | u8 type, unsigned int index, int is_otg); |
226 | 207 | ||
227 | static struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned int len, | 208 | static struct usb_request *gs_alloc_req(struct usb_ep *ep, unsigned int len, |
@@ -258,7 +239,7 @@ static const char *EP_IN_NAME; | |||
258 | static const char *EP_OUT_NAME; | 239 | static const char *EP_OUT_NAME; |
259 | static const char *EP_NOTIFY_NAME; | 240 | static const char *EP_NOTIFY_NAME; |
260 | 241 | ||
261 | static struct semaphore gs_open_close_sem[GS_NUM_PORTS]; | 242 | static struct mutex gs_open_close_lock[GS_NUM_PORTS]; |
262 | 243 | ||
263 | static unsigned int read_q_size = GS_DEFAULT_READ_Q_SIZE; | 244 | static unsigned int read_q_size = GS_DEFAULT_READ_Q_SIZE; |
264 | static unsigned int write_q_size = GS_DEFAULT_WRITE_Q_SIZE; | 245 | static unsigned int write_q_size = GS_DEFAULT_WRITE_Q_SIZE; |
@@ -414,18 +395,18 @@ static const struct usb_cdc_header_desc gs_header_desc = { | |||
414 | }; | 395 | }; |
415 | 396 | ||
416 | static const struct usb_cdc_call_mgmt_descriptor gs_call_mgmt_descriptor = { | 397 | static const struct usb_cdc_call_mgmt_descriptor gs_call_mgmt_descriptor = { |
417 | .bLength = sizeof(gs_call_mgmt_descriptor), | 398 | .bLength = sizeof(gs_call_mgmt_descriptor), |
418 | .bDescriptorType = USB_DT_CS_INTERFACE, | 399 | .bDescriptorType = USB_DT_CS_INTERFACE, |
419 | .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE, | 400 | .bDescriptorSubType = USB_CDC_CALL_MANAGEMENT_TYPE, |
420 | .bmCapabilities = 0, | 401 | .bmCapabilities = 0, |
421 | .bDataInterface = 1, /* index of data interface */ | 402 | .bDataInterface = 1, /* index of data interface */ |
422 | }; | 403 | }; |
423 | 404 | ||
424 | static struct usb_cdc_acm_descriptor gs_acm_descriptor = { | 405 | static struct usb_cdc_acm_descriptor gs_acm_descriptor = { |
425 | .bLength = sizeof(gs_acm_descriptor), | 406 | .bLength = sizeof(gs_acm_descriptor), |
426 | .bDescriptorType = USB_DT_CS_INTERFACE, | 407 | .bDescriptorType = USB_DT_CS_INTERFACE, |
427 | .bDescriptorSubType = USB_CDC_ACM_TYPE, | 408 | .bDescriptorSubType = USB_CDC_ACM_TYPE, |
428 | .bmCapabilities = 0, | 409 | .bmCapabilities = 0, |
429 | }; | 410 | }; |
430 | 411 | ||
431 | static const struct usb_cdc_union_desc gs_union_desc = { | 412 | static const struct usb_cdc_union_desc gs_union_desc = { |
@@ -435,7 +416,7 @@ static const struct usb_cdc_union_desc gs_union_desc = { | |||
435 | .bMasterInterface0 = 0, /* index of control interface */ | 416 | .bMasterInterface0 = 0, /* index of control interface */ |
436 | .bSlaveInterface0 = 1, /* index of data interface */ | 417 | .bSlaveInterface0 = 1, /* index of data interface */ |
437 | }; | 418 | }; |
438 | 419 | ||
439 | static struct usb_endpoint_descriptor gs_fullspeed_notify_desc = { | 420 | static struct usb_endpoint_descriptor gs_fullspeed_notify_desc = { |
440 | .bLength = USB_DT_ENDPOINT_SIZE, | 421 | .bLength = USB_DT_ENDPOINT_SIZE, |
441 | .bDescriptorType = USB_DT_ENDPOINT, | 422 | .bDescriptorType = USB_DT_ENDPOINT, |
@@ -481,7 +462,6 @@ static const struct usb_descriptor_header *gs_acm_fullspeed_function[] = { | |||
481 | NULL, | 462 | NULL, |
482 | }; | 463 | }; |
483 | 464 | ||
484 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
485 | static struct usb_endpoint_descriptor gs_highspeed_notify_desc = { | 465 | static struct usb_endpoint_descriptor gs_highspeed_notify_desc = { |
486 | .bLength = USB_DT_ENDPOINT_SIZE, | 466 | .bLength = USB_DT_ENDPOINT_SIZE, |
487 | .bDescriptorType = USB_DT_ENDPOINT, | 467 | .bDescriptorType = USB_DT_ENDPOINT, |
@@ -535,15 +515,13 @@ static const struct usb_descriptor_header *gs_acm_highspeed_function[] = { | |||
535 | NULL, | 515 | NULL, |
536 | }; | 516 | }; |
537 | 517 | ||
538 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | ||
539 | |||
540 | 518 | ||
541 | /* Module */ | 519 | /* Module */ |
542 | MODULE_DESCRIPTION(GS_LONG_NAME); | 520 | MODULE_DESCRIPTION(GS_LONG_NAME); |
543 | MODULE_AUTHOR("Al Borchers"); | 521 | MODULE_AUTHOR("Al Borchers"); |
544 | MODULE_LICENSE("GPL"); | 522 | MODULE_LICENSE("GPL"); |
545 | 523 | ||
546 | #ifdef GS_DEBUG | 524 | #ifdef DEBUG |
547 | module_param(debug, int, S_IRUGO|S_IWUSR); | 525 | module_param(debug, int, S_IRUGO|S_IWUSR); |
548 | MODULE_PARM_DESC(debug, "Enable debugging, 0=off, 1=on"); | 526 | MODULE_PARM_DESC(debug, "Enable debugging, 0=off, 1=on"); |
549 | #endif | 527 | #endif |
@@ -595,7 +573,7 @@ static int __init gs_module_init(void) | |||
595 | tty_set_operations(gs_tty_driver, &gs_tty_ops); | 573 | tty_set_operations(gs_tty_driver, &gs_tty_ops); |
596 | 574 | ||
597 | for (i=0; i < GS_NUM_PORTS; i++) | 575 | for (i=0; i < GS_NUM_PORTS; i++) |
598 | sema_init(&gs_open_close_sem[i], 1); | 576 | mutex_init(&gs_open_close_lock[i]); |
599 | 577 | ||
600 | retval = tty_register_driver(gs_tty_driver); | 578 | retval = tty_register_driver(gs_tty_driver); |
601 | if (retval) { | 579 | if (retval) { |
@@ -635,7 +613,7 @@ static int gs_open(struct tty_struct *tty, struct file *file) | |||
635 | struct gs_port *port; | 613 | struct gs_port *port; |
636 | struct gs_dev *dev; | 614 | struct gs_dev *dev; |
637 | struct gs_buf *buf; | 615 | struct gs_buf *buf; |
638 | struct semaphore *sem; | 616 | struct mutex *mtx; |
639 | int ret; | 617 | int ret; |
640 | 618 | ||
641 | port_num = tty->index; | 619 | port_num = tty->index; |
@@ -656,10 +634,10 @@ static int gs_open(struct tty_struct *tty, struct file *file) | |||
656 | return -ENODEV; | 634 | return -ENODEV; |
657 | } | 635 | } |
658 | 636 | ||
659 | sem = &gs_open_close_sem[port_num]; | 637 | mtx = &gs_open_close_lock[port_num]; |
660 | if (down_interruptible(sem)) { | 638 | if (mutex_lock_interruptible(mtx)) { |
661 | printk(KERN_ERR | 639 | printk(KERN_ERR |
662 | "gs_open: (%d,%p,%p) interrupted waiting for semaphore\n", | 640 | "gs_open: (%d,%p,%p) interrupted waiting for mutex\n", |
663 | port_num, tty, file); | 641 | port_num, tty, file); |
664 | return -ERESTARTSYS; | 642 | return -ERESTARTSYS; |
665 | } | 643 | } |
@@ -754,12 +732,12 @@ static int gs_open(struct tty_struct *tty, struct file *file) | |||
754 | 732 | ||
755 | exit_unlock_port: | 733 | exit_unlock_port: |
756 | spin_unlock_irqrestore(&port->port_lock, flags); | 734 | spin_unlock_irqrestore(&port->port_lock, flags); |
757 | up(sem); | 735 | mutex_unlock(mtx); |
758 | return ret; | 736 | return ret; |
759 | 737 | ||
760 | exit_unlock_dev: | 738 | exit_unlock_dev: |
761 | spin_unlock_irqrestore(&dev->dev_lock, flags); | 739 | spin_unlock_irqrestore(&dev->dev_lock, flags); |
762 | up(sem); | 740 | mutex_unlock(mtx); |
763 | return ret; | 741 | return ret; |
764 | 742 | ||
765 | } | 743 | } |
@@ -781,7 +759,7 @@ exit_unlock_dev: | |||
781 | static void gs_close(struct tty_struct *tty, struct file *file) | 759 | static void gs_close(struct tty_struct *tty, struct file *file) |
782 | { | 760 | { |
783 | struct gs_port *port = tty->driver_data; | 761 | struct gs_port *port = tty->driver_data; |
784 | struct semaphore *sem; | 762 | struct mutex *mtx; |
785 | 763 | ||
786 | if (port == NULL) { | 764 | if (port == NULL) { |
787 | printk(KERN_ERR "gs_close: NULL port pointer\n"); | 765 | printk(KERN_ERR "gs_close: NULL port pointer\n"); |
@@ -790,8 +768,8 @@ static void gs_close(struct tty_struct *tty, struct file *file) | |||
790 | 768 | ||
791 | gs_debug("gs_close: (%d,%p,%p)\n", port->port_num, tty, file); | 769 | gs_debug("gs_close: (%d,%p,%p)\n", port->port_num, tty, file); |
792 | 770 | ||
793 | sem = &gs_open_close_sem[port->port_num]; | 771 | mtx = &gs_open_close_lock[port->port_num]; |
794 | down(sem); | 772 | mutex_lock(mtx); |
795 | 773 | ||
796 | spin_lock_irq(&port->port_lock); | 774 | spin_lock_irq(&port->port_lock); |
797 | 775 | ||
@@ -846,7 +824,7 @@ static void gs_close(struct tty_struct *tty, struct file *file) | |||
846 | 824 | ||
847 | exit: | 825 | exit: |
848 | spin_unlock_irq(&port->port_lock); | 826 | spin_unlock_irq(&port->port_lock); |
849 | up(sem); | 827 | mutex_unlock(mtx); |
850 | } | 828 | } |
851 | 829 | ||
852 | /* | 830 | /* |
@@ -914,7 +892,8 @@ static void gs_put_char(struct tty_struct *tty, unsigned char ch) | |||
914 | return; | 892 | return; |
915 | } | 893 | } |
916 | 894 | ||
917 | gs_debug("gs_put_char: (%d,%p) char=0x%x, called from %p, %p, %p\n", port->port_num, tty, ch, __builtin_return_address(0), __builtin_return_address(1), __builtin_return_address(2)); | 895 | gs_debug("gs_put_char: (%d,%p) char=0x%x, called from %p\n", |
896 | port->port_num, tty, ch, __builtin_return_address(0)); | ||
918 | 897 | ||
919 | spin_lock_irqsave(&port->port_lock, flags); | 898 | spin_lock_irqsave(&port->port_lock, flags); |
920 | 899 | ||
@@ -1115,7 +1094,11 @@ static int gs_send(struct gs_dev *dev) | |||
1115 | len = gs_send_packet(dev, req->buf, ep->maxpacket); | 1094 | len = gs_send_packet(dev, req->buf, ep->maxpacket); |
1116 | 1095 | ||
1117 | if (len > 0) { | 1096 | if (len > 0) { |
1118 | gs_debug_level(3, "gs_send: len=%d, 0x%2.2x 0x%2.2x 0x%2.2x ...\n", len, *((unsigned char *)req->buf), *((unsigned char *)req->buf+1), *((unsigned char *)req->buf+2)); | 1097 | gs_debug_level(3, "gs_send: len=%d, 0x%2.2x " |
1098 | "0x%2.2x 0x%2.2x ...\n", len, | ||
1099 | *((unsigned char *)req->buf), | ||
1100 | *((unsigned char *)req->buf+1), | ||
1101 | *((unsigned char *)req->buf+2)); | ||
1119 | list_del(&req_entry->re_entry); | 1102 | list_del(&req_entry->re_entry); |
1120 | req->length = len; | 1103 | req->length = len; |
1121 | spin_unlock_irqrestore(&dev->dev_lock, flags); | 1104 | spin_unlock_irqrestore(&dev->dev_lock, flags); |
@@ -1268,7 +1251,7 @@ static void gs_read_complete(struct usb_ep *ep, struct usb_request *req) | |||
1268 | 1251 | ||
1269 | switch(req->status) { | 1252 | switch(req->status) { |
1270 | case 0: | 1253 | case 0: |
1271 | /* normal completion */ | 1254 | /* normal completion */ |
1272 | gs_recv_packet(dev, req->buf, req->actual); | 1255 | gs_recv_packet(dev, req->buf, req->actual); |
1273 | requeue: | 1256 | requeue: |
1274 | req->length = ep->maxpacket; | 1257 | req->length = ep->maxpacket; |
@@ -1405,29 +1388,30 @@ static int __init gs_bind(struct usb_gadget *gadget) | |||
1405 | ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC; | 1388 | ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC; |
1406 | gs_device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; | 1389 | gs_device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; |
1407 | 1390 | ||
1408 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1391 | if (gadget_is_dualspeed(gadget)) { |
1409 | gs_qualifier_desc.bDeviceClass = use_acm | 1392 | gs_qualifier_desc.bDeviceClass = use_acm |
1410 | ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC; | 1393 | ? USB_CLASS_COMM : USB_CLASS_VENDOR_SPEC; |
1411 | /* assume ep0 uses the same packet size for both speeds */ | 1394 | /* assume ep0 uses the same packet size for both speeds */ |
1412 | gs_qualifier_desc.bMaxPacketSize0 = gs_device_desc.bMaxPacketSize0; | 1395 | gs_qualifier_desc.bMaxPacketSize0 = |
1413 | /* assume endpoints are dual-speed */ | 1396 | gs_device_desc.bMaxPacketSize0; |
1414 | gs_highspeed_notify_desc.bEndpointAddress = | 1397 | /* assume endpoints are dual-speed */ |
1415 | gs_fullspeed_notify_desc.bEndpointAddress; | 1398 | gs_highspeed_notify_desc.bEndpointAddress = |
1416 | gs_highspeed_in_desc.bEndpointAddress = | 1399 | gs_fullspeed_notify_desc.bEndpointAddress; |
1417 | gs_fullspeed_in_desc.bEndpointAddress; | 1400 | gs_highspeed_in_desc.bEndpointAddress = |
1418 | gs_highspeed_out_desc.bEndpointAddress = | 1401 | gs_fullspeed_in_desc.bEndpointAddress; |
1419 | gs_fullspeed_out_desc.bEndpointAddress; | 1402 | gs_highspeed_out_desc.bEndpointAddress = |
1420 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | 1403 | gs_fullspeed_out_desc.bEndpointAddress; |
1404 | } | ||
1421 | 1405 | ||
1422 | usb_gadget_set_selfpowered(gadget); | 1406 | usb_gadget_set_selfpowered(gadget); |
1423 | 1407 | ||
1424 | if (gadget->is_otg) { | 1408 | if (gadget_is_otg(gadget)) { |
1425 | gs_otg_descriptor.bmAttributes |= USB_OTG_HNP, | 1409 | gs_otg_descriptor.bmAttributes |= USB_OTG_HNP, |
1426 | gs_bulk_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 1410 | gs_bulk_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
1427 | gs_acm_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 1411 | gs_acm_config_desc.bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
1428 | } | 1412 | } |
1429 | 1413 | ||
1430 | gs_device = dev = kmalloc(sizeof(struct gs_dev), GFP_KERNEL); | 1414 | gs_device = dev = kzalloc(sizeof(struct gs_dev), GFP_KERNEL); |
1431 | if (dev == NULL) | 1415 | if (dev == NULL) |
1432 | return -ENOMEM; | 1416 | return -ENOMEM; |
1433 | 1417 | ||
@@ -1435,7 +1419,6 @@ static int __init gs_bind(struct usb_gadget *gadget) | |||
1435 | init_utsname()->sysname, init_utsname()->release, | 1419 | init_utsname()->sysname, init_utsname()->release, |
1436 | gadget->name); | 1420 | gadget->name); |
1437 | 1421 | ||
1438 | memset(dev, 0, sizeof(struct gs_dev)); | ||
1439 | dev->dev_gadget = gadget; | 1422 | dev->dev_gadget = gadget; |
1440 | spin_lock_init(&dev->dev_lock); | 1423 | spin_lock_init(&dev->dev_lock); |
1441 | INIT_LIST_HEAD(&dev->dev_req_list); | 1424 | INIT_LIST_HEAD(&dev->dev_req_list); |
@@ -1487,6 +1470,12 @@ static void /* __init_or_exit */ gs_unbind(struct usb_gadget *gadget) | |||
1487 | dev->dev_ctrl_req = NULL; | 1470 | dev->dev_ctrl_req = NULL; |
1488 | } | 1471 | } |
1489 | gs_free_ports(dev); | 1472 | gs_free_ports(dev); |
1473 | if (dev->dev_notify_ep) | ||
1474 | usb_ep_disable(dev->dev_notify_ep); | ||
1475 | if (dev->dev_in_ep) | ||
1476 | usb_ep_disable(dev->dev_in_ep); | ||
1477 | if (dev->dev_out_ep) | ||
1478 | usb_ep_disable(dev->dev_out_ep); | ||
1490 | kfree(dev); | 1479 | kfree(dev); |
1491 | set_gadget_data(gadget, NULL); | 1480 | set_gadget_data(gadget, NULL); |
1492 | } | 1481 | } |
@@ -1570,9 +1559,8 @@ static int gs_setup_standard(struct usb_gadget *gadget, | |||
1570 | memcpy(req->buf, &gs_device_desc, ret); | 1559 | memcpy(req->buf, &gs_device_desc, ret); |
1571 | break; | 1560 | break; |
1572 | 1561 | ||
1573 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
1574 | case USB_DT_DEVICE_QUALIFIER: | 1562 | case USB_DT_DEVICE_QUALIFIER: |
1575 | if (!gadget->is_dualspeed) | 1563 | if (!gadget_is_dualspeed(gadget)) |
1576 | break; | 1564 | break; |
1577 | ret = min(wLength, | 1565 | ret = min(wLength, |
1578 | (u16)sizeof(struct usb_qualifier_descriptor)); | 1566 | (u16)sizeof(struct usb_qualifier_descriptor)); |
@@ -1580,14 +1568,13 @@ static int gs_setup_standard(struct usb_gadget *gadget, | |||
1580 | break; | 1568 | break; |
1581 | 1569 | ||
1582 | case USB_DT_OTHER_SPEED_CONFIG: | 1570 | case USB_DT_OTHER_SPEED_CONFIG: |
1583 | if (!gadget->is_dualspeed) | 1571 | if (!gadget_is_dualspeed(gadget)) |
1584 | break; | 1572 | break; |
1585 | /* fall through */ | 1573 | /* fall through */ |
1586 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | ||
1587 | case USB_DT_CONFIG: | 1574 | case USB_DT_CONFIG: |
1588 | ret = gs_build_config_buf(req->buf, gadget->speed, | 1575 | ret = gs_build_config_buf(req->buf, gadget, |
1589 | wValue >> 8, wValue & 0xff, | 1576 | wValue >> 8, wValue & 0xff, |
1590 | gadget->is_otg); | 1577 | gadget_is_otg(gadget)); |
1591 | if (ret >= 0) | 1578 | if (ret >= 0) |
1592 | ret = min(wLength, (u16)ret); | 1579 | ret = min(wLength, (u16)ret); |
1593 | break; | 1580 | break; |
@@ -1691,14 +1678,12 @@ static int gs_setup_class(struct usb_gadget *gadget, | |||
1691 | 1678 | ||
1692 | switch (ctrl->bRequest) { | 1679 | switch (ctrl->bRequest) { |
1693 | case USB_CDC_REQ_SET_LINE_CODING: | 1680 | case USB_CDC_REQ_SET_LINE_CODING: |
1694 | ret = min(wLength, | 1681 | /* FIXME Submit req to read the data; have its completion |
1695 | (u16)sizeof(struct usb_cdc_line_coding)); | 1682 | * handler copy that data to port->port_line_coding (iff |
1696 | if (port) { | 1683 | * it's valid) and maybe pass it on. Until then, fail. |
1697 | spin_lock(&port->port_lock); | 1684 | */ |
1698 | memcpy(&port->port_line_coding, req->buf, ret); | 1685 | printk(KERN_WARNING "gs_setup: set_line_coding " |
1699 | spin_unlock(&port->port_lock); | 1686 | "unuspported\n"); |
1700 | } | ||
1701 | ret = 0; | ||
1702 | break; | 1687 | break; |
1703 | 1688 | ||
1704 | case USB_CDC_REQ_GET_LINE_CODING: | 1689 | case USB_CDC_REQ_GET_LINE_CODING: |
@@ -1713,11 +1698,18 @@ static int gs_setup_class(struct usb_gadget *gadget, | |||
1713 | break; | 1698 | break; |
1714 | 1699 | ||
1715 | case USB_CDC_REQ_SET_CONTROL_LINE_STATE: | 1700 | case USB_CDC_REQ_SET_CONTROL_LINE_STATE: |
1716 | ret = 0; | 1701 | /* FIXME Submit req to read the data; have its completion |
1702 | * handler use that to set the state (iff it's valid) and | ||
1703 | * maybe pass it on. Until then, fail. | ||
1704 | */ | ||
1705 | printk(KERN_WARNING "gs_setup: set_control_line_state " | ||
1706 | "unuspported\n"); | ||
1717 | break; | 1707 | break; |
1718 | 1708 | ||
1719 | default: | 1709 | default: |
1720 | printk(KERN_ERR "gs_setup: unknown class request, type=%02x, request=%02x, value=%04x, index=%04x, length=%d\n", | 1710 | printk(KERN_ERR "gs_setup: unknown class request, " |
1711 | "type=%02x, request=%02x, value=%04x, " | ||
1712 | "index=%04x, length=%d\n", | ||
1721 | ctrl->bRequestType, ctrl->bRequest, | 1713 | ctrl->bRequestType, ctrl->bRequest, |
1722 | wValue, wIndex, wLength); | 1714 | wValue, wIndex, wLength); |
1723 | break; | 1715 | break; |
@@ -1822,8 +1814,7 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) | |||
1822 | 1814 | ||
1823 | if (EP_NOTIFY_NAME | 1815 | if (EP_NOTIFY_NAME |
1824 | && strcmp(ep->name, EP_NOTIFY_NAME) == 0) { | 1816 | && strcmp(ep->name, EP_NOTIFY_NAME) == 0) { |
1825 | ep_desc = GS_SPEED_SELECT( | 1817 | ep_desc = choose_ep_desc(gadget, |
1826 | gadget->speed == USB_SPEED_HIGH, | ||
1827 | &gs_highspeed_notify_desc, | 1818 | &gs_highspeed_notify_desc, |
1828 | &gs_fullspeed_notify_desc); | 1819 | &gs_fullspeed_notify_desc); |
1829 | ret = usb_ep_enable(ep,ep_desc); | 1820 | ret = usb_ep_enable(ep,ep_desc); |
@@ -1839,9 +1830,8 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) | |||
1839 | } | 1830 | } |
1840 | 1831 | ||
1841 | else if (strcmp(ep->name, EP_IN_NAME) == 0) { | 1832 | else if (strcmp(ep->name, EP_IN_NAME) == 0) { |
1842 | ep_desc = GS_SPEED_SELECT( | 1833 | ep_desc = choose_ep_desc(gadget, |
1843 | gadget->speed == USB_SPEED_HIGH, | 1834 | &gs_highspeed_in_desc, |
1844 | &gs_highspeed_in_desc, | ||
1845 | &gs_fullspeed_in_desc); | 1835 | &gs_fullspeed_in_desc); |
1846 | ret = usb_ep_enable(ep,ep_desc); | 1836 | ret = usb_ep_enable(ep,ep_desc); |
1847 | if (ret == 0) { | 1837 | if (ret == 0) { |
@@ -1856,8 +1846,7 @@ static int gs_set_config(struct gs_dev *dev, unsigned config) | |||
1856 | } | 1846 | } |
1857 | 1847 | ||
1858 | else if (strcmp(ep->name, EP_OUT_NAME) == 0) { | 1848 | else if (strcmp(ep->name, EP_OUT_NAME) == 0) { |
1859 | ep_desc = GS_SPEED_SELECT( | 1849 | ep_desc = choose_ep_desc(gadget, |
1860 | gadget->speed == USB_SPEED_HIGH, | ||
1861 | &gs_highspeed_out_desc, | 1850 | &gs_highspeed_out_desc, |
1862 | &gs_fullspeed_out_desc); | 1851 | &gs_fullspeed_out_desc); |
1863 | ret = usb_ep_enable(ep,ep_desc); | 1852 | ret = usb_ep_enable(ep,ep_desc); |
@@ -1976,11 +1965,11 @@ static void gs_reset_config(struct gs_dev *dev) | |||
1976 | * Builds the config descriptors in the given buffer and returns the | 1965 | * Builds the config descriptors in the given buffer and returns the |
1977 | * length, or a negative error number. | 1966 | * length, or a negative error number. |
1978 | */ | 1967 | */ |
1979 | static int gs_build_config_buf(u8 *buf, enum usb_device_speed speed, | 1968 | static int gs_build_config_buf(u8 *buf, struct usb_gadget *g, |
1980 | u8 type, unsigned int index, int is_otg) | 1969 | u8 type, unsigned int index, int is_otg) |
1981 | { | 1970 | { |
1982 | int len; | 1971 | int len; |
1983 | int high_speed; | 1972 | int high_speed = 0; |
1984 | const struct usb_config_descriptor *config_desc; | 1973 | const struct usb_config_descriptor *config_desc; |
1985 | const struct usb_descriptor_header **function; | 1974 | const struct usb_descriptor_header **function; |
1986 | 1975 | ||
@@ -1988,20 +1977,22 @@ static int gs_build_config_buf(u8 *buf, enum usb_device_speed speed, | |||
1988 | return -EINVAL; | 1977 | return -EINVAL; |
1989 | 1978 | ||
1990 | /* other speed switches high and full speed */ | 1979 | /* other speed switches high and full speed */ |
1991 | high_speed = (speed == USB_SPEED_HIGH); | 1980 | if (gadget_is_dualspeed(g)) { |
1992 | if (type == USB_DT_OTHER_SPEED_CONFIG) | 1981 | high_speed = (g->speed == USB_SPEED_HIGH); |
1993 | high_speed = !high_speed; | 1982 | if (type == USB_DT_OTHER_SPEED_CONFIG) |
1983 | high_speed = !high_speed; | ||
1984 | } | ||
1994 | 1985 | ||
1995 | if (use_acm) { | 1986 | if (use_acm) { |
1996 | config_desc = &gs_acm_config_desc; | 1987 | config_desc = &gs_acm_config_desc; |
1997 | function = GS_SPEED_SELECT(high_speed, | 1988 | function = high_speed |
1998 | gs_acm_highspeed_function, | 1989 | ? gs_acm_highspeed_function |
1999 | gs_acm_fullspeed_function); | 1990 | : gs_acm_fullspeed_function; |
2000 | } else { | 1991 | } else { |
2001 | config_desc = &gs_bulk_config_desc; | 1992 | config_desc = &gs_bulk_config_desc; |
2002 | function = GS_SPEED_SELECT(high_speed, | 1993 | function = high_speed |
2003 | gs_bulk_highspeed_function, | 1994 | ? gs_bulk_highspeed_function |
2004 | gs_bulk_fullspeed_function); | 1995 | : gs_bulk_fullspeed_function; |
2005 | } | 1996 | } |
2006 | 1997 | ||
2007 | /* for now, don't advertise srp-only devices */ | 1998 | /* for now, don't advertise srp-only devices */ |
diff --git a/drivers/usb/gadget/usbstring.c b/drivers/usb/gadget/usbstring.c index 3459ea6c6c0..878e428a0ec 100644 --- a/drivers/usb/gadget/usbstring.c +++ b/drivers/usb/gadget/usbstring.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | 16 | ||
17 | #include <linux/usb/ch9.h> | 17 | #include <linux/usb/ch9.h> |
18 | #include <linux/usb_gadget.h> | 18 | #include <linux/usb/gadget.h> |
19 | 19 | ||
20 | #include <asm/unaligned.h> | 20 | #include <asm/unaligned.h> |
21 | 21 | ||
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index a2e6e3fc8c8..fcde5d9c87d 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c | |||
@@ -1,38 +1,22 @@ | |||
1 | /* | 1 | /* |
2 | * zero.c -- Gadget Zero, for USB development | 2 | * zero.c -- Gadget Zero, for USB development |
3 | * | 3 | * |
4 | * Copyright (C) 2003-2004 David Brownell | 4 | * Copyright (C) 2003-2007 David Brownell |
5 | * All rights reserved. | 5 | * All rights reserved. |
6 | * | 6 | * |
7 | * Redistribution and use in source and binary forms, with or without | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * modification, are permitted provided that the following conditions | 8 | * it under the terms of the GNU General Public License as published by |
9 | * are met: | 9 | * the Free Software Foundation; either version 2 of the License, or |
10 | * 1. Redistributions of source code must retain the above copyright | 10 | * (at your option) any later version. |
11 | * notice, this list of conditions, and the following disclaimer, | ||
12 | * without modification. | ||
13 | * 2. Redistributions in binary form must reproduce the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer in the | ||
15 | * documentation and/or other materials provided with the distribution. | ||
16 | * 3. The names of the above-listed copyright holders may not be used | ||
17 | * to endorse or promote products derived from this software without | ||
18 | * specific prior written permission. | ||
19 | * | 11 | * |
20 | * ALTERNATIVELY, this software may be distributed under the terms of the | 12 | * This program is distributed in the hope that it will be useful, |
21 | * GNU General Public License ("GPL") as published by the Free Software | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
22 | * Foundation, either version 2 of that License or (at your option) any | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
23 | * later version. | 15 | * GNU General Public License for more details. |
24 | * | 16 | * |
25 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | 17 | * You should have received a copy of the GNU General Public License |
26 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | 18 | * along with this program; if not, write to the Free Software |
27 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
28 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR | ||
29 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
30 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
31 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
32 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
33 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
34 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
35 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
36 | */ | 20 | */ |
37 | 21 | ||
38 | 22 | ||
@@ -57,40 +41,28 @@ | |||
57 | * Many drivers will only have one configuration, letting them be much | 41 | * Many drivers will only have one configuration, letting them be much |
58 | * simpler if they also don't support high speed operation (like this | 42 | * simpler if they also don't support high speed operation (like this |
59 | * driver does). | 43 | * driver does). |
44 | * | ||
45 | * Why is *this* driver using two configurations, rather than setting up | ||
46 | * two interfaces with different functions? To help verify that multiple | ||
47 | * configuration infrastucture is working correctly; also, so that it can | ||
48 | * work with low capability USB controllers without four bulk endpoints. | ||
60 | */ | 49 | */ |
61 | 50 | ||
62 | #define DEBUG 1 | 51 | /* #define VERBOSE_DEBUG */ |
63 | // #define VERBOSE | ||
64 | 52 | ||
65 | #include <linux/module.h> | ||
66 | #include <linux/kernel.h> | 53 | #include <linux/kernel.h> |
67 | #include <linux/delay.h> | ||
68 | #include <linux/ioport.h> | ||
69 | #include <linux/slab.h> | ||
70 | #include <linux/errno.h> | ||
71 | #include <linux/init.h> | ||
72 | #include <linux/timer.h> | ||
73 | #include <linux/list.h> | ||
74 | #include <linux/interrupt.h> | ||
75 | #include <linux/utsname.h> | 54 | #include <linux/utsname.h> |
76 | #include <linux/device.h> | 55 | #include <linux/device.h> |
77 | #include <linux/moduleparam.h> | ||
78 | |||
79 | #include <asm/byteorder.h> | ||
80 | #include <asm/io.h> | ||
81 | #include <asm/irq.h> | ||
82 | #include <asm/system.h> | ||
83 | #include <asm/unaligned.h> | ||
84 | 56 | ||
85 | #include <linux/usb/ch9.h> | 57 | #include <linux/usb/ch9.h> |
86 | #include <linux/usb_gadget.h> | 58 | #include <linux/usb/gadget.h> |
87 | 59 | ||
88 | #include "gadget_chips.h" | 60 | #include "gadget_chips.h" |
89 | 61 | ||
90 | 62 | ||
91 | /*-------------------------------------------------------------------------*/ | 63 | /*-------------------------------------------------------------------------*/ |
92 | 64 | ||
93 | #define DRIVER_VERSION "St Patrick's Day 2004" | 65 | #define DRIVER_VERSION "Lughnasadh, 2007" |
94 | 66 | ||
95 | static const char shortname [] = "zero"; | 67 | static const char shortname [] = "zero"; |
96 | static const char longname [] = "Gadget Zero"; | 68 | static const char longname [] = "Gadget Zero"; |
@@ -131,30 +103,16 @@ struct zero_dev { | |||
131 | struct timer_list resume; | 103 | struct timer_list resume; |
132 | }; | 104 | }; |
133 | 105 | ||
134 | #define xprintk(d,level,fmt,args...) \ | 106 | #define DBG(d, fmt, args...) \ |
135 | dev_printk(level , &(d)->gadget->dev , fmt , ## args) | 107 | dev_dbg(&(d)->gadget->dev , fmt , ## args) |
136 | 108 | #define VDBG(d, fmt, args...) \ | |
137 | #ifdef DEBUG | 109 | dev_vdbg(&(d)->gadget->dev , fmt , ## args) |
138 | #define DBG(dev,fmt,args...) \ | 110 | #define ERROR(d, fmt, args...) \ |
139 | xprintk(dev , KERN_DEBUG , fmt , ## args) | 111 | dev_err(&(d)->gadget->dev , fmt , ## args) |
140 | #else | 112 | #define WARN(d, fmt, args...) \ |
141 | #define DBG(dev,fmt,args...) \ | 113 | dev_warn(&(d)->gadget->dev , fmt , ## args) |
142 | do { } while (0) | 114 | #define INFO(d, fmt, args...) \ |
143 | #endif /* DEBUG */ | 115 | dev_info(&(d)->gadget->dev , fmt , ## args) |
144 | |||
145 | #ifdef VERBOSE | ||
146 | #define VDBG DBG | ||
147 | #else | ||
148 | #define VDBG(dev,fmt,args...) \ | ||
149 | do { } while (0) | ||
150 | #endif /* VERBOSE */ | ||
151 | |||
152 | #define ERROR(dev,fmt,args...) \ | ||
153 | xprintk(dev , KERN_ERR , fmt , ## args) | ||
154 | #define WARN(dev,fmt,args...) \ | ||
155 | xprintk(dev , KERN_WARNING , fmt , ## args) | ||
156 | #define INFO(dev,fmt,args...) \ | ||
157 | xprintk(dev , KERN_INFO , fmt , ## args) | ||
158 | 116 | ||
159 | /*-------------------------------------------------------------------------*/ | 117 | /*-------------------------------------------------------------------------*/ |
160 | 118 | ||
@@ -326,8 +284,6 @@ static const struct usb_descriptor_header *fs_loopback_function [] = { | |||
326 | NULL, | 284 | NULL, |
327 | }; | 285 | }; |
328 | 286 | ||
329 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
330 | |||
331 | /* | 287 | /* |
332 | * usb 2.0 devices need to expose both high speed and full speed | 288 | * usb 2.0 devices need to expose both high speed and full speed |
333 | * descriptors, unless they only run at full speed. | 289 | * descriptors, unless they only run at full speed. |
@@ -383,17 +339,20 @@ static const struct usb_descriptor_header *hs_loopback_function [] = { | |||
383 | }; | 339 | }; |
384 | 340 | ||
385 | /* maxpacket and other transfer characteristics vary by speed. */ | 341 | /* maxpacket and other transfer characteristics vary by speed. */ |
386 | #define ep_desc(g,hs,fs) (((g)->speed==USB_SPEED_HIGH)?(hs):(fs)) | 342 | static inline struct usb_endpoint_descriptor * |
387 | 343 | ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *hs, | |
388 | #else | 344 | struct usb_endpoint_descriptor *fs) |
345 | { | ||
346 | if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH) | ||
347 | return hs; | ||
348 | return fs; | ||
349 | } | ||
389 | 350 | ||
390 | /* if there's no high speed support, maxpacket doesn't change. */ | 351 | static char manufacturer[50]; |
391 | #define ep_desc(g,hs,fs) fs | ||
392 | 352 | ||
393 | #endif /* !CONFIG_USB_GADGET_DUALSPEED */ | 353 | /* default serial number takes at least two packets */ |
354 | static char serial[] = "0123456789.0123456789.0123456789"; | ||
394 | 355 | ||
395 | static char manufacturer [50]; | ||
396 | static char serial [40]; | ||
397 | 356 | ||
398 | /* static strings, in UTF-8 */ | 357 | /* static strings, in UTF-8 */ |
399 | static struct usb_string strings [] = { | 358 | static struct usb_string strings [] = { |
@@ -435,30 +394,29 @@ config_buf (struct usb_gadget *gadget, | |||
435 | int is_source_sink; | 394 | int is_source_sink; |
436 | int len; | 395 | int len; |
437 | const struct usb_descriptor_header **function; | 396 | const struct usb_descriptor_header **function; |
438 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 397 | int hs = 0; |
439 | int hs = (gadget->speed == USB_SPEED_HIGH); | ||
440 | #endif | ||
441 | 398 | ||
442 | /* two configurations will always be index 0 and index 1 */ | 399 | /* two configurations will always be index 0 and index 1 */ |
443 | if (index > 1) | 400 | if (index > 1) |
444 | return -EINVAL; | 401 | return -EINVAL; |
445 | is_source_sink = loopdefault ? (index == 1) : (index == 0); | 402 | is_source_sink = loopdefault ? (index == 1) : (index == 0); |
446 | 403 | ||
447 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 404 | if (gadget_is_dualspeed(gadget)) { |
448 | if (type == USB_DT_OTHER_SPEED_CONFIG) | 405 | hs = (gadget->speed == USB_SPEED_HIGH); |
449 | hs = !hs; | 406 | if (type == USB_DT_OTHER_SPEED_CONFIG) |
407 | hs = !hs; | ||
408 | } | ||
450 | if (hs) | 409 | if (hs) |
451 | function = is_source_sink | 410 | function = is_source_sink |
452 | ? hs_source_sink_function | 411 | ? hs_source_sink_function |
453 | : hs_loopback_function; | 412 | : hs_loopback_function; |
454 | else | 413 | else |
455 | #endif | ||
456 | function = is_source_sink | 414 | function = is_source_sink |
457 | ? fs_source_sink_function | 415 | ? fs_source_sink_function |
458 | : fs_loopback_function; | 416 | : fs_loopback_function; |
459 | 417 | ||
460 | /* for now, don't advertise srp-only devices */ | 418 | /* for now, don't advertise srp-only devices */ |
461 | if (!gadget->is_otg) | 419 | if (!gadget_is_otg(gadget)) |
462 | function++; | 420 | function++; |
463 | 421 | ||
464 | len = usb_gadget_config_buf (is_source_sink | 422 | len = usb_gadget_config_buf (is_source_sink |
@@ -498,6 +456,19 @@ static void free_ep_req (struct usb_ep *ep, struct usb_request *req) | |||
498 | 456 | ||
499 | /*-------------------------------------------------------------------------*/ | 457 | /*-------------------------------------------------------------------------*/ |
500 | 458 | ||
459 | /* | ||
460 | * SOURCE/SINK FUNCTION ... a primary testing vehicle for USB peripherals, | ||
461 | * this just sinks bulk packets OUT to the peripheral and sources them IN | ||
462 | * to the host, optionally with specific data patterns. | ||
463 | * | ||
464 | * In terms of control messaging, this supports all the standard requests | ||
465 | * plus two that support control-OUT tests. | ||
466 | * | ||
467 | * Note that because this doesn't queue more than one request at a time, | ||
468 | * some other function must be used to test queueing logic. The network | ||
469 | * link (g_ether) is probably the best option for that. | ||
470 | */ | ||
471 | |||
501 | /* optionally require specific source/sink data patterns */ | 472 | /* optionally require specific source/sink data patterns */ |
502 | 473 | ||
503 | static int | 474 | static int |
@@ -534,12 +505,7 @@ check_read_data ( | |||
534 | return 0; | 505 | return 0; |
535 | } | 506 | } |
536 | 507 | ||
537 | static void | 508 | static void reinit_write_data(struct usb_ep *ep, struct usb_request *req) |
538 | reinit_write_data ( | ||
539 | struct zero_dev *dev, | ||
540 | struct usb_ep *ep, | ||
541 | struct usb_request *req | ||
542 | ) | ||
543 | { | 509 | { |
544 | unsigned i; | 510 | unsigned i; |
545 | u8 *buf = req->buf; | 511 | u8 *buf = req->buf; |
@@ -566,16 +532,16 @@ static void source_sink_complete (struct usb_ep *ep, struct usb_request *req) | |||
566 | 532 | ||
567 | switch (status) { | 533 | switch (status) { |
568 | 534 | ||
569 | case 0: /* normal completion? */ | 535 | case 0: /* normal completion? */ |
570 | if (ep == dev->out_ep) { | 536 | if (ep == dev->out_ep) { |
571 | check_read_data (dev, ep, req); | 537 | check_read_data (dev, ep, req); |
572 | memset (req->buf, 0x55, req->length); | 538 | memset (req->buf, 0x55, req->length); |
573 | } else | 539 | } else |
574 | reinit_write_data (dev, ep, req); | 540 | reinit_write_data(ep, req); |
575 | break; | 541 | break; |
576 | 542 | ||
577 | /* this endpoint is normally active while we're configured */ | 543 | /* this endpoint is normally active while we're configured */ |
578 | case -ECONNABORTED: /* hardware forced ep reset */ | 544 | case -ECONNABORTED: /* hardware forced ep reset */ |
579 | case -ECONNRESET: /* request dequeued */ | 545 | case -ECONNRESET: /* request dequeued */ |
580 | case -ESHUTDOWN: /* disconnect from host */ | 546 | case -ESHUTDOWN: /* disconnect from host */ |
581 | VDBG (dev, "%s gone (%d), %d/%d\n", ep->name, status, | 547 | VDBG (dev, "%s gone (%d), %d/%d\n", ep->name, status, |
@@ -607,8 +573,7 @@ static void source_sink_complete (struct usb_ep *ep, struct usb_request *req) | |||
607 | } | 573 | } |
608 | } | 574 | } |
609 | 575 | ||
610 | static struct usb_request * | 576 | static struct usb_request *source_sink_start_ep(struct usb_ep *ep) |
611 | source_sink_start_ep (struct usb_ep *ep, gfp_t gfp_flags) | ||
612 | { | 577 | { |
613 | struct usb_request *req; | 578 | struct usb_request *req; |
614 | int status; | 579 | int status; |
@@ -621,11 +586,11 @@ source_sink_start_ep (struct usb_ep *ep, gfp_t gfp_flags) | |||
621 | req->complete = source_sink_complete; | 586 | req->complete = source_sink_complete; |
622 | 587 | ||
623 | if (strcmp (ep->name, EP_IN_NAME) == 0) | 588 | if (strcmp (ep->name, EP_IN_NAME) == 0) |
624 | reinit_write_data (ep->driver_data, ep, req); | 589 | reinit_write_data(ep, req); |
625 | else | 590 | else |
626 | memset (req->buf, 0x55, req->length); | 591 | memset (req->buf, 0x55, req->length); |
627 | 592 | ||
628 | status = usb_ep_queue (ep, req, gfp_flags); | 593 | status = usb_ep_queue(ep, req, GFP_ATOMIC); |
629 | if (status) { | 594 | if (status) { |
630 | struct zero_dev *dev = ep->driver_data; | 595 | struct zero_dev *dev = ep->driver_data; |
631 | 596 | ||
@@ -637,8 +602,7 @@ source_sink_start_ep (struct usb_ep *ep, gfp_t gfp_flags) | |||
637 | return req; | 602 | return req; |
638 | } | 603 | } |
639 | 604 | ||
640 | static int | 605 | static int set_source_sink_config(struct zero_dev *dev) |
641 | set_source_sink_config (struct zero_dev *dev, gfp_t gfp_flags) | ||
642 | { | 606 | { |
643 | int result = 0; | 607 | int result = 0; |
644 | struct usb_ep *ep; | 608 | struct usb_ep *ep; |
@@ -653,7 +617,7 @@ set_source_sink_config (struct zero_dev *dev, gfp_t gfp_flags) | |||
653 | result = usb_ep_enable (ep, d); | 617 | result = usb_ep_enable (ep, d); |
654 | if (result == 0) { | 618 | if (result == 0) { |
655 | ep->driver_data = dev; | 619 | ep->driver_data = dev; |
656 | if (source_sink_start_ep (ep, gfp_flags) != 0) { | 620 | if (source_sink_start_ep(ep) != NULL) { |
657 | dev->in_ep = ep; | 621 | dev->in_ep = ep; |
658 | continue; | 622 | continue; |
659 | } | 623 | } |
@@ -667,7 +631,7 @@ set_source_sink_config (struct zero_dev *dev, gfp_t gfp_flags) | |||
667 | result = usb_ep_enable (ep, d); | 631 | result = usb_ep_enable (ep, d); |
668 | if (result == 0) { | 632 | if (result == 0) { |
669 | ep->driver_data = dev; | 633 | ep->driver_data = dev; |
670 | if (source_sink_start_ep (ep, gfp_flags) != 0) { | 634 | if (source_sink_start_ep(ep) != NULL) { |
671 | dev->out_ep = ep; | 635 | dev->out_ep = ep; |
672 | continue; | 636 | continue; |
673 | } | 637 | } |
@@ -699,7 +663,7 @@ static void loopback_complete (struct usb_ep *ep, struct usb_request *req) | |||
699 | 663 | ||
700 | switch (status) { | 664 | switch (status) { |
701 | 665 | ||
702 | case 0: /* normal completion? */ | 666 | case 0: /* normal completion? */ |
703 | if (ep == dev->out_ep) { | 667 | if (ep == dev->out_ep) { |
704 | /* loop this OUT packet back IN to the host */ | 668 | /* loop this OUT packet back IN to the host */ |
705 | req->zero = (req->actual < req->length); | 669 | req->zero = (req->actual < req->length); |
@@ -733,7 +697,7 @@ static void loopback_complete (struct usb_ep *ep, struct usb_request *req) | |||
733 | * rely on the hardware driver to clean up on disconnect or | 697 | * rely on the hardware driver to clean up on disconnect or |
734 | * endpoint disable. | 698 | * endpoint disable. |
735 | */ | 699 | */ |
736 | case -ECONNABORTED: /* hardware forced ep reset */ | 700 | case -ECONNABORTED: /* hardware forced ep reset */ |
737 | case -ECONNRESET: /* request dequeued */ | 701 | case -ECONNRESET: /* request dequeued */ |
738 | case -ESHUTDOWN: /* disconnect from host */ | 702 | case -ESHUTDOWN: /* disconnect from host */ |
739 | free_ep_req (ep, req); | 703 | free_ep_req (ep, req); |
@@ -741,8 +705,7 @@ static void loopback_complete (struct usb_ep *ep, struct usb_request *req) | |||
741 | } | 705 | } |
742 | } | 706 | } |
743 | 707 | ||
744 | static int | 708 | static int set_loopback_config(struct zero_dev *dev) |
745 | set_loopback_config (struct zero_dev *dev, gfp_t gfp_flags) | ||
746 | { | 709 | { |
747 | int result = 0; | 710 | int result = 0; |
748 | struct usb_ep *ep; | 711 | struct usb_ep *ep; |
@@ -842,8 +805,7 @@ static void zero_reset_config (struct zero_dev *dev) | |||
842 | * code can do, perhaps by disallowing more than one configuration or | 805 | * code can do, perhaps by disallowing more than one configuration or |
843 | * by limiting configuration choices (like the pxa2xx). | 806 | * by limiting configuration choices (like the pxa2xx). |
844 | */ | 807 | */ |
845 | static int | 808 | static int zero_set_config(struct zero_dev *dev, unsigned number) |
846 | zero_set_config (struct zero_dev *dev, unsigned number, gfp_t gfp_flags) | ||
847 | { | 809 | { |
848 | int result = 0; | 810 | int result = 0; |
849 | struct usb_gadget *gadget = dev->gadget; | 811 | struct usb_gadget *gadget = dev->gadget; |
@@ -853,17 +815,17 @@ zero_set_config (struct zero_dev *dev, unsigned number, gfp_t gfp_flags) | |||
853 | 815 | ||
854 | if (gadget_is_sa1100 (gadget) && dev->config) { | 816 | if (gadget_is_sa1100 (gadget) && dev->config) { |
855 | /* tx fifo is full, but we can't clear it...*/ | 817 | /* tx fifo is full, but we can't clear it...*/ |
856 | INFO (dev, "can't change configurations\n"); | 818 | ERROR(dev, "can't change configurations\n"); |
857 | return -ESPIPE; | 819 | return -ESPIPE; |
858 | } | 820 | } |
859 | zero_reset_config (dev); | 821 | zero_reset_config (dev); |
860 | 822 | ||
861 | switch (number) { | 823 | switch (number) { |
862 | case CONFIG_SOURCE_SINK: | 824 | case CONFIG_SOURCE_SINK: |
863 | result = set_source_sink_config (dev, gfp_flags); | 825 | result = set_source_sink_config(dev); |
864 | break; | 826 | break; |
865 | case CONFIG_LOOPBACK: | 827 | case CONFIG_LOOPBACK: |
866 | result = set_loopback_config (dev, gfp_flags); | 828 | result = set_loopback_config(dev); |
867 | break; | 829 | break; |
868 | default: | 830 | default: |
869 | result = -EINVAL; | 831 | result = -EINVAL; |
@@ -883,7 +845,7 @@ zero_set_config (struct zero_dev *dev, unsigned number, gfp_t gfp_flags) | |||
883 | case USB_SPEED_LOW: speed = "low"; break; | 845 | case USB_SPEED_LOW: speed = "low"; break; |
884 | case USB_SPEED_FULL: speed = "full"; break; | 846 | case USB_SPEED_FULL: speed = "full"; break; |
885 | case USB_SPEED_HIGH: speed = "high"; break; | 847 | case USB_SPEED_HIGH: speed = "high"; break; |
886 | default: speed = "?"; break; | 848 | default: speed = "?"; break; |
887 | } | 849 | } |
888 | 850 | ||
889 | dev->config = number; | 851 | dev->config = number; |
@@ -936,19 +898,17 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
936 | value = min (w_length, (u16) sizeof device_desc); | 898 | value = min (w_length, (u16) sizeof device_desc); |
937 | memcpy (req->buf, &device_desc, value); | 899 | memcpy (req->buf, &device_desc, value); |
938 | break; | 900 | break; |
939 | #ifdef CONFIG_USB_GADGET_DUALSPEED | ||
940 | case USB_DT_DEVICE_QUALIFIER: | 901 | case USB_DT_DEVICE_QUALIFIER: |
941 | if (!gadget->is_dualspeed) | 902 | if (!gadget_is_dualspeed(gadget)) |
942 | break; | 903 | break; |
943 | value = min (w_length, (u16) sizeof dev_qualifier); | 904 | value = min (w_length, (u16) sizeof dev_qualifier); |
944 | memcpy (req->buf, &dev_qualifier, value); | 905 | memcpy (req->buf, &dev_qualifier, value); |
945 | break; | 906 | break; |
946 | 907 | ||
947 | case USB_DT_OTHER_SPEED_CONFIG: | 908 | case USB_DT_OTHER_SPEED_CONFIG: |
948 | if (!gadget->is_dualspeed) | 909 | if (!gadget_is_dualspeed(gadget)) |
949 | break; | 910 | break; |
950 | // FALLTHROUGH | 911 | // FALLTHROUGH |
951 | #endif /* CONFIG_USB_GADGET_DUALSPEED */ | ||
952 | case USB_DT_CONFIG: | 912 | case USB_DT_CONFIG: |
953 | value = config_buf (gadget, req->buf, | 913 | value = config_buf (gadget, req->buf, |
954 | w_value >> 8, | 914 | w_value >> 8, |
@@ -982,7 +942,7 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
982 | else | 942 | else |
983 | VDBG (dev, "HNP inactive\n"); | 943 | VDBG (dev, "HNP inactive\n"); |
984 | spin_lock (&dev->lock); | 944 | spin_lock (&dev->lock); |
985 | value = zero_set_config (dev, w_value, GFP_ATOMIC); | 945 | value = zero_set_config(dev, w_value); |
986 | spin_unlock (&dev->lock); | 946 | spin_unlock (&dev->lock); |
987 | break; | 947 | break; |
988 | case USB_REQ_GET_CONFIGURATION: | 948 | case USB_REQ_GET_CONFIGURATION: |
@@ -1011,7 +971,7 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) | |||
1011 | * use this "reset the config" shortcut. | 971 | * use this "reset the config" shortcut. |
1012 | */ | 972 | */ |
1013 | zero_reset_config (dev); | 973 | zero_reset_config (dev); |
1014 | zero_set_config (dev, config, GFP_ATOMIC); | 974 | zero_set_config(dev, config); |
1015 | value = 0; | 975 | value = 0; |
1016 | } | 976 | } |
1017 | spin_unlock (&dev->lock); | 977 | spin_unlock (&dev->lock); |
@@ -1161,7 +1121,7 @@ autoconf_fail: | |||
1161 | } | 1121 | } |
1162 | EP_IN_NAME = ep->name; | 1122 | EP_IN_NAME = ep->name; |
1163 | ep->driver_data = ep; /* claim */ | 1123 | ep->driver_data = ep; /* claim */ |
1164 | 1124 | ||
1165 | ep = usb_ep_autoconfig (gadget, &fs_sink_desc); | 1125 | ep = usb_ep_autoconfig (gadget, &fs_sink_desc); |
1166 | if (!ep) | 1126 | if (!ep) |
1167 | goto autoconf_fail; | 1127 | goto autoconf_fail; |
@@ -1205,16 +1165,18 @@ autoconf_fail: | |||
1205 | 1165 | ||
1206 | device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; | 1166 | device_desc.bMaxPacketSize0 = gadget->ep0->maxpacket; |
1207 | 1167 | ||
1208 | #ifdef CONFIG_USB_GADGET_DUALSPEED | 1168 | if (gadget_is_dualspeed(gadget)) { |
1209 | /* assume ep0 uses the same value for both speeds ... */ | 1169 | /* assume ep0 uses the same value for both speeds ... */ |
1210 | dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0; | 1170 | dev_qualifier.bMaxPacketSize0 = device_desc.bMaxPacketSize0; |
1211 | 1171 | ||
1212 | /* and that all endpoints are dual-speed */ | 1172 | /* and that all endpoints are dual-speed */ |
1213 | hs_source_desc.bEndpointAddress = fs_source_desc.bEndpointAddress; | 1173 | hs_source_desc.bEndpointAddress = |
1214 | hs_sink_desc.bEndpointAddress = fs_sink_desc.bEndpointAddress; | 1174 | fs_source_desc.bEndpointAddress; |
1215 | #endif | 1175 | hs_sink_desc.bEndpointAddress = |
1176 | fs_sink_desc.bEndpointAddress; | ||
1177 | } | ||
1216 | 1178 | ||
1217 | if (gadget->is_otg) { | 1179 | if (gadget_is_otg(gadget)) { |
1218 | otg_descriptor.bmAttributes |= USB_OTG_HNP, | 1180 | otg_descriptor.bmAttributes |= USB_OTG_HNP, |
1219 | source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 1181 | source_sink_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
1220 | loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; | 1182 | loopback_config.bmAttributes |= USB_CONFIG_ATT_WAKEUP; |
@@ -1292,23 +1254,18 @@ static struct usb_gadget_driver zero_driver = { | |||
1292 | .suspend = zero_suspend, | 1254 | .suspend = zero_suspend, |
1293 | .resume = zero_resume, | 1255 | .resume = zero_resume, |
1294 | 1256 | ||
1295 | .driver = { | 1257 | .driver = { |
1296 | .name = (char *) shortname, | 1258 | .name = (char *) shortname, |
1297 | .owner = THIS_MODULE, | 1259 | .owner = THIS_MODULE, |
1298 | }, | 1260 | }, |
1299 | }; | 1261 | }; |
1300 | 1262 | ||
1301 | MODULE_AUTHOR ("David Brownell"); | 1263 | MODULE_AUTHOR("David Brownell"); |
1302 | MODULE_LICENSE ("Dual BSD/GPL"); | 1264 | MODULE_LICENSE("GPL"); |
1303 | 1265 | ||
1304 | 1266 | ||
1305 | static int __init init (void) | 1267 | static int __init init (void) |
1306 | { | 1268 | { |
1307 | /* a real value would likely come through some id prom | ||
1308 | * or module option. this one takes at least two packets. | ||
1309 | */ | ||
1310 | strlcpy (serial, "0123456789.0123456789.0123456789", sizeof serial); | ||
1311 | |||
1312 | return usb_gadget_register_driver (&zero_driver); | 1269 | return usb_gadget_register_driver (&zero_driver); |
1313 | } | 1270 | } |
1314 | module_init (init); | 1271 | module_init (init); |
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 2f529828c74..c978d622fa8 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig | |||
@@ -154,6 +154,19 @@ config USB_OHCI_HCD_PCI | |||
154 | Enables support for PCI-bus plug-in USB controller cards. | 154 | Enables support for PCI-bus plug-in USB controller cards. |
155 | If unsure, say Y. | 155 | If unsure, say Y. |
156 | 156 | ||
157 | config USB_OHCI_HCD_SSB | ||
158 | bool "OHCI support for Broadcom SSB OHCI core" | ||
159 | depends on USB_OHCI_HCD && SSB && EXPERIMENTAL | ||
160 | default n | ||
161 | ---help--- | ||
162 | Support for the Sonics Silicon Backplane (SSB) attached | ||
163 | Broadcom USB OHCI core. | ||
164 | |||
165 | This device is present in some embedded devices with | ||
166 | Broadcom based SSB bus. | ||
167 | |||
168 | If unsure, say N. | ||
169 | |||
157 | config USB_OHCI_BIG_ENDIAN_DESC | 170 | config USB_OHCI_BIG_ENDIAN_DESC |
158 | bool | 171 | bool |
159 | depends on USB_OHCI_HCD | 172 | depends on USB_OHCI_HCD |
@@ -237,7 +250,7 @@ config USB_SL811_CS | |||
237 | module will be called "sl811_cs". | 250 | module will be called "sl811_cs". |
238 | 251 | ||
239 | config USB_R8A66597_HCD | 252 | config USB_R8A66597_HCD |
240 | tristate "R8A66597 HCD suppoort" | 253 | tristate "R8A66597 HCD support" |
241 | depends on USB | 254 | depends on USB |
242 | help | 255 | help |
243 | The R8A66597 is a USB 2.0 host and peripheral controller. | 256 | The R8A66597 is a USB 2.0 host and peripheral controller. |
diff --git a/drivers/usb/host/ehci-au1xxx.c b/drivers/usb/host/ehci-au1xxx.c index 5d1b12aad77..766ef68a0b4 100644 --- a/drivers/usb/host/ehci-au1xxx.c +++ b/drivers/usb/host/ehci-au1xxx.c | |||
@@ -1,8 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * EHCI HCD (Host Controller Driver) for USB. | 2 | * EHCI HCD (Host Controller Driver) for USB. |
3 | * | 3 | * |
4 | * (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net> | ||
5 | * | ||
6 | * Bus Glue for AMD Alchemy Au1xxx | 4 | * Bus Glue for AMD Alchemy Au1xxx |
7 | * | 5 | * |
8 | * Based on "ohci-au1xxx.c" by Matt Porter <mporter@kernel.crashing.org> | 6 | * Based on "ohci-au1xxx.c" by Matt Porter <mporter@kernel.crashing.org> |
@@ -196,6 +194,9 @@ static const struct hc_driver ehci_au1xxx_hc_driver = { | |||
196 | 194 | ||
197 | /* | 195 | /* |
198 | * basic lifecycle operations | 196 | * basic lifecycle operations |
197 | * | ||
198 | * FIXME -- ehci_init() doesn't do enough here. | ||
199 | * See ehci-ppc-soc for a complete implementation. | ||
199 | */ | 200 | */ |
200 | .reset = ehci_init, | 201 | .reset = ehci_init, |
201 | .start = ehci_run, | 202 | .start = ehci_run, |
@@ -219,10 +220,8 @@ static const struct hc_driver ehci_au1xxx_hc_driver = { | |||
219 | */ | 220 | */ |
220 | .hub_status_data = ehci_hub_status_data, | 221 | .hub_status_data = ehci_hub_status_data, |
221 | .hub_control = ehci_hub_control, | 222 | .hub_control = ehci_hub_control, |
222 | #ifdef CONFIG_PM | 223 | .bus_suspend = ehci_bus_suspend, |
223 | .hub_suspend = ehci_hub_suspend, | 224 | .bus_resume = ehci_bus_resume, |
224 | .hub_resume = ehci_hub_resume, | ||
225 | #endif | ||
226 | }; | 225 | }; |
227 | 226 | ||
228 | /*-------------------------------------------------------------------------*/ | 227 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index c4e15ed1405..c1514442883 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c | |||
@@ -275,58 +275,6 @@ static void ehci_work(struct ehci_hcd *ehci); | |||
275 | 275 | ||
276 | /*-------------------------------------------------------------------------*/ | 276 | /*-------------------------------------------------------------------------*/ |
277 | 277 | ||
278 | #ifdef CONFIG_CPU_FREQ | ||
279 | |||
280 | #include <linux/cpufreq.h> | ||
281 | |||
282 | static void ehci_cpufreq_pause (struct ehci_hcd *ehci) | ||
283 | { | ||
284 | unsigned long flags; | ||
285 | |||
286 | spin_lock_irqsave(&ehci->lock, flags); | ||
287 | if (!ehci->cpufreq_changing++) | ||
288 | qh_inactivate_split_intr_qhs(ehci); | ||
289 | spin_unlock_irqrestore(&ehci->lock, flags); | ||
290 | } | ||
291 | |||
292 | static void ehci_cpufreq_unpause (struct ehci_hcd *ehci) | ||
293 | { | ||
294 | unsigned long flags; | ||
295 | |||
296 | spin_lock_irqsave(&ehci->lock, flags); | ||
297 | if (!--ehci->cpufreq_changing) | ||
298 | qh_reactivate_split_intr_qhs(ehci); | ||
299 | spin_unlock_irqrestore(&ehci->lock, flags); | ||
300 | } | ||
301 | |||
302 | /* | ||
303 | * ehci_cpufreq_notifier is needed to avoid MMF errors that occur when | ||
304 | * EHCI controllers that don't cache many uframes get delayed trying to | ||
305 | * read main memory during CPU frequency transitions. This can cause | ||
306 | * split interrupt transactions to not be completed in the required uframe. | ||
307 | * This has been observed on the Broadcom/ServerWorks HT1000 controller. | ||
308 | */ | ||
309 | static int ehci_cpufreq_notifier(struct notifier_block *nb, unsigned long val, | ||
310 | void *data) | ||
311 | { | ||
312 | struct ehci_hcd *ehci = container_of(nb, struct ehci_hcd, | ||
313 | cpufreq_transition); | ||
314 | |||
315 | switch (val) { | ||
316 | case CPUFREQ_PRECHANGE: | ||
317 | ehci_cpufreq_pause(ehci); | ||
318 | break; | ||
319 | case CPUFREQ_POSTCHANGE: | ||
320 | ehci_cpufreq_unpause(ehci); | ||
321 | break; | ||
322 | } | ||
323 | return 0; | ||
324 | } | ||
325 | |||
326 | #endif | ||
327 | |||
328 | /*-------------------------------------------------------------------------*/ | ||
329 | |||
330 | static void ehci_watchdog (unsigned long param) | 278 | static void ehci_watchdog (unsigned long param) |
331 | { | 279 | { |
332 | struct ehci_hcd *ehci = (struct ehci_hcd *) param; | 280 | struct ehci_hcd *ehci = (struct ehci_hcd *) param; |
@@ -460,10 +408,6 @@ static void ehci_stop (struct usb_hcd *hcd) | |||
460 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); | 408 | ehci_writel(ehci, 0, &ehci->regs->intr_enable); |
461 | spin_unlock_irq(&ehci->lock); | 409 | spin_unlock_irq(&ehci->lock); |
462 | 410 | ||
463 | #ifdef CONFIG_CPU_FREQ | ||
464 | cpufreq_unregister_notifier(&ehci->cpufreq_transition, | ||
465 | CPUFREQ_TRANSITION_NOTIFIER); | ||
466 | #endif | ||
467 | /* let companion controllers work when we aren't */ | 411 | /* let companion controllers work when we aren't */ |
468 | ehci_writel(ehci, 0, &ehci->regs->configured_flag); | 412 | ehci_writel(ehci, 0, &ehci->regs->configured_flag); |
469 | 413 | ||
@@ -569,17 +513,6 @@ static int ehci_init(struct usb_hcd *hcd) | |||
569 | } | 513 | } |
570 | ehci->command = temp; | 514 | ehci->command = temp; |
571 | 515 | ||
572 | #ifdef CONFIG_CPU_FREQ | ||
573 | INIT_LIST_HEAD(&ehci->split_intr_qhs); | ||
574 | /* | ||
575 | * If the EHCI controller caches enough uframes, this probably | ||
576 | * isn't needed unless there are so many low/full speed devices | ||
577 | * that the controller's can't cache it all. | ||
578 | */ | ||
579 | ehci->cpufreq_transition.notifier_call = ehci_cpufreq_notifier; | ||
580 | cpufreq_register_notifier(&ehci->cpufreq_transition, | ||
581 | CPUFREQ_TRANSITION_NOTIFIER); | ||
582 | #endif | ||
583 | return 0; | 516 | return 0; |
584 | } | 517 | } |
585 | 518 | ||
@@ -637,10 +570,18 @@ static int ehci_run (struct usb_hcd *hcd) | |||
637 | * are explicitly handed to companion controller(s), so no TT is | 570 | * are explicitly handed to companion controller(s), so no TT is |
638 | * involved with the root hub. (Except where one is integrated, | 571 | * involved with the root hub. (Except where one is integrated, |
639 | * and there's no companion controller unless maybe for USB OTG.) | 572 | * and there's no companion controller unless maybe for USB OTG.) |
573 | * | ||
574 | * Turning on the CF flag will transfer ownership of all ports | ||
575 | * from the companions to the EHCI controller. If any of the | ||
576 | * companions are in the middle of a port reset at the time, it | ||
577 | * could cause trouble. Write-locking ehci_cf_port_reset_rwsem | ||
578 | * guarantees that no resets are in progress. | ||
640 | */ | 579 | */ |
580 | down_write(&ehci_cf_port_reset_rwsem); | ||
641 | hcd->state = HC_STATE_RUNNING; | 581 | hcd->state = HC_STATE_RUNNING; |
642 | ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); | 582 | ehci_writel(ehci, FLAG_CF, &ehci->regs->configured_flag); |
643 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ | 583 | ehci_readl(ehci, &ehci->regs->command); /* unblock posted writes */ |
584 | up_write(&ehci_cf_port_reset_rwsem); | ||
644 | 585 | ||
645 | temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); | 586 | temp = HC_VERSION(ehci_readl(ehci, &ehci->caps->hc_capbase)); |
646 | ehci_info (ehci, | 587 | ehci_info (ehci, |
@@ -786,7 +727,6 @@ dead: | |||
786 | */ | 727 | */ |
787 | static int ehci_urb_enqueue ( | 728 | static int ehci_urb_enqueue ( |
788 | struct usb_hcd *hcd, | 729 | struct usb_hcd *hcd, |
789 | struct usb_host_endpoint *ep, | ||
790 | struct urb *urb, | 730 | struct urb *urb, |
791 | gfp_t mem_flags | 731 | gfp_t mem_flags |
792 | ) { | 732 | ) { |
@@ -801,12 +741,12 @@ static int ehci_urb_enqueue ( | |||
801 | default: | 741 | default: |
802 | if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags)) | 742 | if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags)) |
803 | return -ENOMEM; | 743 | return -ENOMEM; |
804 | return submit_async (ehci, ep, urb, &qtd_list, mem_flags); | 744 | return submit_async(ehci, urb, &qtd_list, mem_flags); |
805 | 745 | ||
806 | case PIPE_INTERRUPT: | 746 | case PIPE_INTERRUPT: |
807 | if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags)) | 747 | if (!qh_urb_transaction (ehci, urb, &qtd_list, mem_flags)) |
808 | return -ENOMEM; | 748 | return -ENOMEM; |
809 | return intr_submit (ehci, ep, urb, &qtd_list, mem_flags); | 749 | return intr_submit(ehci, urb, &qtd_list, mem_flags); |
810 | 750 | ||
811 | case PIPE_ISOCHRONOUS: | 751 | case PIPE_ISOCHRONOUS: |
812 | if (urb->dev->speed == USB_SPEED_HIGH) | 752 | if (urb->dev->speed == USB_SPEED_HIGH) |
@@ -844,13 +784,18 @@ static void unlink_async (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
844 | * completions normally happen asynchronously | 784 | * completions normally happen asynchronously |
845 | */ | 785 | */ |
846 | 786 | ||
847 | static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) | 787 | static int ehci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) |
848 | { | 788 | { |
849 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); | 789 | struct ehci_hcd *ehci = hcd_to_ehci (hcd); |
850 | struct ehci_qh *qh; | 790 | struct ehci_qh *qh; |
851 | unsigned long flags; | 791 | unsigned long flags; |
792 | int rc; | ||
852 | 793 | ||
853 | spin_lock_irqsave (&ehci->lock, flags); | 794 | spin_lock_irqsave (&ehci->lock, flags); |
795 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); | ||
796 | if (rc) | ||
797 | goto done; | ||
798 | |||
854 | switch (usb_pipetype (urb->pipe)) { | 799 | switch (usb_pipetype (urb->pipe)) { |
855 | // case PIPE_CONTROL: | 800 | // case PIPE_CONTROL: |
856 | // case PIPE_BULK: | 801 | // case PIPE_BULK: |
@@ -905,7 +850,7 @@ static int ehci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) | |||
905 | } | 850 | } |
906 | done: | 851 | done: |
907 | spin_unlock_irqrestore (&ehci->lock, flags); | 852 | spin_unlock_irqrestore (&ehci->lock, flags); |
908 | return 0; | 853 | return rc; |
909 | } | 854 | } |
910 | 855 | ||
911 | /*-------------------------------------------------------------------------*/ | 856 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ehci-mem.c b/drivers/usb/host/ehci-mem.c index 8816d09903d..0431397836f 100644 --- a/drivers/usb/host/ehci-mem.c +++ b/drivers/usb/host/ehci-mem.c | |||
@@ -94,9 +94,6 @@ static struct ehci_qh *ehci_qh_alloc (struct ehci_hcd *ehci, gfp_t flags) | |||
94 | qh->qh_dma = dma; | 94 | qh->qh_dma = dma; |
95 | // INIT_LIST_HEAD (&qh->qh_list); | 95 | // INIT_LIST_HEAD (&qh->qh_list); |
96 | INIT_LIST_HEAD (&qh->qtd_list); | 96 | INIT_LIST_HEAD (&qh->qtd_list); |
97 | #ifdef CONFIG_CPU_FREQ | ||
98 | INIT_LIST_HEAD (&qh->split_intr_qhs); | ||
99 | #endif | ||
100 | 97 | ||
101 | /* dummy td enables safe urb queuing */ | 98 | /* dummy td enables safe urb queuing */ |
102 | qh->dummy = ehci_qtd_alloc (ehci, flags); | 99 | qh->dummy = ehci_qtd_alloc (ehci, flags); |
diff --git a/drivers/usb/host/ehci-pci.c b/drivers/usb/host/ehci-pci.c index a7816e392a8..ad0d4965f2f 100644 --- a/drivers/usb/host/ehci-pci.c +++ b/drivers/usb/host/ehci-pci.c | |||
@@ -58,8 +58,6 @@ static int ehci_pci_reinit(struct ehci_hcd *ehci, struct pci_dev *pdev) | |||
58 | if (!retval) | 58 | if (!retval) |
59 | ehci_dbg(ehci, "MWI active\n"); | 59 | ehci_dbg(ehci, "MWI active\n"); |
60 | 60 | ||
61 | ehci_port_power(ehci, 0); | ||
62 | |||
63 | return 0; | 61 | return 0; |
64 | } | 62 | } |
65 | 63 | ||
@@ -156,8 +154,7 @@ static int ehci_pci_setup(struct usb_hcd *hcd) | |||
156 | break; | 154 | break; |
157 | } | 155 | } |
158 | 156 | ||
159 | if (ehci_is_TDI(ehci)) | 157 | ehci_reset(ehci); |
160 | ehci_reset(ehci); | ||
161 | 158 | ||
162 | /* at least the Genesys GL880S needs fixup here */ | 159 | /* at least the Genesys GL880S needs fixup here */ |
163 | temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params); | 160 | temp = HCS_N_CC(ehci->hcs_params) * HCS_N_PCC(ehci->hcs_params); |
diff --git a/drivers/usb/host/ehci-ppc-soc.c b/drivers/usb/host/ehci-ppc-soc.c index c2cedb09ed8..452d4b1bc85 100644 --- a/drivers/usb/host/ehci-ppc-soc.c +++ b/drivers/usb/host/ehci-ppc-soc.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * Bus Glue for PPC On-Chip EHCI driver | 6 | * Bus Glue for PPC On-Chip EHCI driver |
7 | * Tested on AMCC 440EPx | 7 | * Tested on AMCC 440EPx |
8 | * | 8 | * |
9 | * Based on "ehci-au12xx.c" by David Brownell <dbrownell@users.sourceforge.net> | 9 | * Based on "ehci-au1xxx.c" by K.Boge <karsten.boge@amd.com> |
10 | * | 10 | * |
11 | * This file is licenced under the GPL. | 11 | * This file is licenced under the GPL. |
12 | */ | 12 | */ |
@@ -15,6 +15,24 @@ | |||
15 | 15 | ||
16 | extern int usb_disabled(void); | 16 | extern int usb_disabled(void); |
17 | 17 | ||
18 | /* called during probe() after chip reset completes */ | ||
19 | static int ehci_ppc_soc_setup(struct usb_hcd *hcd) | ||
20 | { | ||
21 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
22 | int retval; | ||
23 | |||
24 | retval = ehci_halt(ehci); | ||
25 | if (retval) | ||
26 | return retval; | ||
27 | |||
28 | retval = ehci_init(hcd); | ||
29 | if (retval) | ||
30 | return retval; | ||
31 | |||
32 | ehci->sbrn = 0x20; | ||
33 | return ehci_reset(ehci); | ||
34 | } | ||
35 | |||
18 | /** | 36 | /** |
19 | * usb_ehci_ppc_soc_probe - initialize PPC-SoC-based HCDs | 37 | * usb_ehci_ppc_soc_probe - initialize PPC-SoC-based HCDs |
20 | * Context: !in_interrupt() | 38 | * Context: !in_interrupt() |
@@ -120,7 +138,7 @@ static const struct hc_driver ehci_ppc_soc_hc_driver = { | |||
120 | /* | 138 | /* |
121 | * basic lifecycle operations | 139 | * basic lifecycle operations |
122 | */ | 140 | */ |
123 | .reset = ehci_init, | 141 | .reset = ehci_ppc_soc_setup, |
124 | .start = ehci_run, | 142 | .start = ehci_run, |
125 | .stop = ehci_stop, | 143 | .stop = ehci_stop, |
126 | .shutdown = ehci_shutdown, | 144 | .shutdown = ehci_shutdown, |
@@ -142,10 +160,8 @@ static const struct hc_driver ehci_ppc_soc_hc_driver = { | |||
142 | */ | 160 | */ |
143 | .hub_status_data = ehci_hub_status_data, | 161 | .hub_status_data = ehci_hub_status_data, |
144 | .hub_control = ehci_hub_control, | 162 | .hub_control = ehci_hub_control, |
145 | #ifdef CONFIG_PM | 163 | .bus_suspend = ehci_bus_suspend, |
146 | .hub_suspend = ehci_hub_suspend, | 164 | .bus_resume = ehci_bus_resume, |
147 | .hub_resume = ehci_hub_resume, | ||
148 | #endif | ||
149 | }; | 165 | }; |
150 | 166 | ||
151 | static int ehci_hcd_ppc_soc_drv_probe(struct platform_device *pdev) | 167 | static int ehci_hcd_ppc_soc_drv_probe(struct platform_device *pdev) |
diff --git a/drivers/usb/host/ehci-ps3.c b/drivers/usb/host/ehci-ps3.c index 829fe649a98..03a6b2f4e6e 100644 --- a/drivers/usb/host/ehci-ps3.c +++ b/drivers/usb/host/ehci-ps3.c | |||
@@ -47,7 +47,7 @@ static int ps3_ehci_hc_reset(struct usb_hcd *hcd) | |||
47 | if (result) | 47 | if (result) |
48 | return result; | 48 | return result; |
49 | 49 | ||
50 | ehci_port_power(ehci, 0); | 50 | ehci_reset(ehci); |
51 | 51 | ||
52 | return result; | 52 | return result; |
53 | } | 53 | } |
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 2284028f8aa..b10f39c047e 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c | |||
@@ -139,63 +139,65 @@ qh_refresh (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
139 | 139 | ||
140 | /*-------------------------------------------------------------------------*/ | 140 | /*-------------------------------------------------------------------------*/ |
141 | 141 | ||
142 | static void qtd_copy_status ( | 142 | static int qtd_copy_status ( |
143 | struct ehci_hcd *ehci, | 143 | struct ehci_hcd *ehci, |
144 | struct urb *urb, | 144 | struct urb *urb, |
145 | size_t length, | 145 | size_t length, |
146 | u32 token | 146 | u32 token |
147 | ) | 147 | ) |
148 | { | 148 | { |
149 | int status = -EINPROGRESS; | ||
150 | |||
149 | /* count IN/OUT bytes, not SETUP (even short packets) */ | 151 | /* count IN/OUT bytes, not SETUP (even short packets) */ |
150 | if (likely (QTD_PID (token) != 2)) | 152 | if (likely (QTD_PID (token) != 2)) |
151 | urb->actual_length += length - QTD_LENGTH (token); | 153 | urb->actual_length += length - QTD_LENGTH (token); |
152 | 154 | ||
153 | /* don't modify error codes */ | 155 | /* don't modify error codes */ |
154 | if (unlikely (urb->status != -EINPROGRESS)) | 156 | if (unlikely(urb->unlinked)) |
155 | return; | 157 | return status; |
156 | 158 | ||
157 | /* force cleanup after short read; not always an error */ | 159 | /* force cleanup after short read; not always an error */ |
158 | if (unlikely (IS_SHORT_READ (token))) | 160 | if (unlikely (IS_SHORT_READ (token))) |
159 | urb->status = -EREMOTEIO; | 161 | status = -EREMOTEIO; |
160 | 162 | ||
161 | /* serious "can't proceed" faults reported by the hardware */ | 163 | /* serious "can't proceed" faults reported by the hardware */ |
162 | if (token & QTD_STS_HALT) { | 164 | if (token & QTD_STS_HALT) { |
163 | if (token & QTD_STS_BABBLE) { | 165 | if (token & QTD_STS_BABBLE) { |
164 | /* FIXME "must" disable babbling device's port too */ | 166 | /* FIXME "must" disable babbling device's port too */ |
165 | urb->status = -EOVERFLOW; | 167 | status = -EOVERFLOW; |
166 | } else if (token & QTD_STS_MMF) { | 168 | } else if (token & QTD_STS_MMF) { |
167 | /* fs/ls interrupt xfer missed the complete-split */ | 169 | /* fs/ls interrupt xfer missed the complete-split */ |
168 | urb->status = -EPROTO; | 170 | status = -EPROTO; |
169 | } else if (token & QTD_STS_DBE) { | 171 | } else if (token & QTD_STS_DBE) { |
170 | urb->status = (QTD_PID (token) == 1) /* IN ? */ | 172 | status = (QTD_PID (token) == 1) /* IN ? */ |
171 | ? -ENOSR /* hc couldn't read data */ | 173 | ? -ENOSR /* hc couldn't read data */ |
172 | : -ECOMM; /* hc couldn't write data */ | 174 | : -ECOMM; /* hc couldn't write data */ |
173 | } else if (token & QTD_STS_XACT) { | 175 | } else if (token & QTD_STS_XACT) { |
174 | /* timeout, bad crc, wrong PID, etc; retried */ | 176 | /* timeout, bad crc, wrong PID, etc; retried */ |
175 | if (QTD_CERR (token)) | 177 | if (QTD_CERR (token)) |
176 | urb->status = -EPIPE; | 178 | status = -EPIPE; |
177 | else { | 179 | else { |
178 | ehci_dbg (ehci, "devpath %s ep%d%s 3strikes\n", | 180 | ehci_dbg (ehci, "devpath %s ep%d%s 3strikes\n", |
179 | urb->dev->devpath, | 181 | urb->dev->devpath, |
180 | usb_pipeendpoint (urb->pipe), | 182 | usb_pipeendpoint (urb->pipe), |
181 | usb_pipein (urb->pipe) ? "in" : "out"); | 183 | usb_pipein (urb->pipe) ? "in" : "out"); |
182 | urb->status = -EPROTO; | 184 | status = -EPROTO; |
183 | } | 185 | } |
184 | /* CERR nonzero + no errors + halt --> stall */ | 186 | /* CERR nonzero + no errors + halt --> stall */ |
185 | } else if (QTD_CERR (token)) | 187 | } else if (QTD_CERR (token)) |
186 | urb->status = -EPIPE; | 188 | status = -EPIPE; |
187 | else /* unknown */ | 189 | else /* unknown */ |
188 | urb->status = -EPROTO; | 190 | status = -EPROTO; |
189 | 191 | ||
190 | ehci_vdbg (ehci, | 192 | ehci_vdbg (ehci, |
191 | "dev%d ep%d%s qtd token %08x --> status %d\n", | 193 | "dev%d ep%d%s qtd token %08x --> status %d\n", |
192 | usb_pipedevice (urb->pipe), | 194 | usb_pipedevice (urb->pipe), |
193 | usb_pipeendpoint (urb->pipe), | 195 | usb_pipeendpoint (urb->pipe), |
194 | usb_pipein (urb->pipe) ? "in" : "out", | 196 | usb_pipein (urb->pipe) ? "in" : "out", |
195 | token, urb->status); | 197 | token, status); |
196 | 198 | ||
197 | /* if async CSPLIT failed, try cleaning out the TT buffer */ | 199 | /* if async CSPLIT failed, try cleaning out the TT buffer */ |
198 | if (urb->status != -EPIPE | 200 | if (status != -EPIPE |
199 | && urb->dev->tt && !usb_pipeint (urb->pipe) | 201 | && urb->dev->tt && !usb_pipeint (urb->pipe) |
200 | && ((token & QTD_STS_MMF) != 0 | 202 | && ((token & QTD_STS_MMF) != 0 |
201 | || QTD_CERR(token) == 0) | 203 | || QTD_CERR(token) == 0) |
@@ -212,10 +214,12 @@ static void qtd_copy_status ( | |||
212 | usb_hub_tt_clear_buffer (urb->dev, urb->pipe); | 214 | usb_hub_tt_clear_buffer (urb->dev, urb->pipe); |
213 | } | 215 | } |
214 | } | 216 | } |
217 | |||
218 | return status; | ||
215 | } | 219 | } |
216 | 220 | ||
217 | static void | 221 | static void |
218 | ehci_urb_done (struct ehci_hcd *ehci, struct urb *urb) | 222 | ehci_urb_done(struct ehci_hcd *ehci, struct urb *urb, int status) |
219 | __releases(ehci->lock) | 223 | __releases(ehci->lock) |
220 | __acquires(ehci->lock) | 224 | __acquires(ehci->lock) |
221 | { | 225 | { |
@@ -231,25 +235,13 @@ __acquires(ehci->lock) | |||
231 | qh_put (qh); | 235 | qh_put (qh); |
232 | } | 236 | } |
233 | 237 | ||
234 | spin_lock (&urb->lock); | 238 | if (unlikely(urb->unlinked)) { |
235 | urb->hcpriv = NULL; | 239 | COUNT(ehci->stats.unlink); |
236 | switch (urb->status) { | 240 | } else { |
237 | case -EINPROGRESS: /* success */ | 241 | if (likely(status == -EINPROGRESS)) |
238 | urb->status = 0; | 242 | status = 0; |
239 | default: /* fault */ | 243 | COUNT(ehci->stats.complete); |
240 | COUNT (ehci->stats.complete); | ||
241 | break; | ||
242 | case -EREMOTEIO: /* fault or normal */ | ||
243 | if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) | ||
244 | urb->status = 0; | ||
245 | COUNT (ehci->stats.complete); | ||
246 | break; | ||
247 | case -ECONNRESET: /* canceled */ | ||
248 | case -ENOENT: | ||
249 | COUNT (ehci->stats.unlink); | ||
250 | break; | ||
251 | } | 244 | } |
252 | spin_unlock (&urb->lock); | ||
253 | 245 | ||
254 | #ifdef EHCI_URB_TRACE | 246 | #ifdef EHCI_URB_TRACE |
255 | ehci_dbg (ehci, | 247 | ehci_dbg (ehci, |
@@ -257,13 +249,14 @@ __acquires(ehci->lock) | |||
257 | __FUNCTION__, urb->dev->devpath, urb, | 249 | __FUNCTION__, urb->dev->devpath, urb, |
258 | usb_pipeendpoint (urb->pipe), | 250 | usb_pipeendpoint (urb->pipe), |
259 | usb_pipein (urb->pipe) ? "in" : "out", | 251 | usb_pipein (urb->pipe) ? "in" : "out", |
260 | urb->status, | 252 | status, |
261 | urb->actual_length, urb->transfer_buffer_length); | 253 | urb->actual_length, urb->transfer_buffer_length); |
262 | #endif | 254 | #endif |
263 | 255 | ||
264 | /* complete() can reenter this HCD */ | 256 | /* complete() can reenter this HCD */ |
257 | usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); | ||
265 | spin_unlock (&ehci->lock); | 258 | spin_unlock (&ehci->lock); |
266 | usb_hcd_giveback_urb (ehci_to_hcd(ehci), urb); | 259 | usb_hcd_giveback_urb(ehci_to_hcd(ehci), urb, status); |
267 | spin_lock (&ehci->lock); | 260 | spin_lock (&ehci->lock); |
268 | } | 261 | } |
269 | 262 | ||
@@ -283,6 +276,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
283 | { | 276 | { |
284 | struct ehci_qtd *last = NULL, *end = qh->dummy; | 277 | struct ehci_qtd *last = NULL, *end = qh->dummy; |
285 | struct list_head *entry, *tmp; | 278 | struct list_head *entry, *tmp; |
279 | int last_status = -EINPROGRESS; | ||
286 | int stopped; | 280 | int stopped; |
287 | unsigned count = 0; | 281 | unsigned count = 0; |
288 | int do_status = 0; | 282 | int do_status = 0; |
@@ -311,10 +305,7 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
311 | struct ehci_qtd *qtd; | 305 | struct ehci_qtd *qtd; |
312 | struct urb *urb; | 306 | struct urb *urb; |
313 | u32 token = 0; | 307 | u32 token = 0; |
314 | 308 | int qtd_status; | |
315 | /* ignore QHs that are currently inactive */ | ||
316 | if (qh->hw_info1 & __constant_cpu_to_le32(QH_INACTIVATE)) | ||
317 | break; | ||
318 | 309 | ||
319 | qtd = list_entry (entry, struct ehci_qtd, qtd_list); | 310 | qtd = list_entry (entry, struct ehci_qtd, qtd_list); |
320 | urb = qtd->urb; | 311 | urb = qtd->urb; |
@@ -322,11 +313,12 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
322 | /* clean up any state from previous QTD ...*/ | 313 | /* clean up any state from previous QTD ...*/ |
323 | if (last) { | 314 | if (last) { |
324 | if (likely (last->urb != urb)) { | 315 | if (likely (last->urb != urb)) { |
325 | ehci_urb_done (ehci, last->urb); | 316 | ehci_urb_done(ehci, last->urb, last_status); |
326 | count++; | 317 | count++; |
327 | } | 318 | } |
328 | ehci_qtd_free (ehci, last); | 319 | ehci_qtd_free (ehci, last); |
329 | last = NULL; | 320 | last = NULL; |
321 | last_status = -EINPROGRESS; | ||
330 | } | 322 | } |
331 | 323 | ||
332 | /* ignore urbs submitted during completions we reported */ | 324 | /* ignore urbs submitted during completions we reported */ |
@@ -362,13 +354,14 @@ qh_completions (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
362 | stopped = 1; | 354 | stopped = 1; |
363 | 355 | ||
364 | if (unlikely (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state))) | 356 | if (unlikely (!HC_IS_RUNNING (ehci_to_hcd(ehci)->state))) |
365 | urb->status = -ESHUTDOWN; | 357 | last_status = -ESHUTDOWN; |
366 | 358 | ||
367 | /* ignore active urbs unless some previous qtd | 359 | /* ignore active urbs unless some previous qtd |
368 | * for the urb faulted (including short read) or | 360 | * for the urb faulted (including short read) or |
369 | * its urb was canceled. we may patch qh or qtds. | 361 | * its urb was canceled. we may patch qh or qtds. |
370 | */ | 362 | */ |
371 | if (likely (urb->status == -EINPROGRESS)) | 363 | if (likely(last_status == -EINPROGRESS && |
364 | !urb->unlinked)) | ||
372 | continue; | 365 | continue; |
373 | 366 | ||
374 | /* issue status after short control reads */ | 367 | /* issue status after short control reads */ |
@@ -396,11 +389,14 @@ halt: | |||
396 | } | 389 | } |
397 | 390 | ||
398 | /* remove it from the queue */ | 391 | /* remove it from the queue */ |
399 | spin_lock (&urb->lock); | 392 | qtd_status = qtd_copy_status(ehci, urb, qtd->length, token); |
400 | qtd_copy_status (ehci, urb, qtd->length, token); | 393 | if (unlikely(qtd_status == -EREMOTEIO)) { |
401 | do_status = (urb->status == -EREMOTEIO) | 394 | do_status = (!urb->unlinked && |
402 | && usb_pipecontrol (urb->pipe); | 395 | usb_pipecontrol(urb->pipe)); |
403 | spin_unlock (&urb->lock); | 396 | qtd_status = 0; |
397 | } | ||
398 | if (likely(last_status == -EINPROGRESS)) | ||
399 | last_status = qtd_status; | ||
404 | 400 | ||
405 | if (stopped && qtd->qtd_list.prev != &qh->qtd_list) { | 401 | if (stopped && qtd->qtd_list.prev != &qh->qtd_list) { |
406 | last = list_entry (qtd->qtd_list.prev, | 402 | last = list_entry (qtd->qtd_list.prev, |
@@ -413,7 +409,7 @@ halt: | |||
413 | 409 | ||
414 | /* last urb's completion might still need calling */ | 410 | /* last urb's completion might still need calling */ |
415 | if (likely (last != NULL)) { | 411 | if (likely (last != NULL)) { |
416 | ehci_urb_done (ehci, last->urb); | 412 | ehci_urb_done(ehci, last->urb, last_status); |
417 | count++; | 413 | count++; |
418 | ehci_qtd_free (ehci, last); | 414 | ehci_qtd_free (ehci, last); |
419 | } | 415 | } |
@@ -917,7 +913,6 @@ static struct ehci_qh *qh_append_tds ( | |||
917 | static int | 913 | static int |
918 | submit_async ( | 914 | submit_async ( |
919 | struct ehci_hcd *ehci, | 915 | struct ehci_hcd *ehci, |
920 | struct usb_host_endpoint *ep, | ||
921 | struct urb *urb, | 916 | struct urb *urb, |
922 | struct list_head *qtd_list, | 917 | struct list_head *qtd_list, |
923 | gfp_t mem_flags | 918 | gfp_t mem_flags |
@@ -926,10 +921,10 @@ submit_async ( | |||
926 | int epnum; | 921 | int epnum; |
927 | unsigned long flags; | 922 | unsigned long flags; |
928 | struct ehci_qh *qh = NULL; | 923 | struct ehci_qh *qh = NULL; |
929 | int rc = 0; | 924 | int rc; |
930 | 925 | ||
931 | qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list); | 926 | qtd = list_entry (qtd_list->next, struct ehci_qtd, qtd_list); |
932 | epnum = ep->desc.bEndpointAddress; | 927 | epnum = urb->ep->desc.bEndpointAddress; |
933 | 928 | ||
934 | #ifdef EHCI_URB_TRACE | 929 | #ifdef EHCI_URB_TRACE |
935 | ehci_dbg (ehci, | 930 | ehci_dbg (ehci, |
@@ -937,7 +932,7 @@ submit_async ( | |||
937 | __FUNCTION__, urb->dev->devpath, urb, | 932 | __FUNCTION__, urb->dev->devpath, urb, |
938 | epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out", | 933 | epnum & 0x0f, (epnum & USB_DIR_IN) ? "in" : "out", |
939 | urb->transfer_buffer_length, | 934 | urb->transfer_buffer_length, |
940 | qtd, ep->hcpriv); | 935 | qtd, urb->ep->hcpriv); |
941 | #endif | 936 | #endif |
942 | 937 | ||
943 | spin_lock_irqsave (&ehci->lock, flags); | 938 | spin_lock_irqsave (&ehci->lock, flags); |
@@ -946,9 +941,13 @@ submit_async ( | |||
946 | rc = -ESHUTDOWN; | 941 | rc = -ESHUTDOWN; |
947 | goto done; | 942 | goto done; |
948 | } | 943 | } |
944 | rc = usb_hcd_link_urb_to_ep(ehci_to_hcd(ehci), urb); | ||
945 | if (unlikely(rc)) | ||
946 | goto done; | ||
949 | 947 | ||
950 | qh = qh_append_tds (ehci, urb, qtd_list, epnum, &ep->hcpriv); | 948 | qh = qh_append_tds(ehci, urb, qtd_list, epnum, &urb->ep->hcpriv); |
951 | if (unlikely(qh == NULL)) { | 949 | if (unlikely(qh == NULL)) { |
950 | usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); | ||
952 | rc = -ENOMEM; | 951 | rc = -ENOMEM; |
953 | goto done; | 952 | goto done; |
954 | } | 953 | } |
diff --git a/drivers/usb/host/ehci-sched.c b/drivers/usb/host/ehci-sched.c index d4a8ace4967..80d99bce2b3 100644 --- a/drivers/usb/host/ehci-sched.c +++ b/drivers/usb/host/ehci-sched.c | |||
@@ -479,109 +479,6 @@ static int disable_periodic (struct ehci_hcd *ehci) | |||
479 | } | 479 | } |
480 | 480 | ||
481 | /*-------------------------------------------------------------------------*/ | 481 | /*-------------------------------------------------------------------------*/ |
482 | #ifdef CONFIG_CPU_FREQ | ||
483 | |||
484 | static int safe_to_modify_i (struct ehci_hcd *ehci, struct ehci_qh *qh) | ||
485 | { | ||
486 | int now; /* current (frame * 8) + uframe */ | ||
487 | int prev_start, next_start; /* uframes from/to split start */ | ||
488 | int start_uframe = ffs(le32_to_cpup (&qh->hw_info2) & QH_SMASK); | ||
489 | int end_uframe = fls((le32_to_cpup (&qh->hw_info2) & QH_CMASK) >> 8); | ||
490 | int split_duration = end_uframe - start_uframe; | ||
491 | |||
492 | now = readl(&ehci->regs->frame_index) % (ehci->periodic_size << 3); | ||
493 | |||
494 | next_start = ((1024 << 3) + (qh->start << 3) + start_uframe - now) | ||
495 | % (qh->period << 3); | ||
496 | prev_start = (qh->period << 3) - next_start; | ||
497 | |||
498 | /* | ||
499 | * Make sure there will be at least one uframe when qh is safe. | ||
500 | */ | ||
501 | if ((qh->period << 3) <= (ehci->i_thresh + 2 + split_duration)) | ||
502 | /* never safe */ | ||
503 | return -EINVAL; | ||
504 | |||
505 | /* | ||
506 | * Wait 1 uframe after transaction should have started, to make | ||
507 | * sure controller has time to write back overlay, so we can | ||
508 | * check QTD_STS_STS to see if transaction is in progress. | ||
509 | */ | ||
510 | if ((next_start > ehci->i_thresh) && (prev_start > 1)) | ||
511 | /* safe to set "i" bit if split isn't in progress */ | ||
512 | return (qh->hw_token & STATUS_BIT(ehci)) ? 0 : 1; | ||
513 | else | ||
514 | return 0; | ||
515 | } | ||
516 | |||
517 | /* Set inactivate bit for all the split interrupt QHs. */ | ||
518 | static void qh_inactivate_split_intr_qhs (struct ehci_hcd *ehci) | ||
519 | { | ||
520 | struct ehci_qh *qh; | ||
521 | int not_done, safe; | ||
522 | u32 inactivate = INACTIVATE_BIT(ehci); | ||
523 | u32 active = ACTIVE_BIT(ehci); | ||
524 | |||
525 | do { | ||
526 | not_done = 0; | ||
527 | list_for_each_entry(qh, &ehci->split_intr_qhs, | ||
528 | split_intr_qhs) { | ||
529 | if (qh->hw_info1 & inactivate) | ||
530 | /* already off */ | ||
531 | continue; | ||
532 | /* | ||
533 | * To avoid setting "I" after the start split happens, | ||
534 | * don't set it if the QH might be cached in the | ||
535 | * controller. Some HCs (Broadcom/ServerWorks HT1000) | ||
536 | * will stop in the middle of a split transaction when | ||
537 | * the "I" bit is set. | ||
538 | */ | ||
539 | safe = safe_to_modify_i(ehci, qh); | ||
540 | if (safe == 0) { | ||
541 | not_done = 1; | ||
542 | } else if (safe > 0) { | ||
543 | qh->was_active = qh->hw_token & active; | ||
544 | qh->hw_info1 |= inactivate; | ||
545 | } | ||
546 | } | ||
547 | } while (not_done); | ||
548 | wmb(); | ||
549 | } | ||
550 | |||
551 | static void qh_reactivate_split_intr_qhs (struct ehci_hcd *ehci) | ||
552 | { | ||
553 | struct ehci_qh *qh; | ||
554 | u32 token; | ||
555 | int not_done, safe; | ||
556 | u32 inactivate = INACTIVATE_BIT(ehci); | ||
557 | u32 active = ACTIVE_BIT(ehci); | ||
558 | u32 halt = HALT_BIT(ehci); | ||
559 | |||
560 | do { | ||
561 | not_done = 0; | ||
562 | list_for_each_entry(qh, &ehci->split_intr_qhs, split_intr_qhs) { | ||
563 | if (!(qh->hw_info1 & inactivate)) /* already on */ | ||
564 | continue; | ||
565 | /* | ||
566 | * Don't reactivate if cached, or controller might | ||
567 | * overwrite overlay after we modify it! | ||
568 | */ | ||
569 | safe = safe_to_modify_i(ehci, qh); | ||
570 | if (safe == 0) { | ||
571 | not_done = 1; | ||
572 | } else if (safe > 0) { | ||
573 | /* See EHCI 1.0 section 4.15.2.4. */ | ||
574 | token = qh->hw_token; | ||
575 | qh->hw_token = (token | halt) & ~active; | ||
576 | wmb(); | ||
577 | qh->hw_info1 &= ~inactivate; | ||
578 | wmb(); | ||
579 | qh->hw_token = (token & ~halt) | qh->was_active; | ||
580 | } | ||
581 | } | ||
582 | } while (not_done); | ||
583 | } | ||
584 | #endif | ||
585 | 482 | ||
586 | /* periodic schedule slots have iso tds (normal or split) first, then a | 483 | /* periodic schedule slots have iso tds (normal or split) first, then a |
587 | * sparse tree for active interrupt transfers. | 484 | * sparse tree for active interrupt transfers. |
@@ -599,17 +496,6 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
599 | period, hc32_to_cpup(ehci, &qh->hw_info2) & (QH_CMASK | QH_SMASK), | 496 | period, hc32_to_cpup(ehci, &qh->hw_info2) & (QH_CMASK | QH_SMASK), |
600 | qh, qh->start, qh->usecs, qh->c_usecs); | 497 | qh, qh->start, qh->usecs, qh->c_usecs); |
601 | 498 | ||
602 | #ifdef CONFIG_CPU_FREQ | ||
603 | /* | ||
604 | * If low/full speed interrupt QHs are inactive (because of | ||
605 | * cpufreq changing processor speeds), start QH with I flag set-- | ||
606 | * it will automatically be cleared when cpufreq is done. | ||
607 | */ | ||
608 | if (ehci->cpufreq_changing) | ||
609 | if (!(qh->hw_info1 & (cpu_to_le32(1 << 13)))) | ||
610 | qh->hw_info1 |= INACTIVATE_BIT(ehci); | ||
611 | #endif | ||
612 | |||
613 | /* high bandwidth, or otherwise every microframe */ | 499 | /* high bandwidth, or otherwise every microframe */ |
614 | if (period == 0) | 500 | if (period == 0) |
615 | period = 1; | 501 | period = 1; |
@@ -658,12 +544,6 @@ static int qh_link_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
658 | ? ((qh->usecs + qh->c_usecs) / qh->period) | 544 | ? ((qh->usecs + qh->c_usecs) / qh->period) |
659 | : (qh->usecs * 8); | 545 | : (qh->usecs * 8); |
660 | 546 | ||
661 | #ifdef CONFIG_CPU_FREQ | ||
662 | /* add qh to list of low/full speed interrupt QHs, if applicable */ | ||
663 | if (!(qh->hw_info1 & (cpu_to_le32(1 << 13)))) { | ||
664 | list_add(&qh->split_intr_qhs, &ehci->split_intr_qhs); | ||
665 | } | ||
666 | #endif | ||
667 | /* maybe enable periodic schedule processing */ | 547 | /* maybe enable periodic schedule processing */ |
668 | if (!ehci->periodic_sched++) | 548 | if (!ehci->periodic_sched++) |
669 | return enable_periodic (ehci); | 549 | return enable_periodic (ehci); |
@@ -683,13 +563,6 @@ static void qh_unlink_periodic (struct ehci_hcd *ehci, struct ehci_qh *qh) | |||
683 | // THEN | 563 | // THEN |
684 | // qh->hw_info1 |= __constant_cpu_to_hc32(1 << 7 /* "ignore" */); | 564 | // qh->hw_info1 |= __constant_cpu_to_hc32(1 << 7 /* "ignore" */); |
685 | 565 | ||
686 | #ifdef CONFIG_CPU_FREQ | ||
687 | /* remove qh from list of low/full speed interrupt QHs */ | ||
688 | if (!(qh->hw_info1 & (cpu_to_le32(1 << 13)))) { | ||
689 | list_del_init(&qh->split_intr_qhs); | ||
690 | } | ||
691 | #endif | ||
692 | |||
693 | /* high bandwidth, or otherwise part of every microframe */ | 566 | /* high bandwidth, or otherwise part of every microframe */ |
694 | if ((period = qh->period) == 0) | 567 | if ((period = qh->period) == 0) |
695 | period = 1; | 568 | period = 1; |
@@ -924,7 +797,6 @@ done: | |||
924 | 797 | ||
925 | static int intr_submit ( | 798 | static int intr_submit ( |
926 | struct ehci_hcd *ehci, | 799 | struct ehci_hcd *ehci, |
927 | struct usb_host_endpoint *ep, | ||
928 | struct urb *urb, | 800 | struct urb *urb, |
929 | struct list_head *qtd_list, | 801 | struct list_head *qtd_list, |
930 | gfp_t mem_flags | 802 | gfp_t mem_flags |
@@ -932,23 +804,26 @@ static int intr_submit ( | |||
932 | unsigned epnum; | 804 | unsigned epnum; |
933 | unsigned long flags; | 805 | unsigned long flags; |
934 | struct ehci_qh *qh; | 806 | struct ehci_qh *qh; |
935 | int status = 0; | 807 | int status; |
936 | struct list_head empty; | 808 | struct list_head empty; |
937 | 809 | ||
938 | /* get endpoint and transfer/schedule data */ | 810 | /* get endpoint and transfer/schedule data */ |
939 | epnum = ep->desc.bEndpointAddress; | 811 | epnum = urb->ep->desc.bEndpointAddress; |
940 | 812 | ||
941 | spin_lock_irqsave (&ehci->lock, flags); | 813 | spin_lock_irqsave (&ehci->lock, flags); |
942 | 814 | ||
943 | if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, | 815 | if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, |
944 | &ehci_to_hcd(ehci)->flags))) { | 816 | &ehci_to_hcd(ehci)->flags))) { |
945 | status = -ESHUTDOWN; | 817 | status = -ESHUTDOWN; |
946 | goto done; | 818 | goto done_not_linked; |
947 | } | 819 | } |
820 | status = usb_hcd_link_urb_to_ep(ehci_to_hcd(ehci), urb); | ||
821 | if (unlikely(status)) | ||
822 | goto done_not_linked; | ||
948 | 823 | ||
949 | /* get qh and force any scheduling errors */ | 824 | /* get qh and force any scheduling errors */ |
950 | INIT_LIST_HEAD (&empty); | 825 | INIT_LIST_HEAD (&empty); |
951 | qh = qh_append_tds (ehci, urb, &empty, epnum, &ep->hcpriv); | 826 | qh = qh_append_tds(ehci, urb, &empty, epnum, &urb->ep->hcpriv); |
952 | if (qh == NULL) { | 827 | if (qh == NULL) { |
953 | status = -ENOMEM; | 828 | status = -ENOMEM; |
954 | goto done; | 829 | goto done; |
@@ -959,13 +834,16 @@ static int intr_submit ( | |||
959 | } | 834 | } |
960 | 835 | ||
961 | /* then queue the urb's tds to the qh */ | 836 | /* then queue the urb's tds to the qh */ |
962 | qh = qh_append_tds (ehci, urb, qtd_list, epnum, &ep->hcpriv); | 837 | qh = qh_append_tds(ehci, urb, qtd_list, epnum, &urb->ep->hcpriv); |
963 | BUG_ON (qh == NULL); | 838 | BUG_ON (qh == NULL); |
964 | 839 | ||
965 | /* ... update usbfs periodic stats */ | 840 | /* ... update usbfs periodic stats */ |
966 | ehci_to_hcd(ehci)->self.bandwidth_int_reqs++; | 841 | ehci_to_hcd(ehci)->self.bandwidth_int_reqs++; |
967 | 842 | ||
968 | done: | 843 | done: |
844 | if (unlikely(status)) | ||
845 | usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); | ||
846 | done_not_linked: | ||
969 | spin_unlock_irqrestore (&ehci->lock, flags); | 847 | spin_unlock_irqrestore (&ehci->lock, flags); |
970 | if (status) | 848 | if (status) |
971 | qtd_list_free (ehci, urb, qtd_list); | 849 | qtd_list_free (ehci, urb, qtd_list); |
@@ -1749,7 +1627,7 @@ itd_complete ( | |||
1749 | 1627 | ||
1750 | /* give urb back to the driver ... can be out-of-order */ | 1628 | /* give urb back to the driver ... can be out-of-order */ |
1751 | dev = urb->dev; | 1629 | dev = urb->dev; |
1752 | ehci_urb_done (ehci, urb); | 1630 | ehci_urb_done(ehci, urb, 0); |
1753 | urb = NULL; | 1631 | urb = NULL; |
1754 | 1632 | ||
1755 | /* defer stopping schedule; completion can submit */ | 1633 | /* defer stopping schedule; completion can submit */ |
@@ -1813,12 +1691,19 @@ static int itd_submit (struct ehci_hcd *ehci, struct urb *urb, | |||
1813 | /* schedule ... need to lock */ | 1691 | /* schedule ... need to lock */ |
1814 | spin_lock_irqsave (&ehci->lock, flags); | 1692 | spin_lock_irqsave (&ehci->lock, flags); |
1815 | if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, | 1693 | if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, |
1816 | &ehci_to_hcd(ehci)->flags))) | 1694 | &ehci_to_hcd(ehci)->flags))) { |
1817 | status = -ESHUTDOWN; | 1695 | status = -ESHUTDOWN; |
1818 | else | 1696 | goto done_not_linked; |
1819 | status = iso_stream_schedule (ehci, urb, stream); | 1697 | } |
1698 | status = usb_hcd_link_urb_to_ep(ehci_to_hcd(ehci), urb); | ||
1699 | if (unlikely(status)) | ||
1700 | goto done_not_linked; | ||
1701 | status = iso_stream_schedule(ehci, urb, stream); | ||
1820 | if (likely (status == 0)) | 1702 | if (likely (status == 0)) |
1821 | itd_link_urb (ehci, urb, ehci->periodic_size << 3, stream); | 1703 | itd_link_urb (ehci, urb, ehci->periodic_size << 3, stream); |
1704 | else | ||
1705 | usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); | ||
1706 | done_not_linked: | ||
1822 | spin_unlock_irqrestore (&ehci->lock, flags); | 1707 | spin_unlock_irqrestore (&ehci->lock, flags); |
1823 | 1708 | ||
1824 | done: | 1709 | done: |
@@ -2115,7 +2000,7 @@ sitd_complete ( | |||
2115 | 2000 | ||
2116 | /* give urb back to the driver */ | 2001 | /* give urb back to the driver */ |
2117 | dev = urb->dev; | 2002 | dev = urb->dev; |
2118 | ehci_urb_done (ehci, urb); | 2003 | ehci_urb_done(ehci, urb, 0); |
2119 | urb = NULL; | 2004 | urb = NULL; |
2120 | 2005 | ||
2121 | /* defer stopping schedule; completion can submit */ | 2006 | /* defer stopping schedule; completion can submit */ |
@@ -2176,12 +2061,19 @@ static int sitd_submit (struct ehci_hcd *ehci, struct urb *urb, | |||
2176 | /* schedule ... need to lock */ | 2061 | /* schedule ... need to lock */ |
2177 | spin_lock_irqsave (&ehci->lock, flags); | 2062 | spin_lock_irqsave (&ehci->lock, flags); |
2178 | if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, | 2063 | if (unlikely(!test_bit(HCD_FLAG_HW_ACCESSIBLE, |
2179 | &ehci_to_hcd(ehci)->flags))) | 2064 | &ehci_to_hcd(ehci)->flags))) { |
2180 | status = -ESHUTDOWN; | 2065 | status = -ESHUTDOWN; |
2181 | else | 2066 | goto done_not_linked; |
2182 | status = iso_stream_schedule (ehci, urb, stream); | 2067 | } |
2068 | status = usb_hcd_link_urb_to_ep(ehci_to_hcd(ehci), urb); | ||
2069 | if (unlikely(status)) | ||
2070 | goto done_not_linked; | ||
2071 | status = iso_stream_schedule(ehci, urb, stream); | ||
2183 | if (status == 0) | 2072 | if (status == 0) |
2184 | sitd_link_urb (ehci, urb, ehci->periodic_size << 3, stream); | 2073 | sitd_link_urb (ehci, urb, ehci->periodic_size << 3, stream); |
2074 | else | ||
2075 | usb_hcd_unlink_urb_from_ep(ehci_to_hcd(ehci), urb); | ||
2076 | done_not_linked: | ||
2185 | spin_unlock_irqrestore (&ehci->lock, flags); | 2077 | spin_unlock_irqrestore (&ehci->lock, flags); |
2186 | 2078 | ||
2187 | done: | 2079 | done: |
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 2c68a04230c..951d69fec51 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h | |||
@@ -71,12 +71,6 @@ struct ehci_hcd { /* one per controller */ | |||
71 | __u32 hcs_params; /* cached register copy */ | 71 | __u32 hcs_params; /* cached register copy */ |
72 | spinlock_t lock; | 72 | spinlock_t lock; |
73 | 73 | ||
74 | #ifdef CONFIG_CPU_FREQ | ||
75 | struct notifier_block cpufreq_transition; | ||
76 | int cpufreq_changing; | ||
77 | struct list_head split_intr_qhs; | ||
78 | #endif | ||
79 | |||
80 | /* async schedule support */ | 74 | /* async schedule support */ |
81 | struct ehci_qh *async; | 75 | struct ehci_qh *async; |
82 | struct ehci_qh *reclaim; | 76 | struct ehci_qh *reclaim; |
@@ -439,10 +433,6 @@ struct ehci_qh { | |||
439 | __hc32 hw_next; /* see EHCI 3.6.1 */ | 433 | __hc32 hw_next; /* see EHCI 3.6.1 */ |
440 | __hc32 hw_info1; /* see EHCI 3.6.2 */ | 434 | __hc32 hw_info1; /* see EHCI 3.6.2 */ |
441 | #define QH_HEAD 0x00008000 | 435 | #define QH_HEAD 0x00008000 |
442 | #define QH_INACTIVATE 0x00000080 | ||
443 | |||
444 | #define INACTIVATE_BIT(ehci) cpu_to_hc32(ehci, QH_INACTIVATE) | ||
445 | |||
446 | __hc32 hw_info2; /* see EHCI 3.6.2 */ | 436 | __hc32 hw_info2; /* see EHCI 3.6.2 */ |
447 | #define QH_SMASK 0x000000ff | 437 | #define QH_SMASK 0x000000ff |
448 | #define QH_CMASK 0x0000ff00 | 438 | #define QH_CMASK 0x0000ff00 |
@@ -492,10 +482,6 @@ struct ehci_qh { | |||
492 | unsigned short start; /* where polling starts */ | 482 | unsigned short start; /* where polling starts */ |
493 | #define NO_FRAME ((unsigned short)~0) /* pick new start */ | 483 | #define NO_FRAME ((unsigned short)~0) /* pick new start */ |
494 | struct usb_device *dev; /* access to TT */ | 484 | struct usb_device *dev; /* access to TT */ |
495 | #ifdef CONFIG_CPU_FREQ | ||
496 | struct list_head split_intr_qhs; /* list of split qhs */ | ||
497 | __le32 was_active; /* active bit before "i" set */ | ||
498 | #endif | ||
499 | } __attribute__ ((aligned (32))); | 485 | } __attribute__ ((aligned (32))); |
500 | 486 | ||
501 | /*-------------------------------------------------------------------------*/ | 487 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 46873f2534b..c27417f5b9d 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c | |||
@@ -228,7 +228,6 @@ static void preproc_atl_queue(struct isp116x *isp116x) | |||
228 | struct urb, urb_list); | 228 | struct urb, urb_list); |
229 | ptd = &ep->ptd; | 229 | ptd = &ep->ptd; |
230 | len = ep->length; | 230 | len = ep->length; |
231 | spin_lock(&urb->lock); | ||
232 | ep->data = (unsigned char *)urb->transfer_buffer | 231 | ep->data = (unsigned char *)urb->transfer_buffer |
233 | + urb->actual_length; | 232 | + urb->actual_length; |
234 | 233 | ||
@@ -264,7 +263,6 @@ static void preproc_atl_queue(struct isp116x *isp116x) | |||
264 | | PTD_EP(ep->epnum); | 263 | | PTD_EP(ep->epnum); |
265 | ptd->len = PTD_LEN(len) | PTD_DIR(dir); | 264 | ptd->len = PTD_LEN(len) | PTD_DIR(dir); |
266 | ptd->faddr = PTD_FA(usb_pipedevice(urb->pipe)); | 265 | ptd->faddr = PTD_FA(usb_pipedevice(urb->pipe)); |
267 | spin_unlock(&urb->lock); | ||
268 | if (!ep->active) { | 266 | if (!ep->active) { |
269 | ptd->mps |= PTD_LAST_MSK; | 267 | ptd->mps |= PTD_LAST_MSK; |
270 | isp116x->atl_last_dir = dir; | 268 | isp116x->atl_last_dir = dir; |
@@ -275,6 +273,61 @@ static void preproc_atl_queue(struct isp116x *isp116x) | |||
275 | } | 273 | } |
276 | 274 | ||
277 | /* | 275 | /* |
276 | Take done or failed requests out of schedule. Give back | ||
277 | processed urbs. | ||
278 | */ | ||
279 | static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep, | ||
280 | struct urb *urb, int status) | ||
281 | __releases(isp116x->lock) __acquires(isp116x->lock) | ||
282 | { | ||
283 | unsigned i; | ||
284 | |||
285 | ep->error_count = 0; | ||
286 | |||
287 | if (usb_pipecontrol(urb->pipe)) | ||
288 | ep->nextpid = USB_PID_SETUP; | ||
289 | |||
290 | urb_dbg(urb, "Finish"); | ||
291 | |||
292 | usb_hcd_unlink_urb_from_ep(isp116x_to_hcd(isp116x), urb); | ||
293 | spin_unlock(&isp116x->lock); | ||
294 | usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb, status); | ||
295 | spin_lock(&isp116x->lock); | ||
296 | |||
297 | /* take idle endpoints out of the schedule */ | ||
298 | if (!list_empty(&ep->hep->urb_list)) | ||
299 | return; | ||
300 | |||
301 | /* async deschedule */ | ||
302 | if (!list_empty(&ep->schedule)) { | ||
303 | list_del_init(&ep->schedule); | ||
304 | return; | ||
305 | } | ||
306 | |||
307 | /* periodic deschedule */ | ||
308 | DBG("deschedule qh%d/%p branch %d\n", ep->period, ep, ep->branch); | ||
309 | for (i = ep->branch; i < PERIODIC_SIZE; i += ep->period) { | ||
310 | struct isp116x_ep *temp; | ||
311 | struct isp116x_ep **prev = &isp116x->periodic[i]; | ||
312 | |||
313 | while (*prev && ((temp = *prev) != ep)) | ||
314 | prev = &temp->next; | ||
315 | if (*prev) | ||
316 | *prev = ep->next; | ||
317 | isp116x->load[i] -= ep->load; | ||
318 | } | ||
319 | ep->branch = PERIODIC_SIZE; | ||
320 | isp116x_to_hcd(isp116x)->self.bandwidth_allocated -= | ||
321 | ep->load / ep->period; | ||
322 | |||
323 | /* switch irq type? */ | ||
324 | if (!--isp116x->periodic_count) { | ||
325 | isp116x->irqenb &= ~HCuPINT_SOF; | ||
326 | isp116x->irqenb |= HCuPINT_ATL; | ||
327 | } | ||
328 | } | ||
329 | |||
330 | /* | ||
278 | Analyze transfer results, handle partial transfers and errors | 331 | Analyze transfer results, handle partial transfers and errors |
279 | */ | 332 | */ |
280 | static void postproc_atl_queue(struct isp116x *isp116x) | 333 | static void postproc_atl_queue(struct isp116x *isp116x) |
@@ -284,6 +337,7 @@ static void postproc_atl_queue(struct isp116x *isp116x) | |||
284 | struct usb_device *udev; | 337 | struct usb_device *udev; |
285 | struct ptd *ptd; | 338 | struct ptd *ptd; |
286 | int short_not_ok; | 339 | int short_not_ok; |
340 | int status; | ||
287 | u8 cc; | 341 | u8 cc; |
288 | 342 | ||
289 | for (ep = isp116x->atl_active; ep; ep = ep->active) { | 343 | for (ep = isp116x->atl_active; ep; ep = ep->active) { |
@@ -294,7 +348,7 @@ static void postproc_atl_queue(struct isp116x *isp116x) | |||
294 | ptd = &ep->ptd; | 348 | ptd = &ep->ptd; |
295 | cc = PTD_GET_CC(ptd); | 349 | cc = PTD_GET_CC(ptd); |
296 | short_not_ok = 1; | 350 | short_not_ok = 1; |
297 | spin_lock(&urb->lock); | 351 | status = -EINPROGRESS; |
298 | 352 | ||
299 | /* Data underrun is special. For allowed underrun | 353 | /* Data underrun is special. For allowed underrun |
300 | we clear the error and continue as normal. For | 354 | we clear the error and continue as normal. For |
@@ -302,47 +356,36 @@ static void postproc_atl_queue(struct isp116x *isp116x) | |||
302 | immediately while for control transfer, | 356 | immediately while for control transfer, |
303 | we do a STATUS stage. */ | 357 | we do a STATUS stage. */ |
304 | if (cc == TD_DATAUNDERRUN) { | 358 | if (cc == TD_DATAUNDERRUN) { |
305 | if (!(urb->transfer_flags & URB_SHORT_NOT_OK)) { | 359 | if (!(urb->transfer_flags & URB_SHORT_NOT_OK) || |
306 | DBG("Allowed data underrun\n"); | 360 | usb_pipecontrol(urb->pipe)) { |
361 | DBG("Allowed or control data underrun\n"); | ||
307 | cc = TD_CC_NOERROR; | 362 | cc = TD_CC_NOERROR; |
308 | short_not_ok = 0; | 363 | short_not_ok = 0; |
309 | } else { | 364 | } else { |
310 | ep->error_count = 1; | 365 | ep->error_count = 1; |
311 | if (usb_pipecontrol(urb->pipe)) | 366 | usb_settoggle(udev, ep->epnum, |
312 | ep->nextpid = USB_PID_ACK; | 367 | ep->nextpid == USB_PID_OUT, |
313 | else | 368 | PTD_GET_TOGGLE(ptd)); |
314 | usb_settoggle(udev, ep->epnum, | ||
315 | ep->nextpid == | ||
316 | USB_PID_OUT, | ||
317 | PTD_GET_TOGGLE(ptd)); | ||
318 | urb->actual_length += PTD_GET_COUNT(ptd); | 369 | urb->actual_length += PTD_GET_COUNT(ptd); |
319 | urb->status = cc_to_error[TD_DATAUNDERRUN]; | 370 | status = cc_to_error[TD_DATAUNDERRUN]; |
320 | spin_unlock(&urb->lock); | 371 | goto done; |
321 | continue; | ||
322 | } | 372 | } |
323 | } | 373 | } |
324 | /* Keep underrun error through the STATUS stage */ | ||
325 | if (urb->status == cc_to_error[TD_DATAUNDERRUN]) | ||
326 | cc = TD_DATAUNDERRUN; | ||
327 | 374 | ||
328 | if (cc != TD_CC_NOERROR && cc != TD_NOTACCESSED | 375 | if (cc != TD_CC_NOERROR && cc != TD_NOTACCESSED |
329 | && (++ep->error_count >= 3 || cc == TD_CC_STALL | 376 | && (++ep->error_count >= 3 || cc == TD_CC_STALL |
330 | || cc == TD_DATAOVERRUN)) { | 377 | || cc == TD_DATAOVERRUN)) { |
331 | if (urb->status == -EINPROGRESS) | 378 | status = cc_to_error[cc]; |
332 | urb->status = cc_to_error[cc]; | ||
333 | if (ep->nextpid == USB_PID_ACK) | 379 | if (ep->nextpid == USB_PID_ACK) |
334 | ep->nextpid = 0; | 380 | ep->nextpid = 0; |
335 | spin_unlock(&urb->lock); | 381 | goto done; |
336 | continue; | ||
337 | } | 382 | } |
338 | /* According to usb spec, zero-length Int transfer signals | 383 | /* According to usb spec, zero-length Int transfer signals |
339 | finishing of the urb. Hey, does this apply only | 384 | finishing of the urb. Hey, does this apply only |
340 | for IN endpoints? */ | 385 | for IN endpoints? */ |
341 | if (usb_pipeint(urb->pipe) && !PTD_GET_LEN(ptd)) { | 386 | if (usb_pipeint(urb->pipe) && !PTD_GET_LEN(ptd)) { |
342 | if (urb->status == -EINPROGRESS) | 387 | status = 0; |
343 | urb->status = 0; | 388 | goto done; |
344 | spin_unlock(&urb->lock); | ||
345 | continue; | ||
346 | } | 389 | } |
347 | 390 | ||
348 | /* Relax after previously failed, but later succeeded | 391 | /* Relax after previously failed, but later succeeded |
@@ -381,8 +424,8 @@ static void postproc_atl_queue(struct isp116x *isp116x) | |||
381 | /* All data for this URB is transferred, let's finish */ | 424 | /* All data for this URB is transferred, let's finish */ |
382 | if (usb_pipecontrol(urb->pipe)) | 425 | if (usb_pipecontrol(urb->pipe)) |
383 | ep->nextpid = USB_PID_ACK; | 426 | ep->nextpid = USB_PID_ACK; |
384 | else if (urb->status == -EINPROGRESS) | 427 | else |
385 | urb->status = 0; | 428 | status = 0; |
386 | break; | 429 | break; |
387 | case USB_PID_SETUP: | 430 | case USB_PID_SETUP: |
388 | if (PTD_GET_ACTIVE(ptd) | 431 | if (PTD_GET_ACTIVE(ptd) |
@@ -402,69 +445,16 @@ static void postproc_atl_queue(struct isp116x *isp116x) | |||
402 | if (PTD_GET_ACTIVE(ptd) | 445 | if (PTD_GET_ACTIVE(ptd) |
403 | || (cc != TD_CC_NOERROR && cc < 0x0E)) | 446 | || (cc != TD_CC_NOERROR && cc < 0x0E)) |
404 | break; | 447 | break; |
405 | if (urb->status == -EINPROGRESS) | 448 | status = 0; |
406 | urb->status = 0; | ||
407 | ep->nextpid = 0; | 449 | ep->nextpid = 0; |
408 | break; | 450 | break; |
409 | default: | 451 | default: |
410 | BUG(); | 452 | BUG(); |
411 | } | 453 | } |
412 | spin_unlock(&urb->lock); | ||
413 | } | ||
414 | } | ||
415 | 454 | ||
416 | /* | 455 | done: |
417 | Take done or failed requests out of schedule. Give back | 456 | if (status != -EINPROGRESS || urb->unlinked) |
418 | processed urbs. | 457 | finish_request(isp116x, ep, urb, status); |
419 | */ | ||
420 | static void finish_request(struct isp116x *isp116x, struct isp116x_ep *ep, | ||
421 | struct urb *urb) | ||
422 | __releases(isp116x->lock) __acquires(isp116x->lock) | ||
423 | { | ||
424 | unsigned i; | ||
425 | |||
426 | urb->hcpriv = NULL; | ||
427 | ep->error_count = 0; | ||
428 | |||
429 | if (usb_pipecontrol(urb->pipe)) | ||
430 | ep->nextpid = USB_PID_SETUP; | ||
431 | |||
432 | urb_dbg(urb, "Finish"); | ||
433 | |||
434 | spin_unlock(&isp116x->lock); | ||
435 | usb_hcd_giveback_urb(isp116x_to_hcd(isp116x), urb); | ||
436 | spin_lock(&isp116x->lock); | ||
437 | |||
438 | /* take idle endpoints out of the schedule */ | ||
439 | if (!list_empty(&ep->hep->urb_list)) | ||
440 | return; | ||
441 | |||
442 | /* async deschedule */ | ||
443 | if (!list_empty(&ep->schedule)) { | ||
444 | list_del_init(&ep->schedule); | ||
445 | return; | ||
446 | } | ||
447 | |||
448 | /* periodic deschedule */ | ||
449 | DBG("deschedule qh%d/%p branch %d\n", ep->period, ep, ep->branch); | ||
450 | for (i = ep->branch; i < PERIODIC_SIZE; i += ep->period) { | ||
451 | struct isp116x_ep *temp; | ||
452 | struct isp116x_ep **prev = &isp116x->periodic[i]; | ||
453 | |||
454 | while (*prev && ((temp = *prev) != ep)) | ||
455 | prev = &temp->next; | ||
456 | if (*prev) | ||
457 | *prev = ep->next; | ||
458 | isp116x->load[i] -= ep->load; | ||
459 | } | ||
460 | ep->branch = PERIODIC_SIZE; | ||
461 | isp116x_to_hcd(isp116x)->self.bandwidth_allocated -= | ||
462 | ep->load / ep->period; | ||
463 | |||
464 | /* switch irq type? */ | ||
465 | if (!--isp116x->periodic_count) { | ||
466 | isp116x->irqenb &= ~HCuPINT_SOF; | ||
467 | isp116x->irqenb |= HCuPINT_ATL; | ||
468 | } | 458 | } |
469 | } | 459 | } |
470 | 460 | ||
@@ -570,9 +560,6 @@ static void start_atl_transfers(struct isp116x *isp116x) | |||
570 | */ | 560 | */ |
571 | static void finish_atl_transfers(struct isp116x *isp116x) | 561 | static void finish_atl_transfers(struct isp116x *isp116x) |
572 | { | 562 | { |
573 | struct isp116x_ep *ep; | ||
574 | struct urb *urb; | ||
575 | |||
576 | if (!isp116x->atl_active) | 563 | if (!isp116x->atl_active) |
577 | return; | 564 | return; |
578 | /* Fifo not ready? */ | 565 | /* Fifo not ready? */ |
@@ -582,16 +569,6 @@ static void finish_atl_transfers(struct isp116x *isp116x) | |||
582 | atomic_inc(&isp116x->atl_finishing); | 569 | atomic_inc(&isp116x->atl_finishing); |
583 | unpack_fifo(isp116x); | 570 | unpack_fifo(isp116x); |
584 | postproc_atl_queue(isp116x); | 571 | postproc_atl_queue(isp116x); |
585 | for (ep = isp116x->atl_active; ep; ep = ep->active) { | ||
586 | urb = | ||
587 | container_of(ep->hep->urb_list.next, struct urb, urb_list); | ||
588 | /* USB_PID_ACK check here avoids finishing of | ||
589 | control transfers, for which TD_DATAUNDERRUN | ||
590 | occured, while URB_SHORT_NOT_OK was set */ | ||
591 | if (urb && urb->status != -EINPROGRESS | ||
592 | && ep->nextpid != USB_PID_ACK) | ||
593 | finish_request(isp116x, ep, urb); | ||
594 | } | ||
595 | atomic_dec(&isp116x->atl_finishing); | 572 | atomic_dec(&isp116x->atl_finishing); |
596 | } | 573 | } |
597 | 574 | ||
@@ -685,7 +662,7 @@ static int balance(struct isp116x *isp116x, u16 period, u16 load) | |||
685 | /*-----------------------------------------------------------------*/ | 662 | /*-----------------------------------------------------------------*/ |
686 | 663 | ||
687 | static int isp116x_urb_enqueue(struct usb_hcd *hcd, | 664 | static int isp116x_urb_enqueue(struct usb_hcd *hcd, |
688 | struct usb_host_endpoint *hep, struct urb *urb, | 665 | struct urb *urb, |
689 | gfp_t mem_flags) | 666 | gfp_t mem_flags) |
690 | { | 667 | { |
691 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | 668 | struct isp116x *isp116x = hcd_to_isp116x(hcd); |
@@ -694,6 +671,7 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd, | |||
694 | int is_out = !usb_pipein(pipe); | 671 | int is_out = !usb_pipein(pipe); |
695 | int type = usb_pipetype(pipe); | 672 | int type = usb_pipetype(pipe); |
696 | int epnum = usb_pipeendpoint(pipe); | 673 | int epnum = usb_pipeendpoint(pipe); |
674 | struct usb_host_endpoint *hep = urb->ep; | ||
697 | struct isp116x_ep *ep = NULL; | 675 | struct isp116x_ep *ep = NULL; |
698 | unsigned long flags; | 676 | unsigned long flags; |
699 | int i; | 677 | int i; |
@@ -717,7 +695,12 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd, | |||
717 | if (!HC_IS_RUNNING(hcd->state)) { | 695 | if (!HC_IS_RUNNING(hcd->state)) { |
718 | kfree(ep); | 696 | kfree(ep); |
719 | ret = -ENODEV; | 697 | ret = -ENODEV; |
720 | goto fail; | 698 | goto fail_not_linked; |
699 | } | ||
700 | ret = usb_hcd_link_urb_to_ep(hcd, urb); | ||
701 | if (ret) { | ||
702 | kfree(ep); | ||
703 | goto fail_not_linked; | ||
721 | } | 704 | } |
722 | 705 | ||
723 | if (hep->hcpriv) | 706 | if (hep->hcpriv) |
@@ -820,19 +803,13 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd, | |||
820 | } | 803 | } |
821 | } | 804 | } |
822 | 805 | ||
823 | /* in case of unlink-during-submit */ | ||
824 | spin_lock(&urb->lock); | ||
825 | if (urb->status != -EINPROGRESS) { | ||
826 | spin_unlock(&urb->lock); | ||
827 | finish_request(isp116x, ep, urb); | ||
828 | ret = 0; | ||
829 | goto fail; | ||
830 | } | ||
831 | urb->hcpriv = hep; | 806 | urb->hcpriv = hep; |
832 | spin_unlock(&urb->lock); | ||
833 | start_atl_transfers(isp116x); | 807 | start_atl_transfers(isp116x); |
834 | 808 | ||
835 | fail: | 809 | fail: |
810 | if (ret) | ||
811 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
812 | fail_not_linked: | ||
836 | spin_unlock_irqrestore(&isp116x->lock, flags); | 813 | spin_unlock_irqrestore(&isp116x->lock, flags); |
837 | return ret; | 814 | return ret; |
838 | } | 815 | } |
@@ -840,20 +817,21 @@ static int isp116x_urb_enqueue(struct usb_hcd *hcd, | |||
840 | /* | 817 | /* |
841 | Dequeue URBs. | 818 | Dequeue URBs. |
842 | */ | 819 | */ |
843 | static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | 820 | static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, |
821 | int status) | ||
844 | { | 822 | { |
845 | struct isp116x *isp116x = hcd_to_isp116x(hcd); | 823 | struct isp116x *isp116x = hcd_to_isp116x(hcd); |
846 | struct usb_host_endpoint *hep; | 824 | struct usb_host_endpoint *hep; |
847 | struct isp116x_ep *ep, *ep_act; | 825 | struct isp116x_ep *ep, *ep_act; |
848 | unsigned long flags; | 826 | unsigned long flags; |
827 | int rc; | ||
849 | 828 | ||
850 | spin_lock_irqsave(&isp116x->lock, flags); | 829 | spin_lock_irqsave(&isp116x->lock, flags); |
830 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); | ||
831 | if (rc) | ||
832 | goto done; | ||
833 | |||
851 | hep = urb->hcpriv; | 834 | hep = urb->hcpriv; |
852 | /* URB already unlinked (or never linked)? */ | ||
853 | if (!hep) { | ||
854 | spin_unlock_irqrestore(&isp116x->lock, flags); | ||
855 | return 0; | ||
856 | } | ||
857 | ep = hep->hcpriv; | 835 | ep = hep->hcpriv; |
858 | WARN_ON(hep != ep->hep); | 836 | WARN_ON(hep != ep->hep); |
859 | 837 | ||
@@ -870,10 +848,10 @@ static int isp116x_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | |||
870 | } | 848 | } |
871 | 849 | ||
872 | if (urb) | 850 | if (urb) |
873 | finish_request(isp116x, ep, urb); | 851 | finish_request(isp116x, ep, urb, status); |
874 | 852 | done: | |
875 | spin_unlock_irqrestore(&isp116x->lock, flags); | 853 | spin_unlock_irqrestore(&isp116x->lock, flags); |
876 | return 0; | 854 | return rc; |
877 | } | 855 | } |
878 | 856 | ||
879 | static void isp116x_endpoint_disable(struct usb_hcd *hcd, | 857 | static void isp116x_endpoint_disable(struct usb_hcd *hcd, |
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index 6f9e43e9a6c..ebab5ce8f5c 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c | |||
@@ -24,7 +24,7 @@ | |||
24 | * small: 0) header + data packets 1) just header | 24 | * small: 0) header + data packets 1) just header |
25 | */ | 25 | */ |
26 | static void __maybe_unused | 26 | static void __maybe_unused |
27 | urb_print (struct urb * urb, char * str, int small) | 27 | urb_print(struct urb * urb, char * str, int small, int status) |
28 | { | 28 | { |
29 | unsigned int pipe= urb->pipe; | 29 | unsigned int pipe= urb->pipe; |
30 | 30 | ||
@@ -34,7 +34,7 @@ urb_print (struct urb * urb, char * str, int small) | |||
34 | } | 34 | } |
35 | 35 | ||
36 | #ifndef OHCI_VERBOSE_DEBUG | 36 | #ifndef OHCI_VERBOSE_DEBUG |
37 | if (urb->status != 0) | 37 | if (status != 0) |
38 | #endif | 38 | #endif |
39 | dbg("%s %p dev=%d ep=%d%s-%s flags=%x len=%d/%d stat=%d", | 39 | dbg("%s %p dev=%d ep=%d%s-%s flags=%x len=%d/%d stat=%d", |
40 | str, | 40 | str, |
@@ -46,7 +46,7 @@ urb_print (struct urb * urb, char * str, int small) | |||
46 | urb->transfer_flags, | 46 | urb->transfer_flags, |
47 | urb->actual_length, | 47 | urb->actual_length, |
48 | urb->transfer_buffer_length, | 48 | urb->transfer_buffer_length, |
49 | urb->status); | 49 | status); |
50 | 50 | ||
51 | #ifdef OHCI_VERBOSE_DEBUG | 51 | #ifdef OHCI_VERBOSE_DEBUG |
52 | if (!small) { | 52 | if (!small) { |
@@ -66,7 +66,7 @@ urb_print (struct urb * urb, char * str, int small) | |||
66 | urb->transfer_buffer_length: urb->actual_length; | 66 | urb->transfer_buffer_length: urb->actual_length; |
67 | for (i = 0; i < 16 && i < len; i++) | 67 | for (i = 0; i < 16 && i < len; i++) |
68 | printk (" %02x", ((__u8 *) urb->transfer_buffer) [i]); | 68 | printk (" %02x", ((__u8 *) urb->transfer_buffer) [i]); |
69 | printk ("%s stat:%d\n", i < len? "...": "", urb->status); | 69 | printk ("%s stat:%d\n", i < len? "...": "", status); |
70 | } | 70 | } |
71 | } | 71 | } |
72 | #endif | 72 | #endif |
@@ -74,7 +74,7 @@ urb_print (struct urb * urb, char * str, int small) | |||
74 | 74 | ||
75 | #define ohci_dbg_sw(ohci, next, size, format, arg...) \ | 75 | #define ohci_dbg_sw(ohci, next, size, format, arg...) \ |
76 | do { \ | 76 | do { \ |
77 | if (next) { \ | 77 | if (next != NULL) { \ |
78 | unsigned s_len; \ | 78 | unsigned s_len; \ |
79 | s_len = scnprintf (*next, *size, format, ## arg ); \ | 79 | s_len = scnprintf (*next, *size, format, ## arg ); \ |
80 | *size -= s_len; *next += s_len; \ | 80 | *size -= s_len; *next += s_len; \ |
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 2038125b7f8..240c7f50754 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c | |||
@@ -81,7 +81,6 @@ static void ohci_dump (struct ohci_hcd *ohci, int verbose); | |||
81 | static int ohci_init (struct ohci_hcd *ohci); | 81 | static int ohci_init (struct ohci_hcd *ohci); |
82 | static void ohci_stop (struct usb_hcd *hcd); | 82 | static void ohci_stop (struct usb_hcd *hcd); |
83 | static int ohci_restart (struct ohci_hcd *ohci); | 83 | static int ohci_restart (struct ohci_hcd *ohci); |
84 | static void ohci_quirk_nec_worker (struct work_struct *work); | ||
85 | 84 | ||
86 | #include "ohci-hub.c" | 85 | #include "ohci-hub.c" |
87 | #include "ohci-dbg.c" | 86 | #include "ohci-dbg.c" |
@@ -118,7 +117,6 @@ MODULE_PARM_DESC (no_handshake, "true (not default) disables BIOS handshake"); | |||
118 | */ | 117 | */ |
119 | static int ohci_urb_enqueue ( | 118 | static int ohci_urb_enqueue ( |
120 | struct usb_hcd *hcd, | 119 | struct usb_hcd *hcd, |
121 | struct usb_host_endpoint *ep, | ||
122 | struct urb *urb, | 120 | struct urb *urb, |
123 | gfp_t mem_flags | 121 | gfp_t mem_flags |
124 | ) { | 122 | ) { |
@@ -131,11 +129,11 @@ static int ohci_urb_enqueue ( | |||
131 | int retval = 0; | 129 | int retval = 0; |
132 | 130 | ||
133 | #ifdef OHCI_VERBOSE_DEBUG | 131 | #ifdef OHCI_VERBOSE_DEBUG |
134 | urb_print (urb, "SUB", usb_pipein (pipe)); | 132 | urb_print(urb, "SUB", usb_pipein(pipe), -EINPROGRESS); |
135 | #endif | 133 | #endif |
136 | 134 | ||
137 | /* every endpoint has a ed, locate and maybe (re)initialize it */ | 135 | /* every endpoint has a ed, locate and maybe (re)initialize it */ |
138 | if (! (ed = ed_get (ohci, ep, urb->dev, pipe, urb->interval))) | 136 | if (! (ed = ed_get (ohci, urb->ep, urb->dev, pipe, urb->interval))) |
139 | return -ENOMEM; | 137 | return -ENOMEM; |
140 | 138 | ||
141 | /* for the private part of the URB we need the number of TDs (size) */ | 139 | /* for the private part of the URB we need the number of TDs (size) */ |
@@ -171,11 +169,10 @@ static int ohci_urb_enqueue ( | |||
171 | } | 169 | } |
172 | 170 | ||
173 | /* allocate the private part of the URB */ | 171 | /* allocate the private part of the URB */ |
174 | urb_priv = kmalloc (sizeof (urb_priv_t) + size * sizeof (struct td *), | 172 | urb_priv = kzalloc (sizeof (urb_priv_t) + size * sizeof (struct td *), |
175 | mem_flags); | 173 | mem_flags); |
176 | if (!urb_priv) | 174 | if (!urb_priv) |
177 | return -ENOMEM; | 175 | return -ENOMEM; |
178 | memset (urb_priv, 0, sizeof (urb_priv_t) + size * sizeof (struct td *)); | ||
179 | INIT_LIST_HEAD (&urb_priv->pending); | 176 | INIT_LIST_HEAD (&urb_priv->pending); |
180 | urb_priv->length = size; | 177 | urb_priv->length = size; |
181 | urb_priv->ed = ed; | 178 | urb_priv->ed = ed; |
@@ -201,22 +198,17 @@ static int ohci_urb_enqueue ( | |||
201 | retval = -ENODEV; | 198 | retval = -ENODEV; |
202 | goto fail; | 199 | goto fail; |
203 | } | 200 | } |
204 | 201 | retval = usb_hcd_link_urb_to_ep(hcd, urb); | |
205 | /* in case of unlink-during-submit */ | 202 | if (retval) |
206 | spin_lock (&urb->lock); | ||
207 | if (urb->status != -EINPROGRESS) { | ||
208 | spin_unlock (&urb->lock); | ||
209 | urb->hcpriv = urb_priv; | ||
210 | finish_urb (ohci, urb); | ||
211 | retval = 0; | ||
212 | goto fail; | 203 | goto fail; |
213 | } | ||
214 | 204 | ||
215 | /* schedule the ed if needed */ | 205 | /* schedule the ed if needed */ |
216 | if (ed->state == ED_IDLE) { | 206 | if (ed->state == ED_IDLE) { |
217 | retval = ed_schedule (ohci, ed); | 207 | retval = ed_schedule (ohci, ed); |
218 | if (retval < 0) | 208 | if (retval < 0) { |
219 | goto fail0; | 209 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
210 | goto fail; | ||
211 | } | ||
220 | if (ed->type == PIPE_ISOCHRONOUS) { | 212 | if (ed->type == PIPE_ISOCHRONOUS) { |
221 | u16 frame = ohci_frame_no(ohci); | 213 | u16 frame = ohci_frame_no(ohci); |
222 | 214 | ||
@@ -240,8 +232,6 @@ static int ohci_urb_enqueue ( | |||
240 | urb->hcpriv = urb_priv; | 232 | urb->hcpriv = urb_priv; |
241 | td_submit_urb (ohci, urb); | 233 | td_submit_urb (ohci, urb); |
242 | 234 | ||
243 | fail0: | ||
244 | spin_unlock (&urb->lock); | ||
245 | fail: | 235 | fail: |
246 | if (retval) | 236 | if (retval) |
247 | urb_free_priv (ohci, urb_priv); | 237 | urb_free_priv (ohci, urb_priv); |
@@ -250,22 +240,26 @@ fail: | |||
250 | } | 240 | } |
251 | 241 | ||
252 | /* | 242 | /* |
253 | * decouple the URB from the HC queues (TDs, urb_priv); it's | 243 | * decouple the URB from the HC queues (TDs, urb_priv). |
254 | * already marked using urb->status. reporting is always done | 244 | * reporting is always done |
255 | * asynchronously, and we might be dealing with an urb that's | 245 | * asynchronously, and we might be dealing with an urb that's |
256 | * partially transferred, or an ED with other urbs being unlinked. | 246 | * partially transferred, or an ED with other urbs being unlinked. |
257 | */ | 247 | */ |
258 | static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) | 248 | static int ohci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) |
259 | { | 249 | { |
260 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 250 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
261 | unsigned long flags; | 251 | unsigned long flags; |
252 | int rc; | ||
262 | 253 | ||
263 | #ifdef OHCI_VERBOSE_DEBUG | 254 | #ifdef OHCI_VERBOSE_DEBUG |
264 | urb_print (urb, "UNLINK", 1); | 255 | urb_print(urb, "UNLINK", 1, status); |
265 | #endif | 256 | #endif |
266 | 257 | ||
267 | spin_lock_irqsave (&ohci->lock, flags); | 258 | spin_lock_irqsave (&ohci->lock, flags); |
268 | if (HC_IS_RUNNING(hcd->state)) { | 259 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); |
260 | if (rc) { | ||
261 | ; /* Do nothing */ | ||
262 | } else if (HC_IS_RUNNING(hcd->state)) { | ||
269 | urb_priv_t *urb_priv; | 263 | urb_priv_t *urb_priv; |
270 | 264 | ||
271 | /* Unless an IRQ completed the unlink while it was being | 265 | /* Unless an IRQ completed the unlink while it was being |
@@ -283,10 +277,10 @@ static int ohci_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) | |||
283 | * any more ... just clean up every urb's memory. | 277 | * any more ... just clean up every urb's memory. |
284 | */ | 278 | */ |
285 | if (urb->hcpriv) | 279 | if (urb->hcpriv) |
286 | finish_urb (ohci, urb); | 280 | finish_urb(ohci, urb, status); |
287 | } | 281 | } |
288 | spin_unlock_irqrestore (&ohci->lock, flags); | 282 | spin_unlock_irqrestore (&ohci->lock, flags); |
289 | return 0; | 283 | return rc; |
290 | } | 284 | } |
291 | 285 | ||
292 | /*-------------------------------------------------------------------------*/ | 286 | /*-------------------------------------------------------------------------*/ |
@@ -315,6 +309,8 @@ rescan: | |||
315 | if (!HC_IS_RUNNING (hcd->state)) { | 309 | if (!HC_IS_RUNNING (hcd->state)) { |
316 | sanitize: | 310 | sanitize: |
317 | ed->state = ED_IDLE; | 311 | ed->state = ED_IDLE; |
312 | if (quirk_zfmicro(ohci) && ed->type == PIPE_INTERRUPT) | ||
313 | ohci->eds_scheduled--; | ||
318 | finish_unlinks (ohci, 0); | 314 | finish_unlinks (ohci, 0); |
319 | } | 315 | } |
320 | 316 | ||
@@ -322,7 +318,12 @@ sanitize: | |||
322 | case ED_UNLINK: /* wait for hw to finish? */ | 318 | case ED_UNLINK: /* wait for hw to finish? */ |
323 | /* major IRQ delivery trouble loses INTR_SF too... */ | 319 | /* major IRQ delivery trouble loses INTR_SF too... */ |
324 | if (limit-- == 0) { | 320 | if (limit-- == 0) { |
325 | ohci_warn (ohci, "IRQ INTR_SF lossage\n"); | 321 | ohci_warn(ohci, "ED unlink timeout\n"); |
322 | if (quirk_zfmicro(ohci)) { | ||
323 | ohci_warn(ohci, "Attempting ZF TD recovery\n"); | ||
324 | ohci->ed_to_check = ed; | ||
325 | ohci->zf_delay = 2; | ||
326 | } | ||
326 | goto sanitize; | 327 | goto sanitize; |
327 | } | 328 | } |
328 | spin_unlock_irqrestore (&ohci->lock, flags); | 329 | spin_unlock_irqrestore (&ohci->lock, flags); |
@@ -380,6 +381,93 @@ ohci_shutdown (struct usb_hcd *hcd) | |||
380 | (void) ohci_readl (ohci, &ohci->regs->control); | 381 | (void) ohci_readl (ohci, &ohci->regs->control); |
381 | } | 382 | } |
382 | 383 | ||
384 | static int check_ed(struct ohci_hcd *ohci, struct ed *ed) | ||
385 | { | ||
386 | return (hc32_to_cpu(ohci, ed->hwINFO) & ED_IN) != 0 | ||
387 | && (hc32_to_cpu(ohci, ed->hwHeadP) & TD_MASK) | ||
388 | == (hc32_to_cpu(ohci, ed->hwTailP) & TD_MASK) | ||
389 | && !list_empty(&ed->td_list); | ||
390 | } | ||
391 | |||
392 | /* ZF Micro watchdog timer callback. The ZF Micro chipset sometimes completes | ||
393 | * an interrupt TD but neglects to add it to the donelist. On systems with | ||
394 | * this chipset, we need to periodically check the state of the queues to look | ||
395 | * for such "lost" TDs. | ||
396 | */ | ||
397 | static void unlink_watchdog_func(unsigned long _ohci) | ||
398 | { | ||
399 | long flags; | ||
400 | unsigned max; | ||
401 | unsigned seen_count = 0; | ||
402 | unsigned i; | ||
403 | struct ed **seen = NULL; | ||
404 | struct ohci_hcd *ohci = (struct ohci_hcd *) _ohci; | ||
405 | |||
406 | spin_lock_irqsave(&ohci->lock, flags); | ||
407 | max = ohci->eds_scheduled; | ||
408 | if (!max) | ||
409 | goto done; | ||
410 | |||
411 | if (ohci->ed_to_check) | ||
412 | goto out; | ||
413 | |||
414 | seen = kcalloc(max, sizeof *seen, GFP_ATOMIC); | ||
415 | if (!seen) | ||
416 | goto out; | ||
417 | |||
418 | for (i = 0; i < NUM_INTS; i++) { | ||
419 | struct ed *ed = ohci->periodic[i]; | ||
420 | |||
421 | while (ed) { | ||
422 | unsigned temp; | ||
423 | |||
424 | /* scan this branch of the periodic schedule tree */ | ||
425 | for (temp = 0; temp < seen_count; temp++) { | ||
426 | if (seen[temp] == ed) { | ||
427 | /* we've checked it and what's after */ | ||
428 | ed = NULL; | ||
429 | break; | ||
430 | } | ||
431 | } | ||
432 | if (!ed) | ||
433 | break; | ||
434 | seen[seen_count++] = ed; | ||
435 | if (!check_ed(ohci, ed)) { | ||
436 | ed = ed->ed_next; | ||
437 | continue; | ||
438 | } | ||
439 | |||
440 | /* HC's TD list is empty, but HCD sees at least one | ||
441 | * TD that's not been sent through the donelist. | ||
442 | */ | ||
443 | ohci->ed_to_check = ed; | ||
444 | ohci->zf_delay = 2; | ||
445 | |||
446 | /* The HC may wait until the next frame to report the | ||
447 | * TD as done through the donelist and INTR_WDH. (We | ||
448 | * just *assume* it's not a multi-TD interrupt URB; | ||
449 | * those could defer the IRQ more than one frame, using | ||
450 | * DI...) Check again after the next INTR_SF. | ||
451 | */ | ||
452 | ohci_writel(ohci, OHCI_INTR_SF, | ||
453 | &ohci->regs->intrstatus); | ||
454 | ohci_writel(ohci, OHCI_INTR_SF, | ||
455 | &ohci->regs->intrenable); | ||
456 | |||
457 | /* flush those writes */ | ||
458 | (void) ohci_readl(ohci, &ohci->regs->control); | ||
459 | |||
460 | goto out; | ||
461 | } | ||
462 | } | ||
463 | out: | ||
464 | kfree(seen); | ||
465 | if (ohci->eds_scheduled) | ||
466 | mod_timer(&ohci->unlink_watchdog, round_jiffies_relative(HZ)); | ||
467 | done: | ||
468 | spin_unlock_irqrestore(&ohci->lock, flags); | ||
469 | } | ||
470 | |||
383 | /*-------------------------------------------------------------------------* | 471 | /*-------------------------------------------------------------------------* |
384 | * HC functions | 472 | * HC functions |
385 | *-------------------------------------------------------------------------*/ | 473 | *-------------------------------------------------------------------------*/ |
@@ -617,6 +705,15 @@ retry: | |||
617 | mdelay ((temp >> 23) & 0x1fe); | 705 | mdelay ((temp >> 23) & 0x1fe); |
618 | hcd->state = HC_STATE_RUNNING; | 706 | hcd->state = HC_STATE_RUNNING; |
619 | 707 | ||
708 | if (quirk_zfmicro(ohci)) { | ||
709 | /* Create timer to watch for bad queue state on ZF Micro */ | ||
710 | setup_timer(&ohci->unlink_watchdog, unlink_watchdog_func, | ||
711 | (unsigned long) ohci); | ||
712 | |||
713 | ohci->eds_scheduled = 0; | ||
714 | ohci->ed_to_check = NULL; | ||
715 | } | ||
716 | |||
620 | ohci_dump (ohci, 1); | 717 | ohci_dump (ohci, 1); |
621 | 718 | ||
622 | return 0; | 719 | return 0; |
@@ -630,10 +727,11 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
630 | { | 727 | { |
631 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 728 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
632 | struct ohci_regs __iomem *regs = ohci->regs; | 729 | struct ohci_regs __iomem *regs = ohci->regs; |
633 | int ints; | 730 | int ints; |
634 | 731 | ||
635 | /* we can eliminate a (slow) ohci_readl() | 732 | /* we can eliminate a (slow) ohci_readl() |
636 | if _only_ WDH caused this irq */ | 733 | * if _only_ WDH caused this irq |
734 | */ | ||
637 | if ((ohci->hcca->done_head != 0) | 735 | if ((ohci->hcca->done_head != 0) |
638 | && ! (hc32_to_cpup (ohci, &ohci->hcca->done_head) | 736 | && ! (hc32_to_cpup (ohci, &ohci->hcca->done_head) |
639 | & 0x01)) { | 737 | & 0x01)) { |
@@ -652,7 +750,7 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
652 | 750 | ||
653 | if (ints & OHCI_INTR_UE) { | 751 | if (ints & OHCI_INTR_UE) { |
654 | // e.g. due to PCI Master/Target Abort | 752 | // e.g. due to PCI Master/Target Abort |
655 | if (ohci->flags & OHCI_QUIRK_NEC) { | 753 | if (quirk_nec(ohci)) { |
656 | /* Workaround for a silicon bug in some NEC chips used | 754 | /* Workaround for a silicon bug in some NEC chips used |
657 | * in Apple's PowerBooks. Adapted from Darwin code. | 755 | * in Apple's PowerBooks. Adapted from Darwin code. |
658 | */ | 756 | */ |
@@ -714,6 +812,31 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
714 | ohci_writel (ohci, OHCI_INTR_WDH, ®s->intrenable); | 812 | ohci_writel (ohci, OHCI_INTR_WDH, ®s->intrenable); |
715 | } | 813 | } |
716 | 814 | ||
815 | if (quirk_zfmicro(ohci) && (ints & OHCI_INTR_SF)) { | ||
816 | spin_lock(&ohci->lock); | ||
817 | if (ohci->ed_to_check) { | ||
818 | struct ed *ed = ohci->ed_to_check; | ||
819 | |||
820 | if (check_ed(ohci, ed)) { | ||
821 | /* HC thinks the TD list is empty; HCD knows | ||
822 | * at least one TD is outstanding | ||
823 | */ | ||
824 | if (--ohci->zf_delay == 0) { | ||
825 | struct td *td = list_entry( | ||
826 | ed->td_list.next, | ||
827 | struct td, td_list); | ||
828 | ohci_warn(ohci, | ||
829 | "Reclaiming orphan TD %p\n", | ||
830 | td); | ||
831 | takeback_td(ohci, td); | ||
832 | ohci->ed_to_check = NULL; | ||
833 | } | ||
834 | } else | ||
835 | ohci->ed_to_check = NULL; | ||
836 | } | ||
837 | spin_unlock(&ohci->lock); | ||
838 | } | ||
839 | |||
717 | /* could track INTR_SO to reduce available PCI/... bandwidth */ | 840 | /* could track INTR_SO to reduce available PCI/... bandwidth */ |
718 | 841 | ||
719 | /* handle any pending URB/ED unlinks, leaving INTR_SF enabled | 842 | /* handle any pending URB/ED unlinks, leaving INTR_SF enabled |
@@ -722,7 +845,9 @@ static irqreturn_t ohci_irq (struct usb_hcd *hcd) | |||
722 | spin_lock (&ohci->lock); | 845 | spin_lock (&ohci->lock); |
723 | if (ohci->ed_rm_list) | 846 | if (ohci->ed_rm_list) |
724 | finish_unlinks (ohci, ohci_frame_no(ohci)); | 847 | finish_unlinks (ohci, ohci_frame_no(ohci)); |
725 | if ((ints & OHCI_INTR_SF) != 0 && !ohci->ed_rm_list | 848 | if ((ints & OHCI_INTR_SF) != 0 |
849 | && !ohci->ed_rm_list | ||
850 | && !ohci->ed_to_check | ||
726 | && HC_IS_RUNNING(hcd->state)) | 851 | && HC_IS_RUNNING(hcd->state)) |
727 | ohci_writel (ohci, OHCI_INTR_SF, ®s->intrdisable); | 852 | ohci_writel (ohci, OHCI_INTR_SF, ®s->intrdisable); |
728 | spin_unlock (&ohci->lock); | 853 | spin_unlock (&ohci->lock); |
@@ -752,6 +877,9 @@ static void ohci_stop (struct usb_hcd *hcd) | |||
752 | free_irq(hcd->irq, hcd); | 877 | free_irq(hcd->irq, hcd); |
753 | hcd->irq = -1; | 878 | hcd->irq = -1; |
754 | 879 | ||
880 | if (quirk_zfmicro(ohci)) | ||
881 | del_timer(&ohci->unlink_watchdog); | ||
882 | |||
755 | remove_debug_files (ohci); | 883 | remove_debug_files (ohci); |
756 | ohci_mem_cleanup (ohci); | 884 | ohci_mem_cleanup (ohci); |
757 | if (ohci->hcca) { | 885 | if (ohci->hcca) { |
@@ -799,9 +927,8 @@ static int ohci_restart (struct ohci_hcd *ohci) | |||
799 | ed, ed->state); | 927 | ed, ed->state); |
800 | } | 928 | } |
801 | 929 | ||
802 | spin_lock (&urb->lock); | 930 | if (!urb->unlinked) |
803 | urb->status = -ESHUTDOWN; | 931 | urb->unlinked = -ESHUTDOWN; |
804 | spin_unlock (&urb->lock); | ||
805 | } | 932 | } |
806 | finish_unlinks (ohci, 0); | 933 | finish_unlinks (ohci, 0); |
807 | spin_unlock_irq(&ohci->lock); | 934 | spin_unlock_irq(&ohci->lock); |
@@ -829,27 +956,6 @@ static int ohci_restart (struct ohci_hcd *ohci) | |||
829 | 956 | ||
830 | /*-------------------------------------------------------------------------*/ | 957 | /*-------------------------------------------------------------------------*/ |
831 | 958 | ||
832 | /* NEC workaround */ | ||
833 | static void ohci_quirk_nec_worker(struct work_struct *work) | ||
834 | { | ||
835 | struct ohci_hcd *ohci = container_of(work, struct ohci_hcd, nec_work); | ||
836 | int status; | ||
837 | |||
838 | status = ohci_init(ohci); | ||
839 | if (status != 0) { | ||
840 | ohci_err(ohci, "Restarting NEC controller failed " | ||
841 | "in ohci_init, %d\n", status); | ||
842 | return; | ||
843 | } | ||
844 | |||
845 | status = ohci_restart(ohci); | ||
846 | if (status != 0) | ||
847 | ohci_err(ohci, "Restarting NEC controller failed " | ||
848 | "in ohci_restart, %d\n", status); | ||
849 | } | ||
850 | |||
851 | /*-------------------------------------------------------------------------*/ | ||
852 | |||
853 | #define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC | 959 | #define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC |
854 | 960 | ||
855 | MODULE_AUTHOR (DRIVER_AUTHOR); | 961 | MODULE_AUTHOR (DRIVER_AUTHOR); |
@@ -927,11 +1033,17 @@ MODULE_LICENSE ("GPL"); | |||
927 | #define PS3_SYSTEM_BUS_DRIVER ps3_ohci_driver | 1033 | #define PS3_SYSTEM_BUS_DRIVER ps3_ohci_driver |
928 | #endif | 1034 | #endif |
929 | 1035 | ||
1036 | #ifdef CONFIG_USB_OHCI_HCD_SSB | ||
1037 | #include "ohci-ssb.c" | ||
1038 | #define SSB_OHCI_DRIVER ssb_ohci_driver | ||
1039 | #endif | ||
1040 | |||
930 | #if !defined(PCI_DRIVER) && \ | 1041 | #if !defined(PCI_DRIVER) && \ |
931 | !defined(PLATFORM_DRIVER) && \ | 1042 | !defined(PLATFORM_DRIVER) && \ |
932 | !defined(OF_PLATFORM_DRIVER) && \ | 1043 | !defined(OF_PLATFORM_DRIVER) && \ |
933 | !defined(SA1111_DRIVER) && \ | 1044 | !defined(SA1111_DRIVER) && \ |
934 | !defined(PS3_SYSTEM_BUS_DRIVER) | 1045 | !defined(PS3_SYSTEM_BUS_DRIVER) && \ |
1046 | !defined(SSB_OHCI_DRIVER) | ||
935 | #error "missing bus glue for ohci-hcd" | 1047 | #error "missing bus glue for ohci-hcd" |
936 | #endif | 1048 | #endif |
937 | 1049 | ||
@@ -976,10 +1088,20 @@ static int __init ohci_hcd_mod_init(void) | |||
976 | goto error_pci; | 1088 | goto error_pci; |
977 | #endif | 1089 | #endif |
978 | 1090 | ||
1091 | #ifdef SSB_OHCI_DRIVER | ||
1092 | retval = ssb_driver_register(&SSB_OHCI_DRIVER); | ||
1093 | if (retval) | ||
1094 | goto error_ssb; | ||
1095 | #endif | ||
1096 | |||
979 | return retval; | 1097 | return retval; |
980 | 1098 | ||
981 | /* Error path */ | 1099 | /* Error path */ |
1100 | #ifdef SSB_OHCI_DRIVER | ||
1101 | error_ssb: | ||
1102 | #endif | ||
982 | #ifdef PCI_DRIVER | 1103 | #ifdef PCI_DRIVER |
1104 | pci_unregister_driver(&PCI_DRIVER); | ||
983 | error_pci: | 1105 | error_pci: |
984 | #endif | 1106 | #endif |
985 | #ifdef SA1111_DRIVER | 1107 | #ifdef SA1111_DRIVER |
@@ -1004,6 +1126,9 @@ module_init(ohci_hcd_mod_init); | |||
1004 | 1126 | ||
1005 | static void __exit ohci_hcd_mod_exit(void) | 1127 | static void __exit ohci_hcd_mod_exit(void) |
1006 | { | 1128 | { |
1129 | #ifdef SSB_OHCI_DRIVER | ||
1130 | ssb_driver_unregister(&SSB_OHCI_DRIVER); | ||
1131 | #endif | ||
1007 | #ifdef PCI_DRIVER | 1132 | #ifdef PCI_DRIVER |
1008 | pci_unregister_driver(&PCI_DRIVER); | 1133 | pci_unregister_driver(&PCI_DRIVER); |
1009 | #endif | 1134 | #endif |
diff --git a/drivers/usb/host/ohci-mem.c b/drivers/usb/host/ohci-mem.c index 450c7b460c5..2f20d3dc895 100644 --- a/drivers/usb/host/ohci-mem.c +++ b/drivers/usb/host/ohci-mem.c | |||
@@ -28,7 +28,6 @@ static void ohci_hcd_init (struct ohci_hcd *ohci) | |||
28 | ohci->next_statechange = jiffies; | 28 | ohci->next_statechange = jiffies; |
29 | spin_lock_init (&ohci->lock); | 29 | spin_lock_init (&ohci->lock); |
30 | INIT_LIST_HEAD (&ohci->pending); | 30 | INIT_LIST_HEAD (&ohci->pending); |
31 | INIT_WORK (&ohci->nec_work, ohci_quirk_nec_worker); | ||
32 | } | 31 | } |
33 | 32 | ||
34 | /*-------------------------------------------------------------------------*/ | 33 | /*-------------------------------------------------------------------------*/ |
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index a5e2eb85d07..d0360f65ebd 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -84,7 +84,7 @@ static int ohci_quirk_zfmicro(struct usb_hcd *hcd) | |||
84 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 84 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
85 | 85 | ||
86 | ohci->flags |= OHCI_QUIRK_ZFMICRO; | 86 | ohci->flags |= OHCI_QUIRK_ZFMICRO; |
87 | ohci_dbg (ohci, "enabled Compaq ZFMicro chipset quirk\n"); | 87 | ohci_dbg(ohci, "enabled Compaq ZFMicro chipset quirks\n"); |
88 | 88 | ||
89 | return 0; | 89 | return 0; |
90 | } | 90 | } |
@@ -113,11 +113,31 @@ static int ohci_quirk_toshiba_scc(struct usb_hcd *hcd) | |||
113 | 113 | ||
114 | /* Check for NEC chip and apply quirk for allegedly lost interrupts. | 114 | /* Check for NEC chip and apply quirk for allegedly lost interrupts. |
115 | */ | 115 | */ |
116 | |||
117 | static void ohci_quirk_nec_worker(struct work_struct *work) | ||
118 | { | ||
119 | struct ohci_hcd *ohci = container_of(work, struct ohci_hcd, nec_work); | ||
120 | int status; | ||
121 | |||
122 | status = ohci_init(ohci); | ||
123 | if (status != 0) { | ||
124 | ohci_err(ohci, "Restarting NEC controller failed in %s, %d\n", | ||
125 | "ohci_init", status); | ||
126 | return; | ||
127 | } | ||
128 | |||
129 | status = ohci_restart(ohci); | ||
130 | if (status != 0) | ||
131 | ohci_err(ohci, "Restarting NEC controller failed in %s, %d\n", | ||
132 | "ohci_restart", status); | ||
133 | } | ||
134 | |||
116 | static int ohci_quirk_nec(struct usb_hcd *hcd) | 135 | static int ohci_quirk_nec(struct usb_hcd *hcd) |
117 | { | 136 | { |
118 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | 137 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); |
119 | 138 | ||
120 | ohci->flags |= OHCI_QUIRK_NEC; | 139 | ohci->flags |= OHCI_QUIRK_NEC; |
140 | INIT_WORK(&ohci->nec_work, ohci_quirk_nec_worker); | ||
121 | ohci_dbg (ohci, "enabled NEC chipset lost interrupt quirk\n"); | 141 | ohci_dbg (ohci, "enabled NEC chipset lost interrupt quirk\n"); |
122 | 142 | ||
123 | return 0; | 143 | return 0; |
diff --git a/drivers/usb/host/ohci-ppc-of.c b/drivers/usb/host/ohci-ppc-of.c index c43b66acd4d..0a742692015 100644 --- a/drivers/usb/host/ohci-ppc-of.c +++ b/drivers/usb/host/ohci-ppc-of.c | |||
@@ -134,8 +134,11 @@ ohci_hcd_ppc_of_probe(struct of_device *op, const struct of_device_id *match) | |||
134 | } | 134 | } |
135 | 135 | ||
136 | ohci = hcd_to_ohci(hcd); | 136 | ohci = hcd_to_ohci(hcd); |
137 | if (is_bigendian) | 137 | if (is_bigendian) { |
138 | ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; | 138 | ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; |
139 | if (of_device_is_compatible(dn, "mpc5200-ohci")) | ||
140 | ohci->flags |= OHCI_QUIRK_FRAME_NO; | ||
141 | } | ||
139 | 142 | ||
140 | ohci_hcd_init(ohci); | 143 | ohci_hcd_init(ohci); |
141 | 144 | ||
diff --git a/drivers/usb/host/ohci-ppc-soc.c b/drivers/usb/host/ohci-ppc-soc.c index 1a2e1777ca6..f95be1896b0 100644 --- a/drivers/usb/host/ohci-ppc-soc.c +++ b/drivers/usb/host/ohci-ppc-soc.c | |||
@@ -73,6 +73,11 @@ static int usb_hcd_ppc_soc_probe(const struct hc_driver *driver, | |||
73 | 73 | ||
74 | ohci = hcd_to_ohci(hcd); | 74 | ohci = hcd_to_ohci(hcd); |
75 | ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; | 75 | ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC; |
76 | |||
77 | #ifdef CONFIG_PPC_MPC52xx | ||
78 | /* MPC52xx doesn't need frame_no shift */ | ||
79 | ohci->flags |= OHCI_QUIRK_FRAME_NO; | ||
80 | #endif | ||
76 | ohci_hcd_init(ohci); | 81 | ohci_hcd_init(ohci); |
77 | 82 | ||
78 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); | 83 | retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); |
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 830a3fe8615..51817322232 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c | |||
@@ -36,29 +36,15 @@ static void urb_free_priv (struct ohci_hcd *hc, urb_priv_t *urb_priv) | |||
36 | * PRECONDITION: ohci lock held, irqs blocked. | 36 | * PRECONDITION: ohci lock held, irqs blocked. |
37 | */ | 37 | */ |
38 | static void | 38 | static void |
39 | finish_urb (struct ohci_hcd *ohci, struct urb *urb) | 39 | finish_urb(struct ohci_hcd *ohci, struct urb *urb, int status) |
40 | __releases(ohci->lock) | 40 | __releases(ohci->lock) |
41 | __acquires(ohci->lock) | 41 | __acquires(ohci->lock) |
42 | { | 42 | { |
43 | // ASSERT (urb->hcpriv != 0); | 43 | // ASSERT (urb->hcpriv != 0); |
44 | 44 | ||
45 | urb_free_priv (ohci, urb->hcpriv); | 45 | urb_free_priv (ohci, urb->hcpriv); |
46 | urb->hcpriv = NULL; | 46 | if (likely(status == -EINPROGRESS)) |
47 | 47 | status = 0; | |
48 | spin_lock (&urb->lock); | ||
49 | if (likely (urb->status == -EINPROGRESS)) | ||
50 | urb->status = 0; | ||
51 | /* report short control reads right even though the data TD always | ||
52 | * has TD_R set. (much simpler, but creates the 1-td limit.) | ||
53 | */ | ||
54 | if (unlikely (urb->transfer_flags & URB_SHORT_NOT_OK) | ||
55 | && unlikely (usb_pipecontrol (urb->pipe)) | ||
56 | && urb->actual_length < urb->transfer_buffer_length | ||
57 | && usb_pipein (urb->pipe) | ||
58 | && urb->status == 0) { | ||
59 | urb->status = -EREMOTEIO; | ||
60 | } | ||
61 | spin_unlock (&urb->lock); | ||
62 | 48 | ||
63 | switch (usb_pipetype (urb->pipe)) { | 49 | switch (usb_pipetype (urb->pipe)) { |
64 | case PIPE_ISOCHRONOUS: | 50 | case PIPE_ISOCHRONOUS: |
@@ -70,12 +56,13 @@ __acquires(ohci->lock) | |||
70 | } | 56 | } |
71 | 57 | ||
72 | #ifdef OHCI_VERBOSE_DEBUG | 58 | #ifdef OHCI_VERBOSE_DEBUG |
73 | urb_print (urb, "RET", usb_pipeout (urb->pipe)); | 59 | urb_print(urb, "RET", usb_pipeout (urb->pipe), status); |
74 | #endif | 60 | #endif |
75 | 61 | ||
76 | /* urb->complete() can reenter this HCD */ | 62 | /* urb->complete() can reenter this HCD */ |
63 | usb_hcd_unlink_urb_from_ep(ohci_to_hcd(ohci), urb); | ||
77 | spin_unlock (&ohci->lock); | 64 | spin_unlock (&ohci->lock); |
78 | usb_hcd_giveback_urb (ohci_to_hcd(ohci), urb); | 65 | usb_hcd_giveback_urb(ohci_to_hcd(ohci), urb, status); |
79 | spin_lock (&ohci->lock); | 66 | spin_lock (&ohci->lock); |
80 | 67 | ||
81 | /* stop periodic dma if it's not needed */ | 68 | /* stop periodic dma if it's not needed */ |
@@ -179,6 +166,10 @@ static int ed_schedule (struct ohci_hcd *ohci, struct ed *ed) | |||
179 | ed->ed_prev = NULL; | 166 | ed->ed_prev = NULL; |
180 | ed->ed_next = NULL; | 167 | ed->ed_next = NULL; |
181 | ed->hwNextED = 0; | 168 | ed->hwNextED = 0; |
169 | if (quirk_zfmicro(ohci) | ||
170 | && (ed->type == PIPE_INTERRUPT) | ||
171 | && !(ohci->eds_scheduled++)) | ||
172 | mod_timer(&ohci->unlink_watchdog, round_jiffies_relative(HZ)); | ||
182 | wmb (); | 173 | wmb (); |
183 | 174 | ||
184 | /* we care about rm_list when setting CLE/BLE in case the HC was at | 175 | /* we care about rm_list when setting CLE/BLE in case the HC was at |
@@ -708,19 +699,18 @@ static void td_submit_urb ( | |||
708 | * Done List handling functions | 699 | * Done List handling functions |
709 | *-------------------------------------------------------------------------*/ | 700 | *-------------------------------------------------------------------------*/ |
710 | 701 | ||
711 | /* calculate transfer length/status and update the urb | 702 | /* calculate transfer length/status and update the urb */ |
712 | * PRECONDITION: irqsafe (only for urb->status locking) | 703 | static int td_done(struct ohci_hcd *ohci, struct urb *urb, struct td *td) |
713 | */ | ||
714 | static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td) | ||
715 | { | 704 | { |
716 | u32 tdINFO = hc32_to_cpup (ohci, &td->hwINFO); | 705 | u32 tdINFO = hc32_to_cpup (ohci, &td->hwINFO); |
717 | int cc = 0; | 706 | int cc = 0; |
707 | int status = -EINPROGRESS; | ||
718 | 708 | ||
719 | list_del (&td->td_list); | 709 | list_del (&td->td_list); |
720 | 710 | ||
721 | /* ISO ... drivers see per-TD length/status */ | 711 | /* ISO ... drivers see per-TD length/status */ |
722 | if (tdINFO & TD_ISO) { | 712 | if (tdINFO & TD_ISO) { |
723 | u16 tdPSW = ohci_hwPSW (ohci, td, 0); | 713 | u16 tdPSW = ohci_hwPSW(ohci, td, 0); |
724 | int dlen = 0; | 714 | int dlen = 0; |
725 | 715 | ||
726 | /* NOTE: assumes FC in tdINFO == 0, and that | 716 | /* NOTE: assumes FC in tdINFO == 0, and that |
@@ -729,7 +719,7 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td) | |||
729 | 719 | ||
730 | cc = (tdPSW >> 12) & 0xF; | 720 | cc = (tdPSW >> 12) & 0xF; |
731 | if (tdINFO & TD_CC) /* hc didn't touch? */ | 721 | if (tdINFO & TD_CC) /* hc didn't touch? */ |
732 | return; | 722 | return status; |
733 | 723 | ||
734 | if (usb_pipeout (urb->pipe)) | 724 | if (usb_pipeout (urb->pipe)) |
735 | dlen = urb->iso_frame_desc [td->index].length; | 725 | dlen = urb->iso_frame_desc [td->index].length; |
@@ -762,12 +752,8 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td) | |||
762 | if (cc == TD_DATAUNDERRUN | 752 | if (cc == TD_DATAUNDERRUN |
763 | && !(urb->transfer_flags & URB_SHORT_NOT_OK)) | 753 | && !(urb->transfer_flags & URB_SHORT_NOT_OK)) |
764 | cc = TD_CC_NOERROR; | 754 | cc = TD_CC_NOERROR; |
765 | if (cc != TD_CC_NOERROR && cc < 0x0E) { | 755 | if (cc != TD_CC_NOERROR && cc < 0x0E) |
766 | spin_lock (&urb->lock); | 756 | status = cc_to_error[cc]; |
767 | if (urb->status == -EINPROGRESS) | ||
768 | urb->status = cc_to_error [cc]; | ||
769 | spin_unlock (&urb->lock); | ||
770 | } | ||
771 | 757 | ||
772 | /* count all non-empty packets except control SETUP packet */ | 758 | /* count all non-empty packets except control SETUP packet */ |
773 | if ((type != PIPE_CONTROL || td->index != 0) && tdBE != 0) { | 759 | if ((type != PIPE_CONTROL || td->index != 0) && tdBE != 0) { |
@@ -786,14 +772,15 @@ static void td_done (struct ohci_hcd *ohci, struct urb *urb, struct td *td) | |||
786 | urb->actual_length, | 772 | urb->actual_length, |
787 | urb->transfer_buffer_length); | 773 | urb->transfer_buffer_length); |
788 | } | 774 | } |
775 | return status; | ||
789 | } | 776 | } |
790 | 777 | ||
791 | /*-------------------------------------------------------------------------*/ | 778 | /*-------------------------------------------------------------------------*/ |
792 | 779 | ||
793 | static inline struct td * | 780 | static void ed_halted(struct ohci_hcd *ohci, struct td *td, int cc) |
794 | ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) | ||
795 | { | 781 | { |
796 | struct urb *urb = td->urb; | 782 | struct urb *urb = td->urb; |
783 | urb_priv_t *urb_priv = urb->hcpriv; | ||
797 | struct ed *ed = td->ed; | 784 | struct ed *ed = td->ed; |
798 | struct list_head *tmp = td->td_list.next; | 785 | struct list_head *tmp = td->td_list.next; |
799 | __hc32 toggle = ed->hwHeadP & cpu_to_hc32 (ohci, ED_C); | 786 | __hc32 toggle = ed->hwHeadP & cpu_to_hc32 (ohci, ED_C); |
@@ -805,13 +792,12 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) | |||
805 | wmb (); | 792 | wmb (); |
806 | ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_H); | 793 | ed->hwHeadP &= ~cpu_to_hc32 (ohci, ED_H); |
807 | 794 | ||
808 | /* put any later tds from this urb onto the donelist, after 'td', | 795 | /* Get rid of all later tds from this urb. We don't have |
809 | * order won't matter here: no errors, and nothing was transferred. | 796 | * to be careful: no errors and nothing was transferred. |
810 | * also patch the ed so it looks as if those tds completed normally. | 797 | * Also patch the ed so it looks as if those tds completed normally. |
811 | */ | 798 | */ |
812 | while (tmp != &ed->td_list) { | 799 | while (tmp != &ed->td_list) { |
813 | struct td *next; | 800 | struct td *next; |
814 | __hc32 info; | ||
815 | 801 | ||
816 | next = list_entry (tmp, struct td, td_list); | 802 | next = list_entry (tmp, struct td, td_list); |
817 | tmp = next->td_list.next; | 803 | tmp = next->td_list.next; |
@@ -826,14 +812,9 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) | |||
826 | * then we need to leave the control STATUS packet queued | 812 | * then we need to leave the control STATUS packet queued |
827 | * and clear ED_SKIP. | 813 | * and clear ED_SKIP. |
828 | */ | 814 | */ |
829 | info = next->hwINFO; | ||
830 | info |= cpu_to_hc32 (ohci, TD_DONE); | ||
831 | info &= ~cpu_to_hc32 (ohci, TD_CC); | ||
832 | next->hwINFO = info; | ||
833 | |||
834 | next->next_dl_td = rev; | ||
835 | rev = next; | ||
836 | 815 | ||
816 | list_del(&next->td_list); | ||
817 | urb_priv->td_cnt++; | ||
837 | ed->hwHeadP = next->hwNextTD | toggle; | 818 | ed->hwHeadP = next->hwNextTD | toggle; |
838 | } | 819 | } |
839 | 820 | ||
@@ -859,8 +840,6 @@ ed_halted (struct ohci_hcd *ohci, struct td *td, int cc, struct td *rev) | |||
859 | hc32_to_cpu (ohci, td->hwINFO), | 840 | hc32_to_cpu (ohci, td->hwINFO), |
860 | cc, cc_to_error [cc]); | 841 | cc, cc_to_error [cc]); |
861 | } | 842 | } |
862 | |||
863 | return rev; | ||
864 | } | 843 | } |
865 | 844 | ||
866 | /* replies to the request have to be on a FIFO basis so | 845 | /* replies to the request have to be on a FIFO basis so |
@@ -897,7 +876,7 @@ static struct td *dl_reverse_done_list (struct ohci_hcd *ohci) | |||
897 | */ | 876 | */ |
898 | if (cc != TD_CC_NOERROR | 877 | if (cc != TD_CC_NOERROR |
899 | && (td->ed->hwHeadP & cpu_to_hc32 (ohci, ED_H))) | 878 | && (td->ed->hwHeadP & cpu_to_hc32 (ohci, ED_H))) |
900 | td_rev = ed_halted (ohci, td, cc, td_rev); | 879 | ed_halted(ohci, td, cc); |
901 | 880 | ||
902 | td->next_dl_td = td_rev; | 881 | td->next_dl_td = td_rev; |
903 | td_rev = td; | 882 | td_rev = td; |
@@ -940,8 +919,12 @@ skip_ed: | |||
940 | TD_MASK; | 919 | TD_MASK; |
941 | 920 | ||
942 | /* INTR_WDH may need to clean up first */ | 921 | /* INTR_WDH may need to clean up first */ |
943 | if (td->td_dma != head) | 922 | if (td->td_dma != head) { |
944 | goto skip_ed; | 923 | if (ed == ohci->ed_to_check) |
924 | ohci->ed_to_check = NULL; | ||
925 | else | ||
926 | goto skip_ed; | ||
927 | } | ||
945 | } | 928 | } |
946 | } | 929 | } |
947 | 930 | ||
@@ -974,7 +957,7 @@ rescan_this: | |||
974 | urb = td->urb; | 957 | urb = td->urb; |
975 | urb_priv = td->urb->hcpriv; | 958 | urb_priv = td->urb->hcpriv; |
976 | 959 | ||
977 | if (urb->status == -EINPROGRESS) { | 960 | if (!urb->unlinked) { |
978 | prev = &td->hwNextTD; | 961 | prev = &td->hwNextTD; |
979 | continue; | 962 | continue; |
980 | } | 963 | } |
@@ -990,7 +973,7 @@ rescan_this: | |||
990 | /* if URB is done, clean up */ | 973 | /* if URB is done, clean up */ |
991 | if (urb_priv->td_cnt == urb_priv->length) { | 974 | if (urb_priv->td_cnt == urb_priv->length) { |
992 | modified = completed = 1; | 975 | modified = completed = 1; |
993 | finish_urb (ohci, urb); | 976 | finish_urb(ohci, urb, 0); |
994 | } | 977 | } |
995 | } | 978 | } |
996 | if (completed && !list_empty (&ed->td_list)) | 979 | if (completed && !list_empty (&ed->td_list)) |
@@ -998,6 +981,8 @@ rescan_this: | |||
998 | 981 | ||
999 | /* ED's now officially unlinked, hc doesn't see */ | 982 | /* ED's now officially unlinked, hc doesn't see */ |
1000 | ed->state = ED_IDLE; | 983 | ed->state = ED_IDLE; |
984 | if (quirk_zfmicro(ohci) && ed->type == PIPE_INTERRUPT) | ||
985 | ohci->eds_scheduled--; | ||
1001 | ed->hwHeadP &= ~cpu_to_hc32(ohci, ED_H); | 986 | ed->hwHeadP &= ~cpu_to_hc32(ohci, ED_H); |
1002 | ed->hwNextED = 0; | 987 | ed->hwNextED = 0; |
1003 | wmb (); | 988 | wmb (); |
@@ -1021,7 +1006,7 @@ rescan_this: | |||
1021 | 1006 | ||
1022 | if (ohci->ed_controltail) { | 1007 | if (ohci->ed_controltail) { |
1023 | command |= OHCI_CLF; | 1008 | command |= OHCI_CLF; |
1024 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) | 1009 | if (quirk_zfmicro(ohci)) |
1025 | mdelay(1); | 1010 | mdelay(1); |
1026 | if (!(ohci->hc_control & OHCI_CTRL_CLE)) { | 1011 | if (!(ohci->hc_control & OHCI_CTRL_CLE)) { |
1027 | control |= OHCI_CTRL_CLE; | 1012 | control |= OHCI_CTRL_CLE; |
@@ -1031,7 +1016,7 @@ rescan_this: | |||
1031 | } | 1016 | } |
1032 | if (ohci->ed_bulktail) { | 1017 | if (ohci->ed_bulktail) { |
1033 | command |= OHCI_BLF; | 1018 | command |= OHCI_BLF; |
1034 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) | 1019 | if (quirk_zfmicro(ohci)) |
1035 | mdelay(1); | 1020 | mdelay(1); |
1036 | if (!(ohci->hc_control & OHCI_CTRL_BLE)) { | 1021 | if (!(ohci->hc_control & OHCI_CTRL_BLE)) { |
1037 | control |= OHCI_CTRL_BLE; | 1022 | control |= OHCI_CTRL_BLE; |
@@ -1043,13 +1028,13 @@ rescan_this: | |||
1043 | /* CLE/BLE to enable, CLF/BLF to (maybe) kickstart */ | 1028 | /* CLE/BLE to enable, CLF/BLF to (maybe) kickstart */ |
1044 | if (control) { | 1029 | if (control) { |
1045 | ohci->hc_control |= control; | 1030 | ohci->hc_control |= control; |
1046 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) | 1031 | if (quirk_zfmicro(ohci)) |
1047 | mdelay(1); | 1032 | mdelay(1); |
1048 | ohci_writel (ohci, ohci->hc_control, | 1033 | ohci_writel (ohci, ohci->hc_control, |
1049 | &ohci->regs->control); | 1034 | &ohci->regs->control); |
1050 | } | 1035 | } |
1051 | if (command) { | 1036 | if (command) { |
1052 | if (ohci->flags & OHCI_QUIRK_ZFMICRO) | 1037 | if (quirk_zfmicro(ohci)) |
1053 | mdelay(1); | 1038 | mdelay(1); |
1054 | ohci_writel (ohci, command, &ohci->regs->cmdstatus); | 1039 | ohci_writel (ohci, command, &ohci->regs->cmdstatus); |
1055 | } | 1040 | } |
@@ -1061,11 +1046,60 @@ rescan_this: | |||
1061 | /*-------------------------------------------------------------------------*/ | 1046 | /*-------------------------------------------------------------------------*/ |
1062 | 1047 | ||
1063 | /* | 1048 | /* |
1049 | * Used to take back a TD from the host controller. This would normally be | ||
1050 | * called from within dl_done_list, however it may be called directly if the | ||
1051 | * HC no longer sees the TD and it has not appeared on the donelist (after | ||
1052 | * two frames). This bug has been observed on ZF Micro systems. | ||
1053 | */ | ||
1054 | static void takeback_td(struct ohci_hcd *ohci, struct td *td) | ||
1055 | { | ||
1056 | struct urb *urb = td->urb; | ||
1057 | urb_priv_t *urb_priv = urb->hcpriv; | ||
1058 | struct ed *ed = td->ed; | ||
1059 | int status; | ||
1060 | |||
1061 | /* update URB's length and status from TD */ | ||
1062 | status = td_done(ohci, urb, td); | ||
1063 | urb_priv->td_cnt++; | ||
1064 | |||
1065 | /* If all this urb's TDs are done, call complete() */ | ||
1066 | if (urb_priv->td_cnt == urb_priv->length) | ||
1067 | finish_urb(ohci, urb, status); | ||
1068 | |||
1069 | /* clean schedule: unlink EDs that are no longer busy */ | ||
1070 | if (list_empty(&ed->td_list)) { | ||
1071 | if (ed->state == ED_OPER) | ||
1072 | start_ed_unlink(ohci, ed); | ||
1073 | |||
1074 | /* ... reenabling halted EDs only after fault cleanup */ | ||
1075 | } else if ((ed->hwINFO & cpu_to_hc32(ohci, ED_SKIP | ED_DEQUEUE)) | ||
1076 | == cpu_to_hc32(ohci, ED_SKIP)) { | ||
1077 | td = list_entry(ed->td_list.next, struct td, td_list); | ||
1078 | if (!(td->hwINFO & cpu_to_hc32(ohci, TD_DONE))) { | ||
1079 | ed->hwINFO &= ~cpu_to_hc32(ohci, ED_SKIP); | ||
1080 | /* ... hc may need waking-up */ | ||
1081 | switch (ed->type) { | ||
1082 | case PIPE_CONTROL: | ||
1083 | ohci_writel(ohci, OHCI_CLF, | ||
1084 | &ohci->regs->cmdstatus); | ||
1085 | break; | ||
1086 | case PIPE_BULK: | ||
1087 | ohci_writel(ohci, OHCI_BLF, | ||
1088 | &ohci->regs->cmdstatus); | ||
1089 | break; | ||
1090 | } | ||
1091 | } | ||
1092 | } | ||
1093 | } | ||
1094 | |||
1095 | /* | ||
1064 | * Process normal completions (error or success) and clean the schedules. | 1096 | * Process normal completions (error or success) and clean the schedules. |
1065 | * | 1097 | * |
1066 | * This is the main path for handing urbs back to drivers. The only other | 1098 | * This is the main path for handing urbs back to drivers. The only other |
1067 | * path is finish_unlinks(), which unlinks URBs using ed_rm_list, instead of | 1099 | * normal path is finish_unlinks(), which unlinks URBs using ed_rm_list, |
1068 | * scanning the (re-reversed) donelist as this does. | 1100 | * instead of scanning the (re-reversed) donelist as this does. There's |
1101 | * an abnormal path too, handling a quirk in some Compaq silicon: URBs | ||
1102 | * with TDs that appear to be orphaned are directly reclaimed. | ||
1069 | */ | 1103 | */ |
1070 | static void | 1104 | static void |
1071 | dl_done_list (struct ohci_hcd *ohci) | 1105 | dl_done_list (struct ohci_hcd *ohci) |
@@ -1074,44 +1108,7 @@ dl_done_list (struct ohci_hcd *ohci) | |||
1074 | 1108 | ||
1075 | while (td) { | 1109 | while (td) { |
1076 | struct td *td_next = td->next_dl_td; | 1110 | struct td *td_next = td->next_dl_td; |
1077 | struct urb *urb = td->urb; | 1111 | takeback_td(ohci, td); |
1078 | urb_priv_t *urb_priv = urb->hcpriv; | ||
1079 | struct ed *ed = td->ed; | ||
1080 | |||
1081 | /* update URB's length and status from TD */ | ||
1082 | td_done (ohci, urb, td); | ||
1083 | urb_priv->td_cnt++; | ||
1084 | |||
1085 | /* If all this urb's TDs are done, call complete() */ | ||
1086 | if (urb_priv->td_cnt == urb_priv->length) | ||
1087 | finish_urb (ohci, urb); | ||
1088 | |||
1089 | /* clean schedule: unlink EDs that are no longer busy */ | ||
1090 | if (list_empty (&ed->td_list)) { | ||
1091 | if (ed->state == ED_OPER) | ||
1092 | start_ed_unlink (ohci, ed); | ||
1093 | |||
1094 | /* ... reenabling halted EDs only after fault cleanup */ | ||
1095 | } else if ((ed->hwINFO & cpu_to_hc32 (ohci, | ||
1096 | ED_SKIP | ED_DEQUEUE)) | ||
1097 | == cpu_to_hc32 (ohci, ED_SKIP)) { | ||
1098 | td = list_entry (ed->td_list.next, struct td, td_list); | ||
1099 | if (!(td->hwINFO & cpu_to_hc32 (ohci, TD_DONE))) { | ||
1100 | ed->hwINFO &= ~cpu_to_hc32 (ohci, ED_SKIP); | ||
1101 | /* ... hc may need waking-up */ | ||
1102 | switch (ed->type) { | ||
1103 | case PIPE_CONTROL: | ||
1104 | ohci_writel (ohci, OHCI_CLF, | ||
1105 | &ohci->regs->cmdstatus); | ||
1106 | break; | ||
1107 | case PIPE_BULK: | ||
1108 | ohci_writel (ohci, OHCI_BLF, | ||
1109 | &ohci->regs->cmdstatus); | ||
1110 | break; | ||
1111 | } | ||
1112 | } | ||
1113 | } | ||
1114 | |||
1115 | td = td_next; | 1112 | td = td_next; |
1116 | } | 1113 | } |
1117 | } | 1114 | } |
diff --git a/drivers/usb/host/ohci-ssb.c b/drivers/usb/host/ohci-ssb.c new file mode 100644 index 00000000000..bc3e785d8c0 --- /dev/null +++ b/drivers/usb/host/ohci-ssb.c | |||
@@ -0,0 +1,247 @@ | |||
1 | /* | ||
2 | * Sonics Silicon Backplane | ||
3 | * Broadcom USB-core OHCI driver | ||
4 | * | ||
5 | * Copyright 2007 Michael Buesch <mb@bu3sch.de> | ||
6 | * | ||
7 | * Derived from the OHCI-PCI driver | ||
8 | * Copyright 1999 Roman Weissgaerber | ||
9 | * Copyright 2000-2002 David Brownell | ||
10 | * Copyright 1999 Linus Torvalds | ||
11 | * Copyright 1999 Gregory P. Smith | ||
12 | * | ||
13 | * Derived from the USBcore related parts of Broadcom-SB | ||
14 | * Copyright 2005 Broadcom Corporation | ||
15 | * | ||
16 | * Licensed under the GNU/GPL. See COPYING for details. | ||
17 | */ | ||
18 | #include <linux/ssb/ssb.h> | ||
19 | |||
20 | |||
21 | #define SSB_OHCI_TMSLOW_HOSTMODE (1 << 29) | ||
22 | |||
23 | struct ssb_ohci_device { | ||
24 | struct ohci_hcd ohci; /* _must_ be at the beginning. */ | ||
25 | |||
26 | u32 enable_flags; | ||
27 | }; | ||
28 | |||
29 | static inline | ||
30 | struct ssb_ohci_device *hcd_to_ssb_ohci(struct usb_hcd *hcd) | ||
31 | { | ||
32 | return (struct ssb_ohci_device *)(hcd->hcd_priv); | ||
33 | } | ||
34 | |||
35 | |||
36 | static int ssb_ohci_reset(struct usb_hcd *hcd) | ||
37 | { | ||
38 | struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd); | ||
39 | struct ohci_hcd *ohci = &ohcidev->ohci; | ||
40 | int err; | ||
41 | |||
42 | ohci_hcd_init(ohci); | ||
43 | err = ohci_init(ohci); | ||
44 | |||
45 | return err; | ||
46 | } | ||
47 | |||
48 | static int ssb_ohci_start(struct usb_hcd *hcd) | ||
49 | { | ||
50 | struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd); | ||
51 | struct ohci_hcd *ohci = &ohcidev->ohci; | ||
52 | int err; | ||
53 | |||
54 | err = ohci_run(ohci); | ||
55 | if (err < 0) { | ||
56 | ohci_err(ohci, "can't start\n"); | ||
57 | ohci_stop(hcd); | ||
58 | } | ||
59 | |||
60 | return err; | ||
61 | } | ||
62 | |||
63 | #ifdef CONFIG_PM | ||
64 | static int ssb_ohci_hcd_suspend(struct usb_hcd *hcd, pm_message_t message) | ||
65 | { | ||
66 | struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd); | ||
67 | struct ohci_hcd *ohci = &ohcidev->ohci; | ||
68 | unsigned long flags; | ||
69 | |||
70 | spin_lock_irqsave(&ohci->lock, flags); | ||
71 | |||
72 | ohci_writel(ohci, OHCI_INTR_MIE, &ohci->regs->intrdisable); | ||
73 | ohci_readl(ohci, &ohci->regs->intrdisable); /* commit write */ | ||
74 | |||
75 | /* make sure snapshot being resumed re-enumerates everything */ | ||
76 | if (message.event == PM_EVENT_PRETHAW) | ||
77 | ohci_usb_reset(ohci); | ||
78 | |||
79 | clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
80 | |||
81 | spin_unlock_irqrestore(&ohci->lock, flags); | ||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | static int ssb_ohci_hcd_resume(struct usb_hcd *hcd) | ||
86 | { | ||
87 | set_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); | ||
88 | usb_hcd_resume_root_hub(hcd); | ||
89 | return 0; | ||
90 | } | ||
91 | #endif /* CONFIG_PM */ | ||
92 | |||
93 | static const struct hc_driver ssb_ohci_hc_driver = { | ||
94 | .description = "ssb-usb-ohci", | ||
95 | .product_desc = "SSB OHCI Controller", | ||
96 | .hcd_priv_size = sizeof(struct ssb_ohci_device), | ||
97 | |||
98 | .irq = ohci_irq, | ||
99 | .flags = HCD_MEMORY | HCD_USB11, | ||
100 | |||
101 | .reset = ssb_ohci_reset, | ||
102 | .start = ssb_ohci_start, | ||
103 | .stop = ohci_stop, | ||
104 | .shutdown = ohci_shutdown, | ||
105 | |||
106 | #ifdef CONFIG_PM | ||
107 | .suspend = ssb_ohci_hcd_suspend, | ||
108 | .resume = ssb_ohci_hcd_resume, | ||
109 | #endif | ||
110 | |||
111 | .urb_enqueue = ohci_urb_enqueue, | ||
112 | .urb_dequeue = ohci_urb_dequeue, | ||
113 | .endpoint_disable = ohci_endpoint_disable, | ||
114 | |||
115 | .get_frame_number = ohci_get_frame, | ||
116 | |||
117 | .hub_status_data = ohci_hub_status_data, | ||
118 | .hub_control = ohci_hub_control, | ||
119 | .hub_irq_enable = ohci_rhsc_enable, | ||
120 | .bus_suspend = ohci_bus_suspend, | ||
121 | .bus_resume = ohci_bus_resume, | ||
122 | |||
123 | .start_port_reset = ohci_start_port_reset, | ||
124 | }; | ||
125 | |||
126 | static void ssb_ohci_detach(struct ssb_device *dev) | ||
127 | { | ||
128 | struct usb_hcd *hcd = ssb_get_drvdata(dev); | ||
129 | |||
130 | usb_remove_hcd(hcd); | ||
131 | iounmap(hcd->regs); | ||
132 | usb_put_hcd(hcd); | ||
133 | ssb_device_disable(dev, 0); | ||
134 | } | ||
135 | |||
136 | static int ssb_ohci_attach(struct ssb_device *dev) | ||
137 | { | ||
138 | struct ssb_ohci_device *ohcidev; | ||
139 | struct usb_hcd *hcd; | ||
140 | int err = -ENOMEM; | ||
141 | u32 tmp, flags = 0; | ||
142 | |||
143 | if (dev->id.coreid == SSB_DEV_USB11_HOSTDEV) | ||
144 | flags |= SSB_OHCI_TMSLOW_HOSTMODE; | ||
145 | |||
146 | ssb_device_enable(dev, flags); | ||
147 | |||
148 | hcd = usb_create_hcd(&ssb_ohci_hc_driver, dev->dev, | ||
149 | dev->dev->bus_id); | ||
150 | if (!hcd) | ||
151 | goto err_dev_disable; | ||
152 | ohcidev = hcd_to_ssb_ohci(hcd); | ||
153 | ohcidev->enable_flags = flags; | ||
154 | |||
155 | tmp = ssb_read32(dev, SSB_ADMATCH0); | ||
156 | hcd->rsrc_start = ssb_admatch_base(tmp); | ||
157 | hcd->rsrc_len = ssb_admatch_size(tmp); | ||
158 | hcd->regs = ioremap_nocache(hcd->rsrc_start, hcd->rsrc_len); | ||
159 | if (!hcd->regs) | ||
160 | goto err_put_hcd; | ||
161 | err = usb_add_hcd(hcd, dev->irq, IRQF_SHARED); | ||
162 | if (err) | ||
163 | goto err_iounmap; | ||
164 | |||
165 | ssb_set_drvdata(dev, hcd); | ||
166 | |||
167 | return err; | ||
168 | |||
169 | err_iounmap: | ||
170 | iounmap(hcd->regs); | ||
171 | err_put_hcd: | ||
172 | usb_put_hcd(hcd); | ||
173 | err_dev_disable: | ||
174 | ssb_device_disable(dev, flags); | ||
175 | return err; | ||
176 | } | ||
177 | |||
178 | static int ssb_ohci_probe(struct ssb_device *dev, | ||
179 | const struct ssb_device_id *id) | ||
180 | { | ||
181 | int err; | ||
182 | u16 chipid_top; | ||
183 | |||
184 | /* USBcores are only connected on embedded devices. */ | ||
185 | chipid_top = (dev->bus->chip_id & 0xFF00); | ||
186 | if (chipid_top != 0x4700 && chipid_top != 0x5300) | ||
187 | return -ENODEV; | ||
188 | |||
189 | /* TODO: Probably need checks here; is the core connected? */ | ||
190 | |||
191 | if (usb_disabled()) | ||
192 | return -ENODEV; | ||
193 | |||
194 | /* We currently always attach SSB_DEV_USB11_HOSTDEV | ||
195 | * as HOST OHCI. If we want to attach it as Client device, | ||
196 | * we must branch here and call into the (yet to | ||
197 | * be written) Client mode driver. Same for remove(). */ | ||
198 | |||
199 | err = ssb_ohci_attach(dev); | ||
200 | |||
201 | return err; | ||
202 | } | ||
203 | |||
204 | static void ssb_ohci_remove(struct ssb_device *dev) | ||
205 | { | ||
206 | ssb_ohci_detach(dev); | ||
207 | } | ||
208 | |||
209 | #ifdef CONFIG_PM | ||
210 | |||
211 | static int ssb_ohci_suspend(struct ssb_device *dev, pm_message_t state) | ||
212 | { | ||
213 | ssb_device_disable(dev, 0); | ||
214 | |||
215 | return 0; | ||
216 | } | ||
217 | |||
218 | static int ssb_ohci_resume(struct ssb_device *dev) | ||
219 | { | ||
220 | struct usb_hcd *hcd = ssb_get_drvdata(dev); | ||
221 | struct ssb_ohci_device *ohcidev = hcd_to_ssb_ohci(hcd); | ||
222 | |||
223 | ssb_device_enable(dev, ohcidev->enable_flags); | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | #else /* !CONFIG_PM */ | ||
229 | #define ssb_ohci_suspend NULL | ||
230 | #define ssb_ohci_resume NULL | ||
231 | #endif /* CONFIG_PM */ | ||
232 | |||
233 | static const struct ssb_device_id ssb_ohci_table[] = { | ||
234 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOSTDEV, SSB_ANY_REV), | ||
235 | SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_USB11_HOST, SSB_ANY_REV), | ||
236 | SSB_DEVTABLE_END | ||
237 | }; | ||
238 | MODULE_DEVICE_TABLE(ssb, ssb_ohci_table); | ||
239 | |||
240 | static struct ssb_driver ssb_ohci_driver = { | ||
241 | .name = KBUILD_MODNAME, | ||
242 | .id_table = ssb_ohci_table, | ||
243 | .probe = ssb_ohci_probe, | ||
244 | .remove = ssb_ohci_remove, | ||
245 | .suspend = ssb_ohci_suspend, | ||
246 | .resume = ssb_ohci_resume, | ||
247 | }; | ||
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 4ada43cf138..47c5c66a282 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h | |||
@@ -398,11 +398,38 @@ struct ohci_hcd { | |||
398 | #define OHCI_QUIRK_BE_MMIO 0x10 /* BE registers */ | 398 | #define OHCI_QUIRK_BE_MMIO 0x10 /* BE registers */ |
399 | #define OHCI_QUIRK_ZFMICRO 0x20 /* Compaq ZFMicro chipset*/ | 399 | #define OHCI_QUIRK_ZFMICRO 0x20 /* Compaq ZFMicro chipset*/ |
400 | #define OHCI_QUIRK_NEC 0x40 /* lost interrupts */ | 400 | #define OHCI_QUIRK_NEC 0x40 /* lost interrupts */ |
401 | #define OHCI_QUIRK_FRAME_NO 0x80 /* no big endian frame_no shift */ | ||
401 | // there are also chip quirks/bugs in init logic | 402 | // there are also chip quirks/bugs in init logic |
402 | 403 | ||
403 | struct work_struct nec_work; /* Worker for NEC quirk */ | 404 | struct work_struct nec_work; /* Worker for NEC quirk */ |
405 | |||
406 | /* Needed for ZF Micro quirk */ | ||
407 | struct timer_list unlink_watchdog; | ||
408 | unsigned eds_scheduled; | ||
409 | struct ed *ed_to_check; | ||
410 | unsigned zf_delay; | ||
404 | }; | 411 | }; |
405 | 412 | ||
413 | #ifdef CONFIG_PCI | ||
414 | static inline int quirk_nec(struct ohci_hcd *ohci) | ||
415 | { | ||
416 | return ohci->flags & OHCI_QUIRK_NEC; | ||
417 | } | ||
418 | static inline int quirk_zfmicro(struct ohci_hcd *ohci) | ||
419 | { | ||
420 | return ohci->flags & OHCI_QUIRK_ZFMICRO; | ||
421 | } | ||
422 | #else | ||
423 | static inline int quirk_nec(struct ohci_hcd *ohci) | ||
424 | { | ||
425 | return 0; | ||
426 | } | ||
427 | static inline int quirk_zfmicro(struct ohci_hcd *ohci) | ||
428 | { | ||
429 | return 0; | ||
430 | } | ||
431 | #endif | ||
432 | |||
406 | /* convert between an hcd pointer and the corresponding ohci_hcd */ | 433 | /* convert between an hcd pointer and the corresponding ohci_hcd */ |
407 | static inline struct ohci_hcd *hcd_to_ohci (struct usb_hcd *hcd) | 434 | static inline struct ohci_hcd *hcd_to_ohci (struct usb_hcd *hcd) |
408 | { | 435 | { |
@@ -607,15 +634,12 @@ static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x) | |||
607 | /* HCCA frame number is 16 bits, but is accessed as 32 bits since not all | 634 | /* HCCA frame number is 16 bits, but is accessed as 32 bits since not all |
608 | * hardware handles 16 bit reads. That creates a different confusion on | 635 | * hardware handles 16 bit reads. That creates a different confusion on |
609 | * some big-endian SOC implementations. Same thing happens with PSW access. | 636 | * some big-endian SOC implementations. Same thing happens with PSW access. |
610 | * | ||
611 | * FIXME: Deal with that as a runtime quirk when STB03xxx is ported over | ||
612 | * to arch/powerpc | ||
613 | */ | 637 | */ |
614 | 638 | ||
615 | #ifdef CONFIG_STB03xxx | 639 | #ifdef CONFIG_PPC_MPC52xx |
616 | #define OHCI_BE_FRAME_NO_SHIFT 16 | 640 | #define big_endian_frame_no_quirk(ohci) (ohci->flags & OHCI_QUIRK_FRAME_NO) |
617 | #else | 641 | #else |
618 | #define OHCI_BE_FRAME_NO_SHIFT 0 | 642 | #define big_endian_frame_no_quirk(ohci) 0 |
619 | #endif | 643 | #endif |
620 | 644 | ||
621 | static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) | 645 | static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) |
@@ -623,7 +647,8 @@ static inline u16 ohci_frame_no(const struct ohci_hcd *ohci) | |||
623 | u32 tmp; | 647 | u32 tmp; |
624 | if (big_endian_desc(ohci)) { | 648 | if (big_endian_desc(ohci)) { |
625 | tmp = be32_to_cpup((__force __be32 *)&ohci->hcca->frame_no); | 649 | tmp = be32_to_cpup((__force __be32 *)&ohci->hcca->frame_no); |
626 | tmp >>= OHCI_BE_FRAME_NO_SHIFT; | 650 | if (!big_endian_frame_no_quirk(ohci)) |
651 | tmp >>= 16; | ||
627 | } else | 652 | } else |
628 | tmp = le32_to_cpup((__force __le32 *)&ohci->hcca->frame_no); | 653 | tmp = le32_to_cpup((__force __le32 *)&ohci->hcca->frame_no); |
629 | 654 | ||
diff --git a/drivers/usb/host/r8a66597-hcd.c b/drivers/usb/host/r8a66597-hcd.c index a7a7070c6e2..ae8ec4474eb 100644 --- a/drivers/usb/host/r8a66597-hcd.c +++ b/drivers/usb/host/r8a66597-hcd.c | |||
@@ -35,10 +35,8 @@ | |||
35 | #include <linux/interrupt.h> | 35 | #include <linux/interrupt.h> |
36 | #include <linux/usb.h> | 36 | #include <linux/usb.h> |
37 | #include <linux/platform_device.h> | 37 | #include <linux/platform_device.h> |
38 | 38 | #include <linux/io.h> | |
39 | #include <asm/io.h> | 39 | #include <linux/irq.h> |
40 | #include <asm/irq.h> | ||
41 | #include <asm/system.h> | ||
42 | 40 | ||
43 | #include "../core/hcd.h" | 41 | #include "../core/hcd.h" |
44 | #include "r8a66597.h" | 42 | #include "r8a66597.h" |
@@ -54,16 +52,21 @@ static const char hcd_name[] = "r8a66597_hcd"; | |||
54 | /* module parameters */ | 52 | /* module parameters */ |
55 | static unsigned short clock = XTAL12; | 53 | static unsigned short clock = XTAL12; |
56 | module_param(clock, ushort, 0644); | 54 | module_param(clock, ushort, 0644); |
57 | MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0(default=0)"); | 55 | MODULE_PARM_DESC(clock, "input clock: 48MHz=32768, 24MHz=16384, 12MHz=0 " |
56 | "(default=0)"); | ||
57 | |||
58 | static unsigned short vif = LDRV; | 58 | static unsigned short vif = LDRV; |
59 | module_param(vif, ushort, 0644); | 59 | module_param(vif, ushort, 0644); |
60 | MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0(default=32768)"); | 60 | MODULE_PARM_DESC(vif, "input VIF: 3.3V=32768, 1.5V=0(default=32768)"); |
61 | static unsigned short endian = 0; | 61 | |
62 | static unsigned short endian; | ||
62 | module_param(endian, ushort, 0644); | 63 | module_param(endian, ushort, 0644); |
63 | MODULE_PARM_DESC(endian, "data endian: big=256, little=0(default=0)"); | 64 | MODULE_PARM_DESC(endian, "data endian: big=256, little=0 (default=0)"); |
65 | |||
64 | static unsigned short irq_sense = INTL; | 66 | static unsigned short irq_sense = INTL; |
65 | module_param(irq_sense, ushort, 0644); | 67 | module_param(irq_sense, ushort, 0644); |
66 | MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=32, falling edge=0(default=32)"); | 68 | MODULE_PARM_DESC(irq_sense, "IRQ sense: low level=32, falling edge=0 " |
69 | "(default=32)"); | ||
67 | 70 | ||
68 | static void packet_write(struct r8a66597 *r8a66597, u16 pipenum); | 71 | static void packet_write(struct r8a66597 *r8a66597, u16 pipenum); |
69 | static int r8a66597_get_frame(struct usb_hcd *hcd); | 72 | static int r8a66597_get_frame(struct usb_hcd *hcd); |
@@ -308,7 +311,7 @@ static int make_r8a66597_device(struct r8a66597 *r8a66597, | |||
308 | struct r8a66597_device *dev; | 311 | struct r8a66597_device *dev; |
309 | int usb_address = urb->setup_packet[2]; /* urb->pipe is address 0 */ | 312 | int usb_address = urb->setup_packet[2]; /* urb->pipe is address 0 */ |
310 | 313 | ||
311 | dev = kzalloc(sizeof(struct r8a66597_device), GFP_KERNEL); | 314 | dev = kzalloc(sizeof(struct r8a66597_device), GFP_ATOMIC); |
312 | if (dev == NULL) | 315 | if (dev == NULL) |
313 | return -ENOMEM; | 316 | return -ENOMEM; |
314 | 317 | ||
@@ -611,33 +614,33 @@ static u16 get_empty_pipenum(struct r8a66597 *r8a66597, | |||
611 | u16 array[R8A66597_MAX_NUM_PIPE], i = 0, min; | 614 | u16 array[R8A66597_MAX_NUM_PIPE], i = 0, min; |
612 | 615 | ||
613 | memset(array, 0, sizeof(array)); | 616 | memset(array, 0, sizeof(array)); |
614 | switch(ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { | 617 | switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) { |
615 | case USB_ENDPOINT_XFER_BULK: | 618 | case USB_ENDPOINT_XFER_BULK: |
616 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 619 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) |
617 | array[i++] = 4; | 620 | array[i++] = 4; |
618 | else { | 621 | else { |
619 | array[i++] = 3; | 622 | array[i++] = 3; |
620 | array[i++] = 5; | 623 | array[i++] = 5; |
621 | } | 624 | } |
622 | break; | 625 | break; |
623 | case USB_ENDPOINT_XFER_INT: | 626 | case USB_ENDPOINT_XFER_INT: |
624 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) { | 627 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) { |
625 | array[i++] = 6; | 628 | array[i++] = 6; |
626 | array[i++] = 7; | 629 | array[i++] = 7; |
627 | array[i++] = 8; | 630 | array[i++] = 8; |
628 | } else | 631 | } else |
629 | array[i++] = 9; | 632 | array[i++] = 9; |
630 | break; | 633 | break; |
631 | case USB_ENDPOINT_XFER_ISOC: | 634 | case USB_ENDPOINT_XFER_ISOC: |
632 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) | 635 | if (ep->bEndpointAddress & USB_ENDPOINT_DIR_MASK) |
633 | array[i++] = 2; | 636 | array[i++] = 2; |
634 | else | 637 | else |
635 | array[i++] = 1; | 638 | array[i++] = 1; |
636 | break; | 639 | break; |
637 | default: | 640 | default: |
638 | err("Illegal type"); | 641 | err("Illegal type"); |
639 | return 0; | 642 | return 0; |
640 | } | 643 | } |
641 | 644 | ||
642 | i = 1; | 645 | i = 1; |
643 | min = array[0]; | 646 | min = array[0]; |
@@ -654,7 +657,7 @@ static u16 get_r8a66597_type(__u8 type) | |||
654 | { | 657 | { |
655 | u16 r8a66597_type; | 658 | u16 r8a66597_type; |
656 | 659 | ||
657 | switch(type) { | 660 | switch (type) { |
658 | case USB_ENDPOINT_XFER_BULK: | 661 | case USB_ENDPOINT_XFER_BULK: |
659 | r8a66597_type = R8A66597_BULK; | 662 | r8a66597_type = R8A66597_BULK; |
660 | break; | 663 | break; |
@@ -779,10 +782,12 @@ static void force_dequeue(struct r8a66597 *r8a66597, u16 pipenum, u16 address) | |||
779 | kfree(td); | 782 | kfree(td); |
780 | 783 | ||
781 | if (urb) { | 784 | if (urb) { |
782 | urb->status = -ENODEV; | 785 | usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597), |
783 | urb->hcpriv = NULL; | 786 | urb); |
787 | |||
784 | spin_unlock(&r8a66597->lock); | 788 | spin_unlock(&r8a66597->lock); |
785 | usb_hcd_giveback_urb(r8a66597_to_hcd(r8a66597), urb); | 789 | usb_hcd_giveback_urb(r8a66597_to_hcd(r8a66597), urb, |
790 | -ENODEV); | ||
786 | spin_lock(&r8a66597->lock); | 791 | spin_lock(&r8a66597->lock); |
787 | } | 792 | } |
788 | break; | 793 | break; |
@@ -829,7 +834,7 @@ static void init_pipe_info(struct r8a66597 *r8a66597, struct urb *urb, | |||
829 | info.pipenum = get_empty_pipenum(r8a66597, ep); | 834 | info.pipenum = get_empty_pipenum(r8a66597, ep); |
830 | info.address = get_urb_to_r8a66597_addr(r8a66597, urb); | 835 | info.address = get_urb_to_r8a66597_addr(r8a66597, urb); |
831 | info.epnum = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; | 836 | info.epnum = ep->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK; |
832 | info.maxpacket = ep->wMaxPacketSize; | 837 | info.maxpacket = le16_to_cpu(ep->wMaxPacketSize); |
833 | info.type = get_r8a66597_type(ep->bmAttributes | 838 | info.type = get_r8a66597_type(ep->bmAttributes |
834 | & USB_ENDPOINT_XFERTYPE_MASK); | 839 | & USB_ENDPOINT_XFERTYPE_MASK); |
835 | info.bufnum = get_bufnum(info.pipenum); | 840 | info.bufnum = get_bufnum(info.pipenum); |
@@ -874,7 +879,7 @@ static void r8a66597_usb_preconnect(struct r8a66597 *r8a66597, int port) | |||
874 | { | 879 | { |
875 | r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_CONNECTION) | 880 | r8a66597->root_hub[port].port |= (1 << USB_PORT_FEAT_CONNECTION) |
876 | | (1 << USB_PORT_FEAT_C_CONNECTION); | 881 | | (1 << USB_PORT_FEAT_C_CONNECTION); |
877 | r8a66597_write(r8a66597, (u16)~DTCH, get_intsts_reg(port)); | 882 | r8a66597_write(r8a66597, ~DTCH, get_intsts_reg(port)); |
878 | r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port)); | 883 | r8a66597_bset(r8a66597, DTCHE, get_intenb_reg(port)); |
879 | } | 884 | } |
880 | 885 | ||
@@ -917,10 +922,10 @@ static void prepare_setup_packet(struct r8a66597 *r8a66597, | |||
917 | 922 | ||
918 | r8a66597_write(r8a66597, make_devsel(td->address) | td->maxpacket, | 923 | r8a66597_write(r8a66597, make_devsel(td->address) | td->maxpacket, |
919 | DCPMAXP); | 924 | DCPMAXP); |
920 | r8a66597_write(r8a66597, (u16)~(SIGN | SACK), INTSTS1); | 925 | r8a66597_write(r8a66597, ~(SIGN | SACK), INTSTS1); |
921 | 926 | ||
922 | for (i = 0; i < 4; i++) { | 927 | for (i = 0; i < 4; i++) { |
923 | r8a66597_write(r8a66597, p[i], setup_addr); | 928 | r8a66597_write(r8a66597, cpu_to_le16(p[i]), setup_addr); |
924 | setup_addr += 2; | 929 | setup_addr += 2; |
925 | } | 930 | } |
926 | r8a66597_write(r8a66597, SUREQ, DCPCTR); | 931 | r8a66597_write(r8a66597, SUREQ, DCPCTR); |
@@ -948,19 +953,18 @@ static void prepare_packet_read(struct r8a66597 *r8a66597, | |||
948 | pipe_irq_disable(r8a66597, td->pipenum); | 953 | pipe_irq_disable(r8a66597, td->pipenum); |
949 | pipe_setting(r8a66597, td); | 954 | pipe_setting(r8a66597, td); |
950 | pipe_stop(r8a66597, td->pipe); | 955 | pipe_stop(r8a66597, td->pipe); |
951 | r8a66597_write(r8a66597, (u16)~(1 << td->pipenum), | 956 | r8a66597_write(r8a66597, ~(1 << td->pipenum), BRDYSTS); |
952 | BRDYSTS); | ||
953 | 957 | ||
954 | if (td->pipe->pipetre) { | 958 | if (td->pipe->pipetre) { |
955 | r8a66597_write(r8a66597, TRCLR, | 959 | r8a66597_write(r8a66597, TRCLR, |
956 | td->pipe->pipetre); | 960 | td->pipe->pipetre); |
957 | r8a66597_write(r8a66597, | 961 | r8a66597_write(r8a66597, |
958 | (urb->transfer_buffer_length | 962 | (urb->transfer_buffer_length |
959 | + td->maxpacket - 1) | 963 | + td->maxpacket - 1) |
960 | / td->maxpacket, | 964 | / td->maxpacket, |
961 | td->pipe->pipetrn); | 965 | td->pipe->pipetrn); |
962 | r8a66597_bset(r8a66597, TRENB, | 966 | r8a66597_bset(r8a66597, TRENB, |
963 | td->pipe->pipetre); | 967 | td->pipe->pipetre); |
964 | } | 968 | } |
965 | 969 | ||
966 | pipe_start(r8a66597, td->pipe); | 970 | pipe_start(r8a66597, td->pipe); |
@@ -991,7 +995,7 @@ static void prepare_packet_write(struct r8a66597 *r8a66597, | |||
991 | if (td->pipe->pipetre) | 995 | if (td->pipe->pipetre) |
992 | r8a66597_bclr(r8a66597, TRENB, td->pipe->pipetre); | 996 | r8a66597_bclr(r8a66597, TRENB, td->pipe->pipetre); |
993 | } | 997 | } |
994 | r8a66597_write(r8a66597, (u16)~(1 << td->pipenum), BRDYSTS); | 998 | r8a66597_write(r8a66597, ~(1 << td->pipenum), BRDYSTS); |
995 | 999 | ||
996 | fifo_change_from_pipe(r8a66597, td->pipe); | 1000 | fifo_change_from_pipe(r8a66597, td->pipe); |
997 | tmp = r8a66597_read(r8a66597, td->pipe->fifoctr); | 1001 | tmp = r8a66597_read(r8a66597, td->pipe->fifoctr); |
@@ -1009,27 +1013,36 @@ static void prepare_status_packet(struct r8a66597 *r8a66597, | |||
1009 | struct urb *urb = td->urb; | 1013 | struct urb *urb = td->urb; |
1010 | 1014 | ||
1011 | r8a66597_pipe_toggle(r8a66597, td->pipe, 1); | 1015 | r8a66597_pipe_toggle(r8a66597, td->pipe, 1); |
1016 | pipe_stop(r8a66597, td->pipe); | ||
1012 | 1017 | ||
1013 | if (urb->setup_packet[0] & USB_ENDPOINT_DIR_MASK) { | 1018 | if (urb->setup_packet[0] & USB_ENDPOINT_DIR_MASK) { |
1014 | r8a66597_bset(r8a66597, R8A66597_DIR, DCPCFG); | 1019 | r8a66597_bset(r8a66597, R8A66597_DIR, DCPCFG); |
1015 | r8a66597_mdfy(r8a66597, ISEL, ISEL | CURPIPE, CFIFOSEL); | 1020 | r8a66597_mdfy(r8a66597, ISEL, ISEL | CURPIPE, CFIFOSEL); |
1016 | r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0); | 1021 | r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0); |
1017 | r8a66597_write(r8a66597, BVAL | BCLR, CFIFOCTR); | 1022 | r8a66597_write(r8a66597, ~BEMP0, BEMPSTS); |
1018 | r8a66597_write(r8a66597, (u16)~BEMP0, BEMPSTS); | 1023 | r8a66597_write(r8a66597, BCLR, CFIFOCTR); |
1024 | r8a66597_write(r8a66597, BVAL, CFIFOCTR); | ||
1019 | enable_irq_empty(r8a66597, 0); | 1025 | enable_irq_empty(r8a66597, 0); |
1020 | } else { | 1026 | } else { |
1021 | r8a66597_bclr(r8a66597, R8A66597_DIR, DCPCFG); | 1027 | r8a66597_bclr(r8a66597, R8A66597_DIR, DCPCFG); |
1022 | r8a66597_mdfy(r8a66597, 0, ISEL | CURPIPE, CFIFOSEL); | 1028 | r8a66597_mdfy(r8a66597, 0, ISEL | CURPIPE, CFIFOSEL); |
1023 | r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0); | 1029 | r8a66597_reg_wait(r8a66597, CFIFOSEL, CURPIPE, 0); |
1024 | r8a66597_write(r8a66597, BCLR, CFIFOCTR); | 1030 | r8a66597_write(r8a66597, BCLR, CFIFOCTR); |
1025 | r8a66597_write(r8a66597, (u16)~BRDY0, BRDYSTS); | ||
1026 | r8a66597_write(r8a66597, (u16)~BEMP0, BEMPSTS); | ||
1027 | enable_irq_ready(r8a66597, 0); | 1031 | enable_irq_ready(r8a66597, 0); |
1028 | } | 1032 | } |
1029 | enable_irq_nrdy(r8a66597, 0); | 1033 | enable_irq_nrdy(r8a66597, 0); |
1030 | pipe_start(r8a66597, td->pipe); | 1034 | pipe_start(r8a66597, td->pipe); |
1031 | } | 1035 | } |
1032 | 1036 | ||
1037 | static int is_set_address(unsigned char *setup_packet) | ||
1038 | { | ||
1039 | if (((setup_packet[0] & USB_TYPE_MASK) == USB_TYPE_STANDARD) && | ||
1040 | setup_packet[1] == USB_REQ_SET_ADDRESS) | ||
1041 | return 1; | ||
1042 | else | ||
1043 | return 0; | ||
1044 | } | ||
1045 | |||
1033 | /* this function must be called with interrupt disabled */ | 1046 | /* this function must be called with interrupt disabled */ |
1034 | static int start_transfer(struct r8a66597 *r8a66597, struct r8a66597_td *td) | 1047 | static int start_transfer(struct r8a66597 *r8a66597, struct r8a66597_td *td) |
1035 | { | 1048 | { |
@@ -1037,7 +1050,7 @@ static int start_transfer(struct r8a66597 *r8a66597, struct r8a66597_td *td) | |||
1037 | 1050 | ||
1038 | switch (td->type) { | 1051 | switch (td->type) { |
1039 | case USB_PID_SETUP: | 1052 | case USB_PID_SETUP: |
1040 | if (td->urb->setup_packet[1] == USB_REQ_SET_ADDRESS) { | 1053 | if (is_set_address(td->urb->setup_packet)) { |
1041 | td->set_address = 1; | 1054 | td->set_address = 1; |
1042 | td->urb->setup_packet[2] = alloc_usb_address(r8a66597, | 1055 | td->urb->setup_packet[2] = alloc_usb_address(r8a66597, |
1043 | td->urb); | 1056 | td->urb); |
@@ -1104,8 +1117,9 @@ static void set_td_timer(struct r8a66597 *r8a66597, struct r8a66597_td *td) | |||
1104 | } | 1117 | } |
1105 | 1118 | ||
1106 | /* this function must be called with interrupt disabled */ | 1119 | /* this function must be called with interrupt disabled */ |
1107 | static void done(struct r8a66597 *r8a66597, struct r8a66597_td *td, | 1120 | static void finish_request(struct r8a66597 *r8a66597, struct r8a66597_td *td, |
1108 | u16 pipenum, struct urb *urb) | 1121 | u16 pipenum, struct urb *urb, int status) |
1122 | __releases(r8a66597->lock) __acquires(r8a66597->lock) | ||
1109 | { | 1123 | { |
1110 | int restart = 0; | 1124 | int restart = 0; |
1111 | struct usb_hcd *hcd = r8a66597_to_hcd(r8a66597); | 1125 | struct usb_hcd *hcd = r8a66597_to_hcd(r8a66597); |
@@ -1113,7 +1127,7 @@ static void done(struct r8a66597 *r8a66597, struct r8a66597_td *td, | |||
1113 | r8a66597->timeout_map &= ~(1 << pipenum); | 1127 | r8a66597->timeout_map &= ~(1 << pipenum); |
1114 | 1128 | ||
1115 | if (likely(td)) { | 1129 | if (likely(td)) { |
1116 | if (td->set_address && urb->status != 0) | 1130 | if (td->set_address && (status != 0 || urb->unlinked)) |
1117 | r8a66597->address_map &= ~(1 << urb->setup_packet[2]); | 1131 | r8a66597->address_map &= ~(1 << urb->setup_packet[2]); |
1118 | 1132 | ||
1119 | pipe_toggle_save(r8a66597, td->pipe, urb); | 1133 | pipe_toggle_save(r8a66597, td->pipe, urb); |
@@ -1128,9 +1142,9 @@ static void done(struct r8a66597 *r8a66597, struct r8a66597_td *td, | |||
1128 | if (usb_pipeisoc(urb->pipe)) | 1142 | if (usb_pipeisoc(urb->pipe)) |
1129 | urb->start_frame = r8a66597_get_frame(hcd); | 1143 | urb->start_frame = r8a66597_get_frame(hcd); |
1130 | 1144 | ||
1131 | urb->hcpriv = NULL; | 1145 | usb_hcd_unlink_urb_from_ep(r8a66597_to_hcd(r8a66597), urb); |
1132 | spin_unlock(&r8a66597->lock); | 1146 | spin_unlock(&r8a66597->lock); |
1133 | usb_hcd_giveback_urb(hcd, urb); | 1147 | usb_hcd_giveback_urb(hcd, urb, status); |
1134 | spin_lock(&r8a66597->lock); | 1148 | spin_lock(&r8a66597->lock); |
1135 | } | 1149 | } |
1136 | 1150 | ||
@@ -1144,14 +1158,6 @@ static void done(struct r8a66597 *r8a66597, struct r8a66597_td *td, | |||
1144 | } | 1158 | } |
1145 | } | 1159 | } |
1146 | 1160 | ||
1147 | /* this function must be called with interrupt disabled */ | ||
1148 | static void finish_request(struct r8a66597 *r8a66597, struct r8a66597_td *td, | ||
1149 | u16 pipenum, struct urb *urb) | ||
1150 | __releases(r8a66597->lock) __acquires(r8a66597->lock) | ||
1151 | { | ||
1152 | done(r8a66597, td, pipenum, urb); | ||
1153 | } | ||
1154 | |||
1155 | static void packet_read(struct r8a66597 *r8a66597, u16 pipenum) | 1161 | static void packet_read(struct r8a66597 *r8a66597, u16 pipenum) |
1156 | { | 1162 | { |
1157 | u16 tmp; | 1163 | u16 tmp; |
@@ -1160,6 +1166,7 @@ static void packet_read(struct r8a66597 *r8a66597, u16 pipenum) | |||
1160 | struct r8a66597_td *td = r8a66597_get_td(r8a66597, pipenum); | 1166 | struct r8a66597_td *td = r8a66597_get_td(r8a66597, pipenum); |
1161 | struct urb *urb; | 1167 | struct urb *urb; |
1162 | int finish = 0; | 1168 | int finish = 0; |
1169 | int status = 0; | ||
1163 | 1170 | ||
1164 | if (unlikely(!td)) | 1171 | if (unlikely(!td)) |
1165 | return; | 1172 | return; |
@@ -1168,17 +1175,15 @@ static void packet_read(struct r8a66597 *r8a66597, u16 pipenum) | |||
1168 | fifo_change_from_pipe(r8a66597, td->pipe); | 1175 | fifo_change_from_pipe(r8a66597, td->pipe); |
1169 | tmp = r8a66597_read(r8a66597, td->pipe->fifoctr); | 1176 | tmp = r8a66597_read(r8a66597, td->pipe->fifoctr); |
1170 | if (unlikely((tmp & FRDY) == 0)) { | 1177 | if (unlikely((tmp & FRDY) == 0)) { |
1171 | urb->status = -EPIPE; | ||
1172 | pipe_stop(r8a66597, td->pipe); | 1178 | pipe_stop(r8a66597, td->pipe); |
1173 | pipe_irq_disable(r8a66597, pipenum); | 1179 | pipe_irq_disable(r8a66597, pipenum); |
1174 | err("in fifo not ready (%d)", pipenum); | 1180 | err("in fifo not ready (%d)", pipenum); |
1175 | finish_request(r8a66597, td, pipenum, td->urb); | 1181 | finish_request(r8a66597, td, pipenum, td->urb, -EPIPE); |
1176 | return; | 1182 | return; |
1177 | } | 1183 | } |
1178 | 1184 | ||
1179 | /* prepare parameters */ | 1185 | /* prepare parameters */ |
1180 | rcv_len = tmp & DTLN; | 1186 | rcv_len = tmp & DTLN; |
1181 | bufsize = td->maxpacket; | ||
1182 | if (usb_pipeisoc(urb->pipe)) { | 1187 | if (usb_pipeisoc(urb->pipe)) { |
1183 | buf = (u16 *)(urb->transfer_buffer + | 1188 | buf = (u16 *)(urb->transfer_buffer + |
1184 | urb->iso_frame_desc[td->iso_cnt].offset); | 1189 | urb->iso_frame_desc[td->iso_cnt].offset); |
@@ -1187,29 +1192,31 @@ static void packet_read(struct r8a66597 *r8a66597, u16 pipenum) | |||
1187 | buf = (void *)urb->transfer_buffer + urb->actual_length; | 1192 | buf = (void *)urb->transfer_buffer + urb->actual_length; |
1188 | urb_len = urb->transfer_buffer_length - urb->actual_length; | 1193 | urb_len = urb->transfer_buffer_length - urb->actual_length; |
1189 | } | 1194 | } |
1190 | if (rcv_len < bufsize) | 1195 | bufsize = min(urb_len, (int) td->maxpacket); |
1191 | size = min(rcv_len, urb_len); | 1196 | if (rcv_len <= bufsize) { |
1192 | else | 1197 | size = rcv_len; |
1193 | size = min(bufsize, urb_len); | 1198 | } else { |
1199 | size = bufsize; | ||
1200 | status = -EOVERFLOW; | ||
1201 | finish = 1; | ||
1202 | } | ||
1194 | 1203 | ||
1195 | /* update parameters */ | 1204 | /* update parameters */ |
1196 | urb->actual_length += size; | 1205 | urb->actual_length += size; |
1197 | if (rcv_len == 0) | 1206 | if (rcv_len == 0) |
1198 | td->zero_packet = 1; | 1207 | td->zero_packet = 1; |
1199 | if ((size % td->maxpacket) > 0) { | 1208 | if (rcv_len < bufsize) { |
1200 | td->short_packet = 1; | 1209 | td->short_packet = 1; |
1201 | if (urb->transfer_buffer_length != urb->actual_length && | ||
1202 | urb->transfer_flags & URB_SHORT_NOT_OK) | ||
1203 | td->urb->status = -EREMOTEIO; | ||
1204 | } | 1210 | } |
1205 | if (usb_pipeisoc(urb->pipe)) { | 1211 | if (usb_pipeisoc(urb->pipe)) { |
1206 | urb->iso_frame_desc[td->iso_cnt].actual_length = size; | 1212 | urb->iso_frame_desc[td->iso_cnt].actual_length = size; |
1207 | urb->iso_frame_desc[td->iso_cnt].status = 0; | 1213 | urb->iso_frame_desc[td->iso_cnt].status = status; |
1208 | td->iso_cnt++; | 1214 | td->iso_cnt++; |
1215 | finish = 0; | ||
1209 | } | 1216 | } |
1210 | 1217 | ||
1211 | /* check transfer finish */ | 1218 | /* check transfer finish */ |
1212 | if (check_transfer_finish(td, urb)) { | 1219 | if (finish || check_transfer_finish(td, urb)) { |
1213 | pipe_stop(r8a66597, td->pipe); | 1220 | pipe_stop(r8a66597, td->pipe); |
1214 | pipe_irq_disable(r8a66597, pipenum); | 1221 | pipe_irq_disable(r8a66597, pipenum); |
1215 | finish = 1; | 1222 | finish = 1; |
@@ -1224,11 +1231,8 @@ static void packet_read(struct r8a66597 *r8a66597, u16 pipenum) | |||
1224 | buf, size); | 1231 | buf, size); |
1225 | } | 1232 | } |
1226 | 1233 | ||
1227 | if (finish && pipenum != 0) { | 1234 | if (finish && pipenum != 0) |
1228 | if (td->urb->status == -EINPROGRESS) | 1235 | finish_request(r8a66597, td, pipenum, urb, status); |
1229 | td->urb->status = 0; | ||
1230 | finish_request(r8a66597, td, pipenum, urb); | ||
1231 | } | ||
1232 | } | 1236 | } |
1233 | 1237 | ||
1234 | static void packet_write(struct r8a66597 *r8a66597, u16 pipenum) | 1238 | static void packet_write(struct r8a66597 *r8a66597, u16 pipenum) |
@@ -1246,11 +1250,10 @@ static void packet_write(struct r8a66597 *r8a66597, u16 pipenum) | |||
1246 | fifo_change_from_pipe(r8a66597, td->pipe); | 1250 | fifo_change_from_pipe(r8a66597, td->pipe); |
1247 | tmp = r8a66597_read(r8a66597, td->pipe->fifoctr); | 1251 | tmp = r8a66597_read(r8a66597, td->pipe->fifoctr); |
1248 | if (unlikely((tmp & FRDY) == 0)) { | 1252 | if (unlikely((tmp & FRDY) == 0)) { |
1249 | urb->status = -EPIPE; | ||
1250 | pipe_stop(r8a66597, td->pipe); | 1253 | pipe_stop(r8a66597, td->pipe); |
1251 | pipe_irq_disable(r8a66597, pipenum); | 1254 | pipe_irq_disable(r8a66597, pipenum); |
1252 | err("out write fifo not ready. (%d)", pipenum); | 1255 | err("out write fifo not ready. (%d)", pipenum); |
1253 | finish_request(r8a66597, td, pipenum, td->urb); | 1256 | finish_request(r8a66597, td, pipenum, urb, -EPIPE); |
1254 | return; | 1257 | return; |
1255 | } | 1258 | } |
1256 | 1259 | ||
@@ -1269,7 +1272,7 @@ static void packet_write(struct r8a66597 *r8a66597, u16 pipenum) | |||
1269 | 1272 | ||
1270 | /* write fifo */ | 1273 | /* write fifo */ |
1271 | if (pipenum > 0) | 1274 | if (pipenum > 0) |
1272 | r8a66597_write(r8a66597, (u16)~(1 << pipenum), BEMPSTS); | 1275 | r8a66597_write(r8a66597, ~(1 << pipenum), BEMPSTS); |
1273 | if (urb->transfer_buffer) { | 1276 | if (urb->transfer_buffer) { |
1274 | r8a66597_write_fifo(r8a66597, td->pipe->fifoaddr, buf, size); | 1277 | r8a66597_write_fifo(r8a66597, td->pipe->fifoaddr, buf, size); |
1275 | if (!usb_pipebulk(urb->pipe) || td->maxpacket != size) | 1278 | if (!usb_pipebulk(urb->pipe) || td->maxpacket != size) |
@@ -1295,7 +1298,7 @@ static void packet_write(struct r8a66597 *r8a66597, u16 pipenum) | |||
1295 | } | 1298 | } |
1296 | 1299 | ||
1297 | 1300 | ||
1298 | static void check_next_phase(struct r8a66597 *r8a66597) | 1301 | static void check_next_phase(struct r8a66597 *r8a66597, int status) |
1299 | { | 1302 | { |
1300 | struct r8a66597_td *td = r8a66597_get_td(r8a66597, 0); | 1303 | struct r8a66597_td *td = r8a66597_get_td(r8a66597, 0); |
1301 | struct urb *urb; | 1304 | struct urb *urb; |
@@ -1308,49 +1311,41 @@ static void check_next_phase(struct r8a66597 *r8a66597) | |||
1308 | switch (td->type) { | 1311 | switch (td->type) { |
1309 | case USB_PID_IN: | 1312 | case USB_PID_IN: |
1310 | case USB_PID_OUT: | 1313 | case USB_PID_OUT: |
1311 | if (urb->status != -EINPROGRESS) { | ||
1312 | finish = 1; | ||
1313 | break; | ||
1314 | } | ||
1315 | if (check_transfer_finish(td, urb)) | 1314 | if (check_transfer_finish(td, urb)) |
1316 | td->type = USB_PID_ACK; | 1315 | td->type = USB_PID_ACK; |
1317 | break; | 1316 | break; |
1318 | case USB_PID_SETUP: | 1317 | case USB_PID_SETUP: |
1319 | if (urb->status != -EINPROGRESS) | 1318 | if (urb->transfer_buffer_length == urb->actual_length) |
1320 | finish = 1; | ||
1321 | else if (urb->transfer_buffer_length == urb->actual_length) { | ||
1322 | td->type = USB_PID_ACK; | 1319 | td->type = USB_PID_ACK; |
1323 | urb->status = 0; | 1320 | else if (usb_pipeout(urb->pipe)) |
1324 | } else if (usb_pipeout(urb->pipe)) | ||
1325 | td->type = USB_PID_OUT; | 1321 | td->type = USB_PID_OUT; |
1326 | else | 1322 | else |
1327 | td->type = USB_PID_IN; | 1323 | td->type = USB_PID_IN; |
1328 | break; | 1324 | break; |
1329 | case USB_PID_ACK: | 1325 | case USB_PID_ACK: |
1330 | finish = 1; | 1326 | finish = 1; |
1331 | if (urb->status == -EINPROGRESS) | ||
1332 | urb->status = 0; | ||
1333 | break; | 1327 | break; |
1334 | } | 1328 | } |
1335 | 1329 | ||
1336 | if (finish) | 1330 | if (finish || status != 0 || urb->unlinked) |
1337 | finish_request(r8a66597, td, 0, urb); | 1331 | finish_request(r8a66597, td, 0, urb, status); |
1338 | else | 1332 | else |
1339 | start_transfer(r8a66597, td); | 1333 | start_transfer(r8a66597, td); |
1340 | } | 1334 | } |
1341 | 1335 | ||
1342 | static void set_urb_error(struct r8a66597 *r8a66597, u16 pipenum) | 1336 | static int get_urb_error(struct r8a66597 *r8a66597, u16 pipenum) |
1343 | { | 1337 | { |
1344 | struct r8a66597_td *td = r8a66597_get_td(r8a66597, pipenum); | 1338 | struct r8a66597_td *td = r8a66597_get_td(r8a66597, pipenum); |
1345 | 1339 | ||
1346 | if (td && td->urb) { | 1340 | if (td) { |
1347 | u16 pid = r8a66597_read(r8a66597, td->pipe->pipectr) & PID; | 1341 | u16 pid = r8a66597_read(r8a66597, td->pipe->pipectr) & PID; |
1348 | 1342 | ||
1349 | if (pid == PID_NAK) | 1343 | if (pid == PID_NAK) |
1350 | td->urb->status = -ECONNRESET; | 1344 | return -ECONNRESET; |
1351 | else | 1345 | else |
1352 | td->urb->status = -EPIPE; | 1346 | return -EPIPE; |
1353 | } | 1347 | } |
1348 | return 0; | ||
1354 | } | 1349 | } |
1355 | 1350 | ||
1356 | static void irq_pipe_ready(struct r8a66597 *r8a66597) | 1351 | static void irq_pipe_ready(struct r8a66597 *r8a66597) |
@@ -1362,14 +1357,14 @@ static void irq_pipe_ready(struct r8a66597 *r8a66597) | |||
1362 | 1357 | ||
1363 | mask = r8a66597_read(r8a66597, BRDYSTS) | 1358 | mask = r8a66597_read(r8a66597, BRDYSTS) |
1364 | & r8a66597_read(r8a66597, BRDYENB); | 1359 | & r8a66597_read(r8a66597, BRDYENB); |
1365 | r8a66597_write(r8a66597, (u16)~mask, BRDYSTS); | 1360 | r8a66597_write(r8a66597, ~mask, BRDYSTS); |
1366 | if (mask & BRDY0) { | 1361 | if (mask & BRDY0) { |
1367 | td = r8a66597_get_td(r8a66597, 0); | 1362 | td = r8a66597_get_td(r8a66597, 0); |
1368 | if (td && td->type == USB_PID_IN) | 1363 | if (td && td->type == USB_PID_IN) |
1369 | packet_read(r8a66597, 0); | 1364 | packet_read(r8a66597, 0); |
1370 | else | 1365 | else |
1371 | pipe_irq_disable(r8a66597, 0); | 1366 | pipe_irq_disable(r8a66597, 0); |
1372 | check_next_phase(r8a66597); | 1367 | check_next_phase(r8a66597, 0); |
1373 | } | 1368 | } |
1374 | 1369 | ||
1375 | for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) { | 1370 | for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) { |
@@ -1397,13 +1392,13 @@ static void irq_pipe_empty(struct r8a66597 *r8a66597) | |||
1397 | 1392 | ||
1398 | mask = r8a66597_read(r8a66597, BEMPSTS) | 1393 | mask = r8a66597_read(r8a66597, BEMPSTS) |
1399 | & r8a66597_read(r8a66597, BEMPENB); | 1394 | & r8a66597_read(r8a66597, BEMPENB); |
1400 | r8a66597_write(r8a66597, (u16)~mask, BEMPSTS); | 1395 | r8a66597_write(r8a66597, ~mask, BEMPSTS); |
1401 | if (mask & BEMP0) { | 1396 | if (mask & BEMP0) { |
1402 | cfifo_change(r8a66597, 0); | 1397 | cfifo_change(r8a66597, 0); |
1403 | td = r8a66597_get_td(r8a66597, 0); | 1398 | td = r8a66597_get_td(r8a66597, 0); |
1404 | if (td && td->type != USB_PID_OUT) | 1399 | if (td && td->type != USB_PID_OUT) |
1405 | disable_irq_empty(r8a66597, 0); | 1400 | disable_irq_empty(r8a66597, 0); |
1406 | check_next_phase(r8a66597); | 1401 | check_next_phase(r8a66597, 0); |
1407 | } | 1402 | } |
1408 | 1403 | ||
1409 | for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) { | 1404 | for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) { |
@@ -1418,9 +1413,8 @@ static void irq_pipe_empty(struct r8a66597 *r8a66597) | |||
1418 | if ((tmp & INBUFM) == 0) { | 1413 | if ((tmp & INBUFM) == 0) { |
1419 | disable_irq_empty(r8a66597, pipenum); | 1414 | disable_irq_empty(r8a66597, pipenum); |
1420 | pipe_irq_disable(r8a66597, pipenum); | 1415 | pipe_irq_disable(r8a66597, pipenum); |
1421 | if (td->urb->status == -EINPROGRESS) | 1416 | finish_request(r8a66597, td, pipenum, td->urb, |
1422 | td->urb->status = 0; | 1417 | 0); |
1423 | finish_request(r8a66597, td, pipenum, td->urb); | ||
1424 | } | 1418 | } |
1425 | } | 1419 | } |
1426 | } | 1420 | } |
@@ -1431,15 +1425,16 @@ static void irq_pipe_nrdy(struct r8a66597 *r8a66597) | |||
1431 | u16 check; | 1425 | u16 check; |
1432 | u16 pipenum; | 1426 | u16 pipenum; |
1433 | u16 mask; | 1427 | u16 mask; |
1428 | int status; | ||
1434 | 1429 | ||
1435 | mask = r8a66597_read(r8a66597, NRDYSTS) | 1430 | mask = r8a66597_read(r8a66597, NRDYSTS) |
1436 | & r8a66597_read(r8a66597, NRDYENB); | 1431 | & r8a66597_read(r8a66597, NRDYENB); |
1437 | r8a66597_write(r8a66597, (u16)~mask, NRDYSTS); | 1432 | r8a66597_write(r8a66597, ~mask, NRDYSTS); |
1438 | if (mask & NRDY0) { | 1433 | if (mask & NRDY0) { |
1439 | cfifo_change(r8a66597, 0); | 1434 | cfifo_change(r8a66597, 0); |
1440 | set_urb_error(r8a66597, 0); | 1435 | status = get_urb_error(r8a66597, 0); |
1441 | pipe_irq_disable(r8a66597, 0); | 1436 | pipe_irq_disable(r8a66597, 0); |
1442 | check_next_phase(r8a66597); | 1437 | check_next_phase(r8a66597, status); |
1443 | } | 1438 | } |
1444 | 1439 | ||
1445 | for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) { | 1440 | for (pipenum = 1; pipenum < R8A66597_MAX_NUM_PIPE; pipenum++) { |
@@ -1450,10 +1445,10 @@ static void irq_pipe_nrdy(struct r8a66597 *r8a66597) | |||
1450 | if (unlikely(!td)) | 1445 | if (unlikely(!td)) |
1451 | continue; | 1446 | continue; |
1452 | 1447 | ||
1453 | set_urb_error(r8a66597, pipenum); | 1448 | status = get_urb_error(r8a66597, pipenum); |
1454 | pipe_irq_disable(r8a66597, pipenum); | 1449 | pipe_irq_disable(r8a66597, pipenum); |
1455 | pipe_stop(r8a66597, td->pipe); | 1450 | pipe_stop(r8a66597, td->pipe); |
1456 | finish_request(r8a66597, td, pipenum, td->urb); | 1451 | finish_request(r8a66597, td, pipenum, td->urb, status); |
1457 | } | 1452 | } |
1458 | } | 1453 | } |
1459 | } | 1454 | } |
@@ -1473,6 +1468,7 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) | |||
1473 | u16 intsts0, intsts1, intsts2; | 1468 | u16 intsts0, intsts1, intsts2; |
1474 | u16 intenb0, intenb1, intenb2; | 1469 | u16 intenb0, intenb1, intenb2; |
1475 | u16 mask0, mask1, mask2; | 1470 | u16 mask0, mask1, mask2; |
1471 | int status; | ||
1476 | 1472 | ||
1477 | spin_lock(&r8a66597->lock); | 1473 | spin_lock(&r8a66597->lock); |
1478 | 1474 | ||
@@ -1488,14 +1484,14 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) | |||
1488 | mask0 = intsts0 & intenb0 & (BEMP | NRDY | BRDY); | 1484 | mask0 = intsts0 & intenb0 & (BEMP | NRDY | BRDY); |
1489 | if (mask2) { | 1485 | if (mask2) { |
1490 | if (mask2 & ATTCH) { | 1486 | if (mask2 & ATTCH) { |
1491 | r8a66597_write(r8a66597, (u16)~ATTCH, INTSTS2); | 1487 | r8a66597_write(r8a66597, ~ATTCH, INTSTS2); |
1492 | r8a66597_bclr(r8a66597, ATTCHE, INTENB2); | 1488 | r8a66597_bclr(r8a66597, ATTCHE, INTENB2); |
1493 | 1489 | ||
1494 | /* start usb bus sampling */ | 1490 | /* start usb bus sampling */ |
1495 | start_root_hub_sampling(r8a66597, 1); | 1491 | start_root_hub_sampling(r8a66597, 1); |
1496 | } | 1492 | } |
1497 | if (mask2 & DTCH) { | 1493 | if (mask2 & DTCH) { |
1498 | r8a66597_write(r8a66597, (u16)~DTCH, INTSTS2); | 1494 | r8a66597_write(r8a66597, ~DTCH, INTSTS2); |
1499 | r8a66597_bclr(r8a66597, DTCHE, INTENB2); | 1495 | r8a66597_bclr(r8a66597, DTCHE, INTENB2); |
1500 | r8a66597_usb_disconnect(r8a66597, 1); | 1496 | r8a66597_usb_disconnect(r8a66597, 1); |
1501 | } | 1497 | } |
@@ -1503,25 +1499,25 @@ static irqreturn_t r8a66597_irq(struct usb_hcd *hcd) | |||
1503 | 1499 | ||
1504 | if (mask1) { | 1500 | if (mask1) { |
1505 | if (mask1 & ATTCH) { | 1501 | if (mask1 & ATTCH) { |
1506 | r8a66597_write(r8a66597, (u16)~ATTCH, INTSTS1); | 1502 | r8a66597_write(r8a66597, ~ATTCH, INTSTS1); |
1507 | r8a66597_bclr(r8a66597, ATTCHE, INTENB1); | 1503 | r8a66597_bclr(r8a66597, ATTCHE, INTENB1); |
1508 | 1504 | ||
1509 | /* start usb bus sampling */ | 1505 | /* start usb bus sampling */ |
1510 | start_root_hub_sampling(r8a66597, 0); | 1506 | start_root_hub_sampling(r8a66597, 0); |
1511 | } | 1507 | } |
1512 | if (mask1 & DTCH) { | 1508 | if (mask1 & DTCH) { |
1513 | r8a66597_write(r8a66597, (u16)~DTCH, INTSTS1); | 1509 | r8a66597_write(r8a66597, ~DTCH, INTSTS1); |
1514 | r8a66597_bclr(r8a66597, DTCHE, INTENB1); | 1510 | r8a66597_bclr(r8a66597, DTCHE, INTENB1); |
1515 | r8a66597_usb_disconnect(r8a66597, 0); | 1511 | r8a66597_usb_disconnect(r8a66597, 0); |
1516 | } | 1512 | } |
1517 | if (mask1 & SIGN) { | 1513 | if (mask1 & SIGN) { |
1518 | r8a66597_write(r8a66597, (u16)~SIGN, INTSTS1); | 1514 | r8a66597_write(r8a66597, ~SIGN, INTSTS1); |
1519 | set_urb_error(r8a66597, 0); | 1515 | status = get_urb_error(r8a66597, 0); |
1520 | check_next_phase(r8a66597); | 1516 | check_next_phase(r8a66597, status); |
1521 | } | 1517 | } |
1522 | if (mask1 & SACK) { | 1518 | if (mask1 & SACK) { |
1523 | r8a66597_write(r8a66597, (u16)~SACK, INTSTS1); | 1519 | r8a66597_write(r8a66597, ~SACK, INTSTS1); |
1524 | check_next_phase(r8a66597); | 1520 | check_next_phase(r8a66597, 0); |
1525 | } | 1521 | } |
1526 | } | 1522 | } |
1527 | if (mask0) { | 1523 | if (mask0) { |
@@ -1663,13 +1659,9 @@ static int check_pipe_config(struct r8a66597 *r8a66597, struct urb *urb) | |||
1663 | static int r8a66597_start(struct usb_hcd *hcd) | 1659 | static int r8a66597_start(struct usb_hcd *hcd) |
1664 | { | 1660 | { |
1665 | struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); | 1661 | struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); |
1666 | int ret; | ||
1667 | 1662 | ||
1668 | hcd->state = HC_STATE_RUNNING; | 1663 | hcd->state = HC_STATE_RUNNING; |
1669 | if ((ret = enable_controller(r8a66597)) < 0) | 1664 | return enable_controller(r8a66597); |
1670 | return ret; | ||
1671 | |||
1672 | return 0; | ||
1673 | } | 1665 | } |
1674 | 1666 | ||
1675 | static void r8a66597_stop(struct usb_hcd *hcd) | 1667 | static void r8a66597_stop(struct usb_hcd *hcd) |
@@ -1696,13 +1688,12 @@ static void set_address_zero(struct r8a66597 *r8a66597, struct urb *urb) | |||
1696 | 1688 | ||
1697 | static struct r8a66597_td *r8a66597_make_td(struct r8a66597 *r8a66597, | 1689 | static struct r8a66597_td *r8a66597_make_td(struct r8a66597 *r8a66597, |
1698 | struct urb *urb, | 1690 | struct urb *urb, |
1699 | struct usb_host_endpoint *hep, | 1691 | struct usb_host_endpoint *hep) |
1700 | gfp_t mem_flags) | ||
1701 | { | 1692 | { |
1702 | struct r8a66597_td *td; | 1693 | struct r8a66597_td *td; |
1703 | u16 pipenum; | 1694 | u16 pipenum; |
1704 | 1695 | ||
1705 | td = kzalloc(sizeof(struct r8a66597_td), mem_flags); | 1696 | td = kzalloc(sizeof(struct r8a66597_td), GFP_ATOMIC); |
1706 | if (td == NULL) | 1697 | if (td == NULL) |
1707 | return NULL; | 1698 | return NULL; |
1708 | 1699 | ||
@@ -1725,23 +1716,28 @@ static struct r8a66597_td *r8a66597_make_td(struct r8a66597 *r8a66597, | |||
1725 | } | 1716 | } |
1726 | 1717 | ||
1727 | static int r8a66597_urb_enqueue(struct usb_hcd *hcd, | 1718 | static int r8a66597_urb_enqueue(struct usb_hcd *hcd, |
1728 | struct usb_host_endpoint *hep, | ||
1729 | struct urb *urb, | 1719 | struct urb *urb, |
1730 | gfp_t mem_flags) | 1720 | gfp_t mem_flags) |
1731 | { | 1721 | { |
1722 | struct usb_host_endpoint *hep = urb->ep; | ||
1732 | struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); | 1723 | struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); |
1733 | struct r8a66597_td *td = NULL; | 1724 | struct r8a66597_td *td = NULL; |
1734 | int ret = 0, request = 0; | 1725 | int ret, request = 0; |
1735 | unsigned long flags; | 1726 | unsigned long flags; |
1736 | 1727 | ||
1737 | spin_lock_irqsave(&r8a66597->lock, flags); | 1728 | spin_lock_irqsave(&r8a66597->lock, flags); |
1738 | if (!get_urb_to_r8a66597_dev(r8a66597, urb)) { | 1729 | if (!get_urb_to_r8a66597_dev(r8a66597, urb)) { |
1739 | ret = -ENODEV; | 1730 | ret = -ENODEV; |
1740 | goto error; | 1731 | goto error_not_linked; |
1741 | } | 1732 | } |
1742 | 1733 | ||
1734 | ret = usb_hcd_link_urb_to_ep(hcd, urb); | ||
1735 | if (ret) | ||
1736 | goto error_not_linked; | ||
1737 | |||
1743 | if (!hep->hcpriv) { | 1738 | if (!hep->hcpriv) { |
1744 | hep->hcpriv = kzalloc(sizeof(struct r8a66597_pipe), mem_flags); | 1739 | hep->hcpriv = kzalloc(sizeof(struct r8a66597_pipe), |
1740 | GFP_ATOMIC); | ||
1745 | if (!hep->hcpriv) { | 1741 | if (!hep->hcpriv) { |
1746 | ret = -ENOMEM; | 1742 | ret = -ENOMEM; |
1747 | goto error; | 1743 | goto error; |
@@ -1755,7 +1751,7 @@ static int r8a66597_urb_enqueue(struct usb_hcd *hcd, | |||
1755 | init_pipe_config(r8a66597, urb); | 1751 | init_pipe_config(r8a66597, urb); |
1756 | 1752 | ||
1757 | set_address_zero(r8a66597, urb); | 1753 | set_address_zero(r8a66597, urb); |
1758 | td = r8a66597_make_td(r8a66597, urb, hep, mem_flags); | 1754 | td = r8a66597_make_td(r8a66597, urb, hep); |
1759 | if (td == NULL) { | 1755 | if (td == NULL) { |
1760 | ret = -ENOMEM; | 1756 | ret = -ENOMEM; |
1761 | goto error; | 1757 | goto error; |
@@ -1763,15 +1759,7 @@ static int r8a66597_urb_enqueue(struct usb_hcd *hcd, | |||
1763 | if (list_empty(&r8a66597->pipe_queue[td->pipenum])) | 1759 | if (list_empty(&r8a66597->pipe_queue[td->pipenum])) |
1764 | request = 1; | 1760 | request = 1; |
1765 | list_add_tail(&td->queue, &r8a66597->pipe_queue[td->pipenum]); | 1761 | list_add_tail(&td->queue, &r8a66597->pipe_queue[td->pipenum]); |
1766 | |||
1767 | spin_lock(&urb->lock); | ||
1768 | if (urb->status != -EINPROGRESS) { | ||
1769 | spin_unlock(&urb->lock); | ||
1770 | ret = -EPIPE; | ||
1771 | goto error; | ||
1772 | } | ||
1773 | urb->hcpriv = td; | 1762 | urb->hcpriv = td; |
1774 | spin_unlock(&urb->lock); | ||
1775 | 1763 | ||
1776 | if (request) { | 1764 | if (request) { |
1777 | ret = start_transfer(r8a66597, td); | 1765 | ret = start_transfer(r8a66597, td); |
@@ -1783,26 +1771,36 @@ static int r8a66597_urb_enqueue(struct usb_hcd *hcd, | |||
1783 | set_td_timer(r8a66597, td); | 1771 | set_td_timer(r8a66597, td); |
1784 | 1772 | ||
1785 | error: | 1773 | error: |
1774 | if (ret) | ||
1775 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
1776 | error_not_linked: | ||
1786 | spin_unlock_irqrestore(&r8a66597->lock, flags); | 1777 | spin_unlock_irqrestore(&r8a66597->lock, flags); |
1787 | return ret; | 1778 | return ret; |
1788 | } | 1779 | } |
1789 | 1780 | ||
1790 | static int r8a66597_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | 1781 | static int r8a66597_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, |
1782 | int status) | ||
1791 | { | 1783 | { |
1792 | struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); | 1784 | struct r8a66597 *r8a66597 = hcd_to_r8a66597(hcd); |
1793 | struct r8a66597_td *td; | 1785 | struct r8a66597_td *td; |
1794 | unsigned long flags; | 1786 | unsigned long flags; |
1787 | int rc; | ||
1795 | 1788 | ||
1796 | spin_lock_irqsave(&r8a66597->lock, flags); | 1789 | spin_lock_irqsave(&r8a66597->lock, flags); |
1790 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); | ||
1791 | if (rc) | ||
1792 | goto done; | ||
1793 | |||
1797 | if (urb->hcpriv) { | 1794 | if (urb->hcpriv) { |
1798 | td = urb->hcpriv; | 1795 | td = urb->hcpriv; |
1799 | pipe_stop(r8a66597, td->pipe); | 1796 | pipe_stop(r8a66597, td->pipe); |
1800 | pipe_irq_disable(r8a66597, td->pipenum); | 1797 | pipe_irq_disable(r8a66597, td->pipenum); |
1801 | disable_irq_empty(r8a66597, td->pipenum); | 1798 | disable_irq_empty(r8a66597, td->pipenum); |
1802 | done(r8a66597, td, td->pipenum, urb); | 1799 | finish_request(r8a66597, td, td->pipenum, urb, status); |
1803 | } | 1800 | } |
1801 | done: | ||
1804 | spin_unlock_irqrestore(&r8a66597->lock, flags); | 1802 | spin_unlock_irqrestore(&r8a66597->lock, flags); |
1805 | return 0; | 1803 | return rc; |
1806 | } | 1804 | } |
1807 | 1805 | ||
1808 | static void r8a66597_endpoint_disable(struct usb_hcd *hcd, | 1806 | static void r8a66597_endpoint_disable(struct usb_hcd *hcd, |
@@ -1832,7 +1830,7 @@ static void r8a66597_endpoint_disable(struct usb_hcd *hcd, | |||
1832 | td = r8a66597_get_td(r8a66597, pipenum); | 1830 | td = r8a66597_get_td(r8a66597, pipenum); |
1833 | if (td) | 1831 | if (td) |
1834 | urb = td->urb; | 1832 | urb = td->urb; |
1835 | done(r8a66597, td, pipenum, urb); | 1833 | finish_request(r8a66597, td, pipenum, urb, -ESHUTDOWN); |
1836 | kfree(hep->hcpriv); | 1834 | kfree(hep->hcpriv); |
1837 | hep->hcpriv = NULL; | 1835 | hep->hcpriv = NULL; |
1838 | spin_unlock_irqrestore(&r8a66597->lock, flags); | 1836 | spin_unlock_irqrestore(&r8a66597->lock, flags); |
@@ -2029,7 +2027,7 @@ static int r8a66597_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
2029 | case GetPortStatus: | 2027 | case GetPortStatus: |
2030 | if (wIndex > R8A66597_MAX_ROOT_HUB) | 2028 | if (wIndex > R8A66597_MAX_ROOT_HUB) |
2031 | goto error; | 2029 | goto error; |
2032 | *(u32 *)buf = rh->port; | 2030 | *(u32 *)buf = cpu_to_le32(rh->port); |
2033 | break; | 2031 | break; |
2034 | case SetPortFeature: | 2032 | case SetPortFeature: |
2035 | if (wIndex > R8A66597_MAX_ROOT_HUB) | 2033 | if (wIndex > R8A66597_MAX_ROOT_HUB) |
@@ -2128,8 +2126,8 @@ static int __init_or_module r8a66597_remove(struct platform_device *pdev) | |||
2128 | struct usb_hcd *hcd = r8a66597_to_hcd(r8a66597); | 2126 | struct usb_hcd *hcd = r8a66597_to_hcd(r8a66597); |
2129 | 2127 | ||
2130 | del_timer_sync(&r8a66597->rh_timer); | 2128 | del_timer_sync(&r8a66597->rh_timer); |
2131 | iounmap((void *)r8a66597->reg); | ||
2132 | usb_remove_hcd(hcd); | 2129 | usb_remove_hcd(hcd); |
2130 | iounmap((void *)r8a66597->reg); | ||
2133 | usb_put_hcd(hcd); | 2131 | usb_put_hcd(hcd); |
2134 | return 0; | 2132 | return 0; |
2135 | } | 2133 | } |
@@ -2210,8 +2208,6 @@ static int __init r8a66597_probe(struct platform_device *pdev) | |||
2210 | clean_up: | 2208 | clean_up: |
2211 | if (reg) | 2209 | if (reg) |
2212 | iounmap(reg); | 2210 | iounmap(reg); |
2213 | if (res) | ||
2214 | release_mem_region(res->start, 1); | ||
2215 | 2211 | ||
2216 | return ret; | 2212 | return ret; |
2217 | } | 2213 | } |
diff --git a/drivers/usb/host/r8a66597.h b/drivers/usb/host/r8a66597.h index 97c2a71ac7a..fe9ceb077d9 100644 --- a/drivers/usb/host/r8a66597.h +++ b/drivers/usb/host/r8a66597.h | |||
@@ -203,14 +203,14 @@ | |||
203 | #define DTLN 0x0FFF /* b11-0: FIFO received data length */ | 203 | #define DTLN 0x0FFF /* b11-0: FIFO received data length */ |
204 | 204 | ||
205 | /* Interrupt Enable Register 0 */ | 205 | /* Interrupt Enable Register 0 */ |
206 | #define VBSE 0x8000 /* b15: VBUS interrupt */ | 206 | #define VBSE 0x8000 /* b15: VBUS interrupt */ |
207 | #define RSME 0x4000 /* b14: Resume interrupt */ | 207 | #define RSME 0x4000 /* b14: Resume interrupt */ |
208 | #define SOFE 0x2000 /* b13: Frame update interrupt */ | 208 | #define SOFE 0x2000 /* b13: Frame update interrupt */ |
209 | #define DVSE 0x1000 /* b12: Device state transition interrupt */ | 209 | #define DVSE 0x1000 /* b12: Device state transition interrupt */ |
210 | #define CTRE 0x0800 /* b11: Control transfer stage transition interrupt */ | 210 | #define CTRE 0x0800 /* b11: Control transfer stage transition interrupt */ |
211 | #define BEMPE 0x0400 /* b10: Buffer empty interrupt */ | 211 | #define BEMPE 0x0400 /* b10: Buffer empty interrupt */ |
212 | #define NRDYE 0x0200 /* b9: Buffer not ready interrupt */ | 212 | #define NRDYE 0x0200 /* b9: Buffer not ready interrupt */ |
213 | #define BRDYE 0x0100 /* b8: Buffer ready interrupt */ | 213 | #define BRDYE 0x0100 /* b8: Buffer ready interrupt */ |
214 | 214 | ||
215 | /* Interrupt Enable Register 1 */ | 215 | /* Interrupt Enable Register 1 */ |
216 | #define OVRCRE 0x8000 /* b15: Over-current interrupt */ | 216 | #define OVRCRE 0x8000 /* b15: Over-current interrupt */ |
@@ -268,16 +268,16 @@ | |||
268 | #define SOF_DISABLE 0x0000 /* SOF OUT Disable */ | 268 | #define SOF_DISABLE 0x0000 /* SOF OUT Disable */ |
269 | 269 | ||
270 | /* Interrupt Status Register 0 */ | 270 | /* Interrupt Status Register 0 */ |
271 | #define VBINT 0x8000 /* b15: VBUS interrupt */ | 271 | #define VBINT 0x8000 /* b15: VBUS interrupt */ |
272 | #define RESM 0x4000 /* b14: Resume interrupt */ | 272 | #define RESM 0x4000 /* b14: Resume interrupt */ |
273 | #define SOFR 0x2000 /* b13: SOF frame update interrupt */ | 273 | #define SOFR 0x2000 /* b13: SOF frame update interrupt */ |
274 | #define DVST 0x1000 /* b12: Device state transition interrupt */ | 274 | #define DVST 0x1000 /* b12: Device state transition interrupt */ |
275 | #define CTRT 0x0800 /* b11: Control transfer stage transition interrupt */ | 275 | #define CTRT 0x0800 /* b11: Control transfer stage transition interrupt */ |
276 | #define BEMP 0x0400 /* b10: Buffer empty interrupt */ | 276 | #define BEMP 0x0400 /* b10: Buffer empty interrupt */ |
277 | #define NRDY 0x0200 /* b9: Buffer not ready interrupt */ | 277 | #define NRDY 0x0200 /* b9: Buffer not ready interrupt */ |
278 | #define BRDY 0x0100 /* b8: Buffer ready interrupt */ | 278 | #define BRDY 0x0100 /* b8: Buffer ready interrupt */ |
279 | #define VBSTS 0x0080 /* b7: VBUS input port */ | 279 | #define VBSTS 0x0080 /* b7: VBUS input port */ |
280 | #define DVSQ 0x0070 /* b6-4: Device state */ | 280 | #define DVSQ 0x0070 /* b6-4: Device state */ |
281 | #define DS_SPD_CNFG 0x0070 /* Suspend Configured */ | 281 | #define DS_SPD_CNFG 0x0070 /* Suspend Configured */ |
282 | #define DS_SPD_ADDR 0x0060 /* Suspend Address */ | 282 | #define DS_SPD_ADDR 0x0060 /* Suspend Address */ |
283 | #define DS_SPD_DFLT 0x0050 /* Suspend Default */ | 283 | #define DS_SPD_DFLT 0x0050 /* Suspend Default */ |
@@ -315,13 +315,10 @@ | |||
315 | /* Micro Frame Number Register */ | 315 | /* Micro Frame Number Register */ |
316 | #define UFRNM 0x0007 /* b2-0: Micro frame number */ | 316 | #define UFRNM 0x0007 /* b2-0: Micro frame number */ |
317 | 317 | ||
318 | /* USB Address / Low Power Status Recovery Register */ | ||
319 | //#define USBADDR 0x007F /* b6-0: USB address */ | ||
320 | |||
321 | /* Default Control Pipe Maxpacket Size Register */ | 318 | /* Default Control Pipe Maxpacket Size Register */ |
322 | /* Pipe Maxpacket Size Register */ | 319 | /* Pipe Maxpacket Size Register */ |
323 | #define DEVSEL 0xF000 /* b15-14: Device address select */ | 320 | #define DEVSEL 0xF000 /* b15-14: Device address select */ |
324 | #define MAXP 0x007F /* b6-0: Maxpacket size of default control pipe */ | 321 | #define MAXP 0x007F /* b6-0: Maxpacket size of default control pipe */ |
325 | 322 | ||
326 | /* Default Control Pipe Control Register */ | 323 | /* Default Control Pipe Control Register */ |
327 | #define BSTS 0x8000 /* b15: Buffer status */ | 324 | #define BSTS 0x8000 /* b15: Buffer status */ |
@@ -366,21 +363,21 @@ | |||
366 | #define MXPS 0x07FF /* b10-0: Maxpacket size */ | 363 | #define MXPS 0x07FF /* b10-0: Maxpacket size */ |
367 | 364 | ||
368 | /* Pipe Cycle Configuration Register */ | 365 | /* Pipe Cycle Configuration Register */ |
369 | #define IFIS 0x1000 /* b12: Isochronous in-buffer flush mode select */ | 366 | #define IFIS 0x1000 /* b12: Isochronous in-buffer flush mode select */ |
370 | #define IITV 0x0007 /* b2-0: Isochronous interval */ | 367 | #define IITV 0x0007 /* b2-0: Isochronous interval */ |
371 | 368 | ||
372 | /* Pipex Control Register */ | 369 | /* Pipex Control Register */ |
373 | #define BSTS 0x8000 /* b15: Buffer status */ | 370 | #define BSTS 0x8000 /* b15: Buffer status */ |
374 | #define INBUFM 0x4000 /* b14: IN buffer monitor (Only for PIPE1 to 5) */ | 371 | #define INBUFM 0x4000 /* b14: IN buffer monitor (Only for PIPE1 to 5) */ |
375 | #define CSCLR 0x2000 /* b13: complete-split status clear */ | 372 | #define CSCLR 0x2000 /* b13: complete-split status clear */ |
376 | #define CSSTS 0x1000 /* b12: complete-split status */ | 373 | #define CSSTS 0x1000 /* b12: complete-split status */ |
377 | #define ATREPM 0x0400 /* b10: Auto repeat mode */ | 374 | #define ATREPM 0x0400 /* b10: Auto repeat mode */ |
378 | #define ACLRM 0x0200 /* b9: Out buffer auto clear mode */ | 375 | #define ACLRM 0x0200 /* b9: Out buffer auto clear mode */ |
379 | #define SQCLR 0x0100 /* b8: Sequence toggle bit clear */ | 376 | #define SQCLR 0x0100 /* b8: Sequence toggle bit clear */ |
380 | #define SQSET 0x0080 /* b7: Sequence toggle bit set */ | 377 | #define SQSET 0x0080 /* b7: Sequence toggle bit set */ |
381 | #define SQMON 0x0040 /* b6: Sequence toggle bit monitor */ | 378 | #define SQMON 0x0040 /* b6: Sequence toggle bit monitor */ |
382 | #define PBUSY 0x0020 /* b5: pipe busy */ | 379 | #define PBUSY 0x0020 /* b5: pipe busy */ |
383 | #define PID 0x0003 /* b1-0: Response PID */ | 380 | #define PID 0x0003 /* b1-0: Response PID */ |
384 | 381 | ||
385 | /* PIPExTRE */ | 382 | /* PIPExTRE */ |
386 | #define TRENB 0x0200 /* b9: Transaction counter enable */ | 383 | #define TRENB 0x0200 /* b9: Transaction counter enable */ |
@@ -407,15 +404,15 @@ | |||
407 | #define make_devsel(addr) (addr << 12) | 404 | #define make_devsel(addr) (addr << 12) |
408 | 405 | ||
409 | struct r8a66597_pipe_info { | 406 | struct r8a66597_pipe_info { |
410 | u16 pipenum; | 407 | u16 pipenum; |
411 | u16 address; /* R8A66597 HCD usb addres */ | 408 | u16 address; /* R8A66597 HCD usb addres */ |
412 | u16 epnum; | 409 | u16 epnum; |
413 | u16 maxpacket; | 410 | u16 maxpacket; |
414 | u16 type; | 411 | u16 type; |
415 | u16 bufnum; | 412 | u16 bufnum; |
416 | u16 buf_bsize; | 413 | u16 buf_bsize; |
417 | u16 interval; | 414 | u16 interval; |
418 | u16 dir_in; | 415 | u16 dir_in; |
419 | }; | 416 | }; |
420 | 417 | ||
421 | struct r8a66597_pipe { | 418 | struct r8a66597_pipe { |
diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index 4cfa3ff2c99..94d859aa73f 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c | |||
@@ -435,14 +435,9 @@ static void finish_request( | |||
435 | if (usb_pipecontrol(urb->pipe)) | 435 | if (usb_pipecontrol(urb->pipe)) |
436 | ep->nextpid = USB_PID_SETUP; | 436 | ep->nextpid = USB_PID_SETUP; |
437 | 437 | ||
438 | spin_lock(&urb->lock); | 438 | usb_hcd_unlink_urb_from_ep(sl811_to_hcd(sl811), urb); |
439 | if (urb->status == -EINPROGRESS) | ||
440 | urb->status = status; | ||
441 | urb->hcpriv = NULL; | ||
442 | spin_unlock(&urb->lock); | ||
443 | |||
444 | spin_unlock(&sl811->lock); | 439 | spin_unlock(&sl811->lock); |
445 | usb_hcd_giveback_urb(sl811_to_hcd(sl811), urb); | 440 | usb_hcd_giveback_urb(sl811_to_hcd(sl811), urb, status); |
446 | spin_lock(&sl811->lock); | 441 | spin_lock(&sl811->lock); |
447 | 442 | ||
448 | /* leave active endpoints in the schedule */ | 443 | /* leave active endpoints in the schedule */ |
@@ -538,35 +533,21 @@ done(struct sl811 *sl811, struct sl811h_ep *ep, u8 bank) | |||
538 | bank + SL11H_XFERCNTREG); | 533 | bank + SL11H_XFERCNTREG); |
539 | if (len > ep->length) { | 534 | if (len > ep->length) { |
540 | len = ep->length; | 535 | len = ep->length; |
541 | urb->status = -EOVERFLOW; | 536 | urbstat = -EOVERFLOW; |
542 | } | 537 | } |
543 | urb->actual_length += len; | 538 | urb->actual_length += len; |
544 | sl811_read_buf(sl811, SL811HS_PACKET_BUF(bank == 0), | 539 | sl811_read_buf(sl811, SL811HS_PACKET_BUF(bank == 0), |
545 | buf, len); | 540 | buf, len); |
546 | usb_dotoggle(udev, ep->epnum, 0); | 541 | usb_dotoggle(udev, ep->epnum, 0); |
547 | if (urb->actual_length == urb->transfer_buffer_length) | 542 | if (urbstat == -EINPROGRESS && |
548 | urbstat = 0; | 543 | (len < ep->maxpacket || |
549 | else if (len < ep->maxpacket) { | 544 | urb->actual_length == |
550 | if (urb->transfer_flags & URB_SHORT_NOT_OK) | 545 | urb->transfer_buffer_length)) { |
551 | urbstat = -EREMOTEIO; | 546 | if (usb_pipecontrol(urb->pipe)) |
547 | ep->nextpid = USB_PID_ACK; | ||
552 | else | 548 | else |
553 | urbstat = 0; | 549 | urbstat = 0; |
554 | } | 550 | } |
555 | if (usb_pipecontrol(urb->pipe) | ||
556 | && (urbstat == -EREMOTEIO | ||
557 | || urbstat == 0)) { | ||
558 | |||
559 | /* NOTE if the status stage STALLs (why?), | ||
560 | * this reports the wrong urb status. | ||
561 | */ | ||
562 | spin_lock(&urb->lock); | ||
563 | if (urb->status == -EINPROGRESS) | ||
564 | urb->status = urbstat; | ||
565 | spin_unlock(&urb->lock); | ||
566 | |||
567 | urb = NULL; | ||
568 | ep->nextpid = USB_PID_ACK; | ||
569 | } | ||
570 | break; | 551 | break; |
571 | case USB_PID_SETUP: | 552 | case USB_PID_SETUP: |
572 | // PACKET("...ACK/setup_%02x qh%p\n", bank, ep); | 553 | // PACKET("...ACK/setup_%02x qh%p\n", bank, ep); |
@@ -605,7 +586,7 @@ done(struct sl811 *sl811, struct sl811h_ep *ep, u8 bank) | |||
605 | bank, status, ep, urbstat); | 586 | bank, status, ep, urbstat); |
606 | } | 587 | } |
607 | 588 | ||
608 | if (urb && (urbstat != -EINPROGRESS || urb->status != -EINPROGRESS)) | 589 | if (urbstat != -EINPROGRESS || urb->unlinked) |
609 | finish_request(sl811, ep, urb, urbstat); | 590 | finish_request(sl811, ep, urb, urbstat); |
610 | } | 591 | } |
611 | 592 | ||
@@ -807,7 +788,6 @@ static int balance(struct sl811 *sl811, u16 period, u16 load) | |||
807 | 788 | ||
808 | static int sl811h_urb_enqueue( | 789 | static int sl811h_urb_enqueue( |
809 | struct usb_hcd *hcd, | 790 | struct usb_hcd *hcd, |
810 | struct usb_host_endpoint *hep, | ||
811 | struct urb *urb, | 791 | struct urb *urb, |
812 | gfp_t mem_flags | 792 | gfp_t mem_flags |
813 | ) { | 793 | ) { |
@@ -820,7 +800,8 @@ static int sl811h_urb_enqueue( | |||
820 | struct sl811h_ep *ep = NULL; | 800 | struct sl811h_ep *ep = NULL; |
821 | unsigned long flags; | 801 | unsigned long flags; |
822 | int i; | 802 | int i; |
823 | int retval = 0; | 803 | int retval; |
804 | struct usb_host_endpoint *hep = urb->ep; | ||
824 | 805 | ||
825 | #ifdef DISABLE_ISO | 806 | #ifdef DISABLE_ISO |
826 | if (type == PIPE_ISOCHRONOUS) | 807 | if (type == PIPE_ISOCHRONOUS) |
@@ -838,7 +819,12 @@ static int sl811h_urb_enqueue( | |||
838 | || !HC_IS_RUNNING(hcd->state)) { | 819 | || !HC_IS_RUNNING(hcd->state)) { |
839 | retval = -ENODEV; | 820 | retval = -ENODEV; |
840 | kfree(ep); | 821 | kfree(ep); |
841 | goto fail; | 822 | goto fail_not_linked; |
823 | } | ||
824 | retval = usb_hcd_link_urb_to_ep(hcd, urb); | ||
825 | if (retval) { | ||
826 | kfree(ep); | ||
827 | goto fail_not_linked; | ||
842 | } | 828 | } |
843 | 829 | ||
844 | if (hep->hcpriv) { | 830 | if (hep->hcpriv) { |
@@ -951,37 +937,31 @@ static int sl811h_urb_enqueue( | |||
951 | sofirq_on(sl811); | 937 | sofirq_on(sl811); |
952 | } | 938 | } |
953 | 939 | ||
954 | /* in case of unlink-during-submit */ | ||
955 | spin_lock(&urb->lock); | ||
956 | if (urb->status != -EINPROGRESS) { | ||
957 | spin_unlock(&urb->lock); | ||
958 | finish_request(sl811, ep, urb, 0); | ||
959 | retval = 0; | ||
960 | goto fail; | ||
961 | } | ||
962 | urb->hcpriv = hep; | 940 | urb->hcpriv = hep; |
963 | spin_unlock(&urb->lock); | ||
964 | |||
965 | start_transfer(sl811); | 941 | start_transfer(sl811); |
966 | sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); | 942 | sl811_write(sl811, SL11H_IRQ_ENABLE, sl811->irq_enable); |
967 | fail: | 943 | fail: |
944 | if (retval) | ||
945 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
946 | fail_not_linked: | ||
968 | spin_unlock_irqrestore(&sl811->lock, flags); | 947 | spin_unlock_irqrestore(&sl811->lock, flags); |
969 | return retval; | 948 | return retval; |
970 | } | 949 | } |
971 | 950 | ||
972 | static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | 951 | static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) |
973 | { | 952 | { |
974 | struct sl811 *sl811 = hcd_to_sl811(hcd); | 953 | struct sl811 *sl811 = hcd_to_sl811(hcd); |
975 | struct usb_host_endpoint *hep; | 954 | struct usb_host_endpoint *hep; |
976 | unsigned long flags; | 955 | unsigned long flags; |
977 | struct sl811h_ep *ep; | 956 | struct sl811h_ep *ep; |
978 | int retval = 0; | 957 | int retval; |
979 | 958 | ||
980 | spin_lock_irqsave(&sl811->lock, flags); | 959 | spin_lock_irqsave(&sl811->lock, flags); |
981 | hep = urb->hcpriv; | 960 | retval = usb_hcd_check_unlink_urb(hcd, urb, status); |
982 | if (!hep) | 961 | if (retval) |
983 | goto fail; | 962 | goto fail; |
984 | 963 | ||
964 | hep = urb->hcpriv; | ||
985 | ep = hep->hcpriv; | 965 | ep = hep->hcpriv; |
986 | if (ep) { | 966 | if (ep) { |
987 | /* finish right away if this urb can't be active ... | 967 | /* finish right away if this urb can't be active ... |
@@ -1029,8 +1009,8 @@ static int sl811h_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | |||
1029 | VDBG("dequeue, urb %p active %s; wait4irq\n", urb, | 1009 | VDBG("dequeue, urb %p active %s; wait4irq\n", urb, |
1030 | (sl811->active_a == ep) ? "A" : "B"); | 1010 | (sl811->active_a == ep) ? "A" : "B"); |
1031 | } else | 1011 | } else |
1032 | fail: | ||
1033 | retval = -EINVAL; | 1012 | retval = -EINVAL; |
1013 | fail: | ||
1034 | spin_unlock_irqrestore(&sl811->lock, flags); | 1014 | spin_unlock_irqrestore(&sl811->lock, flags); |
1035 | return retval; | 1015 | return retval; |
1036 | } | 1016 | } |
diff --git a/drivers/usb/host/sl811_cs.c b/drivers/usb/host/sl811_cs.c index 2d0e73b2009..5da63f53500 100644 --- a/drivers/usb/host/sl811_cs.c +++ b/drivers/usb/host/sl811_cs.c | |||
@@ -278,10 +278,9 @@ static int sl811_cs_probe(struct pcmcia_device *link) | |||
278 | { | 278 | { |
279 | local_info_t *local; | 279 | local_info_t *local; |
280 | 280 | ||
281 | local = kmalloc(sizeof(local_info_t), GFP_KERNEL); | 281 | local = kzalloc(sizeof(local_info_t), GFP_KERNEL); |
282 | if (!local) | 282 | if (!local) |
283 | return -ENOMEM; | 283 | return -ENOMEM; |
284 | memset(local, 0, sizeof(local_info_t)); | ||
285 | local->p_dev = link; | 284 | local->p_dev = link; |
286 | link->priv = local; | 285 | link->priv = local; |
287 | 286 | ||
diff --git a/drivers/usb/host/u132-hcd.c b/drivers/usb/host/u132-hcd.c index e98df2ee990..ac283b09a63 100644 --- a/drivers/usb/host/u132-hcd.c +++ b/drivers/usb/host/u132-hcd.c | |||
@@ -51,7 +51,7 @@ | |||
51 | #include <linux/usb.h> | 51 | #include <linux/usb.h> |
52 | #include <linux/workqueue.h> | 52 | #include <linux/workqueue.h> |
53 | #include <linux/platform_device.h> | 53 | #include <linux/platform_device.h> |
54 | #include <linux/pci_ids.h> | 54 | #include <linux/mutex.h> |
55 | #include <asm/io.h> | 55 | #include <asm/io.h> |
56 | #include <asm/irq.h> | 56 | #include <asm/irq.h> |
57 | #include <asm/system.h> | 57 | #include <asm/system.h> |
@@ -83,7 +83,7 @@ static DECLARE_WAIT_QUEUE_HEAD(u132_hcd_wait); | |||
83 | * u132_module_lock exists to protect access to global variables | 83 | * u132_module_lock exists to protect access to global variables |
84 | * | 84 | * |
85 | */ | 85 | */ |
86 | static struct semaphore u132_module_lock; | 86 | static struct mutex u132_module_lock; |
87 | static int u132_exiting = 0; | 87 | static int u132_exiting = 0; |
88 | static int u132_instances = 0; | 88 | static int u132_instances = 0; |
89 | static struct list_head u132_static_list; | 89 | static struct list_head u132_static_list; |
@@ -183,7 +183,7 @@ struct u132_ring { | |||
183 | struct u132 { | 183 | struct u132 { |
184 | struct kref kref; | 184 | struct kref kref; |
185 | struct list_head u132_list; | 185 | struct list_head u132_list; |
186 | struct semaphore sw_lock; | 186 | struct mutex sw_lock; |
187 | struct semaphore scheduler_lock; | 187 | struct semaphore scheduler_lock; |
188 | struct u132_platform_data *board; | 188 | struct u132_platform_data *board; |
189 | struct platform_device *platform_dev; | 189 | struct platform_device *platform_dev; |
@@ -258,10 +258,10 @@ static void u132_hcd_delete(struct kref *kref) | |||
258 | struct platform_device *pdev = u132->platform_dev; | 258 | struct platform_device *pdev = u132->platform_dev; |
259 | struct usb_hcd *hcd = u132_to_hcd(u132); | 259 | struct usb_hcd *hcd = u132_to_hcd(u132); |
260 | u132->going += 1; | 260 | u132->going += 1; |
261 | down(&u132_module_lock); | 261 | mutex_lock(&u132_module_lock); |
262 | list_del_init(&u132->u132_list); | 262 | list_del_init(&u132->u132_list); |
263 | u132_instances -= 1; | 263 | u132_instances -= 1; |
264 | up(&u132_module_lock); | 264 | mutex_unlock(&u132_module_lock); |
265 | dev_warn(&u132->platform_dev->dev, "FREEING the hcd=%p and thus the u13" | 265 | dev_warn(&u132->platform_dev->dev, "FREEING the hcd=%p and thus the u13" |
266 | "2=%p going=%d pdev=%p\n", hcd, u132, u132->going, pdev); | 266 | "2=%p going=%d pdev=%p\n", hcd, u132, u132->going, pdev); |
267 | usb_put_hcd(hcd); | 267 | usb_put_hcd(hcd); |
@@ -492,20 +492,20 @@ static void u132_hcd_monitor_work(struct work_struct *work) | |||
492 | return; | 492 | return; |
493 | } else { | 493 | } else { |
494 | int retval; | 494 | int retval; |
495 | down(&u132->sw_lock); | 495 | mutex_lock(&u132->sw_lock); |
496 | retval = read_roothub_info(u132); | 496 | retval = read_roothub_info(u132); |
497 | if (retval) { | 497 | if (retval) { |
498 | struct usb_hcd *hcd = u132_to_hcd(u132); | 498 | struct usb_hcd *hcd = u132_to_hcd(u132); |
499 | u132_disable(u132); | 499 | u132_disable(u132); |
500 | u132->going = 1; | 500 | u132->going = 1; |
501 | up(&u132->sw_lock); | 501 | mutex_unlock(&u132->sw_lock); |
502 | usb_hc_died(hcd); | 502 | usb_hc_died(hcd); |
503 | ftdi_elan_gone_away(u132->platform_dev); | 503 | ftdi_elan_gone_away(u132->platform_dev); |
504 | u132_monitor_put_kref(u132); | 504 | u132_monitor_put_kref(u132); |
505 | return; | 505 | return; |
506 | } else { | 506 | } else { |
507 | u132_monitor_requeue_work(u132, 500); | 507 | u132_monitor_requeue_work(u132, 500); |
508 | up(&u132->sw_lock); | 508 | mutex_unlock(&u132->sw_lock); |
509 | return; | 509 | return; |
510 | } | 510 | } |
511 | } | 511 | } |
@@ -518,9 +518,8 @@ static void u132_hcd_giveback_urb(struct u132 *u132, struct u132_endp *endp, | |||
518 | unsigned long irqs; | 518 | unsigned long irqs; |
519 | struct usb_hcd *hcd = u132_to_hcd(u132); | 519 | struct usb_hcd *hcd = u132_to_hcd(u132); |
520 | urb->error_count = 0; | 520 | urb->error_count = 0; |
521 | urb->status = status; | ||
522 | urb->hcpriv = NULL; | ||
523 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | 521 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); |
522 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
524 | endp->queue_next += 1; | 523 | endp->queue_next += 1; |
525 | if (ENDP_QUEUE_SIZE > --endp->queue_size) { | 524 | if (ENDP_QUEUE_SIZE > --endp->queue_size) { |
526 | endp->active = 0; | 525 | endp->active = 0; |
@@ -542,7 +541,7 @@ static void u132_hcd_giveback_urb(struct u132 *u132, struct u132_endp *endp, | |||
542 | u132_ring_queue_work(u132, ring, 0); | 541 | u132_ring_queue_work(u132, ring, 0); |
543 | up(&u132->scheduler_lock); | 542 | up(&u132->scheduler_lock); |
544 | u132_endp_put_kref(u132, endp); | 543 | u132_endp_put_kref(u132, endp); |
545 | usb_hcd_giveback_urb(hcd, urb); | 544 | usb_hcd_giveback_urb(hcd, urb, status); |
546 | return; | 545 | return; |
547 | } | 546 | } |
548 | 547 | ||
@@ -558,9 +557,8 @@ static void u132_hcd_abandon_urb(struct u132 *u132, struct u132_endp *endp, | |||
558 | unsigned long irqs; | 557 | unsigned long irqs; |
559 | struct usb_hcd *hcd = u132_to_hcd(u132); | 558 | struct usb_hcd *hcd = u132_to_hcd(u132); |
560 | urb->error_count = 0; | 559 | urb->error_count = 0; |
561 | urb->status = status; | ||
562 | urb->hcpriv = NULL; | ||
563 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | 560 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); |
561 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
564 | endp->queue_next += 1; | 562 | endp->queue_next += 1; |
565 | if (ENDP_QUEUE_SIZE > --endp->queue_size) { | 563 | if (ENDP_QUEUE_SIZE > --endp->queue_size) { |
566 | endp->active = 0; | 564 | endp->active = 0; |
@@ -575,7 +573,7 @@ static void u132_hcd_abandon_urb(struct u132 *u132, struct u132_endp *endp, | |||
575 | endp->active = 0; | 573 | endp->active = 0; |
576 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | 574 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); |
577 | kfree(urbq); | 575 | kfree(urbq); |
578 | } usb_hcd_giveback_urb(hcd, urb); | 576 | } usb_hcd_giveback_urb(hcd, urb, status); |
579 | return; | 577 | return; |
580 | } | 578 | } |
581 | 579 | ||
@@ -645,12 +643,12 @@ static void u132_hcd_interrupt_recv(void *data, struct urb *urb, u8 *buf, | |||
645 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 643 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
646 | return; | 644 | return; |
647 | } else if (u132->going > 0) { | 645 | } else if (u132->going > 0) { |
648 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 646 | dev_err(&u132->platform_dev->dev, "device is being removed " |
649 | "%p status=%d\n", urb, urb->status); | 647 | "urb=%p\n", urb); |
650 | up(&u132->scheduler_lock); | 648 | up(&u132->scheduler_lock); |
651 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 649 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
652 | return; | 650 | return; |
653 | } else if (urb->status == -EINPROGRESS) { | 651 | } else if (!urb->unlinked) { |
654 | struct u132_ring *ring = endp->ring; | 652 | struct u132_ring *ring = endp->ring; |
655 | u8 *u = urb->transfer_buffer + urb->actual_length; | 653 | u8 *u = urb->transfer_buffer + urb->actual_length; |
656 | u8 *b = buf; | 654 | u8 *b = buf; |
@@ -716,10 +714,10 @@ static void u132_hcd_interrupt_recv(void *data, struct urb *urb, u8 *buf, | |||
716 | return; | 714 | return; |
717 | } | 715 | } |
718 | } else { | 716 | } else { |
719 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 717 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
720 | "s=%d\n", urb, urb->status); | 718 | "unlinked=%d\n", urb, urb->unlinked); |
721 | up(&u132->scheduler_lock); | 719 | up(&u132->scheduler_lock); |
722 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 720 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
723 | return; | 721 | return; |
724 | } | 722 | } |
725 | } | 723 | } |
@@ -744,12 +742,12 @@ static void u132_hcd_bulk_output_sent(void *data, struct urb *urb, u8 *buf, | |||
744 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 742 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
745 | return; | 743 | return; |
746 | } else if (u132->going > 0) { | 744 | } else if (u132->going > 0) { |
747 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 745 | dev_err(&u132->platform_dev->dev, "device is being removed " |
748 | "%p status=%d\n", urb, urb->status); | 746 | "urb=%p\n", urb); |
749 | up(&u132->scheduler_lock); | 747 | up(&u132->scheduler_lock); |
750 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 748 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
751 | return; | 749 | return; |
752 | } else if (urb->status == -EINPROGRESS) { | 750 | } else if (!urb->unlinked) { |
753 | struct u132_ring *ring = endp->ring; | 751 | struct u132_ring *ring = endp->ring; |
754 | urb->actual_length += len; | 752 | urb->actual_length += len; |
755 | endp->toggle_bits = toggle_bits; | 753 | endp->toggle_bits = toggle_bits; |
@@ -768,10 +766,10 @@ static void u132_hcd_bulk_output_sent(void *data, struct urb *urb, u8 *buf, | |||
768 | return; | 766 | return; |
769 | } | 767 | } |
770 | } else { | 768 | } else { |
771 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 769 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
772 | "s=%d\n", urb, urb->status); | 770 | "unlinked=%d\n", urb, urb->unlinked); |
773 | up(&u132->scheduler_lock); | 771 | up(&u132->scheduler_lock); |
774 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 772 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
775 | return; | 773 | return; |
776 | } | 774 | } |
777 | } | 775 | } |
@@ -797,12 +795,12 @@ static void u132_hcd_bulk_input_recv(void *data, struct urb *urb, u8 *buf, | |||
797 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 795 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
798 | return; | 796 | return; |
799 | } else if (u132->going > 0) { | 797 | } else if (u132->going > 0) { |
800 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 798 | dev_err(&u132->platform_dev->dev, "device is being removed " |
801 | "%p status=%d\n", urb, urb->status); | 799 | "urb=%p\n", urb); |
802 | up(&u132->scheduler_lock); | 800 | up(&u132->scheduler_lock); |
803 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 801 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
804 | return; | 802 | return; |
805 | } else if (urb->status == -EINPROGRESS) { | 803 | } else if (!urb->unlinked) { |
806 | struct u132_ring *ring = endp->ring; | 804 | struct u132_ring *ring = endp->ring; |
807 | u8 *u = urb->transfer_buffer + urb->actual_length; | 805 | u8 *u = urb->transfer_buffer + urb->actual_length; |
808 | u8 *b = buf; | 806 | u8 *b = buf; |
@@ -871,10 +869,10 @@ static void u132_hcd_bulk_input_recv(void *data, struct urb *urb, u8 *buf, | |||
871 | return; | 869 | return; |
872 | } | 870 | } |
873 | } else { | 871 | } else { |
874 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 872 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
875 | "s=%d\n", urb, urb->status); | 873 | "unlinked=%d\n", urb, urb->unlinked); |
876 | up(&u132->scheduler_lock); | 874 | up(&u132->scheduler_lock); |
877 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 875 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
878 | return; | 876 | return; |
879 | } | 877 | } |
880 | } | 878 | } |
@@ -898,20 +896,20 @@ static void u132_hcd_configure_empty_sent(void *data, struct urb *urb, u8 *buf, | |||
898 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 896 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
899 | return; | 897 | return; |
900 | } else if (u132->going > 0) { | 898 | } else if (u132->going > 0) { |
901 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 899 | dev_err(&u132->platform_dev->dev, "device is being removed " |
902 | "%p status=%d\n", urb, urb->status); | 900 | "urb=%p\n", urb); |
903 | up(&u132->scheduler_lock); | 901 | up(&u132->scheduler_lock); |
904 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 902 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
905 | return; | 903 | return; |
906 | } else if (urb->status == -EINPROGRESS) { | 904 | } else if (!urb->unlinked) { |
907 | up(&u132->scheduler_lock); | 905 | up(&u132->scheduler_lock); |
908 | u132_hcd_giveback_urb(u132, endp, urb, 0); | 906 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
909 | return; | 907 | return; |
910 | } else { | 908 | } else { |
911 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 909 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
912 | "s=%d\n", urb, urb->status); | 910 | "unlinked=%d\n", urb, urb->unlinked); |
913 | up(&u132->scheduler_lock); | 911 | up(&u132->scheduler_lock); |
914 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 912 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
915 | return; | 913 | return; |
916 | } | 914 | } |
917 | } | 915 | } |
@@ -936,12 +934,12 @@ static void u132_hcd_configure_input_recv(void *data, struct urb *urb, u8 *buf, | |||
936 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 934 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
937 | return; | 935 | return; |
938 | } else if (u132->going > 0) { | 936 | } else if (u132->going > 0) { |
939 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 937 | dev_err(&u132->platform_dev->dev, "device is being removed " |
940 | "%p status=%d\n", urb, urb->status); | 938 | "urb=%p\n", urb); |
941 | up(&u132->scheduler_lock); | 939 | up(&u132->scheduler_lock); |
942 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 940 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
943 | return; | 941 | return; |
944 | } else if (urb->status == -EINPROGRESS) { | 942 | } else if (!urb->unlinked) { |
945 | struct u132_ring *ring = endp->ring; | 943 | struct u132_ring *ring = endp->ring; |
946 | u8 *u = urb->transfer_buffer; | 944 | u8 *u = urb->transfer_buffer; |
947 | u8 *b = buf; | 945 | u8 *b = buf; |
@@ -980,10 +978,10 @@ static void u132_hcd_configure_input_recv(void *data, struct urb *urb, u8 *buf, | |||
980 | return; | 978 | return; |
981 | } | 979 | } |
982 | } else { | 980 | } else { |
983 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 981 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
984 | "s=%d\n", urb, urb->status); | 982 | "unlinked=%d\n", urb, urb->unlinked); |
985 | up(&u132->scheduler_lock); | 983 | up(&u132->scheduler_lock); |
986 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 984 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
987 | return; | 985 | return; |
988 | } | 986 | } |
989 | } | 987 | } |
@@ -1007,20 +1005,20 @@ static void u132_hcd_configure_empty_recv(void *data, struct urb *urb, u8 *buf, | |||
1007 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1005 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1008 | return; | 1006 | return; |
1009 | } else if (u132->going > 0) { | 1007 | } else if (u132->going > 0) { |
1010 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1008 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1011 | "%p status=%d\n", urb, urb->status); | 1009 | "urb=%p\n", urb); |
1012 | up(&u132->scheduler_lock); | 1010 | up(&u132->scheduler_lock); |
1013 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1011 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1014 | return; | 1012 | return; |
1015 | } else if (urb->status == -EINPROGRESS) { | 1013 | } else if (!urb->unlinked) { |
1016 | up(&u132->scheduler_lock); | 1014 | up(&u132->scheduler_lock); |
1017 | u132_hcd_giveback_urb(u132, endp, urb, 0); | 1015 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1018 | return; | 1016 | return; |
1019 | } else { | 1017 | } else { |
1020 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1018 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1021 | "s=%d\n", urb, urb->status); | 1019 | "unlinked=%d\n", urb, urb->unlinked); |
1022 | up(&u132->scheduler_lock); | 1020 | up(&u132->scheduler_lock); |
1023 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1021 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1024 | return; | 1022 | return; |
1025 | } | 1023 | } |
1026 | } | 1024 | } |
@@ -1045,12 +1043,12 @@ static void u132_hcd_configure_setup_sent(void *data, struct urb *urb, u8 *buf, | |||
1045 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1043 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1046 | return; | 1044 | return; |
1047 | } else if (u132->going > 0) { | 1045 | } else if (u132->going > 0) { |
1048 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1046 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1049 | "%p status=%d\n", urb, urb->status); | 1047 | "urb=%p\n", urb); |
1050 | up(&u132->scheduler_lock); | 1048 | up(&u132->scheduler_lock); |
1051 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1049 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1052 | return; | 1050 | return; |
1053 | } else if (urb->status == -EINPROGRESS) { | 1051 | } else if (!urb->unlinked) { |
1054 | if (usb_pipein(urb->pipe)) { | 1052 | if (usb_pipein(urb->pipe)) { |
1055 | int retval; | 1053 | int retval; |
1056 | struct u132_ring *ring = endp->ring; | 1054 | struct u132_ring *ring = endp->ring; |
@@ -1077,10 +1075,10 @@ static void u132_hcd_configure_setup_sent(void *data, struct urb *urb, u8 *buf, | |||
1077 | return; | 1075 | return; |
1078 | } | 1076 | } |
1079 | } else { | 1077 | } else { |
1080 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1078 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1081 | "s=%d\n", urb, urb->status); | 1079 | "unlinked=%d\n", urb, urb->unlinked); |
1082 | up(&u132->scheduler_lock); | 1080 | up(&u132->scheduler_lock); |
1083 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1081 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1084 | return; | 1082 | return; |
1085 | } | 1083 | } |
1086 | } | 1084 | } |
@@ -1106,22 +1104,22 @@ static void u132_hcd_enumeration_empty_recv(void *data, struct urb *urb, | |||
1106 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1104 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1107 | return; | 1105 | return; |
1108 | } else if (u132->going > 0) { | 1106 | } else if (u132->going > 0) { |
1109 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1107 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1110 | "%p status=%d\n", urb, urb->status); | 1108 | "urb=%p\n", urb); |
1111 | up(&u132->scheduler_lock); | 1109 | up(&u132->scheduler_lock); |
1112 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1110 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1113 | return; | 1111 | return; |
1114 | } else if (urb->status == -EINPROGRESS) { | 1112 | } else if (!urb->unlinked) { |
1115 | u132->addr[0].address = 0; | 1113 | u132->addr[0].address = 0; |
1116 | endp->usb_addr = udev->usb_addr; | 1114 | endp->usb_addr = udev->usb_addr; |
1117 | up(&u132->scheduler_lock); | 1115 | up(&u132->scheduler_lock); |
1118 | u132_hcd_giveback_urb(u132, endp, urb, 0); | 1116 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1119 | return; | 1117 | return; |
1120 | } else { | 1118 | } else { |
1121 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1119 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1122 | "s=%d\n", urb, urb->status); | 1120 | "unlinked=%d\n", urb, urb->unlinked); |
1123 | up(&u132->scheduler_lock); | 1121 | up(&u132->scheduler_lock); |
1124 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1122 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1125 | return; | 1123 | return; |
1126 | } | 1124 | } |
1127 | } | 1125 | } |
@@ -1145,12 +1143,12 @@ static void u132_hcd_enumeration_address_sent(void *data, struct urb *urb, | |||
1145 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1143 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1146 | return; | 1144 | return; |
1147 | } else if (u132->going > 0) { | 1145 | } else if (u132->going > 0) { |
1148 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1146 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1149 | "%p status=%d\n", urb, urb->status); | 1147 | "urb=%p\n", urb); |
1150 | up(&u132->scheduler_lock); | 1148 | up(&u132->scheduler_lock); |
1151 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1149 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1152 | return; | 1150 | return; |
1153 | } else if (urb->status == -EINPROGRESS) { | 1151 | } else if (!urb->unlinked) { |
1154 | int retval; | 1152 | int retval; |
1155 | struct u132_ring *ring = endp->ring; | 1153 | struct u132_ring *ring = endp->ring; |
1156 | up(&u132->scheduler_lock); | 1154 | up(&u132->scheduler_lock); |
@@ -1162,10 +1160,10 @@ static void u132_hcd_enumeration_address_sent(void *data, struct urb *urb, | |||
1162 | u132_hcd_giveback_urb(u132, endp, urb, retval); | 1160 | u132_hcd_giveback_urb(u132, endp, urb, retval); |
1163 | return; | 1161 | return; |
1164 | } else { | 1162 | } else { |
1165 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1163 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1166 | "s=%d\n", urb, urb->status); | 1164 | "unlinked=%d\n", urb, urb->unlinked); |
1167 | up(&u132->scheduler_lock); | 1165 | up(&u132->scheduler_lock); |
1168 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1166 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1169 | return; | 1167 | return; |
1170 | } | 1168 | } |
1171 | } | 1169 | } |
@@ -1189,20 +1187,20 @@ static void u132_hcd_initial_empty_sent(void *data, struct urb *urb, u8 *buf, | |||
1189 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1187 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1190 | return; | 1188 | return; |
1191 | } else if (u132->going > 0) { | 1189 | } else if (u132->going > 0) { |
1192 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1190 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1193 | "%p status=%d\n", urb, urb->status); | 1191 | "urb=%p\n", urb); |
1194 | up(&u132->scheduler_lock); | 1192 | up(&u132->scheduler_lock); |
1195 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1193 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1196 | return; | 1194 | return; |
1197 | } else if (urb->status == -EINPROGRESS) { | 1195 | } else if (!urb->unlinked) { |
1198 | up(&u132->scheduler_lock); | 1196 | up(&u132->scheduler_lock); |
1199 | u132_hcd_giveback_urb(u132, endp, urb, 0); | 1197 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1200 | return; | 1198 | return; |
1201 | } else { | 1199 | } else { |
1202 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1200 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1203 | "s=%d\n", urb, urb->status); | 1201 | "unlinked=%d\n", urb, urb->unlinked); |
1204 | up(&u132->scheduler_lock); | 1202 | up(&u132->scheduler_lock); |
1205 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1203 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1206 | return; | 1204 | return; |
1207 | } | 1205 | } |
1208 | } | 1206 | } |
@@ -1227,12 +1225,12 @@ static void u132_hcd_initial_input_recv(void *data, struct urb *urb, u8 *buf, | |||
1227 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1225 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1228 | return; | 1226 | return; |
1229 | } else if (u132->going > 0) { | 1227 | } else if (u132->going > 0) { |
1230 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1228 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1231 | "%p status=%d\n", urb, urb->status); | 1229 | "urb=%p\n", urb); |
1232 | up(&u132->scheduler_lock); | 1230 | up(&u132->scheduler_lock); |
1233 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1231 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1234 | return; | 1232 | return; |
1235 | } else if (urb->status == -EINPROGRESS) { | 1233 | } else if (!urb->unlinked) { |
1236 | int retval; | 1234 | int retval; |
1237 | struct u132_ring *ring = endp->ring; | 1235 | struct u132_ring *ring = endp->ring; |
1238 | u8 *u = urb->transfer_buffer; | 1236 | u8 *u = urb->transfer_buffer; |
@@ -1251,10 +1249,10 @@ static void u132_hcd_initial_input_recv(void *data, struct urb *urb, u8 *buf, | |||
1251 | u132_hcd_giveback_urb(u132, endp, urb, retval); | 1249 | u132_hcd_giveback_urb(u132, endp, urb, retval); |
1252 | return; | 1250 | return; |
1253 | } else { | 1251 | } else { |
1254 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1252 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1255 | "s=%d\n", urb, urb->status); | 1253 | "unlinked=%d\n", urb, urb->unlinked); |
1256 | up(&u132->scheduler_lock); | 1254 | up(&u132->scheduler_lock); |
1257 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1255 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1258 | return; | 1256 | return; |
1259 | } | 1257 | } |
1260 | } | 1258 | } |
@@ -1279,12 +1277,12 @@ static void u132_hcd_initial_setup_sent(void *data, struct urb *urb, u8 *buf, | |||
1279 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); | 1277 | u132_hcd_giveback_urb(u132, endp, urb, -EINTR); |
1280 | return; | 1278 | return; |
1281 | } else if (u132->going > 0) { | 1279 | } else if (u132->going > 0) { |
1282 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 1280 | dev_err(&u132->platform_dev->dev, "device is being removed " |
1283 | "%p status=%d\n", urb, urb->status); | 1281 | "urb=%p\n", urb); |
1284 | up(&u132->scheduler_lock); | 1282 | up(&u132->scheduler_lock); |
1285 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); | 1283 | u132_hcd_giveback_urb(u132, endp, urb, -ENODEV); |
1286 | return; | 1284 | return; |
1287 | } else if (urb->status == -EINPROGRESS) { | 1285 | } else if (!urb->unlinked) { |
1288 | int retval; | 1286 | int retval; |
1289 | struct u132_ring *ring = endp->ring; | 1287 | struct u132_ring *ring = endp->ring; |
1290 | up(&u132->scheduler_lock); | 1288 | up(&u132->scheduler_lock); |
@@ -1296,10 +1294,10 @@ static void u132_hcd_initial_setup_sent(void *data, struct urb *urb, u8 *buf, | |||
1296 | u132_hcd_giveback_urb(u132, endp, urb, retval); | 1294 | u132_hcd_giveback_urb(u132, endp, urb, retval); |
1297 | return; | 1295 | return; |
1298 | } else { | 1296 | } else { |
1299 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p statu" | 1297 | dev_err(&u132->platform_dev->dev, "CALLBACK called urb=%p " |
1300 | "s=%d\n", urb, urb->status); | 1298 | "unlinked=%d\n", urb, urb->unlinked); |
1301 | up(&u132->scheduler_lock); | 1299 | up(&u132->scheduler_lock); |
1302 | u132_hcd_giveback_urb(u132, endp, urb, urb->status); | 1300 | u132_hcd_giveback_urb(u132, endp, urb, 0); |
1303 | return; | 1301 | return; |
1304 | } | 1302 | } |
1305 | } | 1303 | } |
@@ -1519,12 +1517,15 @@ static void u132_hcd_endp_work_scheduler(struct work_struct *work) | |||
1519 | } | 1517 | } |
1520 | } | 1518 | } |
1521 | } | 1519 | } |
1520 | #ifdef CONFIG_PM | ||
1522 | 1521 | ||
1523 | static void port_power(struct u132 *u132, int pn, int is_on) | 1522 | static void port_power(struct u132 *u132, int pn, int is_on) |
1524 | { | 1523 | { |
1525 | u132->port[pn].power = is_on; | 1524 | u132->port[pn].power = is_on; |
1526 | } | 1525 | } |
1527 | 1526 | ||
1527 | #endif | ||
1528 | |||
1528 | static void u132_power(struct u132 *u132, int is_on) | 1529 | static void u132_power(struct u132 *u132, int is_on) |
1529 | { | 1530 | { |
1530 | struct usb_hcd *hcd = u132_to_hcd(u132) | 1531 | struct usb_hcd *hcd = u132_to_hcd(u132) |
@@ -1801,10 +1802,10 @@ static void u132_hcd_stop(struct usb_hcd *hcd) | |||
1801 | dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov" | 1802 | dev_err(&u132->platform_dev->dev, "device hcd=%p is being remov" |
1802 | "ed\n", hcd); | 1803 | "ed\n", hcd); |
1803 | } else { | 1804 | } else { |
1804 | down(&u132->sw_lock); | 1805 | mutex_lock(&u132->sw_lock); |
1805 | msleep(100); | 1806 | msleep(100); |
1806 | u132_power(u132, 0); | 1807 | u132_power(u132, 0); |
1807 | up(&u132->sw_lock); | 1808 | mutex_unlock(&u132->sw_lock); |
1808 | } | 1809 | } |
1809 | } | 1810 | } |
1810 | 1811 | ||
@@ -1826,7 +1827,7 @@ static int u132_hcd_start(struct usb_hcd *hcd) | |||
1826 | (pdev->dev.platform_data))->vendor; | 1827 | (pdev->dev.platform_data))->vendor; |
1827 | u16 device = ((struct u132_platform_data *) | 1828 | u16 device = ((struct u132_platform_data *) |
1828 | (pdev->dev.platform_data))->device; | 1829 | (pdev->dev.platform_data))->device; |
1829 | down(&u132->sw_lock); | 1830 | mutex_lock(&u132->sw_lock); |
1830 | msleep(10); | 1831 | msleep(10); |
1831 | if (vendor == PCI_VENDOR_ID_AMD && device == 0x740c) { | 1832 | if (vendor == PCI_VENDOR_ID_AMD && device == 0x740c) { |
1832 | u132->flags = OHCI_QUIRK_AMD756; | 1833 | u132->flags = OHCI_QUIRK_AMD756; |
@@ -1841,7 +1842,7 @@ static int u132_hcd_start(struct usb_hcd *hcd) | |||
1841 | u132->going = 1; | 1842 | u132->going = 1; |
1842 | } | 1843 | } |
1843 | msleep(100); | 1844 | msleep(100); |
1844 | up(&u132->sw_lock); | 1845 | mutex_unlock(&u132->sw_lock); |
1845 | return retval; | 1846 | return retval; |
1846 | } else { | 1847 | } else { |
1847 | dev_err(&u132->platform_dev->dev, "platform_device missing\n"); | 1848 | dev_err(&u132->platform_dev->dev, "platform_device missing\n"); |
@@ -1861,32 +1862,44 @@ static int u132_hcd_reset(struct usb_hcd *hcd) | |||
1861 | return -ESHUTDOWN; | 1862 | return -ESHUTDOWN; |
1862 | } else { | 1863 | } else { |
1863 | int retval; | 1864 | int retval; |
1864 | down(&u132->sw_lock); | 1865 | mutex_lock(&u132->sw_lock); |
1865 | retval = u132_init(u132); | 1866 | retval = u132_init(u132); |
1866 | if (retval) { | 1867 | if (retval) { |
1867 | u132_disable(u132); | 1868 | u132_disable(u132); |
1868 | u132->going = 1; | 1869 | u132->going = 1; |
1869 | } | 1870 | } |
1870 | up(&u132->sw_lock); | 1871 | mutex_unlock(&u132->sw_lock); |
1871 | return retval; | 1872 | return retval; |
1872 | } | 1873 | } |
1873 | } | 1874 | } |
1874 | 1875 | ||
1875 | static int create_endpoint_and_queue_int(struct u132 *u132, | 1876 | static int create_endpoint_and_queue_int(struct u132 *u132, |
1876 | struct u132_udev *udev, struct usb_host_endpoint *hep, struct urb *urb, | 1877 | struct u132_udev *udev, struct urb *urb, |
1877 | struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, u8 address, | 1878 | struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, u8 address, |
1878 | gfp_t mem_flags) | 1879 | gfp_t mem_flags) |
1879 | { | 1880 | { |
1880 | struct u132_ring *ring; | 1881 | struct u132_ring *ring; |
1881 | unsigned long irqs; | 1882 | unsigned long irqs; |
1882 | u8 endp_number = ++u132->num_endpoints; | 1883 | int rc; |
1883 | struct u132_endp *endp = hep->hcpriv = u132->endp[endp_number - 1] = | 1884 | u8 endp_number; |
1884 | kmalloc(sizeof(struct u132_endp), mem_flags); | 1885 | struct u132_endp *endp = kmalloc(sizeof(struct u132_endp), mem_flags); |
1886 | |||
1885 | if (!endp) { | 1887 | if (!endp) { |
1886 | return -ENOMEM; | 1888 | return -ENOMEM; |
1887 | } | 1889 | } |
1890 | |||
1891 | spin_lock_init(&endp->queue_lock.slock); | ||
1892 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | ||
1893 | rc = usb_hcd_link_urb_to_ep(u132_to_hcd(u132), urb); | ||
1894 | if (rc) { | ||
1895 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | ||
1896 | kfree(endp); | ||
1897 | return rc; | ||
1898 | } | ||
1899 | |||
1900 | endp_number = ++u132->num_endpoints; | ||
1901 | urb->ep->hcpriv = u132->endp[endp_number - 1] = endp; | ||
1888 | INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); | 1902 | INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); |
1889 | spin_lock_init(&endp->queue_lock.slock); | ||
1890 | INIT_LIST_HEAD(&endp->urb_more); | 1903 | INIT_LIST_HEAD(&endp->urb_more); |
1891 | ring = endp->ring = &u132->ring[0]; | 1904 | ring = endp->ring = &u132->ring[0]; |
1892 | if (ring->curr_endp) { | 1905 | if (ring->curr_endp) { |
@@ -1902,7 +1915,7 @@ static int create_endpoint_and_queue_int(struct u132 *u132, | |||
1902 | endp->delayed = 0; | 1915 | endp->delayed = 0; |
1903 | endp->endp_number = endp_number; | 1916 | endp->endp_number = endp_number; |
1904 | endp->u132 = u132; | 1917 | endp->u132 = u132; |
1905 | endp->hep = hep; | 1918 | endp->hep = urb->ep; |
1906 | endp->pipetype = usb_pipetype(urb->pipe); | 1919 | endp->pipetype = usb_pipetype(urb->pipe); |
1907 | u132_endp_init_kref(u132, endp); | 1920 | u132_endp_init_kref(u132, endp); |
1908 | if (usb_pipein(urb->pipe)) { | 1921 | if (usb_pipein(urb->pipe)) { |
@@ -1921,7 +1934,6 @@ static int create_endpoint_and_queue_int(struct u132 *u132, | |||
1921 | u132_udev_get_kref(u132, udev); | 1934 | u132_udev_get_kref(u132, udev); |
1922 | } | 1935 | } |
1923 | urb->hcpriv = u132; | 1936 | urb->hcpriv = u132; |
1924 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | ||
1925 | endp->delayed = 1; | 1937 | endp->delayed = 1; |
1926 | endp->jiffies = jiffies + msecs_to_jiffies(urb->interval); | 1938 | endp->jiffies = jiffies + msecs_to_jiffies(urb->interval); |
1927 | endp->udev_number = address; | 1939 | endp->udev_number = address; |
@@ -1936,8 +1948,8 @@ static int create_endpoint_and_queue_int(struct u132 *u132, | |||
1936 | return 0; | 1948 | return 0; |
1937 | } | 1949 | } |
1938 | 1950 | ||
1939 | static int queue_int_on_old_endpoint(struct u132 *u132, struct u132_udev *udev, | 1951 | static int queue_int_on_old_endpoint(struct u132 *u132, |
1940 | struct usb_host_endpoint *hep, struct urb *urb, | 1952 | struct u132_udev *udev, struct urb *urb, |
1941 | struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, | 1953 | struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, |
1942 | u8 usb_endp, u8 address) | 1954 | u8 usb_endp, u8 address) |
1943 | { | 1955 | { |
@@ -1961,21 +1973,33 @@ static int queue_int_on_old_endpoint(struct u132 *u132, struct u132_udev *udev, | |||
1961 | } | 1973 | } |
1962 | 1974 | ||
1963 | static int create_endpoint_and_queue_bulk(struct u132 *u132, | 1975 | static int create_endpoint_and_queue_bulk(struct u132 *u132, |
1964 | struct u132_udev *udev, struct usb_host_endpoint *hep, struct urb *urb, | 1976 | struct u132_udev *udev, struct urb *urb, |
1965 | struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, u8 address, | 1977 | struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, u8 address, |
1966 | gfp_t mem_flags) | 1978 | gfp_t mem_flags) |
1967 | { | 1979 | { |
1968 | int ring_number; | 1980 | int ring_number; |
1969 | struct u132_ring *ring; | 1981 | struct u132_ring *ring; |
1970 | unsigned long irqs; | 1982 | unsigned long irqs; |
1971 | u8 endp_number = ++u132->num_endpoints; | 1983 | int rc; |
1972 | struct u132_endp *endp = hep->hcpriv = u132->endp[endp_number - 1] = | 1984 | u8 endp_number; |
1973 | kmalloc(sizeof(struct u132_endp), mem_flags); | 1985 | struct u132_endp *endp = kmalloc(sizeof(struct u132_endp), mem_flags); |
1986 | |||
1974 | if (!endp) { | 1987 | if (!endp) { |
1975 | return -ENOMEM; | 1988 | return -ENOMEM; |
1976 | } | 1989 | } |
1990 | |||
1991 | spin_lock_init(&endp->queue_lock.slock); | ||
1992 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | ||
1993 | rc = usb_hcd_link_urb_to_ep(u132_to_hcd(u132), urb); | ||
1994 | if (rc) { | ||
1995 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | ||
1996 | kfree(endp); | ||
1997 | return rc; | ||
1998 | } | ||
1999 | |||
2000 | endp_number = ++u132->num_endpoints; | ||
2001 | urb->ep->hcpriv = u132->endp[endp_number - 1] = endp; | ||
1977 | INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); | 2002 | INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); |
1978 | spin_lock_init(&endp->queue_lock.slock); | ||
1979 | INIT_LIST_HEAD(&endp->urb_more); | 2003 | INIT_LIST_HEAD(&endp->urb_more); |
1980 | endp->dequeueing = 0; | 2004 | endp->dequeueing = 0; |
1981 | endp->edset_flush = 0; | 2005 | endp->edset_flush = 0; |
@@ -1983,7 +2007,7 @@ static int create_endpoint_and_queue_bulk(struct u132 *u132, | |||
1983 | endp->delayed = 0; | 2007 | endp->delayed = 0; |
1984 | endp->endp_number = endp_number; | 2008 | endp->endp_number = endp_number; |
1985 | endp->u132 = u132; | 2009 | endp->u132 = u132; |
1986 | endp->hep = hep; | 2010 | endp->hep = urb->ep; |
1987 | endp->pipetype = usb_pipetype(urb->pipe); | 2011 | endp->pipetype = usb_pipetype(urb->pipe); |
1988 | u132_endp_init_kref(u132, endp); | 2012 | u132_endp_init_kref(u132, endp); |
1989 | if (usb_pipein(urb->pipe)) { | 2013 | if (usb_pipein(urb->pipe)) { |
@@ -2012,7 +2036,6 @@ static int create_endpoint_and_queue_bulk(struct u132 *u132, | |||
2012 | } | 2036 | } |
2013 | ring->length += 1; | 2037 | ring->length += 1; |
2014 | urb->hcpriv = u132; | 2038 | urb->hcpriv = u132; |
2015 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | ||
2016 | endp->udev_number = address; | 2039 | endp->udev_number = address; |
2017 | endp->usb_addr = usb_addr; | 2040 | endp->usb_addr = usb_addr; |
2018 | endp->usb_endp = usb_endp; | 2041 | endp->usb_endp = usb_endp; |
@@ -2026,7 +2049,7 @@ static int create_endpoint_and_queue_bulk(struct u132 *u132, | |||
2026 | } | 2049 | } |
2027 | 2050 | ||
2028 | static int queue_bulk_on_old_endpoint(struct u132 *u132, struct u132_udev *udev, | 2051 | static int queue_bulk_on_old_endpoint(struct u132 *u132, struct u132_udev *udev, |
2029 | struct usb_host_endpoint *hep, struct urb *urb, | 2052 | struct urb *urb, |
2030 | struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, | 2053 | struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, |
2031 | u8 usb_endp, u8 address) | 2054 | u8 usb_endp, u8 address) |
2032 | { | 2055 | { |
@@ -2048,19 +2071,32 @@ static int queue_bulk_on_old_endpoint(struct u132 *u132, struct u132_udev *udev, | |||
2048 | } | 2071 | } |
2049 | 2072 | ||
2050 | static int create_endpoint_and_queue_control(struct u132 *u132, | 2073 | static int create_endpoint_and_queue_control(struct u132 *u132, |
2051 | struct usb_host_endpoint *hep, struct urb *urb, | 2074 | struct urb *urb, |
2052 | struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, | 2075 | struct usb_device *usb_dev, u8 usb_addr, u8 usb_endp, |
2053 | gfp_t mem_flags) | 2076 | gfp_t mem_flags) |
2054 | { | 2077 | { |
2055 | struct u132_ring *ring; | 2078 | struct u132_ring *ring; |
2056 | u8 endp_number = ++u132->num_endpoints; | 2079 | unsigned long irqs; |
2057 | struct u132_endp *endp = hep->hcpriv = u132->endp[endp_number - 1] = | 2080 | int rc; |
2058 | kmalloc(sizeof(struct u132_endp), mem_flags); | 2081 | u8 endp_number; |
2082 | struct u132_endp *endp = kmalloc(sizeof(struct u132_endp), mem_flags); | ||
2083 | |||
2059 | if (!endp) { | 2084 | if (!endp) { |
2060 | return -ENOMEM; | 2085 | return -ENOMEM; |
2061 | } | 2086 | } |
2087 | |||
2088 | spin_lock_init(&endp->queue_lock.slock); | ||
2089 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | ||
2090 | rc = usb_hcd_link_urb_to_ep(u132_to_hcd(u132), urb); | ||
2091 | if (rc) { | ||
2092 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | ||
2093 | kfree(endp); | ||
2094 | return rc; | ||
2095 | } | ||
2096 | |||
2097 | endp_number = ++u132->num_endpoints; | ||
2098 | urb->ep->hcpriv = u132->endp[endp_number - 1] = endp; | ||
2062 | INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); | 2099 | INIT_DELAYED_WORK(&endp->scheduler, u132_hcd_endp_work_scheduler); |
2063 | spin_lock_init(&endp->queue_lock.slock); | ||
2064 | INIT_LIST_HEAD(&endp->urb_more); | 2100 | INIT_LIST_HEAD(&endp->urb_more); |
2065 | ring = endp->ring = &u132->ring[0]; | 2101 | ring = endp->ring = &u132->ring[0]; |
2066 | if (ring->curr_endp) { | 2102 | if (ring->curr_endp) { |
@@ -2076,11 +2112,10 @@ static int create_endpoint_and_queue_control(struct u132 *u132, | |||
2076 | endp->delayed = 0; | 2112 | endp->delayed = 0; |
2077 | endp->endp_number = endp_number; | 2113 | endp->endp_number = endp_number; |
2078 | endp->u132 = u132; | 2114 | endp->u132 = u132; |
2079 | endp->hep = hep; | 2115 | endp->hep = urb->ep; |
2080 | u132_endp_init_kref(u132, endp); | 2116 | u132_endp_init_kref(u132, endp); |
2081 | u132_endp_get_kref(u132, endp); | 2117 | u132_endp_get_kref(u132, endp); |
2082 | if (usb_addr == 0) { | 2118 | if (usb_addr == 0) { |
2083 | unsigned long irqs; | ||
2084 | u8 address = u132->addr[usb_addr].address; | 2119 | u8 address = u132->addr[usb_addr].address; |
2085 | struct u132_udev *udev = &u132->udev[address]; | 2120 | struct u132_udev *udev = &u132->udev[address]; |
2086 | endp->udev_number = address; | 2121 | endp->udev_number = address; |
@@ -2094,7 +2129,6 @@ static int create_endpoint_and_queue_control(struct u132 *u132, | |||
2094 | udev->endp_number_in[usb_endp] = endp_number; | 2129 | udev->endp_number_in[usb_endp] = endp_number; |
2095 | udev->endp_number_out[usb_endp] = endp_number; | 2130 | udev->endp_number_out[usb_endp] = endp_number; |
2096 | urb->hcpriv = u132; | 2131 | urb->hcpriv = u132; |
2097 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | ||
2098 | endp->queue_size = 1; | 2132 | endp->queue_size = 1; |
2099 | endp->queue_last = 0; | 2133 | endp->queue_last = 0; |
2100 | endp->queue_next = 0; | 2134 | endp->queue_next = 0; |
@@ -2103,7 +2137,6 @@ static int create_endpoint_and_queue_control(struct u132 *u132, | |||
2103 | u132_endp_queue_work(u132, endp, 0); | 2137 | u132_endp_queue_work(u132, endp, 0); |
2104 | return 0; | 2138 | return 0; |
2105 | } else { /*(usb_addr > 0) */ | 2139 | } else { /*(usb_addr > 0) */ |
2106 | unsigned long irqs; | ||
2107 | u8 address = u132->addr[usb_addr].address; | 2140 | u8 address = u132->addr[usb_addr].address; |
2108 | struct u132_udev *udev = &u132->udev[address]; | 2141 | struct u132_udev *udev = &u132->udev[address]; |
2109 | endp->udev_number = address; | 2142 | endp->udev_number = address; |
@@ -2117,7 +2150,6 @@ static int create_endpoint_and_queue_control(struct u132 *u132, | |||
2117 | udev->endp_number_in[usb_endp] = endp_number; | 2150 | udev->endp_number_in[usb_endp] = endp_number; |
2118 | udev->endp_number_out[usb_endp] = endp_number; | 2151 | udev->endp_number_out[usb_endp] = endp_number; |
2119 | urb->hcpriv = u132; | 2152 | urb->hcpriv = u132; |
2120 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | ||
2121 | endp->queue_size = 1; | 2153 | endp->queue_size = 1; |
2122 | endp->queue_last = 0; | 2154 | endp->queue_last = 0; |
2123 | endp->queue_next = 0; | 2155 | endp->queue_next = 0; |
@@ -2129,7 +2161,7 @@ static int create_endpoint_and_queue_control(struct u132 *u132, | |||
2129 | } | 2161 | } |
2130 | 2162 | ||
2131 | static int queue_control_on_old_endpoint(struct u132 *u132, | 2163 | static int queue_control_on_old_endpoint(struct u132 *u132, |
2132 | struct usb_host_endpoint *hep, struct urb *urb, | 2164 | struct urb *urb, |
2133 | struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, | 2165 | struct usb_device *usb_dev, struct u132_endp *endp, u8 usb_addr, |
2134 | u8 usb_endp) | 2166 | u8 usb_endp) |
2135 | { | 2167 | { |
@@ -2229,8 +2261,8 @@ static int queue_control_on_old_endpoint(struct u132 *u132, | |||
2229 | } | 2261 | } |
2230 | } | 2262 | } |
2231 | 2263 | ||
2232 | static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | 2264 | static int u132_urb_enqueue(struct usb_hcd *hcd, struct urb *urb, |
2233 | struct urb *urb, gfp_t mem_flags) | 2265 | gfp_t mem_flags) |
2234 | { | 2266 | { |
2235 | struct u132 *u132 = hcd_to_u132(hcd); | 2267 | struct u132 *u132 = hcd_to_u132(hcd); |
2236 | if (irqs_disabled()) { | 2268 | if (irqs_disabled()) { |
@@ -2245,8 +2277,8 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | |||
2245 | , u132->going); | 2277 | , u132->going); |
2246 | return -ENODEV; | 2278 | return -ENODEV; |
2247 | } else if (u132->going > 0) { | 2279 | } else if (u132->going > 0) { |
2248 | dev_err(&u132->platform_dev->dev, "device is being removed urb=" | 2280 | dev_err(&u132->platform_dev->dev, "device is being removed " |
2249 | "%p status=%d\n", urb, urb->status); | 2281 | "urb=%p\n", urb); |
2250 | return -ESHUTDOWN; | 2282 | return -ESHUTDOWN; |
2251 | } else { | 2283 | } else { |
2252 | u8 usb_addr = usb_pipedevice(urb->pipe); | 2284 | u8 usb_addr = usb_pipedevice(urb->pipe); |
@@ -2255,16 +2287,24 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | |||
2255 | if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) { | 2287 | if (usb_pipetype(urb->pipe) == PIPE_INTERRUPT) { |
2256 | u8 address = u132->addr[usb_addr].address; | 2288 | u8 address = u132->addr[usb_addr].address; |
2257 | struct u132_udev *udev = &u132->udev[address]; | 2289 | struct u132_udev *udev = &u132->udev[address]; |
2258 | struct u132_endp *endp = hep->hcpriv; | 2290 | struct u132_endp *endp = urb->ep->hcpriv; |
2259 | urb->actual_length = 0; | 2291 | urb->actual_length = 0; |
2260 | if (endp) { | 2292 | if (endp) { |
2261 | unsigned long irqs; | 2293 | unsigned long irqs; |
2262 | int retval; | 2294 | int retval; |
2263 | spin_lock_irqsave(&endp->queue_lock.slock, | 2295 | spin_lock_irqsave(&endp->queue_lock.slock, |
2264 | irqs); | 2296 | irqs); |
2265 | retval = queue_int_on_old_endpoint(u132, udev, | 2297 | retval = usb_hcd_link_urb_to_ep(hcd, urb); |
2266 | hep, urb, usb_dev, endp, usb_addr, | 2298 | if (retval == 0) { |
2267 | usb_endp, address); | 2299 | retval = queue_int_on_old_endpoint( |
2300 | u132, udev, urb, | ||
2301 | usb_dev, endp, | ||
2302 | usb_addr, usb_endp, | ||
2303 | address); | ||
2304 | if (retval) | ||
2305 | usb_hcd_unlink_urb_from_ep( | ||
2306 | hcd, urb); | ||
2307 | } | ||
2268 | spin_unlock_irqrestore(&endp->queue_lock.slock, | 2308 | spin_unlock_irqrestore(&endp->queue_lock.slock, |
2269 | irqs); | 2309 | irqs); |
2270 | if (retval) { | 2310 | if (retval) { |
@@ -2279,8 +2319,8 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | |||
2279 | return -EINVAL; | 2319 | return -EINVAL; |
2280 | } else { /*(endp == NULL) */ | 2320 | } else { /*(endp == NULL) */ |
2281 | return create_endpoint_and_queue_int(u132, udev, | 2321 | return create_endpoint_and_queue_int(u132, udev, |
2282 | hep, urb, usb_dev, usb_addr, usb_endp, | 2322 | urb, usb_dev, usb_addr, |
2283 | address, mem_flags); | 2323 | usb_endp, address, mem_flags); |
2284 | } | 2324 | } |
2285 | } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { | 2325 | } else if (usb_pipetype(urb->pipe) == PIPE_ISOCHRONOUS) { |
2286 | dev_err(&u132->platform_dev->dev, "the hardware does no" | 2326 | dev_err(&u132->platform_dev->dev, "the hardware does no" |
@@ -2289,16 +2329,24 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | |||
2289 | } else if (usb_pipetype(urb->pipe) == PIPE_BULK) { | 2329 | } else if (usb_pipetype(urb->pipe) == PIPE_BULK) { |
2290 | u8 address = u132->addr[usb_addr].address; | 2330 | u8 address = u132->addr[usb_addr].address; |
2291 | struct u132_udev *udev = &u132->udev[address]; | 2331 | struct u132_udev *udev = &u132->udev[address]; |
2292 | struct u132_endp *endp = hep->hcpriv; | 2332 | struct u132_endp *endp = urb->ep->hcpriv; |
2293 | urb->actual_length = 0; | 2333 | urb->actual_length = 0; |
2294 | if (endp) { | 2334 | if (endp) { |
2295 | unsigned long irqs; | 2335 | unsigned long irqs; |
2296 | int retval; | 2336 | int retval; |
2297 | spin_lock_irqsave(&endp->queue_lock.slock, | 2337 | spin_lock_irqsave(&endp->queue_lock.slock, |
2298 | irqs); | 2338 | irqs); |
2299 | retval = queue_bulk_on_old_endpoint(u132, udev, | 2339 | retval = usb_hcd_link_urb_to_ep(hcd, urb); |
2300 | hep, urb, usb_dev, endp, usb_addr, | 2340 | if (retval == 0) { |
2301 | usb_endp, address); | 2341 | retval = queue_bulk_on_old_endpoint( |
2342 | u132, udev, urb, | ||
2343 | usb_dev, endp, | ||
2344 | usb_addr, usb_endp, | ||
2345 | address); | ||
2346 | if (retval) | ||
2347 | usb_hcd_unlink_urb_from_ep( | ||
2348 | hcd, urb); | ||
2349 | } | ||
2302 | spin_unlock_irqrestore(&endp->queue_lock.slock, | 2350 | spin_unlock_irqrestore(&endp->queue_lock.slock, |
2303 | irqs); | 2351 | irqs); |
2304 | if (retval) { | 2352 | if (retval) { |
@@ -2311,10 +2359,10 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | |||
2311 | return -EINVAL; | 2359 | return -EINVAL; |
2312 | } else | 2360 | } else |
2313 | return create_endpoint_and_queue_bulk(u132, | 2361 | return create_endpoint_and_queue_bulk(u132, |
2314 | udev, hep, urb, usb_dev, usb_addr, | 2362 | udev, urb, usb_dev, usb_addr, |
2315 | usb_endp, address, mem_flags); | 2363 | usb_endp, address, mem_flags); |
2316 | } else { | 2364 | } else { |
2317 | struct u132_endp *endp = hep->hcpriv; | 2365 | struct u132_endp *endp = urb->ep->hcpriv; |
2318 | u16 urb_size = 8; | 2366 | u16 urb_size = 8; |
2319 | u8 *b = urb->setup_packet; | 2367 | u8 *b = urb->setup_packet; |
2320 | int i = 0; | 2368 | int i = 0; |
@@ -2337,9 +2385,16 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | |||
2337 | int retval; | 2385 | int retval; |
2338 | spin_lock_irqsave(&endp->queue_lock.slock, | 2386 | spin_lock_irqsave(&endp->queue_lock.slock, |
2339 | irqs); | 2387 | irqs); |
2340 | retval = queue_control_on_old_endpoint(u132, | 2388 | retval = usb_hcd_link_urb_to_ep(hcd, urb); |
2341 | hep, urb, usb_dev, endp, usb_addr, | 2389 | if (retval == 0) { |
2342 | usb_endp); | 2390 | retval = queue_control_on_old_endpoint( |
2391 | u132, urb, usb_dev, | ||
2392 | endp, usb_addr, | ||
2393 | usb_endp); | ||
2394 | if (retval) | ||
2395 | usb_hcd_unlink_urb_from_ep( | ||
2396 | hcd, urb); | ||
2397 | } | ||
2343 | spin_unlock_irqrestore(&endp->queue_lock.slock, | 2398 | spin_unlock_irqrestore(&endp->queue_lock.slock, |
2344 | irqs); | 2399 | irqs); |
2345 | if (retval) { | 2400 | if (retval) { |
@@ -2352,7 +2407,7 @@ static int u132_urb_enqueue(struct usb_hcd *hcd, struct usb_host_endpoint *hep, | |||
2352 | return -EINVAL; | 2407 | return -EINVAL; |
2353 | } else | 2408 | } else |
2354 | return create_endpoint_and_queue_control(u132, | 2409 | return create_endpoint_and_queue_control(u132, |
2355 | hep, urb, usb_dev, usb_addr, usb_endp, | 2410 | urb, usb_dev, usb_addr, usb_endp, |
2356 | mem_flags); | 2411 | mem_flags); |
2357 | } | 2412 | } |
2358 | } | 2413 | } |
@@ -2371,8 +2426,7 @@ static int dequeue_from_overflow_chain(struct u132 *u132, | |||
2371 | list_del(scan); | 2426 | list_del(scan); |
2372 | endp->queue_size -= 1; | 2427 | endp->queue_size -= 1; |
2373 | urb->error_count = 0; | 2428 | urb->error_count = 0; |
2374 | urb->hcpriv = NULL; | 2429 | usb_hcd_giveback_urb(hcd, urb, 0); |
2375 | usb_hcd_giveback_urb(hcd, urb); | ||
2376 | return 0; | 2430 | return 0; |
2377 | } else | 2431 | } else |
2378 | continue; | 2432 | continue; |
@@ -2387,10 +2441,17 @@ static int dequeue_from_overflow_chain(struct u132 *u132, | |||
2387 | } | 2441 | } |
2388 | 2442 | ||
2389 | static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, | 2443 | static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, |
2390 | struct urb *urb) | 2444 | struct urb *urb, int status) |
2391 | { | 2445 | { |
2392 | unsigned long irqs; | 2446 | unsigned long irqs; |
2447 | int rc; | ||
2448 | |||
2393 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); | 2449 | spin_lock_irqsave(&endp->queue_lock.slock, irqs); |
2450 | rc = usb_hcd_check_unlink_urb(u132_to_hcd(u132), urb, status); | ||
2451 | if (rc) { | ||
2452 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | ||
2453 | return rc; | ||
2454 | } | ||
2394 | if (endp->queue_size == 0) { | 2455 | if (endp->queue_size == 0) { |
2395 | dev_err(&u132->platform_dev->dev, "urb=%p not found in endp[%d]" | 2456 | dev_err(&u132->platform_dev->dev, "urb=%p not found in endp[%d]" |
2396 | "=%p ring[%d] %c%c usb_endp=%d usb_addr=%d\n", urb, | 2457 | "=%p ring[%d] %c%c usb_endp=%d usb_addr=%d\n", urb, |
@@ -2406,11 +2467,10 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, | |||
2406 | endp->edset_flush = 1; | 2467 | endp->edset_flush = 1; |
2407 | u132_endp_queue_work(u132, endp, 0); | 2468 | u132_endp_queue_work(u132, endp, 0); |
2408 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | 2469 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); |
2409 | urb->hcpriv = NULL; | ||
2410 | return 0; | 2470 | return 0; |
2411 | } else { | 2471 | } else { |
2412 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | 2472 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); |
2413 | u132_hcd_abandon_urb(u132, endp, urb, urb->status); | 2473 | u132_hcd_abandon_urb(u132, endp, urb, status); |
2414 | return 0; | 2474 | return 0; |
2415 | } | 2475 | } |
2416 | } else { | 2476 | } else { |
@@ -2435,6 +2495,8 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, | |||
2435 | } | 2495 | } |
2436 | if (urb_slot) { | 2496 | if (urb_slot) { |
2437 | struct usb_hcd *hcd = u132_to_hcd(u132); | 2497 | struct usb_hcd *hcd = u132_to_hcd(u132); |
2498 | |||
2499 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
2438 | endp->queue_size -= 1; | 2500 | endp->queue_size -= 1; |
2439 | if (list_empty(&endp->urb_more)) { | 2501 | if (list_empty(&endp->urb_more)) { |
2440 | spin_unlock_irqrestore(&endp->queue_lock.slock, | 2502 | spin_unlock_irqrestore(&endp->queue_lock.slock, |
@@ -2449,8 +2511,7 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, | |||
2449 | irqs); | 2511 | irqs); |
2450 | kfree(urbq); | 2512 | kfree(urbq); |
2451 | } urb->error_count = 0; | 2513 | } urb->error_count = 0; |
2452 | urb->hcpriv = NULL; | 2514 | usb_hcd_giveback_urb(hcd, urb, status); |
2453 | usb_hcd_giveback_urb(hcd, urb); | ||
2454 | return 0; | 2515 | return 0; |
2455 | } else if (list_empty(&endp->urb_more)) { | 2516 | } else if (list_empty(&endp->urb_more)) { |
2456 | dev_err(&u132->platform_dev->dev, "urb=%p not found in " | 2517 | dev_err(&u132->platform_dev->dev, "urb=%p not found in " |
@@ -2464,7 +2525,10 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, | |||
2464 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | 2525 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); |
2465 | return -EINVAL; | 2526 | return -EINVAL; |
2466 | } else { | 2527 | } else { |
2467 | int retval = dequeue_from_overflow_chain(u132, endp, | 2528 | int retval; |
2529 | |||
2530 | usb_hcd_unlink_urb_from_ep(u132_to_hcd(u132), urb); | ||
2531 | retval = dequeue_from_overflow_chain(u132, endp, | ||
2468 | urb); | 2532 | urb); |
2469 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); | 2533 | spin_unlock_irqrestore(&endp->queue_lock.slock, irqs); |
2470 | return retval; | 2534 | return retval; |
@@ -2472,7 +2536,7 @@ static int u132_endp_urb_dequeue(struct u132 *u132, struct u132_endp *endp, | |||
2472 | } | 2536 | } |
2473 | } | 2537 | } |
2474 | 2538 | ||
2475 | static int u132_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | 2539 | static int u132_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) |
2476 | { | 2540 | { |
2477 | struct u132 *u132 = hcd_to_u132(hcd); | 2541 | struct u132 *u132 = hcd_to_u132(hcd); |
2478 | if (u132->going > 2) { | 2542 | if (u132->going > 2) { |
@@ -2487,11 +2551,11 @@ static int u132_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | |||
2487 | if (usb_pipein(urb->pipe)) { | 2551 | if (usb_pipein(urb->pipe)) { |
2488 | u8 endp_number = udev->endp_number_in[usb_endp]; | 2552 | u8 endp_number = udev->endp_number_in[usb_endp]; |
2489 | struct u132_endp *endp = u132->endp[endp_number - 1]; | 2553 | struct u132_endp *endp = u132->endp[endp_number - 1]; |
2490 | return u132_endp_urb_dequeue(u132, endp, urb); | 2554 | return u132_endp_urb_dequeue(u132, endp, urb, status); |
2491 | } else { | 2555 | } else { |
2492 | u8 endp_number = udev->endp_number_out[usb_endp]; | 2556 | u8 endp_number = udev->endp_number_out[usb_endp]; |
2493 | struct u132_endp *endp = u132->endp[endp_number - 1]; | 2557 | struct u132_endp *endp = u132->endp[endp_number - 1]; |
2494 | return u132_endp_urb_dequeue(u132, endp, urb); | 2558 | return u132_endp_urb_dequeue(u132, endp, urb, status); |
2495 | } | 2559 | } |
2496 | } | 2560 | } |
2497 | } | 2561 | } |
@@ -2801,7 +2865,7 @@ static int u132_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
2801 | return -ESHUTDOWN; | 2865 | return -ESHUTDOWN; |
2802 | } else { | 2866 | } else { |
2803 | int retval = 0; | 2867 | int retval = 0; |
2804 | down(&u132->sw_lock); | 2868 | mutex_lock(&u132->sw_lock); |
2805 | switch (typeReq) { | 2869 | switch (typeReq) { |
2806 | case ClearHubFeature: | 2870 | case ClearHubFeature: |
2807 | switch (wValue) { | 2871 | switch (wValue) { |
@@ -2864,7 +2928,7 @@ static int u132_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
2864 | stall:retval = -EPIPE; | 2928 | stall:retval = -EPIPE; |
2865 | break; | 2929 | break; |
2866 | } | 2930 | } |
2867 | up(&u132->sw_lock); | 2931 | mutex_unlock(&u132->sw_lock); |
2868 | return retval; | 2932 | return retval; |
2869 | } | 2933 | } |
2870 | } | 2934 | } |
@@ -3000,7 +3064,7 @@ static int __devexit u132_remove(struct platform_device *pdev) | |||
3000 | dev_err(&u132->platform_dev->dev, "removing device u132" | 3064 | dev_err(&u132->platform_dev->dev, "removing device u132" |
3001 | ".%d\n", u132->sequence_num); | 3065 | ".%d\n", u132->sequence_num); |
3002 | msleep(100); | 3066 | msleep(100); |
3003 | down(&u132->sw_lock); | 3067 | mutex_lock(&u132->sw_lock); |
3004 | u132_monitor_cancel_work(u132); | 3068 | u132_monitor_cancel_work(u132); |
3005 | while (rings-- > 0) { | 3069 | while (rings-- > 0) { |
3006 | struct u132_ring *ring = &u132->ring[rings]; | 3070 | struct u132_ring *ring = &u132->ring[rings]; |
@@ -3013,7 +3077,7 @@ static int __devexit u132_remove(struct platform_device *pdev) | |||
3013 | u132->going += 1; | 3077 | u132->going += 1; |
3014 | printk(KERN_INFO "removing device u132.%d\n", | 3078 | printk(KERN_INFO "removing device u132.%d\n", |
3015 | u132->sequence_num); | 3079 | u132->sequence_num); |
3016 | up(&u132->sw_lock); | 3080 | mutex_unlock(&u132->sw_lock); |
3017 | usb_remove_hcd(hcd); | 3081 | usb_remove_hcd(hcd); |
3018 | u132_u132_put_kref(u132); | 3082 | u132_u132_put_kref(u132); |
3019 | return 0; | 3083 | return 0; |
@@ -3033,7 +3097,7 @@ static void u132_initialise(struct u132 *u132, struct platform_device *pdev) | |||
3033 | u132->platform_dev = pdev; | 3097 | u132->platform_dev = pdev; |
3034 | u132->power = 0; | 3098 | u132->power = 0; |
3035 | u132->reset = 0; | 3099 | u132->reset = 0; |
3036 | init_MUTEX(&u132->sw_lock); | 3100 | mutex_init(&u132->sw_lock); |
3037 | init_MUTEX(&u132->scheduler_lock); | 3101 | init_MUTEX(&u132->scheduler_lock); |
3038 | while (rings-- > 0) { | 3102 | while (rings-- > 0) { |
3039 | struct u132_ring *ring = &u132->ring[rings]; | 3103 | struct u132_ring *ring = &u132->ring[rings]; |
@@ -3043,7 +3107,7 @@ static void u132_initialise(struct u132 *u132, struct platform_device *pdev) | |||
3043 | ring->curr_endp = NULL; | 3107 | ring->curr_endp = NULL; |
3044 | INIT_DELAYED_WORK(&ring->scheduler, | 3108 | INIT_DELAYED_WORK(&ring->scheduler, |
3045 | u132_hcd_ring_work_scheduler); | 3109 | u132_hcd_ring_work_scheduler); |
3046 | } down(&u132->sw_lock); | 3110 | } mutex_lock(&u132->sw_lock); |
3047 | INIT_DELAYED_WORK(&u132->monitor, u132_hcd_monitor_work); | 3111 | INIT_DELAYED_WORK(&u132->monitor, u132_hcd_monitor_work); |
3048 | while (ports-- > 0) { | 3112 | while (ports-- > 0) { |
3049 | struct u132_port *port = &u132->port[ports]; | 3113 | struct u132_port *port = &u132->port[ports]; |
@@ -3073,7 +3137,7 @@ static void u132_initialise(struct u132 *u132, struct platform_device *pdev) | |||
3073 | while (endps-- > 0) { | 3137 | while (endps-- > 0) { |
3074 | u132->endp[endps] = NULL; | 3138 | u132->endp[endps] = NULL; |
3075 | } | 3139 | } |
3076 | up(&u132->sw_lock); | 3140 | mutex_unlock(&u132->sw_lock); |
3077 | return; | 3141 | return; |
3078 | } | 3142 | } |
3079 | 3143 | ||
@@ -3111,10 +3175,10 @@ static int __devinit u132_probe(struct platform_device *pdev) | |||
3111 | int retval = 0; | 3175 | int retval = 0; |
3112 | struct u132 *u132 = hcd_to_u132(hcd); | 3176 | struct u132 *u132 = hcd_to_u132(hcd); |
3113 | hcd->rsrc_start = 0; | 3177 | hcd->rsrc_start = 0; |
3114 | down(&u132_module_lock); | 3178 | mutex_lock(&u132_module_lock); |
3115 | list_add_tail(&u132->u132_list, &u132_static_list); | 3179 | list_add_tail(&u132->u132_list, &u132_static_list); |
3116 | u132->sequence_num = ++u132_instances; | 3180 | u132->sequence_num = ++u132_instances; |
3117 | up(&u132_module_lock); | 3181 | mutex_unlock(&u132_module_lock); |
3118 | u132_u132_init_kref(u132); | 3182 | u132_u132_init_kref(u132); |
3119 | u132_initialise(u132, pdev); | 3183 | u132_initialise(u132, pdev); |
3120 | hcd->product_desc = "ELAN U132 Host Controller"; | 3184 | hcd->product_desc = "ELAN U132 Host Controller"; |
@@ -3216,7 +3280,7 @@ static int __init u132_hcd_init(void) | |||
3216 | INIT_LIST_HEAD(&u132_static_list); | 3280 | INIT_LIST_HEAD(&u132_static_list); |
3217 | u132_instances = 0; | 3281 | u132_instances = 0; |
3218 | u132_exiting = 0; | 3282 | u132_exiting = 0; |
3219 | init_MUTEX(&u132_module_lock); | 3283 | mutex_init(&u132_module_lock); |
3220 | if (usb_disabled()) | 3284 | if (usb_disabled()) |
3221 | return -ENODEV; | 3285 | return -ENODEV; |
3222 | printk(KERN_INFO "driver %s built at %s on %s\n", hcd_name, __TIME__, | 3286 | printk(KERN_INFO "driver %s built at %s on %s\n", hcd_name, __TIME__, |
@@ -3232,9 +3296,9 @@ static void __exit u132_hcd_exit(void) | |||
3232 | { | 3296 | { |
3233 | struct u132 *u132; | 3297 | struct u132 *u132; |
3234 | struct u132 *temp; | 3298 | struct u132 *temp; |
3235 | down(&u132_module_lock); | 3299 | mutex_lock(&u132_module_lock); |
3236 | u132_exiting += 1; | 3300 | u132_exiting += 1; |
3237 | up(&u132_module_lock); | 3301 | mutex_unlock(&u132_module_lock); |
3238 | list_for_each_entry_safe(u132, temp, &u132_static_list, u132_list) { | 3302 | list_for_each_entry_safe(u132, temp, &u132_static_list, u132_list) { |
3239 | platform_device_unregister(u132->platform_dev); | 3303 | platform_device_unregister(u132->platform_dev); |
3240 | } platform_driver_unregister(&u132_platform_driver); | 3304 | } platform_driver_unregister(&u132_platform_driver); |
diff --git a/drivers/usb/host/uhci-debug.c b/drivers/usb/host/uhci-debug.c index 1497371583b..20cc58b9780 100644 --- a/drivers/usb/host/uhci-debug.c +++ b/drivers/usb/host/uhci-debug.c | |||
@@ -120,8 +120,8 @@ static int uhci_show_urbp(struct urb_priv *urbp, char *buf, int len, int space) | |||
120 | out += sprintf(out, "%s%s", ptype, (urbp->fsbr ? " FSBR" : "")); | 120 | out += sprintf(out, "%s%s", ptype, (urbp->fsbr ? " FSBR" : "")); |
121 | out += sprintf(out, " Actlen=%d", urbp->urb->actual_length); | 121 | out += sprintf(out, " Actlen=%d", urbp->urb->actual_length); |
122 | 122 | ||
123 | if (urbp->urb->status != -EINPROGRESS) | 123 | if (urbp->urb->unlinked) |
124 | out += sprintf(out, " Status=%d", urbp->urb->status); | 124 | out += sprintf(out, " Unlinked=%d", urbp->urb->unlinked); |
125 | out += sprintf(out, "\n"); | 125 | out += sprintf(out, "\n"); |
126 | 126 | ||
127 | i = nactive = ninactive = 0; | 127 | i = nactive = ninactive = 0; |
diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 76c555a67da..4db17f75f4f 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c | |||
@@ -237,7 +237,7 @@ static int resume_detect_interrupts_are_broken(struct uhci_hcd *uhci) | |||
237 | static int remote_wakeup_is_broken(struct uhci_hcd *uhci) | 237 | static int remote_wakeup_is_broken(struct uhci_hcd *uhci) |
238 | { | 238 | { |
239 | int port; | 239 | int port; |
240 | char *sys_info; | 240 | const char *sys_info; |
241 | static char bad_Asus_board[] = "A7V8X"; | 241 | static char bad_Asus_board[] = "A7V8X"; |
242 | 242 | ||
243 | /* One of Asus's motherboards has a bug which causes it to | 243 | /* One of Asus's motherboards has a bug which causes it to |
@@ -933,7 +933,7 @@ static int __init uhci_hcd_init(void) | |||
933 | } | 933 | } |
934 | 934 | ||
935 | uhci_up_cachep = kmem_cache_create("uhci_urb_priv", | 935 | uhci_up_cachep = kmem_cache_create("uhci_urb_priv", |
936 | sizeof(struct urb_priv), 0, 0, NULL, NULL); | 936 | sizeof(struct urb_priv), 0, 0, NULL); |
937 | if (!uhci_up_cachep) | 937 | if (!uhci_up_cachep) |
938 | goto up_failed; | 938 | goto up_failed; |
939 | 939 | ||
diff --git a/drivers/usb/host/uhci-hcd.h b/drivers/usb/host/uhci-hcd.h index 1b3d23406ac..340d6ed3e6e 100644 --- a/drivers/usb/host/uhci-hcd.h +++ b/drivers/usb/host/uhci-hcd.h | |||
@@ -146,7 +146,6 @@ struct uhci_qh { | |||
146 | short phase; /* Between 0 and period-1 */ | 146 | short phase; /* Between 0 and period-1 */ |
147 | short load; /* Periodic time requirement, in us */ | 147 | short load; /* Periodic time requirement, in us */ |
148 | unsigned int iso_frame; /* Frame # for iso_packet_desc */ | 148 | unsigned int iso_frame; /* Frame # for iso_packet_desc */ |
149 | int iso_status; /* Status for Isochronous URBs */ | ||
150 | 149 | ||
151 | int state; /* QH_STATE_xxx; see above */ | 150 | int state; /* QH_STATE_xxx; see above */ |
152 | int type; /* Queue type (control, bulk, etc) */ | 151 | int type; /* Queue type (control, bulk, etc) */ |
@@ -457,21 +456,6 @@ struct urb_priv { | |||
457 | }; | 456 | }; |
458 | 457 | ||
459 | 458 | ||
460 | /* | ||
461 | * Locking in uhci.c | ||
462 | * | ||
463 | * Almost everything relating to the hardware schedule and processing | ||
464 | * of URBs is protected by uhci->lock. urb->status is protected by | ||
465 | * urb->lock; that's the one exception. | ||
466 | * | ||
467 | * To prevent deadlocks, never lock uhci->lock while holding urb->lock. | ||
468 | * The safe order of locking is: | ||
469 | * | ||
470 | * #1 uhci->lock | ||
471 | * #2 urb->lock | ||
472 | */ | ||
473 | |||
474 | |||
475 | /* Some special IDs */ | 459 | /* Some special IDs */ |
476 | 460 | ||
477 | #define PCI_VENDOR_ID_GENESYS 0x17a0 | 461 | #define PCI_VENDOR_ID_GENESYS 0x17a0 |
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c index 4aed305982e..e5d60d5b105 100644 --- a/drivers/usb/host/uhci-q.c +++ b/drivers/usb/host/uhci-q.c | |||
@@ -757,7 +757,6 @@ static void uhci_free_urb_priv(struct uhci_hcd *uhci, | |||
757 | uhci_free_td(uhci, td); | 757 | uhci_free_td(uhci, td); |
758 | } | 758 | } |
759 | 759 | ||
760 | urbp->urb->hcpriv = NULL; | ||
761 | kmem_cache_free(uhci_up_cachep, urbp); | 760 | kmem_cache_free(uhci_up_cachep, urbp); |
762 | } | 761 | } |
763 | 762 | ||
@@ -827,8 +826,10 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
827 | * If direction is "send", change the packet ID from SETUP (0x2D) | 826 | * If direction is "send", change the packet ID from SETUP (0x2D) |
828 | * to OUT (0xE1). Else change it from SETUP to IN (0x69) and | 827 | * to OUT (0xE1). Else change it from SETUP to IN (0x69) and |
829 | * set Short Packet Detect (SPD) for all data packets. | 828 | * set Short Packet Detect (SPD) for all data packets. |
829 | * | ||
830 | * 0-length transfers always get treated as "send". | ||
830 | */ | 831 | */ |
831 | if (usb_pipeout(urb->pipe)) | 832 | if (usb_pipeout(urb->pipe) || len == 0) |
832 | destination ^= (USB_PID_SETUP ^ USB_PID_OUT); | 833 | destination ^= (USB_PID_SETUP ^ USB_PID_OUT); |
833 | else { | 834 | else { |
834 | destination ^= (USB_PID_SETUP ^ USB_PID_IN); | 835 | destination ^= (USB_PID_SETUP ^ USB_PID_IN); |
@@ -839,7 +840,12 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
839 | * Build the DATA TDs | 840 | * Build the DATA TDs |
840 | */ | 841 | */ |
841 | while (len > 0) { | 842 | while (len > 0) { |
842 | int pktsze = min(len, maxsze); | 843 | int pktsze = maxsze; |
844 | |||
845 | if (len <= pktsze) { /* The last data packet */ | ||
846 | pktsze = len; | ||
847 | status &= ~TD_CTRL_SPD; | ||
848 | } | ||
843 | 849 | ||
844 | td = uhci_alloc_td(uhci); | 850 | td = uhci_alloc_td(uhci); |
845 | if (!td) | 851 | if (!td) |
@@ -866,20 +872,10 @@ static int uhci_submit_control(struct uhci_hcd *uhci, struct urb *urb, | |||
866 | goto nomem; | 872 | goto nomem; |
867 | *plink = LINK_TO_TD(td); | 873 | *plink = LINK_TO_TD(td); |
868 | 874 | ||
869 | /* | 875 | /* Change direction for the status transaction */ |
870 | * It's IN if the pipe is an output pipe or we're not expecting | 876 | destination ^= (USB_PID_IN ^ USB_PID_OUT); |
871 | * data back. | ||
872 | */ | ||
873 | destination &= ~TD_TOKEN_PID_MASK; | ||
874 | if (usb_pipeout(urb->pipe) || !urb->transfer_buffer_length) | ||
875 | destination |= USB_PID_IN; | ||
876 | else | ||
877 | destination |= USB_PID_OUT; | ||
878 | |||
879 | destination |= TD_TOKEN_TOGGLE; /* End in Data1 */ | 877 | destination |= TD_TOKEN_TOGGLE; /* End in Data1 */ |
880 | 878 | ||
881 | status &= ~TD_CTRL_SPD; | ||
882 | |||
883 | uhci_add_td_to_urbp(td, urbp); | 879 | uhci_add_td_to_urbp(td, urbp); |
884 | uhci_fill_td(td, status | TD_CTRL_IOC, | 880 | uhci_fill_td(td, status | TD_CTRL_IOC, |
885 | destination | uhci_explen(0), 0); | 881 | destination | uhci_explen(0), 0); |
@@ -1185,10 +1181,18 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) | |||
1185 | } | 1181 | } |
1186 | } | 1182 | } |
1187 | 1183 | ||
1184 | /* Did we receive a short packet? */ | ||
1188 | } else if (len < uhci_expected_length(td_token(td))) { | 1185 | } else if (len < uhci_expected_length(td_token(td))) { |
1189 | 1186 | ||
1190 | /* We received a short packet */ | 1187 | /* For control transfers, go to the status TD if |
1191 | if (urb->transfer_flags & URB_SHORT_NOT_OK) | 1188 | * this isn't already the last data TD */ |
1189 | if (qh->type == USB_ENDPOINT_XFER_CONTROL) { | ||
1190 | if (td->list.next != urbp->td_list.prev) | ||
1191 | ret = 1; | ||
1192 | } | ||
1193 | |||
1194 | /* For bulk and interrupt, this may be an error */ | ||
1195 | else if (urb->transfer_flags & URB_SHORT_NOT_OK) | ||
1192 | ret = -EREMOTEIO; | 1196 | ret = -EREMOTEIO; |
1193 | 1197 | ||
1194 | /* Fixup needed only if this isn't the URB's last TD */ | 1198 | /* Fixup needed only if this isn't the URB's last TD */ |
@@ -1208,10 +1212,6 @@ static int uhci_result_common(struct uhci_hcd *uhci, struct urb *urb) | |||
1208 | 1212 | ||
1209 | err: | 1213 | err: |
1210 | if (ret < 0) { | 1214 | if (ret < 0) { |
1211 | /* In case a control transfer gets an error | ||
1212 | * during the setup stage */ | ||
1213 | urb->actual_length = max(urb->actual_length, 0); | ||
1214 | |||
1215 | /* Note that the queue has stopped and save | 1215 | /* Note that the queue has stopped and save |
1216 | * the next toggle value */ | 1216 | * the next toggle value */ |
1217 | qh->element = UHCI_PTR_TERM; | 1217 | qh->element = UHCI_PTR_TERM; |
@@ -1323,7 +1323,6 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb, | |||
1323 | if (list_empty(&qh->queue)) { | 1323 | if (list_empty(&qh->queue)) { |
1324 | qh->iso_packet_desc = &urb->iso_frame_desc[0]; | 1324 | qh->iso_packet_desc = &urb->iso_frame_desc[0]; |
1325 | qh->iso_frame = urb->start_frame; | 1325 | qh->iso_frame = urb->start_frame; |
1326 | qh->iso_status = 0; | ||
1327 | } | 1326 | } |
1328 | 1327 | ||
1329 | qh->skel = SKEL_ISO; | 1328 | qh->skel = SKEL_ISO; |
@@ -1360,22 +1359,18 @@ static int uhci_result_isochronous(struct uhci_hcd *uhci, struct urb *urb) | |||
1360 | qh->iso_packet_desc->actual_length = actlength; | 1359 | qh->iso_packet_desc->actual_length = actlength; |
1361 | qh->iso_packet_desc->status = status; | 1360 | qh->iso_packet_desc->status = status; |
1362 | } | 1361 | } |
1363 | 1362 | if (status) | |
1364 | if (status) { | ||
1365 | urb->error_count++; | 1363 | urb->error_count++; |
1366 | qh->iso_status = status; | ||
1367 | } | ||
1368 | 1364 | ||
1369 | uhci_remove_td_from_urbp(td); | 1365 | uhci_remove_td_from_urbp(td); |
1370 | uhci_free_td(uhci, td); | 1366 | uhci_free_td(uhci, td); |
1371 | qh->iso_frame += qh->period; | 1367 | qh->iso_frame += qh->period; |
1372 | ++qh->iso_packet_desc; | 1368 | ++qh->iso_packet_desc; |
1373 | } | 1369 | } |
1374 | return qh->iso_status; | 1370 | return 0; |
1375 | } | 1371 | } |
1376 | 1372 | ||
1377 | static int uhci_urb_enqueue(struct usb_hcd *hcd, | 1373 | static int uhci_urb_enqueue(struct usb_hcd *hcd, |
1378 | struct usb_host_endpoint *hep, | ||
1379 | struct urb *urb, gfp_t mem_flags) | 1374 | struct urb *urb, gfp_t mem_flags) |
1380 | { | 1375 | { |
1381 | int ret; | 1376 | int ret; |
@@ -1386,19 +1381,19 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd, | |||
1386 | 1381 | ||
1387 | spin_lock_irqsave(&uhci->lock, flags); | 1382 | spin_lock_irqsave(&uhci->lock, flags); |
1388 | 1383 | ||
1389 | ret = urb->status; | 1384 | ret = usb_hcd_link_urb_to_ep(hcd, urb); |
1390 | if (ret != -EINPROGRESS) /* URB already unlinked! */ | 1385 | if (ret) |
1391 | goto done; | 1386 | goto done_not_linked; |
1392 | 1387 | ||
1393 | ret = -ENOMEM; | 1388 | ret = -ENOMEM; |
1394 | urbp = uhci_alloc_urb_priv(uhci, urb); | 1389 | urbp = uhci_alloc_urb_priv(uhci, urb); |
1395 | if (!urbp) | 1390 | if (!urbp) |
1396 | goto done; | 1391 | goto done; |
1397 | 1392 | ||
1398 | if (hep->hcpriv) | 1393 | if (urb->ep->hcpriv) |
1399 | qh = (struct uhci_qh *) hep->hcpriv; | 1394 | qh = urb->ep->hcpriv; |
1400 | else { | 1395 | else { |
1401 | qh = uhci_alloc_qh(uhci, urb->dev, hep); | 1396 | qh = uhci_alloc_qh(uhci, urb->dev, urb->ep); |
1402 | if (!qh) | 1397 | if (!qh) |
1403 | goto err_no_qh; | 1398 | goto err_no_qh; |
1404 | } | 1399 | } |
@@ -1439,27 +1434,29 @@ static int uhci_urb_enqueue(struct usb_hcd *hcd, | |||
1439 | err_submit_failed: | 1434 | err_submit_failed: |
1440 | if (qh->state == QH_STATE_IDLE) | 1435 | if (qh->state == QH_STATE_IDLE) |
1441 | uhci_make_qh_idle(uhci, qh); /* Reclaim unused QH */ | 1436 | uhci_make_qh_idle(uhci, qh); /* Reclaim unused QH */ |
1442 | |||
1443 | err_no_qh: | 1437 | err_no_qh: |
1444 | uhci_free_urb_priv(uhci, urbp); | 1438 | uhci_free_urb_priv(uhci, urbp); |
1445 | |||
1446 | done: | 1439 | done: |
1440 | if (ret) | ||
1441 | usb_hcd_unlink_urb_from_ep(hcd, urb); | ||
1442 | done_not_linked: | ||
1447 | spin_unlock_irqrestore(&uhci->lock, flags); | 1443 | spin_unlock_irqrestore(&uhci->lock, flags); |
1448 | return ret; | 1444 | return ret; |
1449 | } | 1445 | } |
1450 | 1446 | ||
1451 | static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | 1447 | static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) |
1452 | { | 1448 | { |
1453 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); | 1449 | struct uhci_hcd *uhci = hcd_to_uhci(hcd); |
1454 | unsigned long flags; | 1450 | unsigned long flags; |
1455 | struct urb_priv *urbp; | ||
1456 | struct uhci_qh *qh; | 1451 | struct uhci_qh *qh; |
1452 | int rc; | ||
1457 | 1453 | ||
1458 | spin_lock_irqsave(&uhci->lock, flags); | 1454 | spin_lock_irqsave(&uhci->lock, flags); |
1459 | urbp = urb->hcpriv; | 1455 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); |
1460 | if (!urbp) /* URB was never linked! */ | 1456 | if (rc) |
1461 | goto done; | 1457 | goto done; |
1462 | qh = urbp->qh; | 1458 | |
1459 | qh = ((struct urb_priv *) urb->hcpriv)->qh; | ||
1463 | 1460 | ||
1464 | /* Remove Isochronous TDs from the frame list ASAP */ | 1461 | /* Remove Isochronous TDs from the frame list ASAP */ |
1465 | if (qh->type == USB_ENDPOINT_XFER_ISOC) { | 1462 | if (qh->type == USB_ENDPOINT_XFER_ISOC) { |
@@ -1476,22 +1473,31 @@ static int uhci_urb_dequeue(struct usb_hcd *hcd, struct urb *urb) | |||
1476 | 1473 | ||
1477 | done: | 1474 | done: |
1478 | spin_unlock_irqrestore(&uhci->lock, flags); | 1475 | spin_unlock_irqrestore(&uhci->lock, flags); |
1479 | return 0; | 1476 | return rc; |
1480 | } | 1477 | } |
1481 | 1478 | ||
1482 | /* | 1479 | /* |
1483 | * Finish unlinking an URB and give it back | 1480 | * Finish unlinking an URB and give it back |
1484 | */ | 1481 | */ |
1485 | static void uhci_giveback_urb(struct uhci_hcd *uhci, struct uhci_qh *qh, | 1482 | static void uhci_giveback_urb(struct uhci_hcd *uhci, struct uhci_qh *qh, |
1486 | struct urb *urb) | 1483 | struct urb *urb, int status) |
1487 | __releases(uhci->lock) | 1484 | __releases(uhci->lock) |
1488 | __acquires(uhci->lock) | 1485 | __acquires(uhci->lock) |
1489 | { | 1486 | { |
1490 | struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; | 1487 | struct urb_priv *urbp = (struct urb_priv *) urb->hcpriv; |
1491 | 1488 | ||
1489 | if (qh->type == USB_ENDPOINT_XFER_CONTROL) { | ||
1490 | |||
1491 | /* urb->actual_length < 0 means the setup transaction didn't | ||
1492 | * complete successfully. Either it failed or the URB was | ||
1493 | * unlinked first. Regardless, don't confuse people with a | ||
1494 | * negative length. */ | ||
1495 | urb->actual_length = max(urb->actual_length, 0); | ||
1496 | } | ||
1497 | |||
1492 | /* When giving back the first URB in an Isochronous queue, | 1498 | /* When giving back the first URB in an Isochronous queue, |
1493 | * reinitialize the QH's iso-related members for the next URB. */ | 1499 | * reinitialize the QH's iso-related members for the next URB. */ |
1494 | if (qh->type == USB_ENDPOINT_XFER_ISOC && | 1500 | else if (qh->type == USB_ENDPOINT_XFER_ISOC && |
1495 | urbp->node.prev == &qh->queue && | 1501 | urbp->node.prev == &qh->queue && |
1496 | urbp->node.next != &qh->queue) { | 1502 | urbp->node.next != &qh->queue) { |
1497 | struct urb *nurb = list_entry(urbp->node.next, | 1503 | struct urb *nurb = list_entry(urbp->node.next, |
@@ -1499,7 +1505,6 @@ __acquires(uhci->lock) | |||
1499 | 1505 | ||
1500 | qh->iso_packet_desc = &nurb->iso_frame_desc[0]; | 1506 | qh->iso_packet_desc = &nurb->iso_frame_desc[0]; |
1501 | qh->iso_frame = nurb->start_frame; | 1507 | qh->iso_frame = nurb->start_frame; |
1502 | qh->iso_status = 0; | ||
1503 | } | 1508 | } |
1504 | 1509 | ||
1505 | /* Take the URB off the QH's queue. If the queue is now empty, | 1510 | /* Take the URB off the QH's queue. If the queue is now empty, |
@@ -1512,9 +1517,10 @@ __acquires(uhci->lock) | |||
1512 | } | 1517 | } |
1513 | 1518 | ||
1514 | uhci_free_urb_priv(uhci, urbp); | 1519 | uhci_free_urb_priv(uhci, urbp); |
1520 | usb_hcd_unlink_urb_from_ep(uhci_to_hcd(uhci), urb); | ||
1515 | 1521 | ||
1516 | spin_unlock(&uhci->lock); | 1522 | spin_unlock(&uhci->lock); |
1517 | usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb); | 1523 | usb_hcd_giveback_urb(uhci_to_hcd(uhci), urb, status); |
1518 | spin_lock(&uhci->lock); | 1524 | spin_lock(&uhci->lock); |
1519 | 1525 | ||
1520 | /* If the queue is now empty, we can unlink the QH and give up its | 1526 | /* If the queue is now empty, we can unlink the QH and give up its |
@@ -1550,24 +1556,17 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
1550 | if (status == -EINPROGRESS) | 1556 | if (status == -EINPROGRESS) |
1551 | break; | 1557 | break; |
1552 | 1558 | ||
1553 | spin_lock(&urb->lock); | ||
1554 | if (urb->status == -EINPROGRESS) /* Not dequeued */ | ||
1555 | urb->status = status; | ||
1556 | else | ||
1557 | status = ECONNRESET; /* Not -ECONNRESET */ | ||
1558 | spin_unlock(&urb->lock); | ||
1559 | |||
1560 | /* Dequeued but completed URBs can't be given back unless | 1559 | /* Dequeued but completed URBs can't be given back unless |
1561 | * the QH is stopped or has finished unlinking. */ | 1560 | * the QH is stopped or has finished unlinking. */ |
1562 | if (status == ECONNRESET) { | 1561 | if (urb->unlinked) { |
1563 | if (QH_FINISHED_UNLINKING(qh)) | 1562 | if (QH_FINISHED_UNLINKING(qh)) |
1564 | qh->is_stopped = 1; | 1563 | qh->is_stopped = 1; |
1565 | else if (!qh->is_stopped) | 1564 | else if (!qh->is_stopped) |
1566 | return; | 1565 | return; |
1567 | } | 1566 | } |
1568 | 1567 | ||
1569 | uhci_giveback_urb(uhci, qh, urb); | 1568 | uhci_giveback_urb(uhci, qh, urb, status); |
1570 | if (status < 0 && qh->type != USB_ENDPOINT_XFER_ISOC) | 1569 | if (status < 0) |
1571 | break; | 1570 | break; |
1572 | } | 1571 | } |
1573 | 1572 | ||
@@ -1582,7 +1581,7 @@ static void uhci_scan_qh(struct uhci_hcd *uhci, struct uhci_qh *qh) | |||
1582 | restart: | 1581 | restart: |
1583 | list_for_each_entry(urbp, &qh->queue, node) { | 1582 | list_for_each_entry(urbp, &qh->queue, node) { |
1584 | urb = urbp->urb; | 1583 | urb = urbp->urb; |
1585 | if (urb->status != -EINPROGRESS) { | 1584 | if (urb->unlinked) { |
1586 | 1585 | ||
1587 | /* Fix up the TD links and save the toggles for | 1586 | /* Fix up the TD links and save the toggles for |
1588 | * non-Isochronous queues. For Isochronous queues, | 1587 | * non-Isochronous queues. For Isochronous queues, |
@@ -1591,7 +1590,7 @@ restart: | |||
1591 | qh->is_stopped = 0; | 1590 | qh->is_stopped = 0; |
1592 | return; | 1591 | return; |
1593 | } | 1592 | } |
1594 | uhci_giveback_urb(uhci, qh, urb); | 1593 | uhci_giveback_urb(uhci, qh, urb, 0); |
1595 | goto restart; | 1594 | goto restart; |
1596 | } | 1595 | } |
1597 | } | 1596 | } |
diff --git a/drivers/usb/image/mdc800.c b/drivers/usb/image/mdc800.c index 36502a06f73..d1131a87a5b 100644 --- a/drivers/usb/image/mdc800.c +++ b/drivers/usb/image/mdc800.c | |||
@@ -284,9 +284,9 @@ static void mdc800_usb_irq (struct urb *urb) | |||
284 | int data_received=0, wake_up; | 284 | int data_received=0, wake_up; |
285 | unsigned char* b=urb->transfer_buffer; | 285 | unsigned char* b=urb->transfer_buffer; |
286 | struct mdc800_data* mdc800=urb->context; | 286 | struct mdc800_data* mdc800=urb->context; |
287 | int status = urb->status; | ||
287 | 288 | ||
288 | if (urb->status >= 0) | 289 | if (status >= 0) { |
289 | { | ||
290 | 290 | ||
291 | //dbg ("%i %i %i %i %i %i %i %i \n",b[0],b[1],b[2],b[3],b[4],b[5],b[6],b[7]); | 291 | //dbg ("%i %i %i %i %i %i %i %i \n",b[0],b[1],b[2],b[3],b[4],b[5],b[6],b[7]); |
292 | 292 | ||
@@ -324,7 +324,7 @@ static void mdc800_usb_irq (struct urb *urb) | |||
324 | || | 324 | || |
325 | ((mdc800->camera_request_ready == 3) && (mdc800->camera_busy)) | 325 | ((mdc800->camera_request_ready == 3) && (mdc800->camera_busy)) |
326 | || | 326 | || |
327 | (urb->status < 0) | 327 | (status < 0) |
328 | ); | 328 | ); |
329 | 329 | ||
330 | if (wake_up) | 330 | if (wake_up) |
@@ -376,15 +376,12 @@ static int mdc800_usb_waitForIRQ (int mode, int msec) | |||
376 | static void mdc800_usb_write_notify (struct urb *urb) | 376 | static void mdc800_usb_write_notify (struct urb *urb) |
377 | { | 377 | { |
378 | struct mdc800_data* mdc800=urb->context; | 378 | struct mdc800_data* mdc800=urb->context; |
379 | int status = urb->status; | ||
379 | 380 | ||
380 | if (urb->status != 0) | 381 | if (status != 0) |
381 | { | 382 | err ("writing command fails (status=%i)", status); |
382 | err ("writing command fails (status=%i)", urb->status); | ||
383 | } | ||
384 | else | 383 | else |
385 | { | ||
386 | mdc800->state=READY; | 384 | mdc800->state=READY; |
387 | } | ||
388 | mdc800->written = 1; | 385 | mdc800->written = 1; |
389 | wake_up (&mdc800->write_wait); | 386 | wake_up (&mdc800->write_wait); |
390 | } | 387 | } |
@@ -396,9 +393,9 @@ static void mdc800_usb_write_notify (struct urb *urb) | |||
396 | static void mdc800_usb_download_notify (struct urb *urb) | 393 | static void mdc800_usb_download_notify (struct urb *urb) |
397 | { | 394 | { |
398 | struct mdc800_data* mdc800=urb->context; | 395 | struct mdc800_data* mdc800=urb->context; |
396 | int status = urb->status; | ||
399 | 397 | ||
400 | if (urb->status == 0) | 398 | if (status == 0) { |
401 | { | ||
402 | /* Fill output buffer with these data */ | 399 | /* Fill output buffer with these data */ |
403 | memcpy (mdc800->out, urb->transfer_buffer, 64); | 400 | memcpy (mdc800->out, urb->transfer_buffer, 64); |
404 | mdc800->out_count=64; | 401 | mdc800->out_count=64; |
@@ -408,10 +405,8 @@ static void mdc800_usb_download_notify (struct urb *urb) | |||
408 | { | 405 | { |
409 | mdc800->state=READY; | 406 | mdc800->state=READY; |
410 | } | 407 | } |
411 | } | 408 | } else { |
412 | else | 409 | err ("request bytes fails (status:%i)", status); |
413 | { | ||
414 | err ("request bytes fails (status:%i)", urb->status); | ||
415 | } | 410 | } |
416 | mdc800->downloaded = 1; | 411 | mdc800->downloaded = 1; |
417 | wake_up (&mdc800->download_wait); | 412 | wake_up (&mdc800->download_wait); |
@@ -649,9 +644,9 @@ static int mdc800_device_open (struct inode* inode, struct file *file) | |||
649 | 644 | ||
650 | retval=0; | 645 | retval=0; |
651 | mdc800->irq_urb->dev = mdc800->dev; | 646 | mdc800->irq_urb->dev = mdc800->dev; |
652 | if (usb_submit_urb (mdc800->irq_urb, GFP_KERNEL)) | 647 | retval = usb_submit_urb (mdc800->irq_urb, GFP_KERNEL); |
653 | { | 648 | if (retval) { |
654 | err ("request USB irq fails (submit_retval=%i urb_status=%i).",retval, mdc800->irq_urb->status); | 649 | err ("request USB irq fails (submit_retval=%i).", retval); |
655 | errn = -EIO; | 650 | errn = -EIO; |
656 | goto error_out; | 651 | goto error_out; |
657 | } | 652 | } |
@@ -698,6 +693,7 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l | |||
698 | { | 693 | { |
699 | size_t left=len, sts=len; /* single transfer size */ | 694 | size_t left=len, sts=len; /* single transfer size */ |
700 | char __user *ptr = buf; | 695 | char __user *ptr = buf; |
696 | int retval; | ||
701 | 697 | ||
702 | mutex_lock(&mdc800->io_lock); | 698 | mutex_lock(&mdc800->io_lock); |
703 | if (mdc800->state == NOT_CONNECTED) | 699 | if (mdc800->state == NOT_CONNECTED) |
@@ -737,9 +733,9 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l | |||
737 | 733 | ||
738 | /* Download -> Request new bytes */ | 734 | /* Download -> Request new bytes */ |
739 | mdc800->download_urb->dev = mdc800->dev; | 735 | mdc800->download_urb->dev = mdc800->dev; |
740 | if (usb_submit_urb (mdc800->download_urb, GFP_KERNEL)) | 736 | retval = usb_submit_urb (mdc800->download_urb, GFP_KERNEL); |
741 | { | 737 | if (retval) { |
742 | err ("Can't submit download urb (status=%i)",mdc800->download_urb->status); | 738 | err ("Can't submit download urb (retval=%i)",retval); |
743 | mutex_unlock(&mdc800->io_lock); | 739 | mutex_unlock(&mdc800->io_lock); |
744 | return len-left; | 740 | return len-left; |
745 | } | 741 | } |
@@ -788,6 +784,7 @@ static ssize_t mdc800_device_read (struct file *file, char __user *buf, size_t l | |||
788 | static ssize_t mdc800_device_write (struct file *file, const char __user *buf, size_t len, loff_t *pos) | 784 | static ssize_t mdc800_device_write (struct file *file, const char __user *buf, size_t len, loff_t *pos) |
789 | { | 785 | { |
790 | size_t i=0; | 786 | size_t i=0; |
787 | int retval; | ||
791 | 788 | ||
792 | mutex_lock(&mdc800->io_lock); | 789 | mutex_lock(&mdc800->io_lock); |
793 | if (mdc800->state != READY) | 790 | if (mdc800->state != READY) |
@@ -854,9 +851,9 @@ static ssize_t mdc800_device_write (struct file *file, const char __user *buf, s | |||
854 | mdc800->state=WORKING; | 851 | mdc800->state=WORKING; |
855 | memcpy (mdc800->write_urb->transfer_buffer, mdc800->in,8); | 852 | memcpy (mdc800->write_urb->transfer_buffer, mdc800->in,8); |
856 | mdc800->write_urb->dev = mdc800->dev; | 853 | mdc800->write_urb->dev = mdc800->dev; |
857 | if (usb_submit_urb (mdc800->write_urb, GFP_KERNEL)) | 854 | retval = usb_submit_urb (mdc800->write_urb, GFP_KERNEL); |
858 | { | 855 | if (retval) { |
859 | err ("submitting write urb fails (status=%i)", mdc800->write_urb->status); | 856 | err ("submitting write urb fails (retval=%i)", retval); |
860 | mutex_unlock(&mdc800->io_lock); | 857 | mutex_unlock(&mdc800->io_lock); |
861 | return -EIO; | 858 | return -EIO; |
862 | } | 859 | } |
diff --git a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c index 51bd80d2b8c..768b2c11a23 100644 --- a/drivers/usb/image/microtek.c +++ b/drivers/usb/image/microtek.c | |||
@@ -189,7 +189,7 @@ static struct usb_driver mts_usb_driver = { | |||
189 | #define MTS_DEBUG_INT() \ | 189 | #define MTS_DEBUG_INT() \ |
190 | do { MTS_DEBUG_GOT_HERE(); \ | 190 | do { MTS_DEBUG_GOT_HERE(); \ |
191 | MTS_DEBUG("transfer = 0x%x context = 0x%x\n",(int)transfer,(int)context ); \ | 191 | MTS_DEBUG("transfer = 0x%x context = 0x%x\n",(int)transfer,(int)context ); \ |
192 | MTS_DEBUG("status = 0x%x data-length = 0x%x sent = 0x%x\n",(int)transfer->status,(int)context->data_length, (int)transfer->actual_length ); \ | 192 | MTS_DEBUG("status = 0x%x data-length = 0x%x sent = 0x%x\n",transfer->status,(int)context->data_length, (int)transfer->actual_length ); \ |
193 | mts_debug_dump(context->instance);\ | 193 | mts_debug_dump(context->instance);\ |
194 | } while(0) | 194 | } while(0) |
195 | #else | 195 | #else |
@@ -393,8 +393,6 @@ void mts_int_submit_urb (struct urb* transfer, | |||
393 | context | 393 | context |
394 | ); | 394 | ); |
395 | 395 | ||
396 | transfer->status = 0; | ||
397 | |||
398 | res = usb_submit_urb( transfer, GFP_ATOMIC ); | 396 | res = usb_submit_urb( transfer, GFP_ATOMIC ); |
399 | if ( unlikely(res) ) { | 397 | if ( unlikely(res) ) { |
400 | MTS_INT_ERROR( "could not submit URB! Error was %d\n",(int)res ); | 398 | MTS_INT_ERROR( "could not submit URB! Error was %d\n",(int)res ); |
@@ -444,12 +442,13 @@ static void mts_get_status( struct urb *transfer ) | |||
444 | static void mts_data_done( struct urb* transfer ) | 442 | static void mts_data_done( struct urb* transfer ) |
445 | /* Interrupt context! */ | 443 | /* Interrupt context! */ |
446 | { | 444 | { |
445 | int status = transfer->status; | ||
447 | MTS_INT_INIT(); | 446 | MTS_INT_INIT(); |
448 | 447 | ||
449 | if ( context->data_length != transfer->actual_length ) { | 448 | if ( context->data_length != transfer->actual_length ) { |
450 | context->srb->resid = context->data_length - transfer->actual_length; | 449 | context->srb->resid = context->data_length - transfer->actual_length; |
451 | } else if ( unlikely(transfer->status) ) { | 450 | } else if ( unlikely(status) ) { |
452 | context->srb->result = (transfer->status == -ENOENT ? DID_ABORT : DID_ERROR)<<16; | 451 | context->srb->result = (status == -ENOENT ? DID_ABORT : DID_ERROR)<<16; |
453 | } | 452 | } |
454 | 453 | ||
455 | mts_get_status(transfer); | 454 | mts_get_status(transfer); |
@@ -461,10 +460,11 @@ static void mts_data_done( struct urb* transfer ) | |||
461 | static void mts_command_done( struct urb *transfer ) | 460 | static void mts_command_done( struct urb *transfer ) |
462 | /* Interrupt context! */ | 461 | /* Interrupt context! */ |
463 | { | 462 | { |
463 | int status = transfer->status; | ||
464 | MTS_INT_INIT(); | 464 | MTS_INT_INIT(); |
465 | 465 | ||
466 | if ( unlikely(transfer->status) ) { | 466 | if ( unlikely(status) ) { |
467 | if (transfer->status == -ENOENT) { | 467 | if (status == -ENOENT) { |
468 | /* We are being killed */ | 468 | /* We are being killed */ |
469 | MTS_DEBUG_GOT_HERE(); | 469 | MTS_DEBUG_GOT_HERE(); |
470 | context->srb->result = DID_ABORT<<16; | 470 | context->srb->result = DID_ABORT<<16; |
@@ -502,12 +502,13 @@ static void mts_command_done( struct urb *transfer ) | |||
502 | static void mts_do_sg (struct urb* transfer) | 502 | static void mts_do_sg (struct urb* transfer) |
503 | { | 503 | { |
504 | struct scatterlist * sg; | 504 | struct scatterlist * sg; |
505 | int status = transfer->status; | ||
505 | MTS_INT_INIT(); | 506 | MTS_INT_INIT(); |
506 | 507 | ||
507 | MTS_DEBUG("Processing fragment %d of %d\n", context->fragment,context->srb->use_sg); | 508 | MTS_DEBUG("Processing fragment %d of %d\n", context->fragment,context->srb->use_sg); |
508 | 509 | ||
509 | if (unlikely(transfer->status)) { | 510 | if (unlikely(status)) { |
510 | context->srb->result = (transfer->status == -ENOENT ? DID_ABORT : DID_ERROR)<<16; | 511 | context->srb->result = (status == -ENOENT ? DID_ABORT : DID_ERROR)<<16; |
511 | mts_transfer_cleanup(transfer); | 512 | mts_transfer_cleanup(transfer); |
512 | } | 513 | } |
513 | 514 | ||
diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index d72c42e5f22..5131cbfb2f5 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <linux/usb.h> | 26 | #include <linux/usb.h> |
27 | #include <linux/mutex.h> | ||
27 | #include <asm/uaccess.h> | 28 | #include <asm/uaccess.h> |
28 | 29 | ||
29 | #ifdef CONFIG_USB_DEBUG | 30 | #ifdef CONFIG_USB_DEBUG |
@@ -80,7 +81,7 @@ MODULE_DEVICE_TABLE(usb, device_table); | |||
80 | 81 | ||
81 | /* Structure to hold all of our device specific stuff */ | 82 | /* Structure to hold all of our device specific stuff */ |
82 | struct adu_device { | 83 | struct adu_device { |
83 | struct semaphore sem; /* locks this structure */ | 84 | struct mutex mtx; /* locks this structure */ |
84 | struct usb_device* udev; /* save off the usb device pointer */ | 85 | struct usb_device* udev; /* save off the usb device pointer */ |
85 | struct usb_interface* interface; | 86 | struct usb_interface* interface; |
86 | unsigned char minor; /* the starting minor number for this device */ | 87 | unsigned char minor; /* the starting minor number for this device */ |
@@ -178,17 +179,19 @@ static void adu_delete(struct adu_device *dev) | |||
178 | static void adu_interrupt_in_callback(struct urb *urb) | 179 | static void adu_interrupt_in_callback(struct urb *urb) |
179 | { | 180 | { |
180 | struct adu_device *dev = urb->context; | 181 | struct adu_device *dev = urb->context; |
182 | int status = urb->status; | ||
181 | 183 | ||
182 | dbg(4," %s : enter, status %d", __FUNCTION__, urb->status); | 184 | dbg(4," %s : enter, status %d", __FUNCTION__, status); |
183 | adu_debug_data(5, __FUNCTION__, urb->actual_length, | 185 | adu_debug_data(5, __FUNCTION__, urb->actual_length, |
184 | urb->transfer_buffer); | 186 | urb->transfer_buffer); |
185 | 187 | ||
186 | spin_lock(&dev->buflock); | 188 | spin_lock(&dev->buflock); |
187 | 189 | ||
188 | if (urb->status != 0) { | 190 | if (status != 0) { |
189 | if ((urb->status != -ENOENT) && (urb->status != -ECONNRESET)) { | 191 | if ((status != -ENOENT) && (status != -ECONNRESET) && |
192 | (status != -ESHUTDOWN)) { | ||
190 | dbg(1," %s : nonzero status received: %d", | 193 | dbg(1," %s : nonzero status received: %d", |
191 | __FUNCTION__, urb->status); | 194 | __FUNCTION__, status); |
192 | } | 195 | } |
193 | goto exit; | 196 | goto exit; |
194 | } | 197 | } |
@@ -216,21 +219,22 @@ exit: | |||
216 | wake_up_interruptible(&dev->read_wait); | 219 | wake_up_interruptible(&dev->read_wait); |
217 | adu_debug_data(5, __FUNCTION__, urb->actual_length, | 220 | adu_debug_data(5, __FUNCTION__, urb->actual_length, |
218 | urb->transfer_buffer); | 221 | urb->transfer_buffer); |
219 | dbg(4," %s : leave, status %d", __FUNCTION__, urb->status); | 222 | dbg(4," %s : leave, status %d", __FUNCTION__, status); |
220 | } | 223 | } |
221 | 224 | ||
222 | static void adu_interrupt_out_callback(struct urb *urb) | 225 | static void adu_interrupt_out_callback(struct urb *urb) |
223 | { | 226 | { |
224 | struct adu_device *dev = urb->context; | 227 | struct adu_device *dev = urb->context; |
228 | int status = urb->status; | ||
225 | 229 | ||
226 | dbg(4," %s : enter, status %d", __FUNCTION__, urb->status); | 230 | dbg(4," %s : enter, status %d", __FUNCTION__, status); |
227 | adu_debug_data(5,__FUNCTION__, urb->actual_length, urb->transfer_buffer); | 231 | adu_debug_data(5,__FUNCTION__, urb->actual_length, urb->transfer_buffer); |
228 | 232 | ||
229 | if (urb->status != 0) { | 233 | if (status != 0) { |
230 | if ((urb->status != -ENOENT) && | 234 | if ((status != -ENOENT) && |
231 | (urb->status != -ECONNRESET)) { | 235 | (status != -ECONNRESET)) { |
232 | dbg(1, " %s :nonzero status received: %d", | 236 | dbg(1, " %s :nonzero status received: %d", |
233 | __FUNCTION__, urb->status); | 237 | __FUNCTION__, status); |
234 | } | 238 | } |
235 | goto exit; | 239 | goto exit; |
236 | } | 240 | } |
@@ -240,7 +244,7 @@ exit: | |||
240 | 244 | ||
241 | adu_debug_data(5, __FUNCTION__, urb->actual_length, | 245 | adu_debug_data(5, __FUNCTION__, urb->actual_length, |
242 | urb->transfer_buffer); | 246 | urb->transfer_buffer); |
243 | dbg(4," %s : leave, status %d", __FUNCTION__, urb->status); | 247 | dbg(4," %s : leave, status %d", __FUNCTION__, status); |
244 | } | 248 | } |
245 | 249 | ||
246 | static int adu_open(struct inode *inode, struct file *file) | 250 | static int adu_open(struct inode *inode, struct file *file) |
@@ -269,8 +273,8 @@ static int adu_open(struct inode *inode, struct file *file) | |||
269 | } | 273 | } |
270 | 274 | ||
271 | /* lock this device */ | 275 | /* lock this device */ |
272 | if ((retval = down_interruptible(&dev->sem))) { | 276 | if ((retval = mutex_lock_interruptible(&dev->mtx))) { |
273 | dbg(2, "%s : sem down failed", __FUNCTION__); | 277 | dbg(2, "%s : mutex lock failed", __FUNCTION__); |
274 | goto exit_no_device; | 278 | goto exit_no_device; |
275 | } | 279 | } |
276 | 280 | ||
@@ -299,7 +303,7 @@ static int adu_open(struct inode *inode, struct file *file) | |||
299 | if (retval) | 303 | if (retval) |
300 | --dev->open_count; | 304 | --dev->open_count; |
301 | } | 305 | } |
302 | up(&dev->sem); | 306 | mutex_unlock(&dev->mtx); |
303 | 307 | ||
304 | exit_no_device: | 308 | exit_no_device: |
305 | dbg(2,"%s : leave, return value %d ", __FUNCTION__, retval); | 309 | dbg(2,"%s : leave, return value %d ", __FUNCTION__, retval); |
@@ -347,7 +351,7 @@ static int adu_release(struct inode *inode, struct file *file) | |||
347 | } | 351 | } |
348 | 352 | ||
349 | /* lock our device */ | 353 | /* lock our device */ |
350 | down(&dev->sem); /* not interruptible */ | 354 | mutex_lock(&dev->mtx); /* not interruptible */ |
351 | 355 | ||
352 | if (dev->open_count <= 0) { | 356 | if (dev->open_count <= 0) { |
353 | dbg(1," %s : device not opened", __FUNCTION__); | 357 | dbg(1," %s : device not opened", __FUNCTION__); |
@@ -357,7 +361,7 @@ static int adu_release(struct inode *inode, struct file *file) | |||
357 | 361 | ||
358 | if (dev->udev == NULL) { | 362 | if (dev->udev == NULL) { |
359 | /* the device was unplugged before the file was released */ | 363 | /* the device was unplugged before the file was released */ |
360 | up(&dev->sem); | 364 | mutex_unlock(&dev->mtx); |
361 | adu_delete(dev); | 365 | adu_delete(dev); |
362 | dev = NULL; | 366 | dev = NULL; |
363 | } else { | 367 | } else { |
@@ -367,7 +371,7 @@ static int adu_release(struct inode *inode, struct file *file) | |||
367 | 371 | ||
368 | exit: | 372 | exit: |
369 | if (dev) | 373 | if (dev) |
370 | up(&dev->sem); | 374 | mutex_unlock(&dev->mtx); |
371 | dbg(2," %s : leave, return value %d", __FUNCTION__, retval); | 375 | dbg(2," %s : leave, return value %d", __FUNCTION__, retval); |
372 | return retval; | 376 | return retval; |
373 | } | 377 | } |
@@ -390,7 +394,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, | |||
390 | dev = file->private_data; | 394 | dev = file->private_data; |
391 | dbg(2," %s : dev=%p", __FUNCTION__, dev); | 395 | dbg(2," %s : dev=%p", __FUNCTION__, dev); |
392 | /* lock this object */ | 396 | /* lock this object */ |
393 | if (down_interruptible(&dev->sem)) | 397 | if (mutex_lock_interruptible(&dev->mtx)) |
394 | return -ERESTARTSYS; | 398 | return -ERESTARTSYS; |
395 | 399 | ||
396 | /* verify that the device wasn't unplugged */ | 400 | /* verify that the device wasn't unplugged */ |
@@ -522,7 +526,7 @@ static ssize_t adu_read(struct file *file, __user char *buffer, size_t count, | |||
522 | 526 | ||
523 | exit: | 527 | exit: |
524 | /* unlock the device */ | 528 | /* unlock the device */ |
525 | up(&dev->sem); | 529 | mutex_unlock(&dev->mtx); |
526 | 530 | ||
527 | dbg(2," %s : leave, return value %d", __FUNCTION__, retval); | 531 | dbg(2," %s : leave, return value %d", __FUNCTION__, retval); |
528 | return retval; | 532 | return retval; |
@@ -543,7 +547,7 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, | |||
543 | dev = file->private_data; | 547 | dev = file->private_data; |
544 | 548 | ||
545 | /* lock this object */ | 549 | /* lock this object */ |
546 | retval = down_interruptible(&dev->sem); | 550 | retval = mutex_lock_interruptible(&dev->mtx); |
547 | if (retval) | 551 | if (retval) |
548 | goto exit_nolock; | 552 | goto exit_nolock; |
549 | 553 | ||
@@ -571,9 +575,9 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, | |||
571 | retval = -EINTR; | 575 | retval = -EINTR; |
572 | goto exit; | 576 | goto exit; |
573 | } | 577 | } |
574 | up(&dev->sem); | 578 | mutex_unlock(&dev->mtx); |
575 | timeout = interruptible_sleep_on_timeout(&dev->write_wait, timeout); | 579 | timeout = interruptible_sleep_on_timeout(&dev->write_wait, timeout); |
576 | retval = down_interruptible(&dev->sem); | 580 | retval = mutex_lock_interruptible(&dev->mtx); |
577 | if (retval) { | 581 | if (retval) { |
578 | retval = bytes_written ? bytes_written : retval; | 582 | retval = bytes_written ? bytes_written : retval; |
579 | goto exit_nolock; | 583 | goto exit_nolock; |
@@ -638,7 +642,7 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, | |||
638 | 642 | ||
639 | exit: | 643 | exit: |
640 | /* unlock the device */ | 644 | /* unlock the device */ |
641 | up(&dev->sem); | 645 | mutex_unlock(&dev->mtx); |
642 | exit_nolock: | 646 | exit_nolock: |
643 | 647 | ||
644 | dbg(2," %s : leave, return value %d", __FUNCTION__, retval); | 648 | dbg(2," %s : leave, return value %d", __FUNCTION__, retval); |
@@ -698,7 +702,7 @@ static int adu_probe(struct usb_interface *interface, | |||
698 | goto exit; | 702 | goto exit; |
699 | } | 703 | } |
700 | 704 | ||
701 | init_MUTEX(&dev->sem); | 705 | mutex_init(&dev->mtx); |
702 | spin_lock_init(&dev->buflock); | 706 | spin_lock_init(&dev->buflock); |
703 | dev->udev = udev; | 707 | dev->udev = udev; |
704 | init_waitqueue_head(&dev->read_wait); | 708 | init_waitqueue_head(&dev->read_wait); |
@@ -835,16 +839,16 @@ static void adu_disconnect(struct usb_interface *interface) | |||
835 | usb_deregister_dev(interface, &adu_class); | 839 | usb_deregister_dev(interface, &adu_class); |
836 | dev->minor = 0; | 840 | dev->minor = 0; |
837 | 841 | ||
838 | down(&dev->sem); /* not interruptible */ | 842 | mutex_lock(&dev->mtx); /* not interruptible */ |
839 | 843 | ||
840 | /* if the device is not opened, then we clean up right now */ | 844 | /* if the device is not opened, then we clean up right now */ |
841 | dbg(2," %s : open count %d", __FUNCTION__, dev->open_count); | 845 | dbg(2," %s : open count %d", __FUNCTION__, dev->open_count); |
842 | if (!dev->open_count) { | 846 | if (!dev->open_count) { |
843 | up(&dev->sem); | 847 | mutex_unlock(&dev->mtx); |
844 | adu_delete(dev); | 848 | adu_delete(dev); |
845 | } else { | 849 | } else { |
846 | dev->udev = NULL; | 850 | dev->udev = NULL; |
847 | up(&dev->sem); | 851 | mutex_unlock(&dev->mtx); |
848 | } | 852 | } |
849 | 853 | ||
850 | dev_info(&interface->dev, "ADU device adutux%d now disconnected", | 854 | dev_info(&interface->dev, "ADU device adutux%d now disconnected", |
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c index cf70c16f0e3..1cb56f2d5c8 100644 --- a/drivers/usb/misc/appledisplay.c +++ b/drivers/usb/misc/appledisplay.c | |||
@@ -88,9 +88,10 @@ static void appledisplay_complete(struct urb *urb) | |||
88 | { | 88 | { |
89 | struct appledisplay *pdata = urb->context; | 89 | struct appledisplay *pdata = urb->context; |
90 | unsigned long flags; | 90 | unsigned long flags; |
91 | int status = urb->status; | ||
91 | int retval; | 92 | int retval; |
92 | 93 | ||
93 | switch (urb->status) { | 94 | switch (status) { |
94 | case 0: | 95 | case 0: |
95 | /* success */ | 96 | /* success */ |
96 | break; | 97 | break; |
@@ -102,12 +103,12 @@ static void appledisplay_complete(struct urb *urb) | |||
102 | case -ENOENT: | 103 | case -ENOENT: |
103 | case -ESHUTDOWN: | 104 | case -ESHUTDOWN: |
104 | /* This urb is terminated, clean up */ | 105 | /* This urb is terminated, clean up */ |
105 | dbg("%s - urb shutting down with status: %d", | 106 | dbg("%s - urb shuttingdown with status: %d", |
106 | __FUNCTION__, urb->status); | 107 | __FUNCTION__, status); |
107 | return; | 108 | return; |
108 | default: | 109 | default: |
109 | dbg("%s - nonzero urb status received: %d", | 110 | dbg("%s - nonzero urb status received: %d", |
110 | __FUNCTION__, urb->status); | 111 | __FUNCTION__, status); |
111 | goto exit; | 112 | goto exit; |
112 | } | 113 | } |
113 | 114 | ||
@@ -137,7 +138,7 @@ exit: | |||
137 | 138 | ||
138 | static int appledisplay_bl_update_status(struct backlight_device *bd) | 139 | static int appledisplay_bl_update_status(struct backlight_device *bd) |
139 | { | 140 | { |
140 | struct appledisplay *pdata = class_get_devdata(&bd->class_dev); | 141 | struct appledisplay *pdata = bl_get_data(bd); |
141 | int retval; | 142 | int retval; |
142 | 143 | ||
143 | pdata->msgdata[0] = 0x10; | 144 | pdata->msgdata[0] = 0x10; |
@@ -158,7 +159,7 @@ static int appledisplay_bl_update_status(struct backlight_device *bd) | |||
158 | 159 | ||
159 | static int appledisplay_bl_get_brightness(struct backlight_device *bd) | 160 | static int appledisplay_bl_get_brightness(struct backlight_device *bd) |
160 | { | 161 | { |
161 | struct appledisplay *pdata = class_get_devdata(&bd->class_dev); | 162 | struct appledisplay *pdata = bl_get_data(bd); |
162 | int retval; | 163 | int retval; |
163 | 164 | ||
164 | retval = usb_control_msg( | 165 | retval = usb_control_msg( |
diff --git a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c index 42d4e6454a7..df7e1ecc810 100644 --- a/drivers/usb/misc/auerswald.c +++ b/drivers/usb/misc/auerswald.c | |||
@@ -862,14 +862,16 @@ static void auerswald_ctrlread_wretcomplete (struct urb * urb) | |||
862 | pauerbuf_t bp = (pauerbuf_t) urb->context; | 862 | pauerbuf_t bp = (pauerbuf_t) urb->context; |
863 | pauerswald_t cp; | 863 | pauerswald_t cp; |
864 | int ret; | 864 | int ret; |
865 | int status = urb->status; | ||
866 | |||
865 | dbg ("auerswald_ctrlread_wretcomplete called"); | 867 | dbg ("auerswald_ctrlread_wretcomplete called"); |
866 | dbg ("complete with status: %d", urb->status); | 868 | dbg ("complete with status: %d", status); |
867 | cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl))); | 869 | cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl))); |
868 | 870 | ||
869 | /* check if it is possible to advance */ | 871 | /* check if it is possible to advance */ |
870 | if (!auerswald_status_retry (urb->status) || !cp->usbdev) { | 872 | if (!auerswald_status_retry(status) || !cp->usbdev) { |
871 | /* reuse the buffer */ | 873 | /* reuse the buffer */ |
872 | err ("control dummy: transmission error %d, can not retry", urb->status); | 874 | err ("control dummy: transmission error %d, can not retry", status); |
873 | auerbuf_releasebuf (bp); | 875 | auerbuf_releasebuf (bp); |
874 | /* Wake up all processes waiting for a buffer */ | 876 | /* Wake up all processes waiting for a buffer */ |
875 | wake_up (&cp->bufferwait); | 877 | wake_up (&cp->bufferwait); |
@@ -902,21 +904,23 @@ static void auerswald_ctrlread_complete (struct urb * urb) | |||
902 | pauerswald_t cp; | 904 | pauerswald_t cp; |
903 | pauerscon_t scp; | 905 | pauerscon_t scp; |
904 | pauerbuf_t bp = (pauerbuf_t) urb->context; | 906 | pauerbuf_t bp = (pauerbuf_t) urb->context; |
907 | int status = urb->status; | ||
905 | int ret; | 908 | int ret; |
909 | |||
906 | dbg ("auerswald_ctrlread_complete called"); | 910 | dbg ("auerswald_ctrlread_complete called"); |
907 | 911 | ||
908 | cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl))); | 912 | cp = ((pauerswald_t)((char *)(bp->list)-(unsigned long)(&((pauerswald_t)0)->bufctl))); |
909 | 913 | ||
910 | /* check if there is valid data in this urb */ | 914 | /* check if there is valid data in this urb */ |
911 | if (urb->status) { | 915 | if (status) { |
912 | dbg ("complete with non-zero status: %d", urb->status); | 916 | dbg ("complete with non-zero status: %d", status); |
913 | /* should we do a retry? */ | 917 | /* should we do a retry? */ |
914 | if (!auerswald_status_retry (urb->status) | 918 | if (!auerswald_status_retry(status) |
915 | || !cp->usbdev | 919 | || !cp->usbdev |
916 | || (cp->version < AUV_RETRY) | 920 | || (cp->version < AUV_RETRY) |
917 | || (bp->retries >= AU_RETRIES)) { | 921 | || (bp->retries >= AU_RETRIES)) { |
918 | /* reuse the buffer */ | 922 | /* reuse the buffer */ |
919 | err ("control read: transmission error %d, can not retry", urb->status); | 923 | err ("control read: transmission error %d, can not retry", status); |
920 | auerbuf_releasebuf (bp); | 924 | auerbuf_releasebuf (bp); |
921 | /* Wake up all processes waiting for a buffer */ | 925 | /* Wake up all processes waiting for a buffer */ |
922 | wake_up (&cp->bufferwait); | 926 | wake_up (&cp->bufferwait); |
@@ -974,12 +978,13 @@ static void auerswald_int_complete (struct urb * urb) | |||
974 | unsigned int channelid; | 978 | unsigned int channelid; |
975 | unsigned int bytecount; | 979 | unsigned int bytecount; |
976 | int ret; | 980 | int ret; |
981 | int status = urb->status; | ||
977 | pauerbuf_t bp = NULL; | 982 | pauerbuf_t bp = NULL; |
978 | pauerswald_t cp = (pauerswald_t) urb->context; | 983 | pauerswald_t cp = (pauerswald_t) urb->context; |
979 | 984 | ||
980 | dbg ("%s called", __FUNCTION__); | 985 | dbg ("%s called", __FUNCTION__); |
981 | 986 | ||
982 | switch (urb->status) { | 987 | switch (status) { |
983 | case 0: | 988 | case 0: |
984 | /* success */ | 989 | /* success */ |
985 | break; | 990 | break; |
@@ -987,10 +992,10 @@ static void auerswald_int_complete (struct urb * urb) | |||
987 | case -ENOENT: | 992 | case -ENOENT: |
988 | case -ESHUTDOWN: | 993 | case -ESHUTDOWN: |
989 | /* this urb is terminated, clean up */ | 994 | /* this urb is terminated, clean up */ |
990 | dbg("%s - urb shutting down with status: %d", __FUNCTION__, urb->status); | 995 | dbg("%s - urb shutting down with status: %d", __FUNCTION__, status); |
991 | return; | 996 | return; |
992 | default: | 997 | default: |
993 | dbg("%s - nonzero urb status received: %d", __FUNCTION__, urb->status); | 998 | dbg("%s - nonzero urb status received: %d", __FUNCTION__, status); |
994 | goto exit; | 999 | goto exit; |
995 | } | 1000 | } |
996 | 1001 | ||
diff --git a/drivers/usb/misc/berry_charge.c b/drivers/usb/misc/berry_charge.c index 92c1d2768df..24e2dc3148a 100644 --- a/drivers/usb/misc/berry_charge.c +++ b/drivers/usb/misc/berry_charge.c | |||
@@ -71,7 +71,7 @@ static int magic_charge(struct usb_device *udev) | |||
71 | if (retval != 2) { | 71 | if (retval != 2) { |
72 | dev_err(&udev->dev, "First magic command failed: %d.\n", | 72 | dev_err(&udev->dev, "First magic command failed: %d.\n", |
73 | retval); | 73 | retval); |
74 | return retval; | 74 | goto exit; |
75 | } | 75 | } |
76 | 76 | ||
77 | dbg(&udev->dev, "Sending second magic command\n"); | 77 | dbg(&udev->dev, "Sending second magic command\n"); |
@@ -80,7 +80,7 @@ static int magic_charge(struct usb_device *udev) | |||
80 | if (retval != 0) { | 80 | if (retval != 0) { |
81 | dev_err(&udev->dev, "Second magic command failed: %d.\n", | 81 | dev_err(&udev->dev, "Second magic command failed: %d.\n", |
82 | retval); | 82 | retval); |
83 | return retval; | 83 | goto exit; |
84 | } | 84 | } |
85 | 85 | ||
86 | dbg(&udev->dev, "Calling set_configuration\n"); | 86 | dbg(&udev->dev, "Calling set_configuration\n"); |
@@ -88,6 +88,8 @@ static int magic_charge(struct usb_device *udev) | |||
88 | if (retval) | 88 | if (retval) |
89 | dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval); | 89 | dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval); |
90 | 90 | ||
91 | exit: | ||
92 | kfree(dummy_buffer); | ||
91 | return retval; | 93 | return retval; |
92 | } | 94 | } |
93 | 95 | ||
@@ -112,6 +114,7 @@ static int magic_dual_mode(struct usb_device *udev) | |||
112 | if (retval) | 114 | if (retval) |
113 | dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval); | 115 | dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval); |
114 | 116 | ||
117 | kfree(dummy_buffer); | ||
115 | return retval; | 118 | return retval; |
116 | } | 119 | } |
117 | 120 | ||
diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c index e0f122e131d..d3d8cd6ff10 100644 --- a/drivers/usb/misc/ftdi-elan.c +++ b/drivers/usb/misc/ftdi-elan.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/slab.h> | 44 | #include <linux/slab.h> |
45 | #include <linux/module.h> | 45 | #include <linux/module.h> |
46 | #include <linux/kref.h> | 46 | #include <linux/kref.h> |
47 | #include <linux/mutex.h> | ||
47 | #include <asm/uaccess.h> | 48 | #include <asm/uaccess.h> |
48 | #include <linux/usb.h> | 49 | #include <linux/usb.h> |
49 | #include <linux/workqueue.h> | 50 | #include <linux/workqueue.h> |
@@ -64,7 +65,7 @@ static struct workqueue_struct *respond_queue; | |||
64 | * ftdi_module_lock exists to protect access to global variables | 65 | * ftdi_module_lock exists to protect access to global variables |
65 | * | 66 | * |
66 | */ | 67 | */ |
67 | static struct semaphore ftdi_module_lock; | 68 | static struct mutex ftdi_module_lock; |
68 | static int ftdi_instances = 0; | 69 | static int ftdi_instances = 0; |
69 | static struct list_head ftdi_static_list; | 70 | static struct list_head ftdi_static_list; |
70 | /* | 71 | /* |
@@ -199,10 +200,10 @@ static void ftdi_elan_delete(struct kref *kref) | |||
199 | dev_warn(&ftdi->udev->dev, "FREEING ftdi=%p\n", ftdi); | 200 | dev_warn(&ftdi->udev->dev, "FREEING ftdi=%p\n", ftdi); |
200 | usb_put_dev(ftdi->udev); | 201 | usb_put_dev(ftdi->udev); |
201 | ftdi->disconnected += 1; | 202 | ftdi->disconnected += 1; |
202 | down(&ftdi_module_lock); | 203 | mutex_lock(&ftdi_module_lock); |
203 | list_del_init(&ftdi->ftdi_list); | 204 | list_del_init(&ftdi->ftdi_list); |
204 | ftdi_instances -= 1; | 205 | ftdi_instances -= 1; |
205 | up(&ftdi_module_lock); | 206 | mutex_unlock(&ftdi_module_lock); |
206 | kfree(ftdi->bulk_in_buffer); | 207 | kfree(ftdi->bulk_in_buffer); |
207 | ftdi->bulk_in_buffer = NULL; | 208 | ftdi->bulk_in_buffer = NULL; |
208 | } | 209 | } |
@@ -746,10 +747,12 @@ static ssize_t ftdi_elan_read(struct file *file, char __user *buffer, | |||
746 | static void ftdi_elan_write_bulk_callback(struct urb *urb) | 747 | static void ftdi_elan_write_bulk_callback(struct urb *urb) |
747 | { | 748 | { |
748 | struct usb_ftdi *ftdi = (struct usb_ftdi *)urb->context; | 749 | struct usb_ftdi *ftdi = (struct usb_ftdi *)urb->context; |
749 | if (urb->status && !(urb->status == -ENOENT || urb->status == | 750 | int status = urb->status; |
750 | -ECONNRESET || urb->status == -ESHUTDOWN)) { | 751 | |
752 | if (status && !(status == -ENOENT || status == -ECONNRESET || | ||
753 | status == -ESHUTDOWN)) { | ||
751 | dev_err(&ftdi->udev->dev, "urb=%p write bulk status received: %" | 754 | dev_err(&ftdi->udev->dev, "urb=%p write bulk status received: %" |
752 | "d\n", urb, urb->status); | 755 | "d\n", urb, status); |
753 | } | 756 | } |
754 | usb_buffer_free(urb->dev, urb->transfer_buffer_length, | 757 | usb_buffer_free(urb->dev, urb->transfer_buffer_length, |
755 | urb->transfer_buffer, urb->transfer_dma); | 758 | urb->transfer_buffer, urb->transfer_dma); |
@@ -2774,16 +2777,18 @@ static int ftdi_elan_probe(struct usb_interface *interface, | |||
2774 | size_t buffer_size; | 2777 | size_t buffer_size; |
2775 | int i; | 2778 | int i; |
2776 | int retval = -ENOMEM; | 2779 | int retval = -ENOMEM; |
2777 | struct usb_ftdi *ftdi = kmalloc(sizeof(struct usb_ftdi), GFP_KERNEL); | 2780 | struct usb_ftdi *ftdi; |
2778 | if (ftdi == NULL) { | 2781 | |
2782 | ftdi = kzalloc(sizeof(struct usb_ftdi), GFP_KERNEL); | ||
2783 | if (!ftdi) { | ||
2779 | printk(KERN_ERR "Out of memory\n"); | 2784 | printk(KERN_ERR "Out of memory\n"); |
2780 | return -ENOMEM; | 2785 | return -ENOMEM; |
2781 | } | 2786 | } |
2782 | memset(ftdi, 0x00, sizeof(struct usb_ftdi)); | 2787 | |
2783 | down(&ftdi_module_lock); | 2788 | mutex_lock(&ftdi_module_lock); |
2784 | list_add_tail(&ftdi->ftdi_list, &ftdi_static_list); | 2789 | list_add_tail(&ftdi->ftdi_list, &ftdi_static_list); |
2785 | ftdi->sequence_num = ++ftdi_instances; | 2790 | ftdi->sequence_num = ++ftdi_instances; |
2786 | up(&ftdi_module_lock); | 2791 | mutex_unlock(&ftdi_module_lock); |
2787 | ftdi_elan_init_kref(ftdi); | 2792 | ftdi_elan_init_kref(ftdi); |
2788 | init_MUTEX(&ftdi->sw_lock); | 2793 | init_MUTEX(&ftdi->sw_lock); |
2789 | ftdi->udev = usb_get_dev(interface_to_usbdev(interface)); | 2794 | ftdi->udev = usb_get_dev(interface_to_usbdev(interface)); |
@@ -2909,7 +2914,7 @@ static int __init ftdi_elan_init(void) | |||
2909 | int result; | 2914 | int result; |
2910 | printk(KERN_INFO "driver %s built at %s on %s\n", ftdi_elan_driver.name, | 2915 | printk(KERN_INFO "driver %s built at %s on %s\n", ftdi_elan_driver.name, |
2911 | __TIME__, __DATE__); | 2916 | __TIME__, __DATE__); |
2912 | init_MUTEX(&ftdi_module_lock); | 2917 | mutex_init(&ftdi_module_lock); |
2913 | INIT_LIST_HEAD(&ftdi_static_list); | 2918 | INIT_LIST_HEAD(&ftdi_static_list); |
2914 | status_queue = create_singlethread_workqueue("ftdi-status-control"); | 2919 | status_queue = create_singlethread_workqueue("ftdi-status-control"); |
2915 | if (!status_queue) | 2920 | if (!status_queue) |
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index 28548d18671..46d9f27ec17 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c | |||
@@ -158,9 +158,10 @@ static void iowarrior_callback(struct urb *urb) | |||
158 | int read_idx; | 158 | int read_idx; |
159 | int aux_idx; | 159 | int aux_idx; |
160 | int offset; | 160 | int offset; |
161 | int status; | 161 | int status = urb->status; |
162 | int retval; | ||
162 | 163 | ||
163 | switch (urb->status) { | 164 | switch (status) { |
164 | case 0: | 165 | case 0: |
165 | /* success */ | 166 | /* success */ |
166 | break; | 167 | break; |
@@ -213,10 +214,10 @@ static void iowarrior_callback(struct urb *urb) | |||
213 | wake_up_interruptible(&dev->read_wait); | 214 | wake_up_interruptible(&dev->read_wait); |
214 | 215 | ||
215 | exit: | 216 | exit: |
216 | status = usb_submit_urb(urb, GFP_ATOMIC); | 217 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
217 | if (status) | 218 | if (retval) |
218 | dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d", | 219 | dev_err(&dev->interface->dev, "%s - usb_submit_urb failed with result %d", |
219 | __FUNCTION__, status); | 220 | __FUNCTION__, retval); |
220 | 221 | ||
221 | } | 222 | } |
222 | 223 | ||
@@ -226,13 +227,15 @@ exit: | |||
226 | static void iowarrior_write_callback(struct urb *urb) | 227 | static void iowarrior_write_callback(struct urb *urb) |
227 | { | 228 | { |
228 | struct iowarrior *dev; | 229 | struct iowarrior *dev; |
230 | int status = urb->status; | ||
231 | |||
229 | dev = (struct iowarrior *)urb->context; | 232 | dev = (struct iowarrior *)urb->context; |
230 | /* sync/async unlink faults aren't errors */ | 233 | /* sync/async unlink faults aren't errors */ |
231 | if (urb->status && | 234 | if (status && |
232 | !(urb->status == -ENOENT || | 235 | !(status == -ENOENT || |
233 | urb->status == -ECONNRESET || urb->status == -ESHUTDOWN)) { | 236 | status == -ECONNRESET || status == -ESHUTDOWN)) { |
234 | dbg("%s - nonzero write bulk status received: %d", | 237 | dbg("%s - nonzero write bulk status received: %d", |
235 | __func__, urb->status); | 238 | __func__, status); |
236 | } | 239 | } |
237 | /* free up our allocated buffer */ | 240 | /* free up our allocated buffer */ |
238 | usb_buffer_free(urb->dev, urb->transfer_buffer_length, | 241 | usb_buffer_free(urb->dev, urb->transfer_buffer_length, |
diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index 5e950b90c54..8208496dfc6 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c | |||
@@ -219,16 +219,17 @@ static void ld_usb_interrupt_in_callback(struct urb *urb) | |||
219 | struct ld_usb *dev = urb->context; | 219 | struct ld_usb *dev = urb->context; |
220 | size_t *actual_buffer; | 220 | size_t *actual_buffer; |
221 | unsigned int next_ring_head; | 221 | unsigned int next_ring_head; |
222 | int status = urb->status; | ||
222 | int retval; | 223 | int retval; |
223 | 224 | ||
224 | if (urb->status) { | 225 | if (status) { |
225 | if (urb->status == -ENOENT || | 226 | if (status == -ENOENT || |
226 | urb->status == -ECONNRESET || | 227 | status == -ECONNRESET || |
227 | urb->status == -ESHUTDOWN) { | 228 | status == -ESHUTDOWN) { |
228 | goto exit; | 229 | goto exit; |
229 | } else { | 230 | } else { |
230 | dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n", | 231 | dbg_info(&dev->intf->dev, "%s: nonzero status received: %d\n", |
231 | __FUNCTION__, urb->status); | 232 | __FUNCTION__, status); |
232 | spin_lock(&dev->rbsl); | 233 | spin_lock(&dev->rbsl); |
233 | goto resubmit; /* maybe we can recover */ | 234 | goto resubmit; /* maybe we can recover */ |
234 | } | 235 | } |
@@ -275,14 +276,15 @@ exit: | |||
275 | static void ld_usb_interrupt_out_callback(struct urb *urb) | 276 | static void ld_usb_interrupt_out_callback(struct urb *urb) |
276 | { | 277 | { |
277 | struct ld_usb *dev = urb->context; | 278 | struct ld_usb *dev = urb->context; |
279 | int status = urb->status; | ||
278 | 280 | ||
279 | /* sync/async unlink faults aren't errors */ | 281 | /* sync/async unlink faults aren't errors */ |
280 | if (urb->status && !(urb->status == -ENOENT || | 282 | if (status && !(status == -ENOENT || |
281 | urb->status == -ECONNRESET || | 283 | status == -ECONNRESET || |
282 | urb->status == -ESHUTDOWN)) | 284 | status == -ESHUTDOWN)) |
283 | dbg_info(&dev->intf->dev, | 285 | dbg_info(&dev->intf->dev, |
284 | "%s - nonzero write interrupt status received: %d\n", | 286 | "%s - nonzero write interrupt status received: %d\n", |
285 | __FUNCTION__, urb->status); | 287 | __FUNCTION__, status); |
286 | 288 | ||
287 | dev->interrupt_out_busy = 0; | 289 | dev->interrupt_out_busy = 0; |
288 | wake_up_interruptible(&dev->write_wait); | 290 | wake_up_interruptible(&dev->write_wait); |
diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index 2ed0daea894..561970b889a 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c | |||
@@ -742,19 +742,20 @@ exit: | |||
742 | static void tower_interrupt_in_callback (struct urb *urb) | 742 | static void tower_interrupt_in_callback (struct urb *urb) |
743 | { | 743 | { |
744 | struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context; | 744 | struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context; |
745 | int status = urb->status; | ||
745 | int retval; | 746 | int retval; |
746 | 747 | ||
747 | dbg(4, "%s: enter, status %d", __FUNCTION__, urb->status); | 748 | dbg(4, "%s: enter, status %d", __FUNCTION__, status); |
748 | 749 | ||
749 | lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); | 750 | lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); |
750 | 751 | ||
751 | if (urb->status) { | 752 | if (status) { |
752 | if (urb->status == -ENOENT || | 753 | if (status == -ENOENT || |
753 | urb->status == -ECONNRESET || | 754 | status == -ECONNRESET || |
754 | urb->status == -ESHUTDOWN) { | 755 | status == -ESHUTDOWN) { |
755 | goto exit; | 756 | goto exit; |
756 | } else { | 757 | } else { |
757 | dbg(1, "%s: nonzero status received: %d", __FUNCTION__, urb->status); | 758 | dbg(1, "%s: nonzero status received: %d", __FUNCTION__, status); |
758 | goto resubmit; /* maybe we can recover */ | 759 | goto resubmit; /* maybe we can recover */ |
759 | } | 760 | } |
760 | } | 761 | } |
@@ -788,7 +789,7 @@ exit: | |||
788 | wake_up_interruptible (&dev->read_wait); | 789 | wake_up_interruptible (&dev->read_wait); |
789 | 790 | ||
790 | lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); | 791 | lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); |
791 | dbg(4, "%s: leave, status %d", __FUNCTION__, urb->status); | 792 | dbg(4, "%s: leave, status %d", __FUNCTION__, status); |
792 | } | 793 | } |
793 | 794 | ||
794 | 795 | ||
@@ -798,23 +799,24 @@ exit: | |||
798 | static void tower_interrupt_out_callback (struct urb *urb) | 799 | static void tower_interrupt_out_callback (struct urb *urb) |
799 | { | 800 | { |
800 | struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context; | 801 | struct lego_usb_tower *dev = (struct lego_usb_tower *)urb->context; |
802 | int status = urb->status; | ||
801 | 803 | ||
802 | dbg(4, "%s: enter, status %d", __FUNCTION__, urb->status); | 804 | dbg(4, "%s: enter, status %d", __FUNCTION__, status); |
803 | lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); | 805 | lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); |
804 | 806 | ||
805 | /* sync/async unlink faults aren't errors */ | 807 | /* sync/async unlink faults aren't errors */ |
806 | if (urb->status && !(urb->status == -ENOENT || | 808 | if (status && !(status == -ENOENT || |
807 | urb->status == -ECONNRESET || | 809 | status == -ECONNRESET || |
808 | urb->status == -ESHUTDOWN)) { | 810 | status == -ESHUTDOWN)) { |
809 | dbg(1, "%s - nonzero write bulk status received: %d", | 811 | dbg(1, "%s - nonzero write bulk status received: %d", |
810 | __FUNCTION__, urb->status); | 812 | __FUNCTION__, status); |
811 | } | 813 | } |
812 | 814 | ||
813 | dev->interrupt_out_busy = 0; | 815 | dev->interrupt_out_busy = 0; |
814 | wake_up_interruptible(&dev->write_wait); | 816 | wake_up_interruptible(&dev->write_wait); |
815 | 817 | ||
816 | lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); | 818 | lego_usb_tower_debug_data(5, __FUNCTION__, urb->actual_length, urb->transfer_buffer); |
817 | dbg(4, "%s: leave, status %d", __FUNCTION__, urb->status); | 819 | dbg(4, "%s: leave, status %d", __FUNCTION__, status); |
818 | } | 820 | } |
819 | 821 | ||
820 | 822 | ||
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c index 371bf2b1197..aa9bcceabe7 100644 --- a/drivers/usb/misc/phidgetkit.c +++ b/drivers/usb/misc/phidgetkit.c | |||
@@ -305,9 +305,10 @@ static void interfacekit_irq(struct urb *urb) | |||
305 | struct interfacekit *kit = urb->context; | 305 | struct interfacekit *kit = urb->context; |
306 | unsigned char *buffer = kit->data; | 306 | unsigned char *buffer = kit->data; |
307 | int i, level, sensor; | 307 | int i, level, sensor; |
308 | int status; | 308 | int retval; |
309 | int status = urb->status; | ||
309 | 310 | ||
310 | switch (urb->status) { | 311 | switch (status) { |
311 | case 0: /* success */ | 312 | case 0: /* success */ |
312 | break; | 313 | break; |
313 | case -ECONNRESET: /* unlink */ | 314 | case -ECONNRESET: /* unlink */ |
@@ -377,11 +378,11 @@ static void interfacekit_irq(struct urb *urb) | |||
377 | schedule_delayed_work(&kit->do_notify, 0); | 378 | schedule_delayed_work(&kit->do_notify, 0); |
378 | 379 | ||
379 | resubmit: | 380 | resubmit: |
380 | status = usb_submit_urb(urb, GFP_ATOMIC); | 381 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
381 | if (status) | 382 | if (retval) |
382 | err("can't resubmit intr, %s-%s/interfacekit0, status %d", | 383 | err("can't resubmit intr, %s-%s/interfacekit0, retval %d", |
383 | kit->udev->bus->bus_name, | 384 | kit->udev->bus->bus_name, |
384 | kit->udev->devpath, status); | 385 | kit->udev->devpath, retval); |
385 | } | 386 | } |
386 | 387 | ||
387 | static void do_notify(struct work_struct *work) | 388 | static void do_notify(struct work_struct *work) |
diff --git a/drivers/usb/misc/phidgetmotorcontrol.c b/drivers/usb/misc/phidgetmotorcontrol.c index 5727e1ea2f9..df0ebcdb9d6 100644 --- a/drivers/usb/misc/phidgetmotorcontrol.c +++ b/drivers/usb/misc/phidgetmotorcontrol.c | |||
@@ -95,9 +95,10 @@ static void motorcontrol_irq(struct urb *urb) | |||
95 | struct motorcontrol *mc = urb->context; | 95 | struct motorcontrol *mc = urb->context; |
96 | unsigned char *buffer = mc->data; | 96 | unsigned char *buffer = mc->data; |
97 | int i, level; | 97 | int i, level; |
98 | int status; | 98 | int retval; |
99 | int status = urb->status;; | ||
99 | 100 | ||
100 | switch (urb->status) { | 101 | switch (status) { |
101 | case 0: /* success */ | 102 | case 0: /* success */ |
102 | break; | 103 | break; |
103 | case -ECONNRESET: /* unlink */ | 104 | case -ECONNRESET: /* unlink */ |
@@ -151,12 +152,12 @@ static void motorcontrol_irq(struct urb *urb) | |||
151 | schedule_delayed_work(&mc->do_notify, 0); | 152 | schedule_delayed_work(&mc->do_notify, 0); |
152 | 153 | ||
153 | resubmit: | 154 | resubmit: |
154 | status = usb_submit_urb(urb, GFP_ATOMIC); | 155 | retval = usb_submit_urb(urb, GFP_ATOMIC); |
155 | if (status) | 156 | if (retval) |
156 | dev_err(&mc->intf->dev, | 157 | dev_err(&mc->intf->dev, |
157 | "can't resubmit intr, %s-%s/motorcontrol0, status %d", | 158 | "can't resubmit intr, %s-%s/motorcontrol0, retval %d", |
158 | mc->udev->bus->bus_name, | 159 | mc->udev->bus->bus_name, |
159 | mc->udev->devpath, status); | 160 | mc->udev->devpath, retval); |
160 | } | 161 | } |
161 | 162 | ||
162 | static void do_notify(struct work_struct *work) | 163 | static void do_notify(struct work_struct *work) |
diff --git a/drivers/usb/misc/sisusbvga/sisusb.c b/drivers/usb/misc/sisusbvga/sisusb.c index 9f37ba44c13..9244d067cec 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.c +++ b/drivers/usb/misc/sisusbvga/sisusb.c | |||
@@ -32,7 +32,7 @@ | |||
32 | * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 32 | * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
33 | * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 33 | * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
34 | * | 34 | * |
35 | * Author: Thomas Winischhofer <thomas@winischhofer.net> | 35 | * Author: Thomas Winischhofer <thomas@winischhofer.net> |
36 | * | 36 | * |
37 | */ | 37 | */ |
38 | 38 | ||
@@ -962,12 +962,12 @@ static int sisusb_write_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr, | |||
962 | packet.address = 0x00000194; | 962 | packet.address = 0x00000194; |
963 | packet.data = addr; | 963 | packet.data = addr; |
964 | ret = sisusb_send_bridge_packet(sisusb, 10, | 964 | ret = sisusb_send_bridge_packet(sisusb, 10, |
965 | &packet, 0); | 965 | &packet, 0); |
966 | packet.header = 0x001f; | 966 | packet.header = 0x001f; |
967 | packet.address = 0x00000190; | 967 | packet.address = 0x00000190; |
968 | packet.data = (length & ~3); | 968 | packet.data = (length & ~3); |
969 | ret |= sisusb_send_bridge_packet(sisusb, 10, | 969 | ret |= sisusb_send_bridge_packet(sisusb, 10, |
970 | &packet, 0); | 970 | &packet, 0); |
971 | if (sisusb->flagb0 != 0x16) { | 971 | if (sisusb->flagb0 != 0x16) { |
972 | packet.header = 0x001f; | 972 | packet.header = 0x001f; |
973 | packet.address = 0x00000180; | 973 | packet.address = 0x00000180; |
@@ -1003,23 +1003,17 @@ static int sisusb_write_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr, | |||
1003 | if (ret) { | 1003 | if (ret) { |
1004 | msgcount++; | 1004 | msgcount++; |
1005 | if (msgcount < 500) | 1005 | if (msgcount < 500) |
1006 | printk(KERN_ERR | 1006 | dev_err(&sisusb->sisusb_dev->dev, "Wrote %zd of %d bytes, error %d\n", |
1007 | "sisusbvga[%d]: Wrote %zd of " | 1007 | *bytes_written, length, ret); |
1008 | "%d bytes, error %d\n", | ||
1009 | sisusb->minor, *bytes_written, | ||
1010 | length, ret); | ||
1011 | else if (msgcount == 500) | 1008 | else if (msgcount == 500) |
1012 | printk(KERN_ERR | 1009 | dev_err(&sisusb->sisusb_dev->dev, "Too many errors, logging stopped\n"); |
1013 | "sisusbvga[%d]: Too many errors" | ||
1014 | ", logging stopped\n", | ||
1015 | sisusb->minor); | ||
1016 | } | 1010 | } |
1017 | addr += (*bytes_written); | 1011 | addr += (*bytes_written); |
1018 | length -= (*bytes_written); | 1012 | length -= (*bytes_written); |
1019 | } | 1013 | } |
1020 | 1014 | ||
1021 | if (ret) | 1015 | if (ret) |
1022 | break; | 1016 | break; |
1023 | 1017 | ||
1024 | } | 1018 | } |
1025 | 1019 | ||
@@ -1261,51 +1255,10 @@ static int sisusb_read_mem_bulk(struct sisusb_usb_data *sisusb, u32 addr, | |||
1261 | addr += 4; | 1255 | addr += 4; |
1262 | length -= 4; | 1256 | length -= 4; |
1263 | } | 1257 | } |
1264 | #if 0 /* That does not work, as EP 2 is an OUT EP! */ | ||
1265 | default: | ||
1266 | CLEARPACKET(&packet); | ||
1267 | packet.header = 0x001f; | ||
1268 | packet.address = 0x000001a0; | ||
1269 | packet.data = 0x00000006; | ||
1270 | ret |= sisusb_send_bridge_packet(sisusb, 10, | ||
1271 | &packet, 0); | ||
1272 | packet.header = 0x001f; | ||
1273 | packet.address = 0x000001b0; | ||
1274 | packet.data = (length & ~3) | 0x40000000; | ||
1275 | ret |= sisusb_send_bridge_packet(sisusb, 10, | ||
1276 | &packet, 0); | ||
1277 | packet.header = 0x001f; | ||
1278 | packet.address = 0x000001b4; | ||
1279 | packet.data = addr; | ||
1280 | ret |= sisusb_send_bridge_packet(sisusb, 10, | ||
1281 | &packet, 0); | ||
1282 | packet.header = 0x001f; | ||
1283 | packet.address = 0x000001a4; | ||
1284 | packet.data = 0x00000001; | ||
1285 | ret |= sisusb_send_bridge_packet(sisusb, 10, | ||
1286 | &packet, 0); | ||
1287 | if (userbuffer) { | ||
1288 | ret |= sisusb_recv_bulk_msg(sisusb, | ||
1289 | SISUSB_EP_GFX_BULK_IN, | ||
1290 | (length & ~3), | ||
1291 | NULL, userbuffer, | ||
1292 | bytes_read, 0); | ||
1293 | if (!ret) userbuffer += (*bytes_read); | ||
1294 | } else { | ||
1295 | ret |= sisusb_recv_bulk_msg(sisusb, | ||
1296 | SISUSB_EP_GFX_BULK_IN, | ||
1297 | (length & ~3), | ||
1298 | kernbuffer, NULL, | ||
1299 | bytes_read, 0); | ||
1300 | if (!ret) kernbuffer += (*bytes_read); | ||
1301 | } | ||
1302 | addr += (*bytes_read); | ||
1303 | length -= (*bytes_read); | ||
1304 | #endif | ||
1305 | } | 1258 | } |
1306 | 1259 | ||
1307 | if (ret) | 1260 | if (ret) |
1308 | break; | 1261 | break; |
1309 | } | 1262 | } |
1310 | 1263 | ||
1311 | return ret; | 1264 | return ret; |
@@ -1401,22 +1354,6 @@ sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 *data) | |||
1401 | return(sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, adr, data)); | 1354 | return(sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, adr, data)); |
1402 | } | 1355 | } |
1403 | 1356 | ||
1404 | #if 0 | ||
1405 | |||
1406 | int | ||
1407 | sisusb_writew(struct sisusb_usb_data *sisusb, u32 adr, u16 data) | ||
1408 | { | ||
1409 | return(sisusb_write_memio_word(sisusb, SISUSB_TYPE_MEM, adr, data)); | ||
1410 | } | ||
1411 | |||
1412 | int | ||
1413 | sisusb_readw(struct sisusb_usb_data *sisusb, u32 adr, u16 *data) | ||
1414 | { | ||
1415 | return(sisusb_read_memio_word(sisusb, SISUSB_TYPE_MEM, adr, data)); | ||
1416 | } | ||
1417 | |||
1418 | #endif /* 0 */ | ||
1419 | |||
1420 | int | 1357 | int |
1421 | sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src, | 1358 | sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src, |
1422 | u32 dest, int length, size_t *bytes_written) | 1359 | u32 dest, int length, size_t *bytes_written) |
@@ -1446,10 +1383,10 @@ sisusb_testreadwrite(struct sisusb_usb_data *sisusb) | |||
1446 | sisusb_copy_memory(sisusb, srcbuffer, sisusb->vrambase, 7, &dummy); | 1383 | sisusb_copy_memory(sisusb, srcbuffer, sisusb->vrambase, 7, &dummy); |
1447 | 1384 | ||
1448 | for(i = 1; i <= 7; i++) { | 1385 | for(i = 1; i <= 7; i++) { |
1449 | printk(KERN_DEBUG "sisusb: rwtest %d bytes\n", i); | 1386 | dev_dbg(&sisusb->sisusb_dev->dev, "sisusb: rwtest %d bytes\n", i); |
1450 | sisusb_read_memory(sisusb, destbuffer, sisusb->vrambase, i, &dummy); | 1387 | sisusb_read_memory(sisusb, destbuffer, sisusb->vrambase, i, &dummy); |
1451 | for(j = 0; j < i; j++) { | 1388 | for(j = 0; j < i; j++) { |
1452 | printk(KERN_DEBUG "sisusb: rwtest read[%d] = %x\n", j, destbuffer[j]); | 1389 | dev_dbg(&sisusb->sisusb_dev->dev, "rwtest read[%d] = %x\n", j, destbuffer[j]); |
1453 | } | 1390 | } |
1454 | } | 1391 | } |
1455 | } | 1392 | } |
@@ -1533,9 +1470,9 @@ sisusb_clear_vram(struct sisusb_usb_data *sisusb, u32 address, int length) | |||
1533 | #define SETIREGAND(r,i,a) sisusb_setidxregand(sisusb, r, i, a) | 1470 | #define SETIREGAND(r,i,a) sisusb_setidxregand(sisusb, r, i, a) |
1534 | #define SETIREGANDOR(r,i,a,o) sisusb_setidxregandor(sisusb, r, i, a, o) | 1471 | #define SETIREGANDOR(r,i,a,o) sisusb_setidxregandor(sisusb, r, i, a, o) |
1535 | #define READL(a,d) sisusb_read_memio_long(sisusb, SISUSB_TYPE_MEM, a, d) | 1472 | #define READL(a,d) sisusb_read_memio_long(sisusb, SISUSB_TYPE_MEM, a, d) |
1536 | #define WRITEL(a,d) sisusb_write_memio_long(sisusb, SISUSB_TYPE_MEM, a, d) | 1473 | #define WRITEL(a,d) sisusb_write_memio_long(sisusb, SISUSB_TYPE_MEM, a, d) |
1537 | #define READB(a,d) sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, a, d) | 1474 | #define READB(a,d) sisusb_read_memio_byte(sisusb, SISUSB_TYPE_MEM, a, d) |
1538 | #define WRITEB(a,d) sisusb_write_memio_byte(sisusb, SISUSB_TYPE_MEM, a, d) | 1475 | #define WRITEB(a,d) sisusb_write_memio_byte(sisusb, SISUSB_TYPE_MEM, a, d) |
1539 | 1476 | ||
1540 | static int | 1477 | static int |
1541 | sisusb_triggersr16(struct sisusb_usb_data *sisusb, u8 ramtype) | 1478 | sisusb_triggersr16(struct sisusb_usb_data *sisusb, u8 ramtype) |
@@ -2008,7 +1945,7 @@ sisusb_set_default_mode(struct sisusb_usb_data *sisusb, int touchengines) | |||
2008 | SETIREG(SISSR, 0x26, 0x00); | 1945 | SETIREG(SISSR, 0x26, 0x00); |
2009 | } | 1946 | } |
2010 | 1947 | ||
2011 | SETIREG(SISCR, 0x34, 0x44); /* we just set std mode #44 */ | 1948 | SETIREG(SISCR, 0x34, 0x44); /* we just set std mode #44 */ |
2012 | 1949 | ||
2013 | return ret; | 1950 | return ret; |
2014 | } | 1951 | } |
@@ -2168,17 +2105,12 @@ sisusb_init_gfxcore(struct sisusb_usb_data *sisusb) | |||
2168 | if (ramtype <= 1) { | 2105 | if (ramtype <= 1) { |
2169 | ret |= sisusb_get_sdram_size(sisusb, &iret, bw, chab); | 2106 | ret |= sisusb_get_sdram_size(sisusb, &iret, bw, chab); |
2170 | if (iret) { | 2107 | if (iret) { |
2171 | printk(KERN_ERR "sisusbvga[%d]: RAM size " | 2108 | dev_err(&sisusb->sisusb_dev->dev,"RAM size detection failed, assuming 8MB video RAM\n"); |
2172 | "detection failed, " | ||
2173 | "assuming 8MB video RAM\n", | ||
2174 | sisusb->minor); | ||
2175 | ret |= SETIREG(SISSR,0x14,0x31); | 2109 | ret |= SETIREG(SISSR,0x14,0x31); |
2176 | /* TODO */ | 2110 | /* TODO */ |
2177 | } | 2111 | } |
2178 | } else { | 2112 | } else { |
2179 | printk(KERN_ERR "sisusbvga[%d]: DDR RAM device found, " | 2113 | dev_err(&sisusb->sisusb_dev->dev, "DDR RAM device found, assuming 8MB video RAM\n"); |
2180 | "assuming 8MB video RAM\n", | ||
2181 | sisusb->minor); | ||
2182 | ret |= SETIREG(SISSR,0x14,0x31); | 2114 | ret |= SETIREG(SISSR,0x14,0x31); |
2183 | /* *** TODO *** */ | 2115 | /* *** TODO *** */ |
2184 | } | 2116 | } |
@@ -2249,8 +2181,7 @@ sisusb_get_ramconfig(struct sisusb_usb_data *sisusb) | |||
2249 | break; | 2181 | break; |
2250 | } | 2182 | } |
2251 | 2183 | ||
2252 | printk(KERN_INFO "sisusbvga[%d]: %dMB %s %s, bus width %d\n", | 2184 | dev_info(&sisusb->sisusb_dev->dev, "%dMB %s %s, bus width %d\n", (sisusb->vramsize >> 20), ramtypetext1, |
2253 | sisusb->minor, (sisusb->vramsize >> 20), ramtypetext1, | ||
2254 | ramtypetext2[ramtype], bw); | 2185 | ramtypetext2[ramtype], bw); |
2255 | } | 2186 | } |
2256 | 2187 | ||
@@ -2509,11 +2440,8 @@ sisusb_open(struct inode *inode, struct file *file) | |||
2509 | struct usb_interface *interface; | 2440 | struct usb_interface *interface; |
2510 | int subminor = iminor(inode); | 2441 | int subminor = iminor(inode); |
2511 | 2442 | ||
2512 | if (!(interface = usb_find_interface(&sisusb_driver, subminor))) { | 2443 | if (!(interface = usb_find_interface(&sisusb_driver, subminor))) |
2513 | printk(KERN_ERR "sisusb[%d]: Failed to find interface\n", | ||
2514 | subminor); | ||
2515 | return -ENODEV; | 2444 | return -ENODEV; |
2516 | } | ||
2517 | 2445 | ||
2518 | if (!(sisusb = usb_get_intfdata(interface))) | 2446 | if (!(sisusb = usb_get_intfdata(interface))) |
2519 | return -ENODEV; | 2447 | return -ENODEV; |
@@ -2534,18 +2462,12 @@ sisusb_open(struct inode *inode, struct file *file) | |||
2534 | if (sisusb->sisusb_dev->speed == USB_SPEED_HIGH) { | 2462 | if (sisusb->sisusb_dev->speed == USB_SPEED_HIGH) { |
2535 | if (sisusb_init_gfxdevice(sisusb, 0)) { | 2463 | if (sisusb_init_gfxdevice(sisusb, 0)) { |
2536 | mutex_unlock(&sisusb->lock); | 2464 | mutex_unlock(&sisusb->lock); |
2537 | printk(KERN_ERR | 2465 | dev_err(&sisusb->sisusb_dev->dev, "Failed to initialize device\n"); |
2538 | "sisusbvga[%d]: Failed to initialize " | ||
2539 | "device\n", | ||
2540 | sisusb->minor); | ||
2541 | return -EIO; | 2466 | return -EIO; |
2542 | } | 2467 | } |
2543 | } else { | 2468 | } else { |
2544 | mutex_unlock(&sisusb->lock); | 2469 | mutex_unlock(&sisusb->lock); |
2545 | printk(KERN_ERR | 2470 | dev_err(&sisusb->sisusb_dev->dev, "Device not attached to USB 2.0 hub\n"); |
2546 | "sisusbvga[%d]: Device not attached to " | ||
2547 | "USB 2.0 hub\n", | ||
2548 | sisusb->minor); | ||
2549 | return -EIO; | 2471 | return -EIO; |
2550 | } | 2472 | } |
2551 | } | 2473 | } |
@@ -2586,7 +2508,6 @@ static int | |||
2586 | sisusb_release(struct inode *inode, struct file *file) | 2508 | sisusb_release(struct inode *inode, struct file *file) |
2587 | { | 2509 | { |
2588 | struct sisusb_usb_data *sisusb; | 2510 | struct sisusb_usb_data *sisusb; |
2589 | int myminor; | ||
2590 | 2511 | ||
2591 | if (!(sisusb = (struct sisusb_usb_data *)file->private_data)) | 2512 | if (!(sisusb = (struct sisusb_usb_data *)file->private_data)) |
2592 | return -ENODEV; | 2513 | return -ENODEV; |
@@ -2599,8 +2520,6 @@ sisusb_release(struct inode *inode, struct file *file) | |||
2599 | sisusb_kill_all_busy(sisusb); | 2520 | sisusb_kill_all_busy(sisusb); |
2600 | } | 2521 | } |
2601 | 2522 | ||
2602 | myminor = sisusb->minor; | ||
2603 | |||
2604 | sisusb->isopen = 0; | 2523 | sisusb->isopen = 0; |
2605 | file->private_data = NULL; | 2524 | file->private_data = NULL; |
2606 | 2525 | ||
@@ -2942,7 +2861,7 @@ static int | |||
2942 | sisusb_handle_command(struct sisusb_usb_data *sisusb, struct sisusb_command *y, | 2861 | sisusb_handle_command(struct sisusb_usb_data *sisusb, struct sisusb_command *y, |
2943 | unsigned long arg) | 2862 | unsigned long arg) |
2944 | { | 2863 | { |
2945 | int retval, port, length; | 2864 | int retval, port, length; |
2946 | u32 address; | 2865 | u32 address; |
2947 | 2866 | ||
2948 | /* All our commands require the device | 2867 | /* All our commands require the device |
@@ -3065,12 +2984,12 @@ sisusb_handle_command(struct sisusb_usb_data *sisusb, struct sisusb_command *y, | |||
3065 | 2984 | ||
3066 | static int | 2985 | static int |
3067 | sisusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | 2986 | sisusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, |
3068 | unsigned long arg) | 2987 | unsigned long arg) |
3069 | { | 2988 | { |
3070 | struct sisusb_usb_data *sisusb; | 2989 | struct sisusb_usb_data *sisusb; |
3071 | struct sisusb_info x; | 2990 | struct sisusb_info x; |
3072 | struct sisusb_command y; | 2991 | struct sisusb_command y; |
3073 | int retval = 0; | 2992 | int retval = 0; |
3074 | u32 __user *argp = (u32 __user *)arg; | 2993 | u32 __user *argp = (u32 __user *)arg; |
3075 | 2994 | ||
3076 | if (!(sisusb = (struct sisusb_usb_data *)file->private_data)) | 2995 | if (!(sisusb = (struct sisusb_usb_data *)file->private_data)) |
@@ -3095,7 +3014,7 @@ sisusb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, | |||
3095 | 3014 | ||
3096 | case SISUSB_GET_CONFIG: | 3015 | case SISUSB_GET_CONFIG: |
3097 | 3016 | ||
3098 | x.sisusb_id = SISUSB_ID; | 3017 | x.sisusb_id = SISUSB_ID; |
3099 | x.sisusb_version = SISUSB_VERSION; | 3018 | x.sisusb_version = SISUSB_VERSION; |
3100 | x.sisusb_revision = SISUSB_REVISION; | 3019 | x.sisusb_revision = SISUSB_REVISION; |
3101 | x.sisusb_patchlevel = SISUSB_PATCHLEVEL; | 3020 | x.sisusb_patchlevel = SISUSB_PATCHLEVEL; |
@@ -3164,7 +3083,7 @@ static const struct file_operations usb_sisusb_fops = { | |||
3164 | .release = sisusb_release, | 3083 | .release = sisusb_release, |
3165 | .read = sisusb_read, | 3084 | .read = sisusb_read, |
3166 | .write = sisusb_write, | 3085 | .write = sisusb_write, |
3167 | .llseek = sisusb_lseek, | 3086 | .llseek = sisusb_lseek, |
3168 | #ifdef SISUSB_NEW_CONFIG_COMPAT | 3087 | #ifdef SISUSB_NEW_CONFIG_COMPAT |
3169 | .compat_ioctl = sisusb_compat_ioctl, | 3088 | .compat_ioctl = sisusb_compat_ioctl, |
3170 | #endif | 3089 | #endif |
@@ -3183,17 +3102,13 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3183 | struct usb_device *dev = interface_to_usbdev(intf); | 3102 | struct usb_device *dev = interface_to_usbdev(intf); |
3184 | struct sisusb_usb_data *sisusb; | 3103 | struct sisusb_usb_data *sisusb; |
3185 | int retval = 0, i; | 3104 | int retval = 0, i; |
3186 | const char *memfail = | ||
3187 | KERN_ERR | ||
3188 | "sisusbvga[%d]: Failed to allocate memory for %s buffer\n"; | ||
3189 | 3105 | ||
3190 | printk(KERN_INFO "sisusb: USB2VGA dongle found at address %d\n", | 3106 | dev_info(&dev->dev, "USB2VGA dongle found at address %d\n", |
3191 | dev->devnum); | 3107 | dev->devnum); |
3192 | 3108 | ||
3193 | /* Allocate memory for our private */ | 3109 | /* Allocate memory for our private */ |
3194 | if (!(sisusb = kzalloc(sizeof(*sisusb), GFP_KERNEL))) { | 3110 | if (!(sisusb = kzalloc(sizeof(*sisusb), GFP_KERNEL))) { |
3195 | printk(KERN_ERR | 3111 | dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate memory for private data\n"); |
3196 | "sisusb: Failed to allocate memory for private data\n"); | ||
3197 | return -ENOMEM; | 3112 | return -ENOMEM; |
3198 | } | 3113 | } |
3199 | kref_init(&sisusb->kref); | 3114 | kref_init(&sisusb->kref); |
@@ -3202,8 +3117,7 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3202 | 3117 | ||
3203 | /* Register device */ | 3118 | /* Register device */ |
3204 | if ((retval = usb_register_dev(intf, &usb_sisusb_class))) { | 3119 | if ((retval = usb_register_dev(intf, &usb_sisusb_class))) { |
3205 | printk(KERN_ERR | 3120 | dev_err(&sisusb->sisusb_dev->dev, "Failed to get a minor for device %d\n", |
3206 | "sisusb: Failed to get a minor for device %d\n", | ||
3207 | dev->devnum); | 3121 | dev->devnum); |
3208 | retval = -ENODEV; | 3122 | retval = -ENODEV; |
3209 | goto error_1; | 3123 | goto error_1; |
@@ -3221,7 +3135,7 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3221 | sisusb->ibufsize = SISUSB_IBUF_SIZE; | 3135 | sisusb->ibufsize = SISUSB_IBUF_SIZE; |
3222 | if (!(sisusb->ibuf = usb_buffer_alloc(dev, SISUSB_IBUF_SIZE, | 3136 | if (!(sisusb->ibuf = usb_buffer_alloc(dev, SISUSB_IBUF_SIZE, |
3223 | GFP_KERNEL, &sisusb->transfer_dma_in))) { | 3137 | GFP_KERNEL, &sisusb->transfer_dma_in))) { |
3224 | printk(memfail, "input", sisusb->minor); | 3138 | dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate memory for input buffer"); |
3225 | retval = -ENOMEM; | 3139 | retval = -ENOMEM; |
3226 | goto error_2; | 3140 | goto error_2; |
3227 | } | 3141 | } |
@@ -3233,7 +3147,7 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3233 | GFP_KERNEL, | 3147 | GFP_KERNEL, |
3234 | &sisusb->transfer_dma_out[i]))) { | 3148 | &sisusb->transfer_dma_out[i]))) { |
3235 | if (i == 0) { | 3149 | if (i == 0) { |
3236 | printk(memfail, "output", sisusb->minor); | 3150 | dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate memory for output buffer\n"); |
3237 | retval = -ENOMEM; | 3151 | retval = -ENOMEM; |
3238 | goto error_3; | 3152 | goto error_3; |
3239 | } | 3153 | } |
@@ -3245,9 +3159,7 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3245 | 3159 | ||
3246 | /* Allocate URBs */ | 3160 | /* Allocate URBs */ |
3247 | if (!(sisusb->sisurbin = usb_alloc_urb(0, GFP_KERNEL))) { | 3161 | if (!(sisusb->sisurbin = usb_alloc_urb(0, GFP_KERNEL))) { |
3248 | printk(KERN_ERR | 3162 | dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate URBs\n"); |
3249 | "sisusbvga[%d]: Failed to allocate URBs\n", | ||
3250 | sisusb->minor); | ||
3251 | retval = -ENOMEM; | 3163 | retval = -ENOMEM; |
3252 | goto error_3; | 3164 | goto error_3; |
3253 | } | 3165 | } |
@@ -3255,9 +3167,7 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3255 | 3167 | ||
3256 | for (i = 0; i < sisusb->numobufs; i++) { | 3168 | for (i = 0; i < sisusb->numobufs; i++) { |
3257 | if (!(sisusb->sisurbout[i] = usb_alloc_urb(0, GFP_KERNEL))) { | 3169 | if (!(sisusb->sisurbout[i] = usb_alloc_urb(0, GFP_KERNEL))) { |
3258 | printk(KERN_ERR | 3170 | dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate URBs\n"); |
3259 | "sisusbvga[%d]: Failed to allocate URBs\n", | ||
3260 | sisusb->minor); | ||
3261 | retval = -ENOMEM; | 3171 | retval = -ENOMEM; |
3262 | goto error_4; | 3172 | goto error_4; |
3263 | } | 3173 | } |
@@ -3266,15 +3176,12 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3266 | sisusb->urbstatus[i] = 0; | 3176 | sisusb->urbstatus[i] = 0; |
3267 | } | 3177 | } |
3268 | 3178 | ||
3269 | printk(KERN_INFO "sisusbvga[%d]: Allocated %d output buffers\n", | 3179 | dev_info(&sisusb->sisusb_dev->dev, "Allocated %d output buffers\n", sisusb->numobufs); |
3270 | sisusb->minor, sisusb->numobufs); | ||
3271 | 3180 | ||
3272 | #ifdef INCL_SISUSB_CON | 3181 | #ifdef INCL_SISUSB_CON |
3273 | /* Allocate our SiS_Pr */ | 3182 | /* Allocate our SiS_Pr */ |
3274 | if (!(sisusb->SiS_Pr = kmalloc(sizeof(struct SiS_Private), GFP_KERNEL))) { | 3183 | if (!(sisusb->SiS_Pr = kmalloc(sizeof(struct SiS_Private), GFP_KERNEL))) { |
3275 | printk(KERN_ERR | 3184 | dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate SiS_Pr\n"); |
3276 | "sisusbvga[%d]: Failed to allocate SiS_Pr\n", | ||
3277 | sisusb->minor); | ||
3278 | } | 3185 | } |
3279 | #endif | 3186 | #endif |
3280 | 3187 | ||
@@ -3296,10 +3203,7 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3296 | ret |= register_ioctl32_conversion(SISUSB_GET_CONFIG, NULL); | 3203 | ret |= register_ioctl32_conversion(SISUSB_GET_CONFIG, NULL); |
3297 | ret |= register_ioctl32_conversion(SISUSB_COMMAND, NULL); | 3204 | ret |= register_ioctl32_conversion(SISUSB_COMMAND, NULL); |
3298 | if (ret) | 3205 | if (ret) |
3299 | printk(KERN_ERR | 3206 | dev_err(&sisusb->sisusb_dev->dev, "Error registering ioctl32 translations\n"); |
3300 | "sisusbvga[%d]: Error registering ioctl32 " | ||
3301 | "translations\n", | ||
3302 | sisusb->minor); | ||
3303 | else | 3207 | else |
3304 | sisusb->ioctl32registered = 1; | 3208 | sisusb->ioctl32registered = 1; |
3305 | } | 3209 | } |
@@ -3315,23 +3219,17 @@ static int sisusb_probe(struct usb_interface *intf, | |||
3315 | initscreen = 0; | 3219 | initscreen = 0; |
3316 | #endif | 3220 | #endif |
3317 | if (sisusb_init_gfxdevice(sisusb, initscreen)) | 3221 | if (sisusb_init_gfxdevice(sisusb, initscreen)) |
3318 | printk(KERN_ERR | 3222 | dev_err(&sisusb->sisusb_dev->dev, "Failed to early initialize device\n"); |
3319 | "sisusbvga[%d]: Failed to early " | ||
3320 | "initialize device\n", | ||
3321 | sisusb->minor); | ||
3322 | 3223 | ||
3323 | } else | 3224 | } else |
3324 | printk(KERN_INFO | 3225 | dev_info(&sisusb->sisusb_dev->dev, "Not attached to USB 2.0 hub, deferring init\n"); |
3325 | "sisusbvga[%d]: Not attached to USB 2.0 hub, " | ||
3326 | "deferring init\n", | ||
3327 | sisusb->minor); | ||
3328 | 3226 | ||
3329 | sisusb->ready = 1; | 3227 | sisusb->ready = 1; |
3330 | 3228 | ||
3331 | #ifdef SISUSBENDIANTEST | 3229 | #ifdef SISUSBENDIANTEST |
3332 | printk(KERN_DEBUG "sisusb: *** RWTEST ***\n"); | 3230 | dev_dbg(&sisusb->sisusb_dev->dev, "*** RWTEST ***\n"); |
3333 | sisusb_testreadwrite(sisusb); | 3231 | sisusb_testreadwrite(sisusb); |
3334 | printk(KERN_DEBUG "sisusb: *** RWTEST END ***\n"); | 3232 | dev_dbg(&sisusb->sisusb_dev->dev, "*** RWTEST END ***\n"); |
3335 | #endif | 3233 | #endif |
3336 | 3234 | ||
3337 | #ifdef INCL_SISUSB_CON | 3235 | #ifdef INCL_SISUSB_CON |
@@ -3354,7 +3252,6 @@ error_1: | |||
3354 | static void sisusb_disconnect(struct usb_interface *intf) | 3252 | static void sisusb_disconnect(struct usb_interface *intf) |
3355 | { | 3253 | { |
3356 | struct sisusb_usb_data *sisusb; | 3254 | struct sisusb_usb_data *sisusb; |
3357 | int minor; | ||
3358 | 3255 | ||
3359 | /* This should *not* happen */ | 3256 | /* This should *not* happen */ |
3360 | if (!(sisusb = usb_get_intfdata(intf))) | 3257 | if (!(sisusb = usb_get_intfdata(intf))) |
@@ -3364,8 +3261,6 @@ static void sisusb_disconnect(struct usb_interface *intf) | |||
3364 | sisusb_console_exit(sisusb); | 3261 | sisusb_console_exit(sisusb); |
3365 | #endif | 3262 | #endif |
3366 | 3263 | ||
3367 | minor = sisusb->minor; | ||
3368 | |||
3369 | usb_deregister_dev(intf, &usb_sisusb_class); | 3264 | usb_deregister_dev(intf, &usb_sisusb_class); |
3370 | 3265 | ||
3371 | mutex_lock(&sisusb->lock); | 3266 | mutex_lock(&sisusb->lock); |
@@ -3384,10 +3279,7 @@ static void sisusb_disconnect(struct usb_interface *intf) | |||
3384 | ret |= unregister_ioctl32_conversion(SISUSB_GET_CONFIG); | 3279 | ret |= unregister_ioctl32_conversion(SISUSB_GET_CONFIG); |
3385 | ret |= unregister_ioctl32_conversion(SISUSB_COMMAND); | 3280 | ret |= unregister_ioctl32_conversion(SISUSB_COMMAND); |
3386 | if (ret) { | 3281 | if (ret) { |
3387 | printk(KERN_ERR | 3282 | dev_err(&sisusb->sisusb_dev->dev, "Error unregistering ioctl32 translations\n"); |
3388 | "sisusbvga[%d]: Error unregistering " | ||
3389 | "ioctl32 translations\n", | ||
3390 | minor); | ||
3391 | } | 3283 | } |
3392 | } | 3284 | } |
3393 | #endif | 3285 | #endif |
@@ -3400,10 +3292,11 @@ static void sisusb_disconnect(struct usb_interface *intf) | |||
3400 | /* decrement our usage count */ | 3292 | /* decrement our usage count */ |
3401 | kref_put(&sisusb->kref, sisusb_delete); | 3293 | kref_put(&sisusb->kref, sisusb_delete); |
3402 | 3294 | ||
3403 | printk(KERN_INFO "sisusbvga[%d]: Disconnected\n", minor); | 3295 | dev_info(&sisusb->sisusb_dev->dev, "Disconnected\n"); |
3404 | } | 3296 | } |
3405 | 3297 | ||
3406 | static struct usb_device_id sisusb_table [] = { | 3298 | static struct usb_device_id sisusb_table [] = { |
3299 | { USB_DEVICE(0x0711, 0x0550) }, | ||
3407 | { USB_DEVICE(0x0711, 0x0900) }, | 3300 | { USB_DEVICE(0x0711, 0x0900) }, |
3408 | { USB_DEVICE(0x0711, 0x0901) }, | 3301 | { USB_DEVICE(0x0711, 0x0901) }, |
3409 | { USB_DEVICE(0x0711, 0x0902) }, | 3302 | { USB_DEVICE(0x0711, 0x0902) }, |
@@ -3423,22 +3316,12 @@ static struct usb_driver sisusb_driver = { | |||
3423 | 3316 | ||
3424 | static int __init usb_sisusb_init(void) | 3317 | static int __init usb_sisusb_init(void) |
3425 | { | 3318 | { |
3426 | int retval; | ||
3427 | 3319 | ||
3428 | #ifdef INCL_SISUSB_CON | 3320 | #ifdef INCL_SISUSB_CON |
3429 | sisusb_init_concode(); | 3321 | sisusb_init_concode(); |
3430 | #endif | 3322 | #endif |
3431 | 3323 | ||
3432 | if (!(retval = usb_register(&sisusb_driver))) { | 3324 | return usb_register(&sisusb_driver); |
3433 | |||
3434 | printk(KERN_INFO "sisusb: Driver version %d.%d.%d\n", | ||
3435 | SISUSB_VERSION, SISUSB_REVISION, SISUSB_PATCHLEVEL); | ||
3436 | printk(KERN_INFO | ||
3437 | "sisusb: Copyright (C) 2005 Thomas Winischhofer\n"); | ||
3438 | |||
3439 | } | ||
3440 | |||
3441 | return retval; | ||
3442 | } | 3325 | } |
3443 | 3326 | ||
3444 | static void __exit usb_sisusb_exit(void) | 3327 | static void __exit usb_sisusb_exit(void) |
diff --git a/drivers/usb/misc/sisusbvga/sisusb.h b/drivers/usb/misc/sisusbvga/sisusb.h index 8e1120a6480..d2d7872cd02 100644 --- a/drivers/usb/misc/sisusbvga/sisusb.h +++ b/drivers/usb/misc/sisusbvga/sisusb.h | |||
@@ -8,29 +8,29 @@ | |||
8 | * | 8 | * |
9 | * Otherwise, the following license terms apply: | 9 | * Otherwise, the following license terms apply: |
10 | * | 10 | * |
11 | * * Redistribution and use in source and binary forms, with or without | 11 | * Redistribution and use in source and binary forms, with or without |
12 | * * modification, are permitted provided that the following conditions | 12 | * modification, are permitted provided that the following conditions |
13 | * * are met: | 13 | * are met: |
14 | * * 1) Redistributions of source code must retain the above copyright | 14 | * 1) Redistributions of source code must retain the above copyright |
15 | * * notice, this list of conditions and the following disclaimer. | 15 | * notice, this list of conditions and the following disclaimer. |
16 | * * 2) Redistributions in binary form must reproduce the above copyright | 16 | * 2) Redistributions in binary form must reproduce the above copyright |
17 | * * notice, this list of conditions and the following disclaimer in the | 17 | * notice, this list of conditions and the following disclaimer in the |
18 | * * documentation and/or other materials provided with the distribution. | 18 | * documentation and/or other materials provided with the distribution. |
19 | * * 3) The name of the author may not be used to endorse or promote products | 19 | * 3) The name of the author may not be used to endorse or promote products |
20 | * * derived from this software without specific prior written permission. | 20 | * derived from this software without specific prior written permission. |
21 | * * | ||
22 | * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR | ||
23 | * * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
24 | * * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
25 | * * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
26 | * * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
27 | * * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
28 | * * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
29 | * * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
30 | * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
31 | * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
32 | * | 21 | * |
33 | * Author: Thomas Winischhofer <thomas@winischhofer.net> | 22 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR |
23 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | ||
24 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
25 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
26 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
27 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
28 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
29 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
30 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
31 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
32 | * | ||
33 | * Author: Thomas Winischhofer <thomas@winischhofer.net> | ||
34 | * | 34 | * |
35 | */ | 35 | */ |
36 | 36 | ||
@@ -44,16 +44,14 @@ | |||
44 | #include <linux/mutex.h> | 44 | #include <linux/mutex.h> |
45 | 45 | ||
46 | /* For older kernels, support for text consoles is by default | 46 | /* For older kernels, support for text consoles is by default |
47 | * off. To ensable text console support, change the following: | 47 | * off. To enable text console support, change the following: |
48 | */ | 48 | */ |
49 | #if 0 | 49 | /* #define CONFIG_USB_SISUSBVGA_CON */ |
50 | #define CONFIG_USB_SISUSBVGA_CON | ||
51 | #endif | ||
52 | 50 | ||
53 | /* Version Information */ | 51 | /* Version Information */ |
54 | 52 | ||
55 | #define SISUSB_VERSION 0 | 53 | #define SISUSB_VERSION 0 |
56 | #define SISUSB_REVISION 0 | 54 | #define SISUSB_REVISION 0 |
57 | #define SISUSB_PATCHLEVEL 8 | 55 | #define SISUSB_PATCHLEVEL 8 |
58 | 56 | ||
59 | /* Include console and mode switching code? */ | 57 | /* Include console and mode switching code? */ |
@@ -74,7 +72,7 @@ | |||
74 | #define SISUSB_IBUF_SIZE 0x01000 | 72 | #define SISUSB_IBUF_SIZE 0x01000 |
75 | #define SISUSB_OBUF_SIZE 0x10000 /* fixed */ | 73 | #define SISUSB_OBUF_SIZE 0x10000 /* fixed */ |
76 | 74 | ||
77 | #define NUMOBUFS 8 /* max number of output buffers/output URBs */ | 75 | #define NUMOBUFS 8 /* max number of output buffers/output URBs */ |
78 | 76 | ||
79 | /* About endianness: | 77 | /* About endianness: |
80 | * | 78 | * |
@@ -93,7 +91,7 @@ | |||
93 | */ | 91 | */ |
94 | 92 | ||
95 | #ifdef __BIG_ENDIAN | 93 | #ifdef __BIG_ENDIAN |
96 | #define SISUSB_CORRECT_ENDIANNESS_PACKET(p) \ | 94 | #define SISUSB_CORRECT_ENDIANNESS_PACKET(p) \ |
97 | do { \ | 95 | do { \ |
98 | p->header = cpu_to_le16(p->header); \ | 96 | p->header = cpu_to_le16(p->header); \ |
99 | p->address = cpu_to_le32(p->address); \ | 97 | p->address = cpu_to_le32(p->address); \ |
@@ -105,7 +103,7 @@ | |||
105 | 103 | ||
106 | struct sisusb_usb_data; | 104 | struct sisusb_usb_data; |
107 | 105 | ||
108 | struct sisusb_urb_context { /* urb->context for outbound bulk URBs */ | 106 | struct sisusb_urb_context { /* urb->context for outbound bulk URBs */ |
109 | struct sisusb_usb_data *sisusb; | 107 | struct sisusb_usb_data *sisusb; |
110 | int urbindex; | 108 | int urbindex; |
111 | int *actual_length; | 109 | int *actual_length; |
@@ -116,16 +114,16 @@ struct sisusb_usb_data { | |||
116 | struct usb_interface *interface; | 114 | struct usb_interface *interface; |
117 | struct kref kref; | 115 | struct kref kref; |
118 | wait_queue_head_t wait_q; /* for syncind and timeouts */ | 116 | wait_queue_head_t wait_q; /* for syncind and timeouts */ |
119 | struct mutex lock; /* general race avoidance */ | 117 | struct mutex lock; /* general race avoidance */ |
120 | unsigned int ifnum; /* interface number of the USB device */ | 118 | unsigned int ifnum; /* interface number of the USB device */ |
121 | int minor; /* minor (for logging clarity) */ | 119 | int minor; /* minor (for logging clarity) */ |
122 | int isopen; /* !=0 if open */ | 120 | int isopen; /* !=0 if open */ |
123 | int present; /* !=0 if device is present on the bus */ | 121 | int present; /* !=0 if device is present on the bus */ |
124 | int ready; /* !=0 if device is ready for userland */ | 122 | int ready; /* !=0 if device is ready for userland */ |
125 | #ifdef SISUSB_OLD_CONFIG_COMPAT | 123 | #ifdef SISUSB_OLD_CONFIG_COMPAT |
126 | int ioctl32registered; | 124 | int ioctl32registered; |
127 | #endif | 125 | #endif |
128 | int numobufs; /* number of obufs = number of out urbs */ | 126 | int numobufs; /* number of obufs = number of out urbs */ |
129 | char *obuf[NUMOBUFS], *ibuf; /* transfer buffers */ | 127 | char *obuf[NUMOBUFS], *ibuf; /* transfer buffers */ |
130 | int obufsize, ibufsize; | 128 | int obufsize, ibufsize; |
131 | dma_addr_t transfer_dma_out[NUMOBUFS]; | 129 | dma_addr_t transfer_dma_out[NUMOBUFS]; |
@@ -136,13 +134,13 @@ struct sisusb_usb_data { | |||
136 | unsigned char completein; | 134 | unsigned char completein; |
137 | struct sisusb_urb_context urbout_context[NUMOBUFS]; | 135 | struct sisusb_urb_context urbout_context[NUMOBUFS]; |
138 | unsigned long flagb0; | 136 | unsigned long flagb0; |
139 | unsigned long vrambase; /* framebuffer base */ | 137 | unsigned long vrambase; /* framebuffer base */ |
140 | unsigned int vramsize; /* framebuffer size (bytes) */ | 138 | unsigned int vramsize; /* framebuffer size (bytes) */ |
141 | unsigned long mmiobase; | 139 | unsigned long mmiobase; |
142 | unsigned int mmiosize; | 140 | unsigned int mmiosize; |
143 | unsigned long ioportbase; | 141 | unsigned long ioportbase; |
144 | unsigned char devinit; /* device initialized? */ | 142 | unsigned char devinit; /* device initialized? */ |
145 | unsigned char gfxinit; /* graphics core initialized? */ | 143 | unsigned char gfxinit; /* graphics core initialized? */ |
146 | unsigned short chipid, chipvendor; | 144 | unsigned short chipid, chipvendor; |
147 | unsigned short chiprevision; | 145 | unsigned short chiprevision; |
148 | #ifdef INCL_SISUSB_CON | 146 | #ifdef INCL_SISUSB_CON |
@@ -152,7 +150,7 @@ struct sisusb_usb_data { | |||
152 | int haveconsole, con_first, con_last; | 150 | int haveconsole, con_first, con_last; |
153 | int havethisconsole[MAX_NR_CONSOLES]; | 151 | int havethisconsole[MAX_NR_CONSOLES]; |
154 | int textmodedestroyed; | 152 | int textmodedestroyed; |
155 | unsigned int sisusb_num_columns; /* real number, not vt's idea */ | 153 | unsigned int sisusb_num_columns; /* real number, not vt's idea */ |
156 | int cur_start_addr, con_rolled_over; | 154 | int cur_start_addr, con_rolled_over; |
157 | int sisusb_cursor_loc, bad_cursor_pos; | 155 | int sisusb_cursor_loc, bad_cursor_pos; |
158 | int sisusb_cursor_size_from; | 156 | int sisusb_cursor_size_from; |
@@ -197,7 +195,7 @@ struct sisusb_packet { | |||
197 | unsigned short header; | 195 | unsigned short header; |
198 | u32 address; | 196 | u32 address; |
199 | u32 data; | 197 | u32 data; |
200 | } __attribute__((__packed__)); | 198 | } __attribute__ ((__packed__)); |
201 | 199 | ||
202 | #define CLEARPACKET(packet) memset(packet, 0, 10) | 200 | #define CLEARPACKET(packet) memset(packet, 0, 10) |
203 | 201 | ||
@@ -265,36 +263,36 @@ struct sisusb_packet { | |||
265 | 263 | ||
266 | /* Structure argument for SISUSB_GET_INFO ioctl */ | 264 | /* Structure argument for SISUSB_GET_INFO ioctl */ |
267 | struct sisusb_info { | 265 | struct sisusb_info { |
268 | __u32 sisusb_id; /* for identifying sisusb */ | 266 | __u32 sisusb_id; /* for identifying sisusb */ |
269 | #define SISUSB_ID 0x53495355 /* Identify myself with 'SISU' */ | 267 | #define SISUSB_ID 0x53495355 /* Identify myself with 'SISU' */ |
270 | __u8 sisusb_version; | 268 | __u8 sisusb_version; |
271 | __u8 sisusb_revision; | 269 | __u8 sisusb_revision; |
272 | __u8 sisusb_patchlevel; | 270 | __u8 sisusb_patchlevel; |
273 | __u8 sisusb_gfxinit; /* graphics core initialized? */ | 271 | __u8 sisusb_gfxinit; /* graphics core initialized? */ |
274 | 272 | ||
275 | __u32 sisusb_vrambase; | 273 | __u32 sisusb_vrambase; |
276 | __u32 sisusb_mmiobase; | 274 | __u32 sisusb_mmiobase; |
277 | __u32 sisusb_iobase; | 275 | __u32 sisusb_iobase; |
278 | __u32 sisusb_pcibase; | 276 | __u32 sisusb_pcibase; |
279 | 277 | ||
280 | __u32 sisusb_vramsize; /* framebuffer size in bytes */ | 278 | __u32 sisusb_vramsize; /* framebuffer size in bytes */ |
281 | 279 | ||
282 | __u32 sisusb_minor; | 280 | __u32 sisusb_minor; |
283 | 281 | ||
284 | __u32 sisusb_fbdevactive; /* != 0 if framebuffer device active */ | 282 | __u32 sisusb_fbdevactive; /* != 0 if framebuffer device active */ |
285 | 283 | ||
286 | __u32 sisusb_conactive; /* != 0 if console driver active */ | 284 | __u32 sisusb_conactive; /* != 0 if console driver active */ |
287 | 285 | ||
288 | __u8 sisusb_reserved[28]; /* for future use */ | 286 | __u8 sisusb_reserved[28]; /* for future use */ |
289 | }; | 287 | }; |
290 | 288 | ||
291 | struct sisusb_command { | 289 | struct sisusb_command { |
292 | __u8 operation; /* see below */ | 290 | __u8 operation; /* see below */ |
293 | __u8 data0; /* operation dependent */ | 291 | __u8 data0; /* operation dependent */ |
294 | __u8 data1; /* operation dependent */ | 292 | __u8 data1; /* operation dependent */ |
295 | __u8 data2; /* operation dependent */ | 293 | __u8 data2; /* operation dependent */ |
296 | __u32 data3; /* operation dependent */ | 294 | __u32 data3; /* operation dependent */ |
297 | __u32 data4; /* for future use */ | 295 | __u32 data4; /* for future use */ |
298 | }; | 296 | }; |
299 | 297 | ||
300 | #define SUCMD_GET 0x01 /* for all: data0 = index, data3 = port */ | 298 | #define SUCMD_GET 0x01 /* for all: data0 = index, data3 = port */ |
@@ -306,7 +304,7 @@ struct sisusb_command { | |||
306 | 304 | ||
307 | #define SUCMD_CLRSCR 0x07 /* data0:1:2 = length, data3 = address */ | 305 | #define SUCMD_CLRSCR 0x07 /* data0:1:2 = length, data3 = address */ |
308 | 306 | ||
309 | #define SUCMD_HANDLETEXTMODE 0x08 /* Reset/destroy text mode */ | 307 | #define SUCMD_HANDLETEXTMODE 0x08 /* Reset/destroy text mode */ |
310 | 308 | ||
311 | #define SUCMD_SETMODE 0x09 /* Set a display mode (data3 = SiS mode) */ | 309 | #define SUCMD_SETMODE 0x09 /* Set a display mode (data3 = SiS mode) */ |
312 | #define SUCMD_SETVESAMODE 0x0a /* Set a display mode (data3 = VESA mode) */ | 310 | #define SUCMD_SETVESAMODE 0x0a /* Set a display mode (data3 = VESA mode) */ |
@@ -315,6 +313,4 @@ struct sisusb_command { | |||
315 | #define SISUSB_GET_CONFIG_SIZE _IOR(0xF3,0x3E,__u32) | 313 | #define SISUSB_GET_CONFIG_SIZE _IOR(0xF3,0x3E,__u32) |
316 | #define SISUSB_GET_CONFIG _IOR(0xF3,0x3F,struct sisusb_info) | 314 | #define SISUSB_GET_CONFIG _IOR(0xF3,0x3F,struct sisusb_info) |
317 | 315 | ||
318 | |||
319 | #endif /* SISUSB_H */ | 316 | #endif /* SISUSB_H */ |
320 | |||
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c index 8d0edc867f3..43722e5a49d 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_con.c +++ b/drivers/usb/misc/sisusbvga/sisusb_con.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/kernel.h> | 52 | #include <linux/kernel.h> |
53 | #include <linux/signal.h> | 53 | #include <linux/signal.h> |
54 | #include <linux/fs.h> | 54 | #include <linux/fs.h> |
55 | #include <linux/usb.h> | ||
55 | #include <linux/tty.h> | 56 | #include <linux/tty.h> |
56 | #include <linux/console.h> | 57 | #include <linux/console.h> |
57 | #include <linux/string.h> | 58 | #include <linux/string.h> |
@@ -373,14 +374,6 @@ sisusbcon_putc(struct vc_data *c, int ch, int y, int x) | |||
373 | return; | 374 | return; |
374 | 375 | ||
375 | /* sisusb->lock is down */ | 376 | /* sisusb->lock is down */ |
376 | |||
377 | /* Don't need to put the character into buffer ourselves, | ||
378 | * because the vt does this BEFORE calling us. | ||
379 | */ | ||
380 | #if 0 | ||
381 | sisusbcon_writew(ch, SISUSB_VADDR(x, y)); | ||
382 | #endif | ||
383 | |||
384 | if (sisusb_is_inactive(c, sisusb)) { | 377 | if (sisusb_is_inactive(c, sisusb)) { |
385 | mutex_unlock(&sisusb->lock); | 378 | mutex_unlock(&sisusb->lock); |
386 | return; | 379 | return; |
@@ -490,10 +483,6 @@ sisusbcon_bmove(struct vc_data *c, int sy, int sx, | |||
490 | struct sisusb_usb_data *sisusb; | 483 | struct sisusb_usb_data *sisusb; |
491 | ssize_t written; | 484 | ssize_t written; |
492 | int cols, length; | 485 | int cols, length; |
493 | #if 0 | ||
494 | u16 *src, *dest; | ||
495 | int i; | ||
496 | #endif | ||
497 | 486 | ||
498 | if (width <= 0 || height <= 0) | 487 | if (width <= 0 || height <= 0) |
499 | return; | 488 | return; |
@@ -505,41 +494,6 @@ sisusbcon_bmove(struct vc_data *c, int sy, int sx, | |||
505 | 494 | ||
506 | cols = sisusb->sisusb_num_columns; | 495 | cols = sisusb->sisusb_num_columns; |
507 | 496 | ||
508 | /* Don't need to move data outselves, because | ||
509 | * vt does this BEFORE calling us. | ||
510 | * This is only used by vt's insert/deletechar. | ||
511 | */ | ||
512 | #if 0 | ||
513 | if (sx == 0 && dx == 0 && width >= c->vc_cols && width <= cols) { | ||
514 | |||
515 | sisusbcon_memmovew(SISUSB_VADDR(0, dy), SISUSB_VADDR(0, sy), | ||
516 | height * width * 2); | ||
517 | |||
518 | } else if (dy < sy || (dy == sy && dx < sx)) { | ||
519 | |||
520 | src = SISUSB_VADDR(sx, sy); | ||
521 | dest = SISUSB_VADDR(dx, dy); | ||
522 | |||
523 | for (i = height; i > 0; i--) { | ||
524 | sisusbcon_memmovew(dest, src, width * 2); | ||
525 | src += cols; | ||
526 | dest += cols; | ||
527 | } | ||
528 | |||
529 | } else { | ||
530 | |||
531 | src = SISUSB_VADDR(sx, sy + height - 1); | ||
532 | dest = SISUSB_VADDR(dx, dy + height - 1); | ||
533 | |||
534 | for (i = height; i > 0; i--) { | ||
535 | sisusbcon_memmovew(dest, src, width * 2); | ||
536 | src -= cols; | ||
537 | dest -= cols; | ||
538 | } | ||
539 | |||
540 | } | ||
541 | #endif | ||
542 | |||
543 | if (sisusb_is_inactive(c, sisusb)) { | 497 | if (sisusb_is_inactive(c, sisusb)) { |
544 | mutex_unlock(&sisusb->lock); | 498 | mutex_unlock(&sisusb->lock); |
545 | return; | 499 | return; |
@@ -584,7 +538,7 @@ sisusbcon_switch(struct vc_data *c) | |||
584 | */ | 538 | */ |
585 | if (c->vc_origin == (unsigned long)c->vc_screenbuf) { | 539 | if (c->vc_origin == (unsigned long)c->vc_screenbuf) { |
586 | mutex_unlock(&sisusb->lock); | 540 | mutex_unlock(&sisusb->lock); |
587 | printk(KERN_DEBUG "sisusb: ASSERT ORIGIN != SCREENBUF!\n"); | 541 | dev_dbg(&sisusb->sisusb_dev->dev, "ASSERT ORIGIN != SCREENBUF!\n"); |
588 | return 0; | 542 | return 0; |
589 | } | 543 | } |
590 | 544 | ||
@@ -1475,7 +1429,7 @@ static const struct consw sisusb_dummy_con = { | |||
1475 | int | 1429 | int |
1476 | sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last) | 1430 | sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last) |
1477 | { | 1431 | { |
1478 | int i, ret, minor = sisusb->minor; | 1432 | int i, ret; |
1479 | 1433 | ||
1480 | mutex_lock(&sisusb->lock); | 1434 | mutex_lock(&sisusb->lock); |
1481 | 1435 | ||
@@ -1508,9 +1462,7 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last) | |||
1508 | /* Set up text mode (and upload default font) */ | 1462 | /* Set up text mode (and upload default font) */ |
1509 | if (sisusb_reset_text_mode(sisusb, 1)) { | 1463 | if (sisusb_reset_text_mode(sisusb, 1)) { |
1510 | mutex_unlock(&sisusb->lock); | 1464 | mutex_unlock(&sisusb->lock); |
1511 | printk(KERN_ERR | 1465 | dev_err(&sisusb->sisusb_dev->dev, "Failed to set up text mode\n"); |
1512 | "sisusbvga[%d]: Failed to set up text mode\n", | ||
1513 | minor); | ||
1514 | return 1; | 1466 | return 1; |
1515 | } | 1467 | } |
1516 | 1468 | ||
@@ -1531,9 +1483,7 @@ sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last) | |||
1531 | /* Allocate screen buffer */ | 1483 | /* Allocate screen buffer */ |
1532 | if (!(sisusb->scrbuf = (unsigned long)vmalloc(sisusb->scrbuf_size))) { | 1484 | if (!(sisusb->scrbuf = (unsigned long)vmalloc(sisusb->scrbuf_size))) { |
1533 | mutex_unlock(&sisusb->lock); | 1485 | mutex_unlock(&sisusb->lock); |
1534 | printk(KERN_ERR | 1486 | dev_err(&sisusb->sisusb_dev->dev, "Failed to allocate screen buffer\n"); |
1535 | "sisusbvga[%d]: Failed to allocate screen buffer\n", | ||
1536 | minor); | ||
1537 | return 1; | 1487 | return 1; |
1538 | } | 1488 | } |
1539 | 1489 | ||
diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.c b/drivers/usb/misc/sisusbvga/sisusb_init.c index 9b30f896281..273de5d0934 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_init.c +++ b/drivers/usb/misc/sisusbvga/sisusb_init.c | |||
@@ -32,7 +32,7 @@ | |||
32 | * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 32 | * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
33 | * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 33 | * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
34 | * | 34 | * |
35 | * Author: Thomas Winischhofer <thomas@winischhofer.net> | 35 | * Author: Thomas Winischhofer <thomas@winischhofer.net> |
36 | * | 36 | * |
37 | */ | 37 | */ |
38 | 38 | ||
@@ -55,109 +55,18 @@ | |||
55 | /* POINTER INITIALIZATION */ | 55 | /* POINTER INITIALIZATION */ |
56 | /*********************************************/ | 56 | /*********************************************/ |
57 | 57 | ||
58 | static void | 58 | static void SiSUSB_InitPtr(struct SiS_Private *SiS_Pr) |
59 | SiSUSB_InitPtr(struct SiS_Private *SiS_Pr) | ||
60 | { | 59 | { |
61 | SiS_Pr->SiS_ModeResInfo = SiSUSB_ModeResInfo; | 60 | SiS_Pr->SiS_ModeResInfo = SiSUSB_ModeResInfo; |
62 | SiS_Pr->SiS_StandTable = SiSUSB_StandTable; | 61 | SiS_Pr->SiS_StandTable = SiSUSB_StandTable; |
63 | |||
64 | SiS_Pr->SiS_SModeIDTable = SiSUSB_SModeIDTable; | ||
65 | SiS_Pr->SiS_EModeIDTable = SiSUSB_EModeIDTable; | ||
66 | SiS_Pr->SiS_RefIndex = SiSUSB_RefIndex; | ||
67 | SiS_Pr->SiS_CRT1Table = SiSUSB_CRT1Table; | ||
68 | |||
69 | SiS_Pr->SiS_VCLKData = SiSUSB_VCLKData; | ||
70 | } | ||
71 | |||
72 | /*********************************************/ | ||
73 | /* HELPER: Get ModeID */ | ||
74 | /*********************************************/ | ||
75 | 62 | ||
76 | #if 0 | 63 | SiS_Pr->SiS_SModeIDTable = SiSUSB_SModeIDTable; |
77 | unsigned short | 64 | SiS_Pr->SiS_EModeIDTable = SiSUSB_EModeIDTable; |
78 | SiSUSB_GetModeID(int HDisplay, int VDisplay, int Depth) | 65 | SiS_Pr->SiS_RefIndex = SiSUSB_RefIndex; |
79 | { | 66 | SiS_Pr->SiS_CRT1Table = SiSUSB_CRT1Table; |
80 | unsigned short ModeIndex = 0; | ||
81 | |||
82 | switch (HDisplay) | ||
83 | { | ||
84 | case 320: | ||
85 | if (VDisplay == 200) | ||
86 | ModeIndex = ModeIndex_320x200[Depth]; | ||
87 | else if (VDisplay == 240) | ||
88 | ModeIndex = ModeIndex_320x240[Depth]; | ||
89 | break; | ||
90 | case 400: | ||
91 | if (VDisplay == 300) | ||
92 | ModeIndex = ModeIndex_400x300[Depth]; | ||
93 | break; | ||
94 | case 512: | ||
95 | if (VDisplay == 384) | ||
96 | ModeIndex = ModeIndex_512x384[Depth]; | ||
97 | break; | ||
98 | case 640: | ||
99 | if (VDisplay == 480) | ||
100 | ModeIndex = ModeIndex_640x480[Depth]; | ||
101 | else if (VDisplay == 400) | ||
102 | ModeIndex = ModeIndex_640x400[Depth]; | ||
103 | break; | ||
104 | case 720: | ||
105 | if (VDisplay == 480) | ||
106 | ModeIndex = ModeIndex_720x480[Depth]; | ||
107 | else if (VDisplay == 576) | ||
108 | ModeIndex = ModeIndex_720x576[Depth]; | ||
109 | break; | ||
110 | case 768: | ||
111 | if (VDisplay == 576) | ||
112 | ModeIndex = ModeIndex_768x576[Depth]; | ||
113 | break; | ||
114 | case 800: | ||
115 | if (VDisplay == 600) | ||
116 | ModeIndex = ModeIndex_800x600[Depth]; | ||
117 | else if (VDisplay == 480) | ||
118 | ModeIndex = ModeIndex_800x480[Depth]; | ||
119 | break; | ||
120 | case 848: | ||
121 | if (VDisplay == 480) | ||
122 | ModeIndex = ModeIndex_848x480[Depth]; | ||
123 | break; | ||
124 | case 856: | ||
125 | if (VDisplay == 480) | ||
126 | ModeIndex = ModeIndex_856x480[Depth]; | ||
127 | break; | ||
128 | case 960: | ||
129 | if (VDisplay == 540) | ||
130 | ModeIndex = ModeIndex_960x540[Depth]; | ||
131 | else if (VDisplay == 600) | ||
132 | ModeIndex = ModeIndex_960x600[Depth]; | ||
133 | break; | ||
134 | case 1024: | ||
135 | if (VDisplay == 576) | ||
136 | ModeIndex = ModeIndex_1024x576[Depth]; | ||
137 | else if (VDisplay == 768) | ||
138 | ModeIndex = ModeIndex_1024x768[Depth]; | ||
139 | break; | ||
140 | case 1152: | ||
141 | if (VDisplay == 864) | ||
142 | ModeIndex = ModeIndex_1152x864[Depth]; | ||
143 | break; | ||
144 | case 1280: | ||
145 | switch (VDisplay) { | ||
146 | case 720: | ||
147 | ModeIndex = ModeIndex_1280x720[Depth]; | ||
148 | break; | ||
149 | case 768: | ||
150 | ModeIndex = ModeIndex_1280x768[Depth]; | ||
151 | break; | ||
152 | case 1024: | ||
153 | ModeIndex = ModeIndex_1280x1024[Depth]; | ||
154 | break; | ||
155 | } | ||
156 | } | ||
157 | 67 | ||
158 | return ModeIndex; | 68 | SiS_Pr->SiS_VCLKData = SiSUSB_VCLKData; |
159 | } | 69 | } |
160 | #endif /* 0 */ | ||
161 | 70 | ||
162 | /*********************************************/ | 71 | /*********************************************/ |
163 | /* HELPER: SetReg, GetReg */ | 72 | /* HELPER: SetReg, GetReg */ |
@@ -165,21 +74,20 @@ SiSUSB_GetModeID(int HDisplay, int VDisplay, int Depth) | |||
165 | 74 | ||
166 | static void | 75 | static void |
167 | SiS_SetReg(struct SiS_Private *SiS_Pr, unsigned long port, | 76 | SiS_SetReg(struct SiS_Private *SiS_Pr, unsigned long port, |
168 | unsigned short index, unsigned short data) | 77 | unsigned short index, unsigned short data) |
169 | { | 78 | { |
170 | sisusb_setidxreg(SiS_Pr->sisusb, port, index, data); | 79 | sisusb_setidxreg(SiS_Pr->sisusb, port, index, data); |
171 | } | 80 | } |
172 | 81 | ||
173 | static void | 82 | static void |
174 | SiS_SetRegByte(struct SiS_Private *SiS_Pr, unsigned long port, | 83 | SiS_SetRegByte(struct SiS_Private *SiS_Pr, unsigned long port, |
175 | unsigned short data) | 84 | unsigned short data) |
176 | { | 85 | { |
177 | sisusb_setreg(SiS_Pr->sisusb, port, data); | 86 | sisusb_setreg(SiS_Pr->sisusb, port, data); |
178 | } | 87 | } |
179 | 88 | ||
180 | static unsigned char | 89 | static unsigned char |
181 | SiS_GetReg(struct SiS_Private *SiS_Pr, unsigned long port, | 90 | SiS_GetReg(struct SiS_Private *SiS_Pr, unsigned long port, unsigned short index) |
182 | unsigned short index) | ||
183 | { | 91 | { |
184 | u8 data; | 92 | u8 data; |
185 | 93 | ||
@@ -200,22 +108,22 @@ SiS_GetRegByte(struct SiS_Private *SiS_Pr, unsigned long port) | |||
200 | 108 | ||
201 | static void | 109 | static void |
202 | SiS_SetRegANDOR(struct SiS_Private *SiS_Pr, unsigned long port, | 110 | SiS_SetRegANDOR(struct SiS_Private *SiS_Pr, unsigned long port, |
203 | unsigned short index, unsigned short DataAND, | 111 | unsigned short index, unsigned short DataAND, |
204 | unsigned short DataOR) | 112 | unsigned short DataOR) |
205 | { | 113 | { |
206 | sisusb_setidxregandor(SiS_Pr->sisusb, port, index, DataAND, DataOR); | 114 | sisusb_setidxregandor(SiS_Pr->sisusb, port, index, DataAND, DataOR); |
207 | } | 115 | } |
208 | 116 | ||
209 | static void | 117 | static void |
210 | SiS_SetRegAND(struct SiS_Private *SiS_Pr, unsigned long port, | 118 | SiS_SetRegAND(struct SiS_Private *SiS_Pr, unsigned long port, |
211 | unsigned short index, unsigned short DataAND) | 119 | unsigned short index, unsigned short DataAND) |
212 | { | 120 | { |
213 | sisusb_setidxregand(SiS_Pr->sisusb, port, index, DataAND); | 121 | sisusb_setidxregand(SiS_Pr->sisusb, port, index, DataAND); |
214 | } | 122 | } |
215 | 123 | ||
216 | static void | 124 | static void |
217 | SiS_SetRegOR(struct SiS_Private *SiS_Pr,unsigned long port, | 125 | SiS_SetRegOR(struct SiS_Private *SiS_Pr, unsigned long port, |
218 | unsigned short index, unsigned short DataOR) | 126 | unsigned short index, unsigned short DataOR) |
219 | { | 127 | { |
220 | sisusb_setidxregor(SiS_Pr->sisusb, port, index, DataOR); | 128 | sisusb_setidxregor(SiS_Pr->sisusb, port, index, DataOR); |
221 | } | 129 | } |
@@ -224,8 +132,7 @@ SiS_SetRegOR(struct SiS_Private *SiS_Pr,unsigned long port, | |||
224 | /* HELPER: DisplayOn, DisplayOff */ | 132 | /* HELPER: DisplayOn, DisplayOff */ |
225 | /*********************************************/ | 133 | /*********************************************/ |
226 | 134 | ||
227 | static void | 135 | static void SiS_DisplayOn(struct SiS_Private *SiS_Pr) |
228 | SiS_DisplayOn(struct SiS_Private *SiS_Pr) | ||
229 | { | 136 | { |
230 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, 0xDF); | 137 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, 0xDF); |
231 | } | 138 | } |
@@ -234,8 +141,7 @@ SiS_DisplayOn(struct SiS_Private *SiS_Pr) | |||
234 | /* HELPER: Init Port Addresses */ | 141 | /* HELPER: Init Port Addresses */ |
235 | /*********************************************/ | 142 | /*********************************************/ |
236 | 143 | ||
237 | static void | 144 | static void SiSUSBRegInit(struct SiS_Private *SiS_Pr, unsigned long BaseAddr) |
238 | SiSUSBRegInit(struct SiS_Private *SiS_Pr, unsigned long BaseAddr) | ||
239 | { | 145 | { |
240 | SiS_Pr->SiS_P3c4 = BaseAddr + 0x14; | 146 | SiS_Pr->SiS_P3c4 = BaseAddr + 0x14; |
241 | SiS_Pr->SiS_P3d4 = BaseAddr + 0x24; | 147 | SiS_Pr->SiS_P3d4 = BaseAddr + 0x24; |
@@ -258,8 +164,7 @@ SiSUSBRegInit(struct SiS_Private *SiS_Pr, unsigned long BaseAddr) | |||
258 | /* HELPER: GetSysFlags */ | 164 | /* HELPER: GetSysFlags */ |
259 | /*********************************************/ | 165 | /*********************************************/ |
260 | 166 | ||
261 | static void | 167 | static void SiS_GetSysFlags(struct SiS_Private *SiS_Pr) |
262 | SiS_GetSysFlags(struct SiS_Private *SiS_Pr) | ||
263 | { | 168 | { |
264 | SiS_Pr->SiS_MyCR63 = 0x63; | 169 | SiS_Pr->SiS_MyCR63 = 0x63; |
265 | } | 170 | } |
@@ -268,8 +173,7 @@ SiS_GetSysFlags(struct SiS_Private *SiS_Pr) | |||
268 | /* HELPER: Init PCI & Engines */ | 173 | /* HELPER: Init PCI & Engines */ |
269 | /*********************************************/ | 174 | /*********************************************/ |
270 | 175 | ||
271 | static void | 176 | static void SiSInitPCIetc(struct SiS_Private *SiS_Pr) |
272 | SiSInitPCIetc(struct SiS_Private *SiS_Pr) | ||
273 | { | 177 | { |
274 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x20, 0xa1); | 178 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x20, 0xa1); |
275 | /* - Enable 2D (0x40) | 179 | /* - Enable 2D (0x40) |
@@ -285,8 +189,7 @@ SiSInitPCIetc(struct SiS_Private *SiS_Pr) | |||
285 | /* HELPER: SET SEGMENT REGISTERS */ | 189 | /* HELPER: SET SEGMENT REGISTERS */ |
286 | /*********************************************/ | 190 | /*********************************************/ |
287 | 191 | ||
288 | static void | 192 | static void SiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value) |
289 | SiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value) | ||
290 | { | 193 | { |
291 | unsigned short temp; | 194 | unsigned short temp; |
292 | 195 | ||
@@ -299,8 +202,7 @@ SiS_SetSegRegLower(struct SiS_Private *SiS_Pr, unsigned short value) | |||
299 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd, temp); | 202 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd, temp); |
300 | } | 203 | } |
301 | 204 | ||
302 | static void | 205 | static void SiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value) |
303 | SiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value) | ||
304 | { | 206 | { |
305 | unsigned short temp; | 207 | unsigned short temp; |
306 | 208 | ||
@@ -313,15 +215,13 @@ SiS_SetSegRegUpper(struct SiS_Private *SiS_Pr, unsigned short value) | |||
313 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd, temp); | 215 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3cd, temp); |
314 | } | 216 | } |
315 | 217 | ||
316 | static void | 218 | static void SiS_SetSegmentReg(struct SiS_Private *SiS_Pr, unsigned short value) |
317 | SiS_SetSegmentReg(struct SiS_Private *SiS_Pr, unsigned short value) | ||
318 | { | 219 | { |
319 | SiS_SetSegRegLower(SiS_Pr, value); | 220 | SiS_SetSegRegLower(SiS_Pr, value); |
320 | SiS_SetSegRegUpper(SiS_Pr, value); | 221 | SiS_SetSegRegUpper(SiS_Pr, value); |
321 | } | 222 | } |
322 | 223 | ||
323 | static void | 224 | static void SiS_ResetSegmentReg(struct SiS_Private *SiS_Pr) |
324 | SiS_ResetSegmentReg(struct SiS_Private *SiS_Pr) | ||
325 | { | 225 | { |
326 | SiS_SetSegmentReg(SiS_Pr, 0); | 226 | SiS_SetSegmentReg(SiS_Pr, 0); |
327 | } | 227 | } |
@@ -337,14 +237,12 @@ SiS_SetSegmentRegOver(struct SiS_Private *SiS_Pr, unsigned short value) | |||
337 | SiS_SetSegmentReg(SiS_Pr, value); | 237 | SiS_SetSegmentReg(SiS_Pr, value); |
338 | } | 238 | } |
339 | 239 | ||
340 | static void | 240 | static void SiS_ResetSegmentRegOver(struct SiS_Private *SiS_Pr) |
341 | SiS_ResetSegmentRegOver(struct SiS_Private *SiS_Pr) | ||
342 | { | 241 | { |
343 | SiS_SetSegmentRegOver(SiS_Pr, 0); | 242 | SiS_SetSegmentRegOver(SiS_Pr, 0); |
344 | } | 243 | } |
345 | 244 | ||
346 | static void | 245 | static void SiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr) |
347 | SiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr) | ||
348 | { | 246 | { |
349 | SiS_ResetSegmentReg(SiS_Pr); | 247 | SiS_ResetSegmentReg(SiS_Pr); |
350 | SiS_ResetSegmentRegOver(SiS_Pr); | 248 | SiS_ResetSegmentRegOver(SiS_Pr); |
@@ -356,7 +254,7 @@ SiS_ResetSegmentRegisters(struct SiS_Private *SiS_Pr) | |||
356 | 254 | ||
357 | static int | 255 | static int |
358 | SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo, | 256 | SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo, |
359 | unsigned short *ModeIdIndex) | 257 | unsigned short *ModeIdIndex) |
360 | { | 258 | { |
361 | if ((*ModeNo) <= 0x13) { | 259 | if ((*ModeNo) <= 0x13) { |
362 | 260 | ||
@@ -367,12 +265,14 @@ SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo, | |||
367 | 265 | ||
368 | } else { | 266 | } else { |
369 | 267 | ||
370 | for(*ModeIdIndex = 0; ;(*ModeIdIndex)++) { | 268 | for (*ModeIdIndex = 0;; (*ModeIdIndex)++) { |
371 | 269 | ||
372 | if (SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == (*ModeNo)) | 270 | if (SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == |
271 | (*ModeNo)) | ||
373 | break; | 272 | break; |
374 | 273 | ||
375 | if (SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == 0xFF) | 274 | if (SiS_Pr->SiS_EModeIDTable[*ModeIdIndex].Ext_ModeID == |
275 | 0xFF) | ||
376 | return 0; | 276 | return 0; |
377 | } | 277 | } |
378 | 278 | ||
@@ -385,8 +285,7 @@ SiS_SearchModeID(struct SiS_Private *SiS_Pr, unsigned short *ModeNo, | |||
385 | /* HELPER: ENABLE CRT1 */ | 285 | /* HELPER: ENABLE CRT1 */ |
386 | /*********************************************/ | 286 | /*********************************************/ |
387 | 287 | ||
388 | static void | 288 | static void SiS_HandleCRT1(struct SiS_Private *SiS_Pr) |
389 | SiS_HandleCRT1(struct SiS_Private *SiS_Pr) | ||
390 | { | 289 | { |
391 | /* Enable CRT1 gating */ | 290 | /* Enable CRT1 gating */ |
392 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, SiS_Pr->SiS_MyCR63, 0xbf); | 291 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, SiS_Pr->SiS_MyCR63, 0xbf); |
@@ -398,9 +297,9 @@ SiS_HandleCRT1(struct SiS_Private *SiS_Pr) | |||
398 | 297 | ||
399 | static unsigned short | 298 | static unsigned short |
400 | SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 299 | SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
401 | unsigned short ModeIdIndex) | 300 | unsigned short ModeIdIndex) |
402 | { | 301 | { |
403 | static const unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8}; | 302 | static const unsigned short ColorDepth[6] = { 1, 2, 4, 4, 6, 8 }; |
404 | unsigned short modeflag; | 303 | unsigned short modeflag; |
405 | short index; | 304 | short index; |
406 | 305 | ||
@@ -411,7 +310,8 @@ SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
411 | } | 310 | } |
412 | 311 | ||
413 | index = (modeflag & ModeTypeMask) - ModeEGA; | 312 | index = (modeflag & ModeTypeMask) - ModeEGA; |
414 | if (index < 0) index = 0; | 313 | if (index < 0) |
314 | index = 0; | ||
415 | return ColorDepth[index]; | 315 | return ColorDepth[index]; |
416 | } | 316 | } |
417 | 317 | ||
@@ -421,7 +321,7 @@ SiS_GetColorDepth(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
421 | 321 | ||
422 | static unsigned short | 322 | static unsigned short |
423 | SiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 323 | SiS_GetOffset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
424 | unsigned short ModeIdIndex, unsigned short rrti) | 324 | unsigned short ModeIdIndex, unsigned short rrti) |
425 | { | 325 | { |
426 | unsigned short xres, temp, colordepth, infoflag; | 326 | unsigned short xres, temp, colordepth, infoflag; |
427 | 327 | ||
@@ -458,8 +358,8 @@ SiS_SetSeqRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) | |||
458 | SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0] | 0x20; | 358 | SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[0] | 0x20; |
459 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, SRdata); | 359 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x01, SRdata); |
460 | 360 | ||
461 | for(i = 2; i <= 4; i++) { | 361 | for (i = 2; i <= 4; i++) { |
462 | SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i-1]; | 362 | SRdata = SiS_Pr->SiS_StandTable[StandTableIndex].SR[i - 1]; |
463 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, i, SRdata); | 363 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, i, SRdata); |
464 | } | 364 | } |
465 | } | 365 | } |
@@ -488,7 +388,7 @@ SiS_SetCRTCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) | |||
488 | 388 | ||
489 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, 0x11, 0x7f); | 389 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, 0x11, 0x7f); |
490 | 390 | ||
491 | for(i = 0; i <= 0x18; i++) { | 391 | for (i = 0; i <= 0x18; i++) { |
492 | CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i]; | 392 | CRTCdata = SiS_Pr->SiS_StandTable[StandTableIndex].CRTC[i]; |
493 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, i, CRTCdata); | 393 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, i, CRTCdata); |
494 | } | 394 | } |
@@ -504,7 +404,7 @@ SiS_SetATTRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) | |||
504 | unsigned char ARdata; | 404 | unsigned char ARdata; |
505 | unsigned short i; | 405 | unsigned short i; |
506 | 406 | ||
507 | for(i = 0; i <= 0x13; i++) { | 407 | for (i = 0; i <= 0x13; i++) { |
508 | ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i]; | 408 | ARdata = SiS_Pr->SiS_StandTable[StandTableIndex].ATTR[i]; |
509 | SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da); | 409 | SiS_GetRegByte(SiS_Pr, SiS_Pr->SiS_P3da); |
510 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, i); | 410 | SiS_SetRegByte(SiS_Pr, SiS_Pr->SiS_P3c0, i); |
@@ -529,7 +429,7 @@ SiS_SetGRCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) | |||
529 | unsigned char GRdata; | 429 | unsigned char GRdata; |
530 | unsigned short i; | 430 | unsigned short i; |
531 | 431 | ||
532 | for(i = 0; i <= 0x08; i++) { | 432 | for (i = 0; i <= 0x08; i++) { |
533 | GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i]; | 433 | GRdata = SiS_Pr->SiS_StandTable[StandTableIndex].GRC[i]; |
534 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3ce, i, GRdata); | 434 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3ce, i, GRdata); |
535 | } | 435 | } |
@@ -544,12 +444,11 @@ SiS_SetGRCRegs(struct SiS_Private *SiS_Pr, unsigned short StandTableIndex) | |||
544 | /* CLEAR EXTENDED REGISTERS */ | 444 | /* CLEAR EXTENDED REGISTERS */ |
545 | /*********************************************/ | 445 | /*********************************************/ |
546 | 446 | ||
547 | static void | 447 | static void SiS_ClearExt1Regs(struct SiS_Private *SiS_Pr, unsigned short ModeNo) |
548 | SiS_ClearExt1Regs(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | ||
549 | { | 448 | { |
550 | int i; | 449 | int i; |
551 | 450 | ||
552 | for(i = 0x0A; i <= 0x0E; i++) { | 451 | for (i = 0x0A; i <= 0x0E; i++) { |
553 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, i, 0x00); | 452 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, i, 0x00); |
554 | } | 453 | } |
555 | 454 | ||
@@ -562,15 +461,16 @@ SiS_ClearExt1Regs(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | |||
562 | 461 | ||
563 | static unsigned short | 462 | static unsigned short |
564 | SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 463 | SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
565 | unsigned short ModeIdIndex) | 464 | unsigned short ModeIdIndex) |
566 | { | 465 | { |
567 | unsigned short rrti, i, index, temp; | 466 | unsigned short rrti, i, index, temp; |
568 | 467 | ||
569 | if (ModeNo <= 0x13) | 468 | if (ModeNo <= 0x13) |
570 | return 0xFFFF; | 469 | return 0xFFFF; |
571 | 470 | ||
572 | index = SiS_GetReg(SiS_Pr,SiS_Pr->SiS_P3d4, 0x33) & 0x0F; | 471 | index = SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x33) & 0x0F; |
573 | if (index > 0) index--; | 472 | if (index > 0) |
473 | index--; | ||
574 | 474 | ||
575 | rrti = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex; | 475 | rrti = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].REFindex; |
576 | ModeNo = SiS_Pr->SiS_RefIndex[rrti].ModeID; | 476 | ModeNo = SiS_Pr->SiS_RefIndex[rrti].ModeID; |
@@ -580,13 +480,14 @@ SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
580 | if (SiS_Pr->SiS_RefIndex[rrti + i].ModeID != ModeNo) | 480 | if (SiS_Pr->SiS_RefIndex[rrti + i].ModeID != ModeNo) |
581 | break; | 481 | break; |
582 | 482 | ||
583 | temp = SiS_Pr->SiS_RefIndex[rrti + i].Ext_InfoFlag & ModeTypeMask; | 483 | temp = |
484 | SiS_Pr->SiS_RefIndex[rrti + i].Ext_InfoFlag & ModeTypeMask; | ||
584 | if (temp < SiS_Pr->SiS_ModeType) | 485 | if (temp < SiS_Pr->SiS_ModeType) |
585 | break; | 486 | break; |
586 | 487 | ||
587 | i++; | 488 | i++; |
588 | index--; | 489 | index--; |
589 | } while(index != 0xFFFF); | 490 | } while (index != 0xFFFF); |
590 | 491 | ||
591 | i--; | 492 | i--; |
592 | 493 | ||
@@ -597,8 +498,7 @@ SiS_GetRatePtr(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
597 | /* SYNC */ | 498 | /* SYNC */ |
598 | /*********************************************/ | 499 | /*********************************************/ |
599 | 500 | ||
600 | static void | 501 | static void SiS_SetCRT1Sync(struct SiS_Private *SiS_Pr, unsigned short rrti) |
601 | SiS_SetCRT1Sync(struct SiS_Private *SiS_Pr, unsigned short rrti) | ||
602 | { | 502 | { |
603 | unsigned short sync = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag >> 8; | 503 | unsigned short sync = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag >> 8; |
604 | sync &= 0xC0; | 504 | sync &= 0xC0; |
@@ -612,39 +512,40 @@ SiS_SetCRT1Sync(struct SiS_Private *SiS_Pr, unsigned short rrti) | |||
612 | 512 | ||
613 | static void | 513 | static void |
614 | SiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 514 | SiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
615 | unsigned short ModeIdIndex, unsigned short rrti) | 515 | unsigned short ModeIdIndex, unsigned short rrti) |
616 | { | 516 | { |
617 | unsigned char index; | 517 | unsigned char index; |
618 | unsigned short temp, i, j, modeflag; | 518 | unsigned short temp, i, j, modeflag; |
619 | 519 | ||
620 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4,0x11,0x7f); | 520 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3d4, 0x11, 0x7f); |
621 | 521 | ||
622 | modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; | 522 | modeflag = SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag; |
623 | 523 | ||
624 | index = SiS_Pr->SiS_RefIndex[rrti].Ext_CRT1CRTC; | 524 | index = SiS_Pr->SiS_RefIndex[rrti].Ext_CRT1CRTC; |
625 | 525 | ||
626 | for(i = 0,j = 0; i <= 7; i++, j++) { | 526 | for (i = 0, j = 0; i <= 7; i++, j++) { |
627 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j, | 527 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j, |
628 | SiS_Pr->SiS_CRT1Table[index].CR[i]); | 528 | SiS_Pr->SiS_CRT1Table[index].CR[i]); |
629 | } | 529 | } |
630 | for(j = 0x10; i <= 10; i++, j++) { | 530 | for (j = 0x10; i <= 10; i++, j++) { |
631 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j, | 531 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j, |
632 | SiS_Pr->SiS_CRT1Table[index].CR[i]); | 532 | SiS_Pr->SiS_CRT1Table[index].CR[i]); |
633 | } | 533 | } |
634 | for(j = 0x15; i <= 12; i++, j++) { | 534 | for (j = 0x15; i <= 12; i++, j++) { |
635 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j, | 535 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, j, |
636 | SiS_Pr->SiS_CRT1Table[index].CR[i]); | 536 | SiS_Pr->SiS_CRT1Table[index].CR[i]); |
637 | } | 537 | } |
638 | for(j = 0x0A; i <= 15; i++, j++) { | 538 | for (j = 0x0A; i <= 15; i++, j++) { |
639 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, j, | 539 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, j, |
640 | SiS_Pr->SiS_CRT1Table[index].CR[i]); | 540 | SiS_Pr->SiS_CRT1Table[index].CR[i]); |
641 | } | 541 | } |
642 | 542 | ||
643 | temp = SiS_Pr->SiS_CRT1Table[index].CR[16] & 0xE0; | 543 | temp = SiS_Pr->SiS_CRT1Table[index].CR[16] & 0xE0; |
644 | SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4, 0x0E, temp); | 544 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0E, temp); |
645 | 545 | ||
646 | temp = ((SiS_Pr->SiS_CRT1Table[index].CR[16]) & 0x01) << 5; | 546 | temp = ((SiS_Pr->SiS_CRT1Table[index].CR[16]) & 0x01) << 5; |
647 | if (modeflag & DoubleScanMode) temp |= 0x80; | 547 | if (modeflag & DoubleScanMode) |
548 | temp |= 0x80; | ||
648 | SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3d4, 0x09, 0x5F, temp); | 549 | SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3d4, 0x09, 0x5F, temp); |
649 | 550 | ||
650 | if (SiS_Pr->SiS_ModeType > ModeVGA) | 551 | if (SiS_Pr->SiS_ModeType > ModeVGA) |
@@ -659,10 +560,10 @@ SiS_SetCRT1CRTC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
659 | 560 | ||
660 | static void | 561 | static void |
661 | SiS_SetCRT1Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 562 | SiS_SetCRT1Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
662 | unsigned short ModeIdIndex, unsigned short rrti) | 563 | unsigned short ModeIdIndex, unsigned short rrti) |
663 | { | 564 | { |
664 | unsigned short du = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, rrti); | 565 | unsigned short du = SiS_GetOffset(SiS_Pr, ModeNo, ModeIdIndex, rrti); |
665 | unsigned short infoflag = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag; | 566 | unsigned short infoflag = SiS_Pr->SiS_RefIndex[rrti].Ext_InfoFlag; |
666 | unsigned short temp; | 567 | unsigned short temp; |
667 | 568 | ||
668 | temp = (du >> 8) & 0x0f; | 569 | temp = (du >> 8) & 0x0f; |
@@ -670,11 +571,13 @@ SiS_SetCRT1Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
670 | 571 | ||
671 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x13, (du & 0xFF)); | 572 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x13, (du & 0xFF)); |
672 | 573 | ||
673 | if (infoflag & InterlaceMode) du >>= 1; | 574 | if (infoflag & InterlaceMode) |
575 | du >>= 1; | ||
674 | 576 | ||
675 | du <<= 5; | 577 | du <<= 5; |
676 | temp = (du >> 8) & 0xff; | 578 | temp = (du >> 8) & 0xff; |
677 | if (du & 0xff) temp++; | 579 | if (du & 0xff) |
580 | temp++; | ||
678 | temp++; | 581 | temp++; |
679 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x10, temp); | 582 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x10, temp); |
680 | } | 583 | } |
@@ -685,17 +588,17 @@ SiS_SetCRT1Offset(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
685 | 588 | ||
686 | static void | 589 | static void |
687 | SiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 590 | SiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
688 | unsigned short rrti) | 591 | unsigned short rrti) |
689 | { | 592 | { |
690 | unsigned short index = SiS_Pr->SiS_RefIndex[rrti].Ext_CRTVCLK; | 593 | unsigned short index = SiS_Pr->SiS_RefIndex[rrti].Ext_CRTVCLK; |
691 | unsigned short clka = SiS_Pr->SiS_VCLKData[index].SR2B; | 594 | unsigned short clka = SiS_Pr->SiS_VCLKData[index].SR2B; |
692 | unsigned short clkb = SiS_Pr->SiS_VCLKData[index].SR2C; | 595 | unsigned short clkb = SiS_Pr->SiS_VCLKData[index].SR2C; |
693 | 596 | ||
694 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4,0x31,0xCF); | 597 | SiS_SetRegAND(SiS_Pr, SiS_Pr->SiS_P3c4, 0x31, 0xCF); |
695 | 598 | ||
696 | SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x2B,clka); | 599 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x2B, clka); |
697 | SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x2C,clkb); | 600 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x2C, clkb); |
698 | SiS_SetReg(SiS_Pr,SiS_Pr->SiS_P3c4,0x2D,0x01); | 601 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x2D, 0x01); |
699 | } | 602 | } |
700 | 603 | ||
701 | /*********************************************/ | 604 | /*********************************************/ |
@@ -704,7 +607,7 @@ SiS_SetCRT1VCLK(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
704 | 607 | ||
705 | static void | 608 | static void |
706 | SiS_SetCRT1FIFO_310(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 609 | SiS_SetCRT1FIFO_310(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
707 | unsigned short mi) | 610 | unsigned short mi) |
708 | { | 611 | { |
709 | unsigned short modeflag = SiS_Pr->SiS_EModeIDTable[mi].Ext_ModeFlag; | 612 | unsigned short modeflag = SiS_Pr->SiS_EModeIDTable[mi].Ext_ModeFlag; |
710 | 613 | ||
@@ -729,7 +632,7 @@ SiS_SetCRT1FIFO_310(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
729 | 632 | ||
730 | static void | 633 | static void |
731 | SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 634 | SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
732 | unsigned short rrti) | 635 | unsigned short rrti) |
733 | { | 636 | { |
734 | unsigned short data = 0, VCLK = 0, index = 0; | 637 | unsigned short data = 0, VCLK = 0, index = 0; |
735 | 638 | ||
@@ -738,7 +641,8 @@ SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
738 | VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; | 641 | VCLK = SiS_Pr->SiS_VCLKData[index].CLOCK; |
739 | } | 642 | } |
740 | 643 | ||
741 | if (VCLK >= 166) data |= 0x0c; | 644 | if (VCLK >= 166) |
645 | data |= 0x0c; | ||
742 | SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x32, 0xf3, data); | 646 | SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x32, 0xf3, data); |
743 | 647 | ||
744 | if (VCLK >= 166) | 648 | if (VCLK >= 166) |
@@ -758,7 +662,7 @@ SiS_SetVCLKState(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
758 | 662 | ||
759 | static void | 663 | static void |
760 | SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 664 | SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
761 | unsigned short ModeIdIndex, unsigned short rrti) | 665 | unsigned short ModeIdIndex, unsigned short rrti) |
762 | { | 666 | { |
763 | unsigned short data, infoflag = 0, modeflag; | 667 | unsigned short data, infoflag = 0, modeflag; |
764 | 668 | ||
@@ -778,17 +682,22 @@ SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
778 | data |= 0x02; | 682 | data |= 0x02; |
779 | data |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2); | 683 | data |= ((SiS_Pr->SiS_ModeType - ModeVGA) << 2); |
780 | } | 684 | } |
781 | if (infoflag & InterlaceMode) data |= 0x20; | 685 | if (infoflag & InterlaceMode) |
686 | data |= 0x20; | ||
782 | } | 687 | } |
783 | SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x06, 0xC0, data); | 688 | SiS_SetRegANDOR(SiS_Pr, SiS_Pr->SiS_P3c4, 0x06, 0xC0, data); |
784 | 689 | ||
785 | data = 0; | 690 | data = 0; |
786 | if (infoflag & InterlaceMode) { | 691 | if (infoflag & InterlaceMode) { |
787 | /* data = (Hsync / 8) - ((Htotal / 8) / 2) + 3 */ | 692 | /* data = (Hsync / 8) - ((Htotal / 8) / 2) + 3 */ |
788 | unsigned short hrs = (SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x04) | | 693 | unsigned short hrs = |
789 | ((SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0b) & 0xc0) << 2)) - 3; | 694 | (SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x04) | |
790 | unsigned short hto = (SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x00) | | 695 | ((SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0b) & 0xc0) << 2)) |
791 | ((SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0b) & 0x03) << 8)) + 5; | 696 | - 3; |
697 | unsigned short hto = | ||
698 | (SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x00) | | ||
699 | ((SiS_GetReg(SiS_Pr, SiS_Pr->SiS_P3c4, 0x0b) & 0x03) << 8)) | ||
700 | + 5; | ||
792 | data = hrs - (hto >> 1) + 3; | 701 | data = hrs - (hto >> 1) + 3; |
793 | } | 702 | } |
794 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x19, (data & 0xFF)); | 703 | SiS_SetReg(SiS_Pr, SiS_Pr->SiS_P3d4, 0x19, (data & 0xFF)); |
@@ -829,20 +738,26 @@ SiS_SetCRT1ModeRegs(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
829 | 738 | ||
830 | static void | 739 | static void |
831 | SiS_WriteDAC(struct SiS_Private *SiS_Pr, unsigned long DACData, | 740 | SiS_WriteDAC(struct SiS_Private *SiS_Pr, unsigned long DACData, |
832 | unsigned short shiftflag, unsigned short dl, unsigned short ah, | 741 | unsigned short shiftflag, unsigned short dl, unsigned short ah, |
833 | unsigned short al, unsigned short dh) | 742 | unsigned short al, unsigned short dh) |
834 | { | 743 | { |
835 | unsigned short d1, d2, d3; | 744 | unsigned short d1, d2, d3; |
836 | 745 | ||
837 | switch (dl) { | 746 | switch (dl) { |
838 | case 0: | 747 | case 0: |
839 | d1 = dh; d2 = ah; d3 = al; | 748 | d1 = dh; |
840 | break; | 749 | d2 = ah; |
841 | case 1: | 750 | d3 = al; |
842 | d1 = ah; d2 = al; d3 = dh; | 751 | break; |
843 | break; | 752 | case 1: |
844 | default: | 753 | d1 = ah; |
845 | d1 = al; d2 = dh; d3 = ah; | 754 | d2 = al; |
755 | d3 = dh; | ||
756 | break; | ||
757 | default: | ||
758 | d1 = al; | ||
759 | d2 = dh; | ||
760 | d3 = ah; | ||
846 | } | 761 | } |
847 | SiS_SetRegByte(SiS_Pr, DACData, (d1 << shiftflag)); | 762 | SiS_SetRegByte(SiS_Pr, DACData, (d1 << shiftflag)); |
848 | SiS_SetRegByte(SiS_Pr, DACData, (d2 << shiftflag)); | 763 | SiS_SetRegByte(SiS_Pr, DACData, (d2 << shiftflag)); |
@@ -850,7 +765,8 @@ SiS_WriteDAC(struct SiS_Private *SiS_Pr, unsigned long DACData, | |||
850 | } | 765 | } |
851 | 766 | ||
852 | static void | 767 | static void |
853 | SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short mi) | 768 | SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
769 | unsigned short mi) | ||
854 | { | 770 | { |
855 | unsigned short data, data2, time, i, j, k, m, n, o; | 771 | unsigned short data, data2, time, i, j, k, m, n, o; |
856 | unsigned short si, di, bx, sf; | 772 | unsigned short si, di, bx, sf; |
@@ -884,41 +800,45 @@ SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short mi | |||
884 | 800 | ||
885 | SiS_SetRegByte(SiS_Pr, DACAddr, 0x00); | 801 | SiS_SetRegByte(SiS_Pr, DACAddr, 0x00); |
886 | 802 | ||
887 | for(i = 0; i < j; i++) { | 803 | for (i = 0; i < j; i++) { |
888 | data = table[i]; | 804 | data = table[i]; |
889 | for(k = 0; k < 3; k++) { | 805 | for (k = 0; k < 3; k++) { |
890 | data2 = 0; | 806 | data2 = 0; |
891 | if (data & 0x01) data2 += 0x2A; | 807 | if (data & 0x01) |
892 | if (data & 0x02) data2 += 0x15; | 808 | data2 += 0x2A; |
809 | if (data & 0x02) | ||
810 | data2 += 0x15; | ||
893 | SiS_SetRegByte(SiS_Pr, DACData, (data2 << sf)); | 811 | SiS_SetRegByte(SiS_Pr, DACData, (data2 << sf)); |
894 | data >>= 2; | 812 | data >>= 2; |
895 | } | 813 | } |
896 | } | 814 | } |
897 | 815 | ||
898 | if (time == 256) { | 816 | if (time == 256) { |
899 | for(i = 16; i < 32; i++) { | 817 | for (i = 16; i < 32; i++) { |
900 | data = table[i] << sf; | 818 | data = table[i] << sf; |
901 | for(k = 0; k < 3; k++) | 819 | for (k = 0; k < 3; k++) |
902 | SiS_SetRegByte(SiS_Pr, DACData, data); | 820 | SiS_SetRegByte(SiS_Pr, DACData, data); |
903 | } | 821 | } |
904 | si = 32; | 822 | si = 32; |
905 | for(m = 0; m < 9; m++) { | 823 | for (m = 0; m < 9; m++) { |
906 | di = si; | 824 | di = si; |
907 | bx = si + 4; | 825 | bx = si + 4; |
908 | for(n = 0; n < 3; n++) { | 826 | for (n = 0; n < 3; n++) { |
909 | for(o = 0; o < 5; o++) { | 827 | for (o = 0; o < 5; o++) { |
910 | SiS_WriteDAC(SiS_Pr, DACData, sf, n, | 828 | SiS_WriteDAC(SiS_Pr, DACData, sf, n, |
911 | table[di], table[bx], table[si]); | 829 | table[di], table[bx], |
830 | table[si]); | ||
912 | si++; | 831 | si++; |
913 | } | 832 | } |
914 | si -= 2; | 833 | si -= 2; |
915 | for(o = 0; o < 3; o++) { | 834 | for (o = 0; o < 3; o++) { |
916 | SiS_WriteDAC(SiS_Pr, DACData, sf, n, | 835 | SiS_WriteDAC(SiS_Pr, DACData, sf, n, |
917 | table[di], table[si], table[bx]); | 836 | table[di], table[si], |
837 | table[bx]); | ||
918 | si--; | 838 | si--; |
919 | } | 839 | } |
920 | } | 840 | } |
921 | si += 5; | 841 | si += 5; |
922 | } | 842 | } |
923 | } | 843 | } |
924 | } | 844 | } |
@@ -929,7 +849,7 @@ SiS_LoadDAC(struct SiS_Private *SiS_Pr, unsigned short ModeNo, unsigned short mi | |||
929 | 849 | ||
930 | static void | 850 | static void |
931 | SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | 851 | SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, |
932 | unsigned short ModeIdIndex) | 852 | unsigned short ModeIdIndex) |
933 | { | 853 | { |
934 | unsigned short StandTableIndex, rrti; | 854 | unsigned short StandTableIndex, rrti; |
935 | 855 | ||
@@ -970,11 +890,10 @@ SiS_SetCRT1Group(struct SiS_Private *SiS_Pr, unsigned short ModeNo, | |||
970 | /* SiSSetMode() */ | 890 | /* SiSSetMode() */ |
971 | /*********************************************/ | 891 | /*********************************************/ |
972 | 892 | ||
973 | int | 893 | int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) |
974 | SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | ||
975 | { | 894 | { |
976 | unsigned short ModeIdIndex; | 895 | unsigned short ModeIdIndex; |
977 | unsigned long BaseAddr = SiS_Pr->IOAddress; | 896 | unsigned long BaseAddr = SiS_Pr->IOAddress; |
978 | 897 | ||
979 | SiSUSB_InitPtr(SiS_Pr); | 898 | SiSUSB_InitPtr(SiS_Pr); |
980 | SiSUSBRegInit(SiS_Pr, BaseAddr); | 899 | SiSUSBRegInit(SiS_Pr, BaseAddr); |
@@ -990,7 +909,7 @@ SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | |||
990 | ModeNo &= 0x7f; | 909 | ModeNo &= 0x7f; |
991 | 910 | ||
992 | SiS_Pr->SiS_ModeType = | 911 | SiS_Pr->SiS_ModeType = |
993 | SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag & ModeTypeMask; | 912 | SiS_Pr->SiS_EModeIDTable[ModeIdIndex].Ext_ModeFlag & ModeTypeMask; |
994 | 913 | ||
995 | SiS_Pr->SiS_SetFlag = LowModeTests; | 914 | SiS_Pr->SiS_SetFlag = LowModeTests; |
996 | 915 | ||
@@ -1008,8 +927,7 @@ SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo) | |||
1008 | return 1; | 927 | return 1; |
1009 | } | 928 | } |
1010 | 929 | ||
1011 | int | 930 | int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo) |
1012 | SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo) | ||
1013 | { | 931 | { |
1014 | unsigned short ModeNo = 0; | 932 | unsigned short ModeNo = 0; |
1015 | int i; | 933 | int i; |
@@ -1041,7 +959,3 @@ SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo) | |||
1041 | } | 959 | } |
1042 | 960 | ||
1043 | #endif /* INCL_SISUSB_CON */ | 961 | #endif /* INCL_SISUSB_CON */ |
1044 | |||
1045 | |||
1046 | |||
1047 | |||
diff --git a/drivers/usb/misc/sisusbvga/sisusb_init.h b/drivers/usb/misc/sisusbvga/sisusb_init.h index 864bc0e9659..c46ce42d448 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_init.h +++ b/drivers/usb/misc/sisusbvga/sisusb_init.h | |||
@@ -46,7 +46,7 @@ | |||
46 | * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 46 | * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
47 | * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 47 | * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
48 | * | 48 | * |
49 | * Author: Thomas Winischhofer <thomas@winischhofer.net> | 49 | * Author: Thomas Winischhofer <thomas@winischhofer.net> |
50 | * | 50 | * |
51 | */ | 51 | */ |
52 | 52 | ||
@@ -76,21 +76,21 @@ | |||
76 | #define CRT2Mode 0x0800 | 76 | #define CRT2Mode 0x0800 |
77 | #define HalfDCLK 0x1000 | 77 | #define HalfDCLK 0x1000 |
78 | #define NoSupportSimuTV 0x2000 | 78 | #define NoSupportSimuTV 0x2000 |
79 | #define NoSupportLCDScale 0x4000 /* SiS bridge: No scaling possible (no matter what panel) */ | 79 | #define NoSupportLCDScale 0x4000 /* SiS bridge: No scaling possible (no matter what panel) */ |
80 | #define DoubleScanMode 0x8000 | 80 | #define DoubleScanMode 0x8000 |
81 | 81 | ||
82 | /* Infoflag */ | 82 | /* Infoflag */ |
83 | #define SupportTV 0x0008 | 83 | #define SupportTV 0x0008 |
84 | #define SupportTV1024 0x0800 | 84 | #define SupportTV1024 0x0800 |
85 | #define SupportCHTV 0x0800 | 85 | #define SupportCHTV 0x0800 |
86 | #define Support64048060Hz 0x0800 /* Special for 640x480 LCD */ | 86 | #define Support64048060Hz 0x0800 /* Special for 640x480 LCD */ |
87 | #define SupportHiVision 0x0010 | 87 | #define SupportHiVision 0x0010 |
88 | #define SupportYPbPr750p 0x1000 | 88 | #define SupportYPbPr750p 0x1000 |
89 | #define SupportLCD 0x0020 | 89 | #define SupportLCD 0x0020 |
90 | #define SupportRAMDAC2 0x0040 /* All (<= 100Mhz) */ | 90 | #define SupportRAMDAC2 0x0040 /* All (<= 100Mhz) */ |
91 | #define SupportRAMDAC2_135 0x0100 /* All except DH (<= 135Mhz) */ | 91 | #define SupportRAMDAC2_135 0x0100 /* All except DH (<= 135Mhz) */ |
92 | #define SupportRAMDAC2_162 0x0200 /* B, C (<= 162Mhz) */ | 92 | #define SupportRAMDAC2_162 0x0200 /* B, C (<= 162Mhz) */ |
93 | #define SupportRAMDAC2_202 0x0400 /* C (<= 202Mhz) */ | 93 | #define SupportRAMDAC2_202 0x0400 /* C (<= 202Mhz) */ |
94 | #define InterlaceMode 0x0080 | 94 | #define InterlaceMode 0x0080 |
95 | #define SyncPP 0x0000 | 95 | #define SyncPP 0x0000 |
96 | #define SyncPN 0x4000 | 96 | #define SyncPN 0x4000 |
@@ -129,7 +129,7 @@ | |||
129 | #define SIS_RI_856x480 19 | 129 | #define SIS_RI_856x480 19 |
130 | #define SIS_RI_1280x768 20 | 130 | #define SIS_RI_1280x768 20 |
131 | #define SIS_RI_1400x1050 21 | 131 | #define SIS_RI_1400x1050 21 |
132 | #define SIS_RI_1152x864 22 /* Up to here SiS conforming */ | 132 | #define SIS_RI_1152x864 22 /* Up to here SiS conforming */ |
133 | #define SIS_RI_848x480 23 | 133 | #define SIS_RI_848x480 23 |
134 | #define SIS_RI_1360x768 24 | 134 | #define SIS_RI_1360x768 24 |
135 | #define SIS_RI_1024x600 25 | 135 | #define SIS_RI_1024x600 25 |
@@ -147,691 +147,691 @@ | |||
147 | #define SIS_CRT2_PORT_04 0x04 - 0x30 | 147 | #define SIS_CRT2_PORT_04 0x04 - 0x30 |
148 | 148 | ||
149 | /* Mode numbers */ | 149 | /* Mode numbers */ |
150 | static const unsigned short ModeIndex_320x200[] = {0x59, 0x41, 0x00, 0x4f}; | 150 | static const unsigned short ModeIndex_320x200[] = { 0x59, 0x41, 0x00, 0x4f }; |
151 | static const unsigned short ModeIndex_320x240[] = {0x50, 0x56, 0x00, 0x53}; | 151 | static const unsigned short ModeIndex_320x240[] = { 0x50, 0x56, 0x00, 0x53 }; |
152 | static const unsigned short ModeIndex_400x300[] = {0x51, 0x57, 0x00, 0x54}; | 152 | static const unsigned short ModeIndex_400x300[] = { 0x51, 0x57, 0x00, 0x54 }; |
153 | static const unsigned short ModeIndex_512x384[] = {0x52, 0x58, 0x00, 0x5c}; | 153 | static const unsigned short ModeIndex_512x384[] = { 0x52, 0x58, 0x00, 0x5c }; |
154 | static const unsigned short ModeIndex_640x400[] = {0x2f, 0x5d, 0x00, 0x5e}; | 154 | static const unsigned short ModeIndex_640x400[] = { 0x2f, 0x5d, 0x00, 0x5e }; |
155 | static const unsigned short ModeIndex_640x480[] = {0x2e, 0x44, 0x00, 0x62}; | 155 | static const unsigned short ModeIndex_640x480[] = { 0x2e, 0x44, 0x00, 0x62 }; |
156 | static const unsigned short ModeIndex_720x480[] = {0x31, 0x33, 0x00, 0x35}; | 156 | static const unsigned short ModeIndex_720x480[] = { 0x31, 0x33, 0x00, 0x35 }; |
157 | static const unsigned short ModeIndex_720x576[] = {0x32, 0x34, 0x00, 0x36}; | 157 | static const unsigned short ModeIndex_720x576[] = { 0x32, 0x34, 0x00, 0x36 }; |
158 | static const unsigned short ModeIndex_768x576[] = {0x5f, 0x60, 0x00, 0x61}; | 158 | static const unsigned short ModeIndex_768x576[] = { 0x5f, 0x60, 0x00, 0x61 }; |
159 | static const unsigned short ModeIndex_800x480[] = {0x70, 0x7a, 0x00, 0x76}; | 159 | static const unsigned short ModeIndex_800x480[] = { 0x70, 0x7a, 0x00, 0x76 }; |
160 | static const unsigned short ModeIndex_800x600[] = {0x30, 0x47, 0x00, 0x63}; | 160 | static const unsigned short ModeIndex_800x600[] = { 0x30, 0x47, 0x00, 0x63 }; |
161 | static const unsigned short ModeIndex_848x480[] = {0x39, 0x3b, 0x00, 0x3e}; | 161 | static const unsigned short ModeIndex_848x480[] = { 0x39, 0x3b, 0x00, 0x3e }; |
162 | static const unsigned short ModeIndex_856x480[] = {0x3f, 0x42, 0x00, 0x45}; | 162 | static const unsigned short ModeIndex_856x480[] = { 0x3f, 0x42, 0x00, 0x45 }; |
163 | static const unsigned short ModeIndex_960x540[] = {0x1d, 0x1e, 0x00, 0x1f}; | 163 | static const unsigned short ModeIndex_960x540[] = { 0x1d, 0x1e, 0x00, 0x1f }; |
164 | static const unsigned short ModeIndex_960x600[] = {0x20, 0x21, 0x00, 0x22}; | 164 | static const unsigned short ModeIndex_960x600[] = { 0x20, 0x21, 0x00, 0x22 }; |
165 | static const unsigned short ModeIndex_1024x768[] = {0x38, 0x4a, 0x00, 0x64}; | 165 | static const unsigned short ModeIndex_1024x768[] = { 0x38, 0x4a, 0x00, 0x64 }; |
166 | static const unsigned short ModeIndex_1024x576[] = {0x71, 0x74, 0x00, 0x77}; | 166 | static const unsigned short ModeIndex_1024x576[] = { 0x71, 0x74, 0x00, 0x77 }; |
167 | static const unsigned short ModeIndex_1152x864[] = {0x29, 0x2a, 0x00, 0x2b}; | 167 | static const unsigned short ModeIndex_1152x864[] = { 0x29, 0x2a, 0x00, 0x2b }; |
168 | static const unsigned short ModeIndex_1280x720[] = {0x79, 0x75, 0x00, 0x78}; | 168 | static const unsigned short ModeIndex_1280x720[] = { 0x79, 0x75, 0x00, 0x78 }; |
169 | static const unsigned short ModeIndex_1280x768[] = {0x23, 0x24, 0x00, 0x25}; | 169 | static const unsigned short ModeIndex_1280x768[] = { 0x23, 0x24, 0x00, 0x25 }; |
170 | static const unsigned short ModeIndex_1280x1024[] = {0x3a, 0x4d, 0x00, 0x65}; | 170 | static const unsigned short ModeIndex_1280x1024[] = { 0x3a, 0x4d, 0x00, 0x65 }; |
171 | 171 | ||
172 | static const unsigned char SiS_MDA_DAC[] = | 172 | static const unsigned char SiS_MDA_DAC[] = { |
173 | { | 173 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
174 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 174 | 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, |
175 | 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, | 175 | 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, |
176 | 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, | 176 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, |
177 | 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F, | 177 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
178 | 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, | 178 | 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, |
179 | 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, | 179 | 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, |
180 | 0x15,0x15,0x15,0x15,0x15,0x15,0x15,0x15, | 180 | 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F |
181 | 0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F | ||
182 | }; | 181 | }; |
183 | 182 | ||
184 | static const unsigned char SiS_CGA_DAC[] = | 183 | static const unsigned char SiS_CGA_DAC[] = { |
185 | { | 184 | 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, |
186 | 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15, | 185 | 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, |
187 | 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15, | 186 | 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F, |
188 | 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F, | 187 | 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F, |
189 | 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F, | 188 | 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, |
190 | 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15, | 189 | 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, |
191 | 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15, | 190 | 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F, |
192 | 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F, | 191 | 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F |
193 | 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F | ||
194 | }; | 192 | }; |
195 | 193 | ||
196 | static const unsigned char SiS_EGA_DAC[] = | 194 | static const unsigned char SiS_EGA_DAC[] = { |
197 | { | 195 | 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x05, 0x15, |
198 | 0x00,0x10,0x04,0x14,0x01,0x11,0x05,0x15, | 196 | 0x20, 0x30, 0x24, 0x34, 0x21, 0x31, 0x25, 0x35, |
199 | 0x20,0x30,0x24,0x34,0x21,0x31,0x25,0x35, | 197 | 0x08, 0x18, 0x0C, 0x1C, 0x09, 0x19, 0x0D, 0x1D, |
200 | 0x08,0x18,0x0C,0x1C,0x09,0x19,0x0D,0x1D, | 198 | 0x28, 0x38, 0x2C, 0x3C, 0x29, 0x39, 0x2D, 0x3D, |
201 | 0x28,0x38,0x2C,0x3C,0x29,0x39,0x2D,0x3D, | 199 | 0x02, 0x12, 0x06, 0x16, 0x03, 0x13, 0x07, 0x17, |
202 | 0x02,0x12,0x06,0x16,0x03,0x13,0x07,0x17, | 200 | 0x22, 0x32, 0x26, 0x36, 0x23, 0x33, 0x27, 0x37, |
203 | 0x22,0x32,0x26,0x36,0x23,0x33,0x27,0x37, | 201 | 0x0A, 0x1A, 0x0E, 0x1E, 0x0B, 0x1B, 0x0F, 0x1F, |
204 | 0x0A,0x1A,0x0E,0x1E,0x0B,0x1B,0x0F,0x1F, | 202 | 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F |
205 | 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F | ||
206 | }; | 203 | }; |
207 | 204 | ||
208 | static const unsigned char SiS_VGA_DAC[] = | 205 | static const unsigned char SiS_VGA_DAC[] = { |
209 | { | 206 | 0x00, 0x10, 0x04, 0x14, 0x01, 0x11, 0x09, 0x15, |
210 | 0x00,0x10,0x04,0x14,0x01,0x11,0x09,0x15, | 207 | 0x2A, 0x3A, 0x2E, 0x3E, 0x2B, 0x3B, 0x2F, 0x3F, |
211 | 0x2A,0x3A,0x2E,0x3E,0x2B,0x3B,0x2F,0x3F, | 208 | 0x00, 0x05, 0x08, 0x0B, 0x0E, 0x11, 0x14, 0x18, |
212 | 0x00,0x05,0x08,0x0B,0x0E,0x11,0x14,0x18, | 209 | 0x1C, 0x20, 0x24, 0x28, 0x2D, 0x32, 0x38, 0x3F, |
213 | 0x1C,0x20,0x24,0x28,0x2D,0x32,0x38,0x3F, | 210 | 0x00, 0x10, 0x1F, 0x2F, 0x3F, 0x1F, 0x27, 0x2F, |
214 | 0x00,0x10,0x1F,0x2F,0x3F,0x1F,0x27,0x2F, | 211 | 0x37, 0x3F, 0x2D, 0x31, 0x36, 0x3A, 0x3F, 0x00, |
215 | 0x37,0x3F,0x2D,0x31,0x36,0x3A,0x3F,0x00, | 212 | 0x07, 0x0E, 0x15, 0x1C, 0x0E, 0x11, 0x15, 0x18, |
216 | 0x07,0x0E,0x15,0x1C,0x0E,0x11,0x15,0x18, | 213 | 0x1C, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x00, 0x04, |
217 | 0x1C,0x14,0x16,0x18,0x1A,0x1C,0x00,0x04, | 214 | 0x08, 0x0C, 0x10, 0x08, 0x0A, 0x0C, 0x0E, 0x10, |
218 | 0x08,0x0C,0x10,0x08,0x0A,0x0C,0x0E,0x10, | 215 | 0x0B, 0x0C, 0x0D, 0x0F, 0x10 |
219 | 0x0B,0x0C,0x0D,0x0F,0x10 | ||
220 | }; | 216 | }; |
221 | 217 | ||
222 | static const struct SiS_St SiSUSB_SModeIDTable[] = | 218 | static const struct SiS_St SiSUSB_SModeIDTable[] = { |
223 | { | 219 | {0x03, 0x0010, 0x18, 0x02, 0x02, 0x00, 0x01, 0x03, 0x40}, |
224 | {0x03,0x0010,0x18,0x02,0x02,0x00,0x01,0x03,0x40}, | 220 | {0xff, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} |
225 | {0xff,0x0000,0x00,0x00,0x00,0x00,0x00,0x00,0x00} | ||
226 | }; | 221 | }; |
227 | 222 | ||
228 | static const struct SiS_StResInfo_S SiSUSB_StResInfo[] = | 223 | static const struct SiS_StResInfo_S SiSUSB_StResInfo[] = { |
229 | { | 224 | {640, 400}, |
230 | { 640,400}, | 225 | {640, 350}, |
231 | { 640,350}, | 226 | {720, 400}, |
232 | { 720,400}, | 227 | {720, 350}, |
233 | { 720,350}, | 228 | {640, 480} |
234 | { 640,480} | ||
235 | }; | 229 | }; |
236 | 230 | ||
237 | static const struct SiS_ModeResInfo SiSUSB_ModeResInfo[] = | 231 | static const struct SiS_ModeResInfo SiSUSB_ModeResInfo[] = { |
238 | { | 232 | {320, 200, 8, 8}, /* 0x00 */ |
239 | { 320, 200, 8, 8}, /* 0x00 */ | 233 | {320, 240, 8, 8}, /* 0x01 */ |
240 | { 320, 240, 8, 8}, /* 0x01 */ | 234 | {320, 400, 8, 8}, /* 0x02 */ |
241 | { 320, 400, 8, 8}, /* 0x02 */ | 235 | {400, 300, 8, 8}, /* 0x03 */ |
242 | { 400, 300, 8, 8}, /* 0x03 */ | 236 | {512, 384, 8, 8}, /* 0x04 */ |
243 | { 512, 384, 8, 8}, /* 0x04 */ | 237 | {640, 400, 8, 16}, /* 0x05 */ |
244 | { 640, 400, 8,16}, /* 0x05 */ | 238 | {640, 480, 8, 16}, /* 0x06 */ |
245 | { 640, 480, 8,16}, /* 0x06 */ | 239 | {800, 600, 8, 16}, /* 0x07 */ |
246 | { 800, 600, 8,16}, /* 0x07 */ | 240 | {1024, 768, 8, 16}, /* 0x08 */ |
247 | { 1024, 768, 8,16}, /* 0x08 */ | 241 | {1280, 1024, 8, 16}, /* 0x09 */ |
248 | { 1280,1024, 8,16}, /* 0x09 */ | 242 | {1600, 1200, 8, 16}, /* 0x0a */ |
249 | { 1600,1200, 8,16}, /* 0x0a */ | 243 | {1920, 1440, 8, 16}, /* 0x0b */ |
250 | { 1920,1440, 8,16}, /* 0x0b */ | 244 | {2048, 1536, 8, 16}, /* 0x0c */ |
251 | { 2048,1536, 8,16}, /* 0x0c */ | 245 | {720, 480, 8, 16}, /* 0x0d */ |
252 | { 720, 480, 8,16}, /* 0x0d */ | 246 | {720, 576, 8, 16}, /* 0x0e */ |
253 | { 720, 576, 8,16}, /* 0x0e */ | 247 | {1280, 960, 8, 16}, /* 0x0f */ |
254 | { 1280, 960, 8,16}, /* 0x0f */ | 248 | {800, 480, 8, 16}, /* 0x10 */ |
255 | { 800, 480, 8,16}, /* 0x10 */ | 249 | {1024, 576, 8, 16}, /* 0x11 */ |
256 | { 1024, 576, 8,16}, /* 0x11 */ | 250 | {1280, 720, 8, 16}, /* 0x12 */ |
257 | { 1280, 720, 8,16}, /* 0x12 */ | 251 | {856, 480, 8, 16}, /* 0x13 */ |
258 | { 856, 480, 8,16}, /* 0x13 */ | 252 | {1280, 768, 8, 16}, /* 0x14 */ |
259 | { 1280, 768, 8,16}, /* 0x14 */ | 253 | {1400, 1050, 8, 16}, /* 0x15 */ |
260 | { 1400,1050, 8,16}, /* 0x15 */ | 254 | {1152, 864, 8, 16}, /* 0x16 */ |
261 | { 1152, 864, 8,16}, /* 0x16 */ | 255 | {848, 480, 8, 16}, /* 0x17 */ |
262 | { 848, 480, 8,16}, /* 0x17 */ | 256 | {1360, 768, 8, 16}, /* 0x18 */ |
263 | { 1360, 768, 8,16}, /* 0x18 */ | 257 | {1024, 600, 8, 16}, /* 0x19 */ |
264 | { 1024, 600, 8,16}, /* 0x19 */ | 258 | {1152, 768, 8, 16}, /* 0x1a */ |
265 | { 1152, 768, 8,16}, /* 0x1a */ | 259 | {768, 576, 8, 16}, /* 0x1b */ |
266 | { 768, 576, 8,16}, /* 0x1b */ | 260 | {1360, 1024, 8, 16}, /* 0x1c */ |
267 | { 1360,1024, 8,16}, /* 0x1c */ | 261 | {1680, 1050, 8, 16}, /* 0x1d */ |
268 | { 1680,1050, 8,16}, /* 0x1d */ | 262 | {1280, 800, 8, 16}, /* 0x1e */ |
269 | { 1280, 800, 8,16}, /* 0x1e */ | 263 | {1920, 1080, 8, 16}, /* 0x1f */ |
270 | { 1920,1080, 8,16}, /* 0x1f */ | 264 | {960, 540, 8, 16}, /* 0x20 */ |
271 | { 960, 540, 8,16}, /* 0x20 */ | 265 | {960, 600, 8, 16} /* 0x21 */ |
272 | { 960, 600, 8,16} /* 0x21 */ | ||
273 | }; | 266 | }; |
274 | 267 | ||
275 | static const struct SiS_StandTable SiSUSB_StandTable[] = | 268 | static const struct SiS_StandTable SiSUSB_StandTable[] = { |
276 | { | ||
277 | /* MD_3_400 - mode 0x03 - 400 */ | 269 | /* MD_3_400 - mode 0x03 - 400 */ |
278 | { | 270 | { |
279 | 0x50,0x18,0x10,0x1000, | 271 | 0x50, 0x18, 0x10, 0x1000, |
280 | { 0x00,0x03,0x00,0x02 }, | 272 | {0x00, 0x03, 0x00, 0x02}, |
281 | 0x67, | 273 | 0x67, |
282 | { 0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, | 274 | {0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, |
283 | 0x00,0x4f,0x0d,0x0e,0x00,0x00,0x00,0x00, | 275 | 0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00, |
284 | 0x9c,0x8e,0x8f,0x28,0x1f,0x96,0xb9,0xa3, | 276 | 0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3, |
285 | 0xff }, | 277 | 0xff}, |
286 | { 0x00,0x01,0x02,0x03,0x04,0x05,0x14,0x07, | 278 | {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07, |
287 | 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f, | 279 | 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, |
288 | 0x0c,0x00,0x0f,0x08 }, | 280 | 0x0c, 0x00, 0x0f, 0x08}, |
289 | { 0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00, 0xff } | 281 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x00, 0xff} |
290 | }, | 282 | }, |
291 | /* Generic for VGA and higher */ | 283 | /* Generic for VGA and higher */ |
292 | { | 284 | { |
293 | 0x00,0x00,0x00,0x0000, | 285 | 0x00, 0x00, 0x00, 0x0000, |
294 | { 0x01,0x0f,0x00,0x0e }, | 286 | {0x01, 0x0f, 0x00, 0x0e}, |
295 | 0x23, | 287 | 0x23, |
296 | { 0x5f,0x4f,0x50,0x82,0x54,0x80,0x0b,0x3e, | 288 | {0x5f, 0x4f, 0x50, 0x82, 0x54, 0x80, 0x0b, 0x3e, |
297 | 0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00, | 289 | 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
298 | 0xea,0x8c,0xdf,0x28,0x40,0xe7,0x04,0xa3, | 290 | 0xea, 0x8c, 0xdf, 0x28, 0x40, 0xe7, 0x04, 0xa3, |
299 | 0xff }, | 291 | 0xff}, |
300 | { 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, | 292 | {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, |
301 | 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f, | 293 | 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
302 | 0x01,0x00,0x00,0x00 }, | 294 | 0x01, 0x00, 0x00, 0x00}, |
303 | { 0x00,0x00,0x00,0x00,0x00,0x40,0x05,0x0f, 0xff } | 295 | {0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0f, 0xff} |
304 | } | 296 | } |
305 | }; | 297 | }; |
306 | 298 | ||
307 | static const struct SiS_Ext SiSUSB_EModeIDTable[] = | 299 | static const struct SiS_Ext SiSUSB_EModeIDTable[] = { |
308 | { | 300 | {0x2e, 0x0a1b, 0x0101, SIS_RI_640x480, 0x00, 0x00, 0x05, 0x05, 0x08, 2}, /* 640x480x8 */ |
309 | {0x2e,0x0a1b,0x0101,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x8 */ | 301 | {0x2f, 0x0a1b, 0x0100, SIS_RI_640x400, 0x00, 0x00, 0x05, 0x05, 0x10, 0}, /* 640x400x8 */ |
310 | {0x2f,0x0a1b,0x0100,SIS_RI_640x400, 0x00,0x00,0x05,0x05,0x10, 0}, /* 640x400x8 */ | 302 | {0x30, 0x2a1b, 0x0103, SIS_RI_800x600, 0x00, 0x00, 0x07, 0x06, 0x00, 3}, /* 800x600x8 */ |
311 | {0x30,0x2a1b,0x0103,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x8 */ | 303 | {0x31, 0x4a1b, 0x0000, SIS_RI_720x480, 0x00, 0x00, 0x06, 0x06, 0x11, -1}, /* 720x480x8 */ |
312 | {0x31,0x4a1b,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x8 */ | 304 | {0x32, 0x4a1b, 0x0000, SIS_RI_720x576, 0x00, 0x00, 0x06, 0x06, 0x12, -1}, /* 720x576x8 */ |
313 | {0x32,0x4a1b,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x8 */ | 305 | {0x33, 0x4a1d, 0x0000, SIS_RI_720x480, 0x00, 0x00, 0x06, 0x06, 0x11, -1}, /* 720x480x16 */ |
314 | {0x33,0x4a1d,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x16 */ | 306 | {0x34, 0x6a1d, 0x0000, SIS_RI_720x576, 0x00, 0x00, 0x06, 0x06, 0x12, -1}, /* 720x576x16 */ |
315 | {0x34,0x6a1d,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x16 */ | 307 | {0x35, 0x4a1f, 0x0000, SIS_RI_720x480, 0x00, 0x00, 0x06, 0x06, 0x11, -1}, /* 720x480x32 */ |
316 | {0x35,0x4a1f,0x0000,SIS_RI_720x480, 0x00,0x00,0x06,0x06,0x11,-1}, /* 720x480x32 */ | 308 | {0x36, 0x6a1f, 0x0000, SIS_RI_720x576, 0x00, 0x00, 0x06, 0x06, 0x12, -1}, /* 720x576x32 */ |
317 | {0x36,0x6a1f,0x0000,SIS_RI_720x576, 0x00,0x00,0x06,0x06,0x12,-1}, /* 720x576x32 */ | 309 | {0x38, 0x0a1b, 0x0105, SIS_RI_1024x768, 0x00, 0x00, 0x08, 0x07, 0x13, 4}, /* 1024x768x8 */ |
318 | {0x38,0x0a1b,0x0105,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x8 */ | 310 | {0x3a, 0x0e3b, 0x0107, SIS_RI_1280x1024, 0x00, 0x00, 0x00, 0x00, 0x2f, 8}, /* 1280x1024x8 */ |
319 | {0x3a,0x0e3b,0x0107,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x2f, 8}, /* 1280x1024x8 */ | 311 | {0x41, 0x9a1d, 0x010e, SIS_RI_320x200, 0x00, 0x00, 0x04, 0x04, 0x1a, 0}, /* 320x200x16 */ |
320 | {0x41,0x9a1d,0x010e,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x1a, 0}, /* 320x200x16 */ | 312 | {0x44, 0x0a1d, 0x0111, SIS_RI_640x480, 0x00, 0x00, 0x05, 0x05, 0x08, 2}, /* 640x480x16 */ |
321 | {0x44,0x0a1d,0x0111,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x16 */ | 313 | {0x47, 0x2a1d, 0x0114, SIS_RI_800x600, 0x00, 0x00, 0x07, 0x06, 0x00, 3}, /* 800x600x16 */ |
322 | {0x47,0x2a1d,0x0114,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x16 */ | 314 | {0x4a, 0x0a3d, 0x0117, SIS_RI_1024x768, 0x00, 0x00, 0x08, 0x07, 0x13, 4}, /* 1024x768x16 */ |
323 | {0x4a,0x0a3d,0x0117,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x16 */ | 315 | {0x4d, 0x0e7d, 0x011a, SIS_RI_1280x1024, 0x00, 0x00, 0x00, 0x00, 0x2f, 8}, /* 1280x1024x16 */ |
324 | {0x4d,0x0e7d,0x011a,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x2f, 8}, /* 1280x1024x16 */ | 316 | {0x50, 0x9a1b, 0x0132, SIS_RI_320x240, 0x00, 0x00, 0x04, 0x04, 0x1b, 2}, /* 320x240x8 */ |
325 | {0x50,0x9a1b,0x0132,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x1b, 2}, /* 320x240x8 */ | 317 | {0x51, 0xba1b, 0x0133, SIS_RI_400x300, 0x00, 0x00, 0x07, 0x07, 0x1c, 3}, /* 400x300x8 */ |
326 | {0x51,0xba1b,0x0133,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x1c, 3}, /* 400x300x8 */ | 318 | {0x52, 0xba1b, 0x0134, SIS_RI_512x384, 0x00, 0x00, 0x00, 0x00, 0x1d, 4}, /* 512x384x8 */ |
327 | {0x52,0xba1b,0x0134,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x1d, 4}, /* 512x384x8 */ | 319 | {0x56, 0x9a1d, 0x0135, SIS_RI_320x240, 0x00, 0x00, 0x04, 0x04, 0x1b, 2}, /* 320x240x16 */ |
328 | {0x56,0x9a1d,0x0135,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x1b, 2}, /* 320x240x16 */ | 320 | {0x57, 0xba1d, 0x0136, SIS_RI_400x300, 0x00, 0x00, 0x07, 0x07, 0x1c, 3}, /* 400x300x16 */ |
329 | {0x57,0xba1d,0x0136,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x1c, 3}, /* 400x300x16 */ | 321 | {0x58, 0xba1d, 0x0137, SIS_RI_512x384, 0x00, 0x00, 0x00, 0x00, 0x1d, 4}, /* 512x384x16 */ |
330 | {0x58,0xba1d,0x0137,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x1d, 4}, /* 512x384x16 */ | 322 | {0x59, 0x9a1b, 0x0138, SIS_RI_320x200, 0x00, 0x00, 0x04, 0x04, 0x1a, 0}, /* 320x200x8 */ |
331 | {0x59,0x9a1b,0x0138,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x1a, 0}, /* 320x200x8 */ | 323 | {0x5c, 0xba1f, 0x0000, SIS_RI_512x384, 0x00, 0x00, 0x00, 0x00, 0x1d, 4}, /* 512x384x32 */ |
332 | {0x5c,0xba1f,0x0000,SIS_RI_512x384, 0x00,0x00,0x00,0x00,0x1d, 4}, /* 512x384x32 */ | 324 | {0x5d, 0x0a1d, 0x0139, SIS_RI_640x400, 0x00, 0x00, 0x05, 0x07, 0x10, 0}, /* 640x400x16 */ |
333 | {0x5d,0x0a1d,0x0139,SIS_RI_640x400, 0x00,0x00,0x05,0x07,0x10, 0}, /* 640x400x16 */ | 325 | {0x5e, 0x0a1f, 0x0000, SIS_RI_640x400, 0x00, 0x00, 0x05, 0x07, 0x10, 0}, /* 640x400x32 */ |
334 | {0x5e,0x0a1f,0x0000,SIS_RI_640x400, 0x00,0x00,0x05,0x07,0x10, 0}, /* 640x400x32 */ | 326 | {0x62, 0x0a3f, 0x013a, SIS_RI_640x480, 0x00, 0x00, 0x05, 0x05, 0x08, 2}, /* 640x480x32 */ |
335 | {0x62,0x0a3f,0x013a,SIS_RI_640x480, 0x00,0x00,0x05,0x05,0x08, 2}, /* 640x480x32 */ | 327 | {0x63, 0x2a3f, 0x013b, SIS_RI_800x600, 0x00, 0x00, 0x07, 0x06, 0x00, 3}, /* 800x600x32 */ |
336 | {0x63,0x2a3f,0x013b,SIS_RI_800x600, 0x00,0x00,0x07,0x06,0x00, 3}, /* 800x600x32 */ | 328 | {0x64, 0x0a7f, 0x013c, SIS_RI_1024x768, 0x00, 0x00, 0x08, 0x07, 0x13, 4}, /* 1024x768x32 */ |
337 | {0x64,0x0a7f,0x013c,SIS_RI_1024x768, 0x00,0x00,0x08,0x07,0x13, 4}, /* 1024x768x32 */ | 329 | {0x65, 0x0eff, 0x013d, SIS_RI_1280x1024, 0x00, 0x00, 0x00, 0x00, 0x2f, 8}, /* 1280x1024x32 */ |
338 | {0x65,0x0eff,0x013d,SIS_RI_1280x1024,0x00,0x00,0x00,0x00,0x2f, 8}, /* 1280x1024x32 */ | 330 | {0x70, 0x6a1b, 0x0000, SIS_RI_800x480, 0x00, 0x00, 0x07, 0x07, 0x1e, -1}, /* 800x480x8 */ |
339 | {0x70,0x6a1b,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x1e,-1}, /* 800x480x8 */ | 331 | {0x71, 0x4a1b, 0x0000, SIS_RI_1024x576, 0x00, 0x00, 0x00, 0x00, 0x21, -1}, /* 1024x576x8 */ |
340 | {0x71,0x4a1b,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x21,-1}, /* 1024x576x8 */ | 332 | {0x74, 0x4a1d, 0x0000, SIS_RI_1024x576, 0x00, 0x00, 0x00, 0x00, 0x21, -1}, /* 1024x576x16 */ |
341 | {0x74,0x4a1d,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x21,-1}, /* 1024x576x16 */ | 333 | {0x75, 0x0a3d, 0x0000, SIS_RI_1280x720, 0x00, 0x00, 0x00, 0x00, 0x24, 5}, /* 1280x720x16 */ |
342 | {0x75,0x0a3d,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x24, 5}, /* 1280x720x16 */ | 334 | {0x76, 0x6a1f, 0x0000, SIS_RI_800x480, 0x00, 0x00, 0x07, 0x07, 0x1e, -1}, /* 800x480x32 */ |
343 | {0x76,0x6a1f,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x1e,-1}, /* 800x480x32 */ | 335 | {0x77, 0x4a1f, 0x0000, SIS_RI_1024x576, 0x00, 0x00, 0x00, 0x00, 0x21, -1}, /* 1024x576x32 */ |
344 | {0x77,0x4a1f,0x0000,SIS_RI_1024x576, 0x00,0x00,0x00,0x00,0x21,-1}, /* 1024x576x32 */ | 336 | {0x78, 0x0a3f, 0x0000, SIS_RI_1280x720, 0x00, 0x00, 0x00, 0x00, 0x24, 5}, /* 1280x720x32 */ |
345 | {0x78,0x0a3f,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x24, 5}, /* 1280x720x32 */ | 337 | {0x79, 0x0a3b, 0x0000, SIS_RI_1280x720, 0x00, 0x00, 0x00, 0x00, 0x24, 5}, /* 1280x720x8 */ |
346 | {0x79,0x0a3b,0x0000,SIS_RI_1280x720, 0x00,0x00,0x00,0x00,0x24, 5}, /* 1280x720x8 */ | 338 | {0x7a, 0x6a1d, 0x0000, SIS_RI_800x480, 0x00, 0x00, 0x07, 0x07, 0x1e, -1}, /* 800x480x16 */ |
347 | {0x7a,0x6a1d,0x0000,SIS_RI_800x480, 0x00,0x00,0x07,0x07,0x1e,-1}, /* 800x480x16 */ | 339 | {0x23, 0x0e3b, 0x0000, SIS_RI_1280x768, 0x00, 0x00, 0x00, 0x00, 0x27, 6}, /* 1280x768x8 */ |
348 | {0x23,0x0e3b,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x27, 6}, /* 1280x768x8 */ | 340 | {0x24, 0x0e7d, 0x0000, SIS_RI_1280x768, 0x00, 0x00, 0x00, 0x00, 0x27, 6}, /* 1280x768x16 */ |
349 | {0x24,0x0e7d,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x27, 6}, /* 1280x768x16 */ | 341 | {0x25, 0x0eff, 0x0000, SIS_RI_1280x768, 0x00, 0x00, 0x00, 0x00, 0x27, 6}, /* 1280x768x32 */ |
350 | {0x25,0x0eff,0x0000,SIS_RI_1280x768, 0x00,0x00,0x00,0x00,0x27, 6}, /* 1280x768x32 */ | 342 | {0x39, 0x6a1b, 0x0000, SIS_RI_848x480, 0x00, 0x00, 0x00, 0x00, 0x28, -1}, /* 848x480 */ |
351 | {0x39,0x6a1b,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x28,-1}, /* 848x480 */ | 343 | {0x3b, 0x6a3d, 0x0000, SIS_RI_848x480, 0x00, 0x00, 0x00, 0x00, 0x28, |
352 | {0x3b,0x6a3d,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x28,-1}, | 344 | -1}, |
353 | {0x3e,0x6a7f,0x0000,SIS_RI_848x480, 0x00,0x00,0x00,0x00,0x28,-1}, | 345 | {0x3e, 0x6a7f, 0x0000, SIS_RI_848x480, 0x00, 0x00, 0x00, 0x00, 0x28, |
354 | {0x3f,0x6a1b,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x2a,-1}, /* 856x480 */ | 346 | -1}, |
355 | {0x42,0x6a3d,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x2a,-1}, | 347 | {0x3f, 0x6a1b, 0x0000, SIS_RI_856x480, 0x00, 0x00, 0x00, 0x00, 0x2a, -1}, /* 856x480 */ |
356 | {0x45,0x6a7f,0x0000,SIS_RI_856x480, 0x00,0x00,0x00,0x00,0x2a,-1}, | 348 | {0x42, 0x6a3d, 0x0000, SIS_RI_856x480, 0x00, 0x00, 0x00, 0x00, 0x2a, |
357 | {0x4f,0x9a1f,0x0000,SIS_RI_320x200, 0x00,0x00,0x04,0x04,0x1a, 0}, /* 320x200x32 */ | 349 | -1}, |
358 | {0x53,0x9a1f,0x0000,SIS_RI_320x240, 0x00,0x00,0x04,0x04,0x1b, 2}, /* 320x240x32 */ | 350 | {0x45, 0x6a7f, 0x0000, SIS_RI_856x480, 0x00, 0x00, 0x00, 0x00, 0x2a, |
359 | {0x54,0xba1f,0x0000,SIS_RI_400x300, 0x00,0x00,0x07,0x07,0x1c, 3}, /* 400x300x32 */ | 351 | -1}, |
360 | {0x5f,0x6a1b,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x2c,-1}, /* 768x576 */ | 352 | {0x4f, 0x9a1f, 0x0000, SIS_RI_320x200, 0x00, 0x00, 0x04, 0x04, 0x1a, 0}, /* 320x200x32 */ |
361 | {0x60,0x6a1d,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x2c,-1}, | 353 | {0x53, 0x9a1f, 0x0000, SIS_RI_320x240, 0x00, 0x00, 0x04, 0x04, 0x1b, 2}, /* 320x240x32 */ |
362 | {0x61,0x6a3f,0x0000,SIS_RI_768x576, 0x00,0x00,0x06,0x06,0x2c,-1}, | 354 | {0x54, 0xba1f, 0x0000, SIS_RI_400x300, 0x00, 0x00, 0x07, 0x07, 0x1c, 3}, /* 400x300x32 */ |
363 | {0x1d,0x6a1b,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x2d,-1}, /* 960x540 */ | 355 | {0x5f, 0x6a1b, 0x0000, SIS_RI_768x576, 0x00, 0x00, 0x06, 0x06, 0x2c, -1}, /* 768x576 */ |
364 | {0x1e,0x6a3d,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x2d,-1}, | 356 | {0x60, 0x6a1d, 0x0000, SIS_RI_768x576, 0x00, 0x00, 0x06, 0x06, 0x2c, |
365 | {0x1f,0x6a7f,0x0000,SIS_RI_960x540, 0x00,0x00,0x00,0x00,0x2d,-1}, | 357 | -1}, |
366 | {0x20,0x6a1b,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x2e,-1}, /* 960x600 */ | 358 | {0x61, 0x6a3f, 0x0000, SIS_RI_768x576, 0x00, 0x00, 0x06, 0x06, 0x2c, |
367 | {0x21,0x6a3d,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x2e,-1}, | 359 | -1}, |
368 | {0x22,0x6a7f,0x0000,SIS_RI_960x600, 0x00,0x00,0x00,0x00,0x2e,-1}, | 360 | {0x1d, 0x6a1b, 0x0000, SIS_RI_960x540, 0x00, 0x00, 0x00, 0x00, 0x2d, -1}, /* 960x540 */ |
369 | {0x29,0x4e1b,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x33,-1}, /* 1152x864 */ | 361 | {0x1e, 0x6a3d, 0x0000, SIS_RI_960x540, 0x00, 0x00, 0x00, 0x00, 0x2d, |
370 | {0x2a,0x4e3d,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x33,-1}, | 362 | -1}, |
371 | {0x2b,0x4e7f,0x0000,SIS_RI_1152x864, 0x00,0x00,0x00,0x00,0x33,-1}, | 363 | {0x1f, 0x6a7f, 0x0000, SIS_RI_960x540, 0x00, 0x00, 0x00, 0x00, 0x2d, |
372 | {0xff,0x0000,0x0000,0, 0x00,0x00,0x00,0x00,0x00,-1} | 364 | -1}, |
365 | {0x20, 0x6a1b, 0x0000, SIS_RI_960x600, 0x00, 0x00, 0x00, 0x00, 0x2e, -1}, /* 960x600 */ | ||
366 | {0x21, 0x6a3d, 0x0000, SIS_RI_960x600, 0x00, 0x00, 0x00, 0x00, 0x2e, | ||
367 | -1}, | ||
368 | {0x22, 0x6a7f, 0x0000, SIS_RI_960x600, 0x00, 0x00, 0x00, 0x00, 0x2e, | ||
369 | -1}, | ||
370 | {0x29, 0x4e1b, 0x0000, SIS_RI_1152x864, 0x00, 0x00, 0x00, 0x00, 0x33, -1}, /* 1152x864 */ | ||
371 | {0x2a, 0x4e3d, 0x0000, SIS_RI_1152x864, 0x00, 0x00, 0x00, 0x00, 0x33, | ||
372 | -1}, | ||
373 | {0x2b, 0x4e7f, 0x0000, SIS_RI_1152x864, 0x00, 0x00, 0x00, 0x00, 0x33, | ||
374 | -1}, | ||
375 | {0xff, 0x0000, 0x0000, 0, 0x00, 0x00, 0x00, 0x00, 0x00, -1} | ||
373 | }; | 376 | }; |
374 | 377 | ||
375 | static const struct SiS_Ext2 SiSUSB_RefIndex[] = | 378 | static const struct SiS_Ext2 SiSUSB_RefIndex[] = { |
376 | { | 379 | {0x085f, 0x0d, 0x03, 0x05, 0x05, 0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x0 */ |
377 | {0x085f,0x0d,0x03,0x05,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x0 */ | 380 | {0x0067, 0x0e, 0x04, 0x05, 0x05, 0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x1 */ |
378 | {0x0067,0x0e,0x04,0x05,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x1 */ | 381 | {0x0067, 0x0f, 0x08, 0x48, 0x05, 0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x2 */ |
379 | {0x0067,0x0f,0x08,0x48,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x2 */ | 382 | {0x0067, 0x10, 0x07, 0x8b, 0x05, 0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x3 */ |
380 | {0x0067,0x10,0x07,0x8b,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x3 */ | 383 | {0x0047, 0x11, 0x0a, 0x00, 0x05, 0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x4 */ |
381 | {0x0047,0x11,0x0a,0x00,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x4 */ | 384 | {0x0047, 0x12, 0x0d, 0x00, 0x05, 0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x5 */ |
382 | {0x0047,0x12,0x0d,0x00,0x05,0x30, 800, 600, 0x40, 0x00, 0x00}, /* 0x5 */ | 385 | {0x0047, 0x13, 0x13, 0x00, 0x05, 0x30, 800, 600, 0x20, 0x00, 0x00}, /* 0x6 */ |
383 | {0x0047,0x13,0x13,0x00,0x05,0x30, 800, 600, 0x20, 0x00, 0x00}, /* 0x6 */ | 386 | {0x0107, 0x14, 0x1c, 0x00, 0x05, 0x30, 800, 600, 0x20, 0x00, 0x00}, /* 0x7 */ |
384 | {0x0107,0x14,0x1c,0x00,0x05,0x30, 800, 600, 0x20, 0x00, 0x00}, /* 0x7 */ | 387 | {0xc85f, 0x05, 0x00, 0x04, 0x04, 0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0x8 */ |
385 | {0xc85f,0x05,0x00,0x04,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0x8 */ | 388 | {0xc067, 0x06, 0x02, 0x04, 0x04, 0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0x9 */ |
386 | {0xc067,0x06,0x02,0x04,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0x9 */ | 389 | {0xc067, 0x07, 0x02, 0x47, 0x04, 0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xa */ |
387 | {0xc067,0x07,0x02,0x47,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xa */ | 390 | {0xc067, 0x08, 0x03, 0x8a, 0x04, 0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xb */ |
388 | {0xc067,0x08,0x03,0x8a,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xb */ | 391 | {0xc047, 0x09, 0x05, 0x00, 0x04, 0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xc */ |
389 | {0xc047,0x09,0x05,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xc */ | 392 | {0xc047, 0x0a, 0x09, 0x00, 0x04, 0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xd */ |
390 | {0xc047,0x0a,0x09,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xd */ | 393 | {0xc047, 0x0b, 0x0e, 0x00, 0x04, 0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xe */ |
391 | {0xc047,0x0b,0x0e,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xe */ | 394 | {0xc047, 0x0c, 0x15, 0x00, 0x04, 0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xf */ |
392 | {0xc047,0x0c,0x15,0x00,0x04,0x2e, 640, 480, 0x40, 0x00, 0x00}, /* 0xf */ | 395 | {0x487f, 0x04, 0x00, 0x00, 0x00, 0x2f, 640, 400, 0x30, 0x55, 0x6e}, /* 0x10 */ |
393 | {0x487f,0x04,0x00,0x00,0x00,0x2f, 640, 400, 0x30, 0x55, 0x6e}, /* 0x10 */ | 396 | {0xc06f, 0x3c, 0x01, 0x06, 0x13, 0x31, 720, 480, 0x30, 0x00, 0x00}, /* 0x11 */ |
394 | {0xc06f,0x3c,0x01,0x06,0x13,0x31, 720, 480, 0x30, 0x00, 0x00}, /* 0x11 */ | 397 | {0x006f, 0x3d, 0x6f, 0x06, 0x14, 0x32, 720, 576, 0x30, 0x00, 0x00}, /* 0x12 (6f was 03) */ |
395 | {0x006f,0x3d,0x6f,0x06,0x14,0x32, 720, 576, 0x30, 0x00, 0x00}, /* 0x12 (6f was 03) */ | 398 | {0x0087, 0x15, 0x06, 0x00, 0x06, 0x38, 1024, 768, 0x30, 0x00, 0x00}, /* 0x13 */ |
396 | {0x0087,0x15,0x06,0x00,0x06,0x38,1024, 768, 0x30, 0x00, 0x00}, /* 0x13 */ | 399 | {0xc877, 0x16, 0x0b, 0x06, 0x06, 0x38, 1024, 768, 0x20, 0x00, 0x00}, /* 0x14 */ |
397 | {0xc877,0x16,0x0b,0x06,0x06,0x38,1024, 768, 0x20, 0x00, 0x00}, /* 0x14 */ | 400 | {0xc067, 0x17, 0x0f, 0x49, 0x06, 0x38, 1024, 768, 0x20, 0x00, 0x00}, /* 0x15 */ |
398 | {0xc067,0x17,0x0f,0x49,0x06,0x38,1024, 768, 0x20, 0x00, 0x00}, /* 0x15 */ | 401 | {0x0067, 0x18, 0x11, 0x00, 0x06, 0x38, 1024, 768, 0x20, 0x00, 0x00}, /* 0x16 */ |
399 | {0x0067,0x18,0x11,0x00,0x06,0x38,1024, 768, 0x20, 0x00, 0x00}, /* 0x16 */ | 402 | {0x0047, 0x19, 0x16, 0x8c, 0x06, 0x38, 1024, 768, 0x20, 0x00, 0x00}, /* 0x17 */ |
400 | {0x0047,0x19,0x16,0x8c,0x06,0x38,1024, 768, 0x20, 0x00, 0x00}, /* 0x17 */ | 403 | {0x0107, 0x1a, 0x1b, 0x00, 0x06, 0x38, 1024, 768, 0x10, 0x00, 0x00}, /* 0x18 */ |
401 | {0x0107,0x1a,0x1b,0x00,0x06,0x38,1024, 768, 0x10, 0x00, 0x00}, /* 0x18 */ | 404 | {0x0107, 0x1b, 0x1f, 0x00, 0x06, 0x38, 1024, 768, 0x10, 0x00, 0x00}, /* 0x19 */ |
402 | {0x0107,0x1b,0x1f,0x00,0x06,0x38,1024, 768, 0x10, 0x00, 0x00}, /* 0x19 */ | 405 | {0x407f, 0x00, 0x00, 0x00, 0x00, 0x41, 320, 200, 0x30, 0x56, 0x4e}, /* 0x1a */ |
403 | {0x407f,0x00,0x00,0x00,0x00,0x41, 320, 200, 0x30, 0x56, 0x4e}, /* 0x1a */ | 406 | {0xc07f, 0x01, 0x00, 0x04, 0x04, 0x50, 320, 240, 0x30, 0x00, 0x00}, /* 0x1b */ |
404 | {0xc07f,0x01,0x00,0x04,0x04,0x50, 320, 240, 0x30, 0x00, 0x00}, /* 0x1b */ | 407 | {0x007f, 0x02, 0x04, 0x05, 0x05, 0x51, 400, 300, 0x30, 0x00, 0x00}, /* 0x1c */ |
405 | {0x007f,0x02,0x04,0x05,0x05,0x51, 400, 300, 0x30, 0x00, 0x00}, /* 0x1c */ | 408 | {0xc077, 0x03, 0x0b, 0x06, 0x06, 0x52, 512, 384, 0x30, 0x00, 0x00}, /* 0x1d */ |
406 | {0xc077,0x03,0x0b,0x06,0x06,0x52, 512, 384, 0x30, 0x00, 0x00}, /* 0x1d */ | 409 | {0x0077, 0x32, 0x40, 0x08, 0x18, 0x70, 800, 480, 0x30, 0x00, 0x00}, /* 0x1e */ |
407 | {0x0077,0x32,0x40,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00}, /* 0x1e */ | 410 | {0x0047, 0x33, 0x07, 0x08, 0x18, 0x70, 800, 480, 0x30, 0x00, 0x00}, /* 0x1f */ |
408 | {0x0047,0x33,0x07,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00}, /* 0x1f */ | 411 | {0x0047, 0x34, 0x0a, 0x08, 0x18, 0x70, 800, 480, 0x30, 0x00, 0x00}, /* 0x20 */ |
409 | {0x0047,0x34,0x0a,0x08,0x18,0x70, 800, 480, 0x30, 0x00, 0x00}, /* 0x20 */ | 412 | {0x0077, 0x35, 0x0b, 0x09, 0x19, 0x71, 1024, 576, 0x30, 0x00, 0x00}, /* 0x21 */ |
410 | {0x0077,0x35,0x0b,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00}, /* 0x21 */ | 413 | {0x0047, 0x36, 0x11, 0x09, 0x19, 0x71, 1024, 576, 0x30, 0x00, 0x00}, /* 0x22 */ |
411 | {0x0047,0x36,0x11,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00}, /* 0x22 */ | 414 | {0x0047, 0x37, 0x16, 0x09, 0x19, 0x71, 1024, 576, 0x30, 0x00, 0x00}, /* 0x23 */ |
412 | {0x0047,0x37,0x16,0x09,0x19,0x71,1024, 576, 0x30, 0x00, 0x00}, /* 0x23 */ | 415 | {0x1137, 0x38, 0x19, 0x0a, 0x0c, 0x75, 1280, 720, 0x30, 0x00, 0x00}, /* 0x24 */ |
413 | {0x1137,0x38,0x19,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00}, /* 0x24 */ | 416 | {0x1107, 0x39, 0x1e, 0x0a, 0x0c, 0x75, 1280, 720, 0x30, 0x00, 0x00}, /* 0x25 */ |
414 | {0x1107,0x39,0x1e,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00}, /* 0x25 */ | 417 | {0x1307, 0x3a, 0x20, 0x0a, 0x0c, 0x75, 1280, 720, 0x30, 0x00, 0x00}, /* 0x26 */ |
415 | {0x1307,0x3a,0x20,0x0a,0x0c,0x75,1280, 720, 0x30, 0x00, 0x00}, /* 0x26 */ | 418 | {0x0077, 0x42, 0x5b, 0x08, 0x11, 0x23, 1280, 768, 0x30, 0x00, 0x00}, /* 0x27 */ |
416 | {0x0077,0x42,0x5b,0x08,0x11,0x23,1280, 768, 0x30, 0x00, 0x00}, /* 0x27 */ | 419 | {0x0087, 0x45, 0x57, 0x00, 0x16, 0x39, 848, 480, 0x30, 0x00, 0x00}, /* 0x28 38Hzi */ |
417 | {0x0087,0x45,0x57,0x00,0x16,0x39, 848, 480, 0x30, 0x00, 0x00}, /* 0x28 38Hzi */ | 420 | {0xc067, 0x46, 0x55, 0x0b, 0x16, 0x39, 848, 480, 0x30, 0x00, 0x00}, /* 0x29 848x480-60Hz */ |
418 | {0xc067,0x46,0x55,0x0b,0x16,0x39, 848, 480, 0x30, 0x00, 0x00}, /* 0x29 848x480-60Hz */ | 421 | {0x0087, 0x47, 0x57, 0x00, 0x17, 0x3f, 856, 480, 0x30, 0x00, 0x00}, /* 0x2a 856x480-38Hzi */ |
419 | {0x0087,0x47,0x57,0x00,0x17,0x3f, 856, 480, 0x30, 0x00, 0x00}, /* 0x2a 856x480-38Hzi */ | 422 | {0xc067, 0x48, 0x57, 0x00, 0x17, 0x3f, 856, 480, 0x30, 0x00, 0x00}, /* 0x2b 856x480-60Hz */ |
420 | {0xc067,0x48,0x57,0x00,0x17,0x3f, 856, 480, 0x30, 0x00, 0x00}, /* 0x2b 856x480-60Hz */ | 423 | {0x006f, 0x4d, 0x71, 0x06, 0x15, 0x5f, 768, 576, 0x30, 0x00, 0x00}, /* 0x2c 768x576-56Hz */ |
421 | {0x006f,0x4d,0x71,0x06,0x15,0x5f, 768, 576, 0x30, 0x00, 0x00}, /* 0x2c 768x576-56Hz */ | 424 | {0x0067, 0x52, 0x6a, 0x00, 0x1c, 0x1d, 960, 540, 0x30, 0x00, 0x00}, /* 0x2d 960x540 60Hz */ |
422 | {0x0067,0x52,0x6a,0x00,0x1c,0x1d, 960, 540, 0x30, 0x00, 0x00}, /* 0x2d 960x540 60Hz */ | 425 | {0x0077, 0x53, 0x6b, 0x0b, 0x1d, 0x20, 960, 600, 0x30, 0x00, 0x00}, /* 0x2e 960x600 60Hz */ |
423 | {0x0077,0x53,0x6b,0x0b,0x1d,0x20, 960, 600, 0x30, 0x00, 0x00}, /* 0x2e 960x600 60Hz */ | 426 | {0x0087, 0x1c, 0x11, 0x00, 0x07, 0x3a, 1280, 1024, 0x30, 0x00, 0x00}, /* 0x2f */ |
424 | {0x0087,0x1c,0x11,0x00,0x07,0x3a,1280,1024, 0x30, 0x00, 0x00}, /* 0x2f */ | 427 | {0x0137, 0x1d, 0x19, 0x07, 0x07, 0x3a, 1280, 1024, 0x00, 0x00, 0x00}, /* 0x30 */ |
425 | {0x0137,0x1d,0x19,0x07,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00}, /* 0x30 */ | 428 | {0x0107, 0x1e, 0x1e, 0x00, 0x07, 0x3a, 1280, 1024, 0x00, 0x00, 0x00}, /* 0x31 */ |
426 | {0x0107,0x1e,0x1e,0x00,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00}, /* 0x31 */ | 429 | {0x0207, 0x1f, 0x20, 0x00, 0x07, 0x3a, 1280, 1024, 0x00, 0x00, 0x00}, /* 0x32 */ |
427 | {0x0207,0x1f,0x20,0x00,0x07,0x3a,1280,1024, 0x00, 0x00, 0x00}, /* 0x32 */ | 430 | {0x0127, 0x54, 0x6d, 0x00, 0x1a, 0x29, 1152, 864, 0x30, 0x00, 0x00}, /* 0x33 1152x864-60Hz */ |
428 | {0x0127,0x54,0x6d,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00}, /* 0x33 1152x864-60Hz */ | 431 | {0x0127, 0x44, 0x19, 0x00, 0x1a, 0x29, 1152, 864, 0x30, 0x00, 0x00}, /* 0x34 1152x864-75Hz */ |
429 | {0x0127,0x44,0x19,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00}, /* 0x34 1152x864-75Hz */ | 432 | {0x0127, 0x4a, 0x1e, 0x00, 0x1a, 0x29, 1152, 864, 0x30, 0x00, 0x00}, /* 0x35 1152x864-85Hz */ |
430 | {0x0127,0x4a,0x1e,0x00,0x1a,0x29,1152, 864, 0x30, 0x00, 0x00}, /* 0x35 1152x864-85Hz */ | 433 | {0xffff, 0x00, 0x00, 0x00, 0x00, 0x00, 0, 0, 0, 0x00, 0x00} |
431 | {0xffff,0x00,0x00,0x00,0x00,0x00, 0, 0, 0, 0x00, 0x00} | ||
432 | }; | 434 | }; |
433 | 435 | ||
434 | static const struct SiS_CRT1Table SiSUSB_CRT1Table[] = | 436 | static const struct SiS_CRT1Table SiSUSB_CRT1Table[] = { |
435 | { | 437 | {{0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0xbf, 0x1f, |
436 | {{0x2d,0x27,0x28,0x90,0x2c,0x80,0xbf,0x1f, | 438 | 0x9c, 0x8e, 0x8f, 0x96, 0xb9, 0x30, 0x00, 0x00, |
437 | 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x00, | 439 | 0x00}}, /* 0x0 */ |
438 | 0x00}}, /* 0x0 */ | 440 | {{0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0x0b, 0x3e, |
439 | {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, | 441 | 0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x00, |
440 | 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00, | 442 | 0x00}}, /* 0x1 */ |
441 | 0x00}}, /* 0x1 */ | 443 | {{0x3d, 0x31, 0x31, 0x81, 0x37, 0x1f, 0x72, 0xf0, |
442 | {{0x3d,0x31,0x31,0x81,0x37,0x1f,0x72,0xf0, | 444 | 0x58, 0x8c, 0x57, 0x57, 0x73, 0x20, 0x00, 0x05, |
443 | 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x05, | 445 | 0x01}}, /* 0x2 */ |
444 | 0x01}}, /* 0x2 */ | 446 | {{0x4f, 0x3f, 0x3f, 0x93, 0x45, 0x0d, 0x24, 0xf5, |
445 | {{0x4f,0x3f,0x3f,0x93,0x45,0x0d,0x24,0xf5, | 447 | 0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x01, |
446 | 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x01, | 448 | 0x01}}, /* 0x3 */ |
447 | 0x01}}, /* 0x3 */ | 449 | {{0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f, |
448 | {{0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f, | 450 | 0x9c, 0x8e, 0x8f, 0x96, 0xb9, 0x30, 0x00, 0x05, |
449 | 0x9c,0x8e,0x8f,0x96,0xb9,0x30,0x00,0x05, | 451 | 0x00}}, /* 0x4 */ |
450 | 0x00}}, /* 0x4 */ | 452 | {{0x5f, 0x4f, 0x4f, 0x83, 0x55, 0x81, 0x0b, 0x3e, |
451 | {{0x5f,0x4f,0x4f,0x83,0x55,0x81,0x0b,0x3e, | 453 | 0xe9, 0x8b, 0xdf, 0xe8, 0x0c, 0x00, 0x00, 0x05, |
452 | 0xe9,0x8b,0xdf,0xe8,0x0c,0x00,0x00,0x05, | 454 | 0x00}}, /* 0x5 */ |
453 | 0x00}}, /* 0x5 */ | 455 | {{0x63, 0x4f, 0x4f, 0x87, 0x56, 0x9b, 0x06, 0x3e, |
454 | {{0x63,0x4f,0x4f,0x87,0x56,0x9b,0x06,0x3e, | 456 | 0xe8, 0x8a, 0xdf, 0xe7, 0x07, 0x00, 0x00, 0x01, |
455 | 0xe8,0x8a,0xdf,0xe7,0x07,0x00,0x00,0x01, | 457 | 0x00}}, /* 0x6 */ |
456 | 0x00}}, /* 0x6 */ | 458 | {{0x64, 0x4f, 0x4f, 0x88, 0x55, 0x9d, 0xf2, 0x1f, |
457 | {{0x64,0x4f,0x4f,0x88,0x55,0x9d,0xf2,0x1f, | 459 | 0xe0, 0x83, 0xdf, 0xdf, 0xf3, 0x10, 0x00, 0x01, |
458 | 0xe0,0x83,0xdf,0xdf,0xf3,0x10,0x00,0x01, | 460 | 0x00}}, /* 0x7 */ |
459 | 0x00}}, /* 0x7 */ | 461 | {{0x63, 0x4f, 0x4f, 0x87, 0x5a, 0x81, 0xfb, 0x1f, |
460 | {{0x63,0x4f,0x4f,0x87,0x5a,0x81,0xfb,0x1f, | 462 | 0xe0, 0x83, 0xdf, 0xdf, 0xfc, 0x10, 0x00, 0x05, |
461 | 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05, | 463 | 0x00}}, /* 0x8 */ |
462 | 0x00}}, /* 0x8 */ | 464 | {{0x65, 0x4f, 0x4f, 0x89, 0x58, 0x80, 0xfb, 0x1f, |
463 | {{0x65,0x4f,0x4f,0x89,0x58,0x80,0xfb,0x1f, | 465 | 0xe0, 0x83, 0xdf, 0xdf, 0xfc, 0x10, 0x00, 0x05, |
464 | 0xe0,0x83,0xdf,0xdf,0xfc,0x10,0x00,0x05, | 466 | 0x61}}, /* 0x9 */ |
465 | 0x61}}, /* 0x9 */ | 467 | {{0x65, 0x4f, 0x4f, 0x89, 0x58, 0x80, 0x01, 0x3e, |
466 | {{0x65,0x4f,0x4f,0x89,0x58,0x80,0x01,0x3e, | 468 | 0xe0, 0x83, 0xdf, 0xdf, 0x02, 0x00, 0x00, 0x05, |
467 | 0xe0,0x83,0xdf,0xdf,0x02,0x00,0x00,0x05, | 469 | 0x61}}, /* 0xa */ |
468 | 0x61}}, /* 0xa */ | 470 | {{0x67, 0x4f, 0x4f, 0x8b, 0x58, 0x81, 0x0d, 0x3e, |
469 | {{0x67,0x4f,0x4f,0x8b,0x58,0x81,0x0d,0x3e, | 471 | 0xe0, 0x83, 0xdf, 0xdf, 0x0e, 0x00, 0x00, 0x05, |
470 | 0xe0,0x83,0xdf,0xdf,0x0e,0x00,0x00,0x05, | 472 | 0x61}}, /* 0xb */ |
471 | 0x61}}, /* 0xb */ | 473 | {{0x65, 0x4f, 0x4f, 0x89, 0x57, 0x9f, 0xfb, 0x1f, |
472 | {{0x65,0x4f,0x4f,0x89,0x57,0x9f,0xfb,0x1f, | 474 | 0xe6, 0x8a, 0xdf, 0xdf, 0xfc, 0x10, 0x00, 0x01, |
473 | 0xe6,0x8a,0xdf,0xdf,0xfc,0x10,0x00,0x01, | 475 | 0x00}}, /* 0xc */ |
474 | 0x00}}, /* 0xc */ | 476 | {{0x7b, 0x63, 0x63, 0x9f, 0x6a, 0x93, 0x6f, 0xf0, |
475 | {{0x7b,0x63,0x63,0x9f,0x6a,0x93,0x6f,0xf0, | 477 | 0x58, 0x8a, 0x57, 0x57, 0x70, 0x20, 0x00, 0x05, |
476 | 0x58,0x8a,0x57,0x57,0x70,0x20,0x00,0x05, | 478 | 0x01}}, /* 0xd */ |
477 | 0x01}}, /* 0xd */ | 479 | {{0x7f, 0x63, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xf0, |
478 | {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xf0, | 480 | 0x58, 0x8c, 0x57, 0x57, 0x73, 0x20, 0x00, 0x06, |
479 | 0x58,0x8c,0x57,0x57,0x73,0x20,0x00,0x06, | 481 | 0x01}}, /* 0xe */ |
480 | 0x01}}, /* 0xe */ | 482 | {{0x7d, 0x63, 0x63, 0x81, 0x6e, 0x1d, 0x98, 0xf0, |
481 | {{0x7d,0x63,0x63,0x81,0x6e,0x1d,0x98,0xf0, | 483 | 0x7c, 0x82, 0x57, 0x57, 0x99, 0x00, 0x00, 0x06, |
482 | 0x7c,0x82,0x57,0x57,0x99,0x00,0x00,0x06, | 484 | 0x01}}, /* 0xf */ |
483 | 0x01}}, /* 0xf */ | 485 | {{0x7f, 0x63, 0x63, 0x83, 0x69, 0x13, 0x6f, 0xf0, |
484 | {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xf0, | 486 | 0x58, 0x8b, 0x57, 0x57, 0x70, 0x20, 0x00, 0x06, |
485 | 0x58,0x8b,0x57,0x57,0x70,0x20,0x00,0x06, | 487 | 0x01}}, /* 0x10 */ |
486 | 0x01}}, /* 0x10 */ | 488 | {{0x7e, 0x63, 0x63, 0x82, 0x6b, 0x13, 0x75, 0xf0, |
487 | {{0x7e,0x63,0x63,0x82,0x6b,0x13,0x75,0xf0, | 489 | 0x58, 0x8b, 0x57, 0x57, 0x76, 0x20, 0x00, 0x06, |
488 | 0x58,0x8b,0x57,0x57,0x76,0x20,0x00,0x06, | 490 | 0x01}}, /* 0x11 */ |
489 | 0x01}}, /* 0x11 */ | 491 | {{0x81, 0x63, 0x63, 0x85, 0x6d, 0x18, 0x7a, 0xf0, |
490 | {{0x81,0x63,0x63,0x85,0x6d,0x18,0x7a,0xf0, | 492 | 0x58, 0x8b, 0x57, 0x57, 0x7b, 0x20, 0x00, 0x06, |
491 | 0x58,0x8b,0x57,0x57,0x7b,0x20,0x00,0x06, | 493 | 0x61}}, /* 0x12 */ |
492 | 0x61}}, /* 0x12 */ | 494 | {{0x83, 0x63, 0x63, 0x87, 0x6e, 0x19, 0x81, 0xf0, |
493 | {{0x83,0x63,0x63,0x87,0x6e,0x19,0x81,0xf0, | 495 | 0x58, 0x8b, 0x57, 0x57, 0x82, 0x20, 0x00, 0x06, |
494 | 0x58,0x8b,0x57,0x57,0x82,0x20,0x00,0x06, | 496 | 0x61}}, /* 0x13 */ |
495 | 0x61}}, /* 0x13 */ | 497 | {{0x85, 0x63, 0x63, 0x89, 0x6f, 0x1a, 0x91, 0xf0, |
496 | {{0x85,0x63,0x63,0x89,0x6f,0x1a,0x91,0xf0, | 498 | 0x58, 0x8b, 0x57, 0x57, 0x92, 0x20, 0x00, 0x06, |
497 | 0x58,0x8b,0x57,0x57,0x92,0x20,0x00,0x06, | 499 | 0x61}}, /* 0x14 */ |
498 | 0x61}}, /* 0x14 */ | 500 | {{0x99, 0x7f, 0x7f, 0x9d, 0x84, 0x1a, 0x96, 0x1f, |
499 | {{0x99,0x7f,0x7f,0x9d,0x84,0x1a,0x96,0x1f, | 501 | 0x7f, 0x83, 0x7f, 0x7f, 0x97, 0x10, 0x00, 0x02, |
500 | 0x7f,0x83,0x7f,0x7f,0x97,0x10,0x00,0x02, | 502 | 0x00}}, /* 0x15 */ |
501 | 0x00}}, /* 0x15 */ | 503 | {{0xa3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5, |
502 | {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5, | 504 | 0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x02, |
503 | 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02, | 505 | 0x01}}, /* 0x16 */ |
504 | 0x01}}, /* 0x16 */ | 506 | {{0xa1, 0x7f, 0x7f, 0x85, 0x86, 0x97, 0x24, 0xf5, |
505 | {{0xa1,0x7f,0x7f,0x85,0x86,0x97,0x24,0xf5, | 507 | 0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x02, |
506 | 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02, | 508 | 0x01}}, /* 0x17 */ |
507 | 0x01}}, /* 0x17 */ | 509 | {{0x9f, 0x7f, 0x7f, 0x83, 0x85, 0x91, 0x1e, 0xf5, |
508 | {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf5, | 510 | 0x00, 0x83, 0xff, 0xff, 0x1f, 0x10, 0x00, 0x02, |
509 | 0x00,0x83,0xff,0xff,0x1f,0x10,0x00,0x02, | 511 | 0x01}}, /* 0x18 */ |
510 | 0x01}}, /* 0x18 */ | 512 | {{0xa7, 0x7f, 0x7f, 0x8b, 0x89, 0x95, 0x26, 0xf5, |
511 | {{0xa7,0x7f,0x7f,0x8b,0x89,0x95,0x26,0xf5, | 513 | 0x00, 0x83, 0xff, 0xff, 0x27, 0x10, 0x00, 0x02, |
512 | 0x00,0x83,0xff,0xff,0x27,0x10,0x00,0x02, | 514 | 0x01}}, /* 0x19 */ |
513 | 0x01}}, /* 0x19 */ | 515 | {{0xa9, 0x7f, 0x7f, 0x8d, 0x8c, 0x9a, 0x2c, 0xf5, |
514 | {{0xa9,0x7f,0x7f,0x8d,0x8c,0x9a,0x2c,0xf5, | 516 | 0x00, 0x83, 0xff, 0xff, 0x2d, 0x14, 0x00, 0x02, |
515 | 0x00,0x83,0xff,0xff,0x2d,0x14,0x00,0x02, | 517 | 0x62}}, /* 0x1a */ |
516 | 0x62}}, /* 0x1a */ | 518 | {{0xab, 0x7f, 0x7f, 0x8f, 0x8d, 0x9b, 0x35, 0xf5, |
517 | {{0xab,0x7f,0x7f,0x8f,0x8d,0x9b,0x35,0xf5, | 519 | 0x00, 0x83, 0xff, 0xff, 0x36, 0x14, 0x00, 0x02, |
518 | 0x00,0x83,0xff,0xff,0x36,0x14,0x00,0x02, | 520 | 0x62}}, /* 0x1b */ |
519 | 0x62}}, /* 0x1b */ | 521 | {{0xcf, 0x9f, 0x9f, 0x93, 0xb2, 0x01, 0x14, 0xba, |
520 | {{0xcf,0x9f,0x9f,0x93,0xb2,0x01,0x14,0xba, | 522 | 0x00, 0x83, 0xff, 0xff, 0x15, 0x00, 0x00, 0x03, |
521 | 0x00,0x83,0xff,0xff,0x15,0x00,0x00,0x03, | 523 | 0x00}}, /* 0x1c */ |
522 | 0x00}}, /* 0x1c */ | 524 | {{0xce, 0x9f, 0x9f, 0x92, 0xa9, 0x17, 0x28, 0x5a, |
523 | {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0x5a, | 525 | 0x00, 0x83, 0xff, 0xff, 0x29, 0x09, 0x00, 0x07, |
524 | 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07, | 526 | 0x01}}, /* 0x1d */ |
525 | 0x01}}, /* 0x1d */ | 527 | {{0xce, 0x9f, 0x9f, 0x92, 0xa5, 0x17, 0x28, 0x5a, |
526 | {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0x5a, | 528 | 0x00, 0x83, 0xff, 0xff, 0x29, 0x09, 0x00, 0x07, |
527 | 0x00,0x83,0xff,0xff,0x29,0x09,0x00,0x07, | 529 | 0x01}}, /* 0x1e */ |
528 | 0x01}}, /* 0x1e */ | 530 | {{0xd3, 0x9f, 0x9f, 0x97, 0xab, 0x1f, 0x2e, 0x5a, |
529 | {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0x5a, | 531 | 0x00, 0x83, 0xff, 0xff, 0x2f, 0x09, 0x00, 0x07, |
530 | 0x00,0x83,0xff,0xff,0x2f,0x09,0x00,0x07, | 532 | 0x01}}, /* 0x1f */ |
531 | 0x01}}, /* 0x1f */ | 533 | {{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10, |
532 | {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, | 534 | 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04, |
533 | 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, | 535 | 0x00}}, /* 0x20 */ |
534 | 0x00}}, /* 0x20 */ | 536 | {{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10, |
535 | {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, | 537 | 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04, |
536 | 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, | 538 | 0x00}}, /* 0x21 */ |
537 | 0x00}}, /* 0x21 */ | 539 | {{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10, |
538 | {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, | 540 | 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04, |
539 | 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, | 541 | 0x00}}, /* 0x22 */ |
540 | 0x00}}, /* 0x22 */ | 542 | {{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10, |
541 | {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, | 543 | 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04, |
542 | 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, | 544 | 0x00}}, /* 0x23 */ |
543 | 0x00}}, /* 0x23 */ | 545 | {{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10, |
544 | {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, | 546 | 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04, |
545 | 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, | 547 | 0x00}}, /* 0x24 */ |
546 | 0x00}}, /* 0x24 */ | 548 | {{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10, |
547 | {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, | 549 | 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04, |
548 | 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, | 550 | 0x00}}, /* 0x25 */ |
549 | 0x00}}, /* 0x25 */ | 551 | {{0x09, 0xc7, 0xc7, 0x8d, 0xd3, 0x0b, 0xe0, 0x10, |
550 | {{0x09,0xc7,0xc7,0x8d,0xd3,0x0b,0xe0,0x10, | 552 | 0xb0, 0x83, 0xaf, 0xaf, 0xe1, 0x2f, 0x01, 0x04, |
551 | 0xb0,0x83,0xaf,0xaf,0xe1,0x2f,0x01,0x04, | 553 | 0x00}}, /* 0x26 */ |
552 | 0x00}}, /* 0x26 */ | 554 | {{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f, |
553 | {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f, | 555 | 0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01, |
554 | 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01, | 556 | 0x00}}, /* 0x27 */ |
555 | 0x00}}, /* 0x27 */ | 557 | {{0x43, 0xef, 0xef, 0x87, 0x06, 0x00, 0xd4, 0x1f, |
556 | {{0x43,0xef,0xef,0x87,0x06,0x00,0xd4,0x1f, | 558 | 0xa0, 0x83, 0x9f, 0x9f, 0xd5, 0x1f, 0x41, 0x05, |
557 | 0xa0,0x83,0x9f,0x9f,0xd5,0x1f,0x41,0x05, | 559 | 0x63}}, /* 0x28 */ |
558 | 0x63}}, /* 0x28 */ | 560 | {{0x45, 0xef, 0xef, 0x89, 0x07, 0x01, 0xd9, 0x1f, |
559 | {{0x45,0xef,0xef,0x89,0x07,0x01,0xd9,0x1f, | 561 | 0xa0, 0x83, 0x9f, 0x9f, 0xda, 0x1f, 0x41, 0x05, |
560 | 0xa0,0x83,0x9f,0x9f,0xda,0x1f,0x41,0x05, | 562 | 0x63}}, /* 0x29 */ |
561 | 0x63}}, /* 0x29 */ | 563 | {{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f, |
562 | {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f, | 564 | 0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01, |
563 | 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01, | 565 | 0x00}}, /* 0x2a */ |
564 | 0x00}}, /* 0x2a */ | 566 | {{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f, |
565 | {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f, | 567 | 0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01, |
566 | 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01, | 568 | 0x00}}, /* 0x2b */ |
567 | 0x00}}, /* 0x2b */ | 569 | {{0x40, 0xef, 0xef, 0x84, 0x03, 0x1d, 0xda, 0x1f, |
568 | {{0x40,0xef,0xef,0x84,0x03,0x1d,0xda,0x1f, | 570 | 0xa0, 0x83, 0x9f, 0x9f, 0xdb, 0x1f, 0x41, 0x01, |
569 | 0xa0,0x83,0x9f,0x9f,0xdb,0x1f,0x41,0x01, | 571 | 0x00}}, /* 0x2c */ |
570 | 0x00}}, /* 0x2c */ | 572 | {{0x59, 0xff, 0xff, 0x9d, 0x17, 0x13, 0x33, 0xba, |
571 | {{0x59,0xff,0xff,0x9d,0x17,0x13,0x33,0xba, | 573 | 0x00, 0x83, 0xff, 0xff, 0x34, 0x0f, 0x41, 0x05, |
572 | 0x00,0x83,0xff,0xff,0x34,0x0f,0x41,0x05, | 574 | 0x44}}, /* 0x2d */ |
573 | 0x44}}, /* 0x2d */ | 575 | {{0x5b, 0xff, 0xff, 0x9f, 0x18, 0x14, 0x38, 0xba, |
574 | {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x38,0xba, | 576 | 0x00, 0x83, 0xff, 0xff, 0x39, 0x0f, 0x41, 0x05, |
575 | 0x00,0x83,0xff,0xff,0x39,0x0f,0x41,0x05, | 577 | 0x44}}, /* 0x2e */ |
576 | 0x44}}, /* 0x2e */ | 578 | {{0x5b, 0xff, 0xff, 0x9f, 0x18, 0x14, 0x3d, 0xba, |
577 | {{0x5b,0xff,0xff,0x9f,0x18,0x14,0x3d,0xba, | 579 | 0x00, 0x83, 0xff, 0xff, 0x3e, 0x0f, 0x41, 0x05, |
578 | 0x00,0x83,0xff,0xff,0x3e,0x0f,0x41,0x05, | 580 | 0x44}}, /* 0x2f */ |
579 | 0x44}}, /* 0x2f */ | 581 | {{0x5d, 0xff, 0xff, 0x81, 0x19, 0x95, 0x41, 0xba, |
580 | {{0x5d,0xff,0xff,0x81,0x19,0x95,0x41,0xba, | 582 | 0x00, 0x84, 0xff, 0xff, 0x42, 0x0f, 0x41, 0x05, |
581 | 0x00,0x84,0xff,0xff,0x42,0x0f,0x41,0x05, | 583 | 0x44}}, /* 0x30 */ |
582 | 0x44}}, /* 0x30 */ | 584 | {{0x55, 0xff, 0xff, 0x99, 0x0d, 0x0c, 0x3e, 0xba, |
583 | {{0x55,0xff,0xff,0x99,0x0d,0x0c,0x3e,0xba, | 585 | 0x00, 0x84, 0xff, 0xff, 0x3f, 0x0f, 0x41, 0x05, |
584 | 0x00,0x84,0xff,0xff,0x3f,0x0f,0x41,0x05, | 586 | 0x00}}, /* 0x31 */ |
585 | 0x00}}, /* 0x31 */ | 587 | {{0x7f, 0x63, 0x63, 0x83, 0x6c, 0x1c, 0x72, 0xba, |
586 | {{0x7f,0x63,0x63,0x83,0x6c,0x1c,0x72,0xba, | 588 | 0x27, 0x8b, 0xdf, 0xdf, 0x73, 0x00, 0x00, 0x06, |
587 | 0x27,0x8b,0xdf,0xdf,0x73,0x00,0x00,0x06, | 589 | 0x01}}, /* 0x32 */ |
588 | 0x01}}, /* 0x32 */ | 590 | {{0x7f, 0x63, 0x63, 0x83, 0x69, 0x13, 0x6f, 0xba, |
589 | {{0x7f,0x63,0x63,0x83,0x69,0x13,0x6f,0xba, | 591 | 0x26, 0x89, 0xdf, 0xdf, 0x6f, 0x00, 0x00, 0x06, |
590 | 0x26,0x89,0xdf,0xdf,0x6f,0x00,0x00,0x06, | 592 | 0x01}}, /* 0x33 */ |
591 | 0x01}}, /* 0x33 */ | 593 | {{0x7f, 0x63, 0x63, 0x82, 0x6b, 0x13, 0x75, 0xba, |
592 | {{0x7f,0x63,0x63,0x82,0x6b,0x13,0x75,0xba, | 594 | 0x29, 0x8c, 0xdf, 0xdf, 0x75, 0x00, 0x00, 0x06, |
593 | 0x29,0x8c,0xdf,0xdf,0x75,0x00,0x00,0x06, | 595 | 0x01}}, /* 0x34 */ |
594 | 0x01}}, /* 0x34 */ | 596 | {{0xa3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf1, |
595 | {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf1, | 597 | 0xaf, 0x85, 0x3f, 0x3f, 0x25, 0x30, 0x00, 0x02, |
596 | 0xaf,0x85,0x3f,0x3f,0x25,0x30,0x00,0x02, | 598 | 0x01}}, /* 0x35 */ |
597 | 0x01}}, /* 0x35 */ | 599 | {{0x9f, 0x7f, 0x7f, 0x83, 0x85, 0x91, 0x1e, 0xf1, |
598 | {{0x9f,0x7f,0x7f,0x83,0x85,0x91,0x1e,0xf1, | 600 | 0xad, 0x81, 0x3f, 0x3f, 0x1f, 0x30, 0x00, 0x02, |
599 | 0xad,0x81,0x3f,0x3f,0x1f,0x30,0x00,0x02, | 601 | 0x01}}, /* 0x36 */ |
600 | 0x01}}, /* 0x36 */ | 602 | {{0xa7, 0x7f, 0x7f, 0x88, 0x89, 0x95, 0x26, 0xf1, |
601 | {{0xa7,0x7f,0x7f,0x88,0x89,0x95,0x26,0xf1, | 603 | 0xb1, 0x85, 0x3f, 0x3f, 0x27, 0x30, 0x00, 0x02, |
602 | 0xb1,0x85,0x3f,0x3f,0x27,0x30,0x00,0x02, | 604 | 0x01}}, /* 0x37 */ |
603 | 0x01}}, /* 0x37 */ | 605 | {{0xce, 0x9f, 0x9f, 0x92, 0xa9, 0x17, 0x28, 0xc4, |
604 | {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x28,0xc4, | 606 | 0x7a, 0x8e, 0xcf, 0xcf, 0x29, 0x21, 0x00, 0x07, |
605 | 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07, | 607 | 0x01}}, /* 0x38 */ |
606 | 0x01}}, /* 0x38 */ | 608 | {{0xce, 0x9f, 0x9f, 0x92, 0xa5, 0x17, 0x28, 0xd4, |
607 | {{0xce,0x9f,0x9f,0x92,0xa5,0x17,0x28,0xd4, | 609 | 0x7a, 0x8e, 0xcf, 0xcf, 0x29, 0x21, 0x00, 0x07, |
608 | 0x7a,0x8e,0xcf,0xcf,0x29,0x21,0x00,0x07, | 610 | 0x01}}, /* 0x39 */ |
609 | 0x01}}, /* 0x39 */ | 611 | {{0xd3, 0x9f, 0x9f, 0x97, 0xab, 0x1f, 0x2e, 0xd4, |
610 | {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0x2e,0xd4, | 612 | 0x7d, 0x81, 0xcf, 0xcf, 0x2f, 0x21, 0x00, 0x07, |
611 | 0x7d,0x81,0xcf,0xcf,0x2f,0x21,0x00,0x07, | 613 | 0x01}}, /* 0x3a */ |
612 | 0x01}}, /* 0x3a */ | 614 | {{0xdc, 0x9f, 0x9f, 0x80, 0xaf, 0x9d, 0xe6, 0xff, |
613 | {{0xdc,0x9f,0x9f,0x80,0xaf,0x9d,0xe6,0xff, | 615 | 0xc0, 0x83, 0xbf, 0xbf, 0xe7, 0x10, 0x00, 0x07, |
614 | 0xc0,0x83,0xbf,0xbf,0xe7,0x10,0x00,0x07, | 616 | 0x01}}, /* 0x3b */ |
615 | 0x01}}, /* 0x3b */ | 617 | {{0x6b, 0x59, 0x59, 0x8f, 0x5e, 0x8c, 0x0b, 0x3e, |
616 | {{0x6b,0x59,0x59,0x8f,0x5e,0x8c,0x0b,0x3e, | 618 | 0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x05, |
617 | 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x05, | 619 | 0x00}}, /* 0x3c */ |
618 | 0x00}}, /* 0x3c */ | 620 | {{0x6d, 0x59, 0x59, 0x91, 0x60, 0x89, 0x53, 0xf0, |
619 | {{0x6d,0x59,0x59,0x91,0x60,0x89,0x53,0xf0, | 621 | 0x41, 0x84, 0x3f, 0x3f, 0x54, 0x00, 0x00, 0x05, |
620 | 0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05, | 622 | 0x41}}, /* 0x3d */ |
621 | 0x41}}, /* 0x3d */ | 623 | {{0x86, 0x6a, 0x6a, 0x8a, 0x74, 0x06, 0x8c, 0x15, |
622 | {{0x86,0x6a,0x6a,0x8a,0x74,0x06,0x8c,0x15, | 624 | 0x4f, 0x83, 0xef, 0xef, 0x8d, 0x30, 0x00, 0x02, |
623 | 0x4f,0x83,0xef,0xef,0x8d,0x30,0x00,0x02, | 625 | 0x00}}, /* 0x3e */ |
624 | 0x00}}, /* 0x3e */ | 626 | {{0x81, 0x6a, 0x6a, 0x85, 0x70, 0x00, 0x0f, 0x3e, |
625 | {{0x81,0x6a,0x6a,0x85,0x70,0x00,0x0f,0x3e, | 627 | 0xeb, 0x8e, 0xdf, 0xdf, 0x10, 0x00, 0x00, 0x02, |
626 | 0xeb,0x8e,0xdf,0xdf,0x10,0x00,0x00,0x02, | 628 | 0x00}}, /* 0x3f */ |
627 | 0x00}}, /* 0x3f */ | 629 | {{0xa3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x1e, 0xf1, |
628 | {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x1e,0xf1, | 630 | 0xae, 0x85, 0x57, 0x57, 0x1f, 0x30, 0x00, 0x02, |
629 | 0xae,0x85,0x57,0x57,0x1f,0x30,0x00,0x02, | 631 | 0x01}}, /* 0x40 */ |
630 | 0x01}}, /* 0x40 */ | 632 | {{0xa3, 0x7f, 0x7f, 0x87, 0x86, 0x97, 0x24, 0xf5, |
631 | {{0xa3,0x7f,0x7f,0x87,0x86,0x97,0x24,0xf5, | 633 | 0x02, 0x88, 0xff, 0xff, 0x25, 0x10, 0x00, 0x02, |
632 | 0x02,0x88,0xff,0xff,0x25,0x10,0x00,0x02, | 634 | 0x01}}, /* 0x41 */ |
633 | 0x01}}, /* 0x41 */ | 635 | {{0xce, 0x9f, 0x9f, 0x92, 0xa9, 0x17, 0x20, 0xf5, |
634 | {{0xce,0x9f,0x9f,0x92,0xa9,0x17,0x20,0xf5, | 636 | 0x03, 0x88, 0xff, 0xff, 0x21, 0x10, 0x00, 0x07, |
635 | 0x03,0x88,0xff,0xff,0x21,0x10,0x00,0x07, | 637 | 0x01}}, /* 0x42 */ |
636 | 0x01}}, /* 0x42 */ | 638 | {{0xe6, 0xae, 0xae, 0x8a, 0xbd, 0x90, 0x3d, 0x10, |
637 | {{0xe6,0xae,0xae,0x8a,0xbd,0x90,0x3d,0x10, | 639 | 0x1a, 0x8d, 0x19, 0x19, 0x3e, 0x2f, 0x00, 0x03, |
638 | 0x1a,0x8d,0x19,0x19,0x3e,0x2f,0x00,0x03, | 640 | 0x00}}, /* 0x43 */ |
639 | 0x00}}, /* 0x43 */ | 641 | {{0xc3, 0x8f, 0x8f, 0x87, 0x9b, 0x0b, 0x82, 0xef, |
640 | {{0xc3,0x8f,0x8f,0x87,0x9b,0x0b,0x82,0xef, | 642 | 0x60, 0x83, 0x5f, 0x5f, 0x83, 0x10, 0x00, 0x07, |
641 | 0x60,0x83,0x5f,0x5f,0x83,0x10,0x00,0x07, | 643 | 0x01}}, /* 0x44 */ |
642 | 0x01}}, /* 0x44 */ | 644 | {{0x86, 0x69, 0x69, 0x8A, 0x74, 0x06, 0x8C, 0x15, |
643 | {{0x86,0x69,0x69,0x8A,0x74,0x06,0x8C,0x15, | 645 | 0x4F, 0x83, 0xEF, 0xEF, 0x8D, 0x30, 0x00, 0x02, |
644 | 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02, | 646 | 0x00}}, /* 0x45 */ |
645 | 0x00}}, /* 0x45 */ | 647 | {{0x83, 0x69, 0x69, 0x87, 0x6f, 0x1d, 0x03, 0x3E, |
646 | {{0x83,0x69,0x69,0x87,0x6f,0x1d,0x03,0x3E, | 648 | 0xE5, 0x8d, 0xDF, 0xe4, 0x04, 0x00, 0x00, 0x06, |
647 | 0xE5,0x8d,0xDF,0xe4,0x04,0x00,0x00,0x06, | 649 | 0x00}}, /* 0x46 */ |
648 | 0x00}}, /* 0x46 */ | 650 | {{0x86, 0x6A, 0x6A, 0x8A, 0x74, 0x06, 0x8C, 0x15, |
649 | {{0x86,0x6A,0x6A,0x8A,0x74,0x06,0x8C,0x15, | 651 | 0x4F, 0x83, 0xEF, 0xEF, 0x8D, 0x30, 0x00, 0x02, |
650 | 0x4F,0x83,0xEF,0xEF,0x8D,0x30,0x00,0x02, | 652 | 0x00}}, /* 0x47 */ |
651 | 0x00}}, /* 0x47 */ | 653 | {{0x81, 0x6A, 0x6A, 0x85, 0x70, 0x00, 0x0F, 0x3E, |
652 | {{0x81,0x6A,0x6A,0x85,0x70,0x00,0x0F,0x3E, | 654 | 0xEB, 0x8E, 0xDF, 0xDF, 0x10, 0x00, 0x00, 0x02, |
653 | 0xEB,0x8E,0xDF,0xDF,0x10,0x00,0x00,0x02, | 655 | 0x00}}, /* 0x48 */ |
654 | 0x00}}, /* 0x48 */ | 656 | {{0xdd, 0xa9, 0xa9, 0x81, 0xb4, 0x97, 0x26, 0xfd, |
655 | {{0xdd,0xa9,0xa9,0x81,0xb4,0x97,0x26,0xfd, | 657 | 0x01, 0x8d, 0xff, 0x00, 0x27, 0x10, 0x00, 0x03, |
656 | 0x01,0x8d,0xff,0x00,0x27,0x10,0x00,0x03, | 658 | 0x01}}, /* 0x49 */ |
657 | 0x01}}, /* 0x49 */ | 659 | {{0xd9, 0x8f, 0x8f, 0x9d, 0xba, 0x0a, 0x8a, 0xff, |
658 | {{0xd9,0x8f,0x8f,0x9d,0xba,0x0a,0x8a,0xff, | 660 | 0x60, 0x8b, 0x5f, 0x5f, 0x8b, 0x10, 0x00, 0x03, |
659 | 0x60,0x8b,0x5f,0x5f,0x8b,0x10,0x00,0x03, | 661 | 0x01}}, /* 0x4a */ |
660 | 0x01}}, /* 0x4a */ | 662 | {{0xea, 0xae, 0xae, 0x8e, 0xba, 0x82, 0x40, 0x10, |
661 | {{0xea,0xae,0xae,0x8e,0xba,0x82,0x40,0x10, | 663 | 0x1b, 0x87, 0x19, 0x1a, 0x41, 0x0f, 0x00, 0x03, |
662 | 0x1b,0x87,0x19,0x1a,0x41,0x0f,0x00,0x03, | 664 | 0x00}}, /* 0x4b */ |
663 | 0x00}}, /* 0x4b */ | 665 | {{0xd3, 0x9f, 0x9f, 0x97, 0xab, 0x1f, 0xf1, 0xff, |
664 | {{0xd3,0x9f,0x9f,0x97,0xab,0x1f,0xf1,0xff, | 666 | 0xc0, 0x83, 0xbf, 0xbf, 0xf2, 0x10, 0x00, 0x07, |
665 | 0xc0,0x83,0xbf,0xbf,0xf2,0x10,0x00,0x07, | 667 | 0x01}}, /* 0x4c */ |
666 | 0x01}}, /* 0x4c */ | 668 | {{0x75, 0x5f, 0x5f, 0x99, 0x66, 0x90, 0x53, 0xf0, |
667 | {{0x75,0x5f,0x5f,0x99,0x66,0x90,0x53,0xf0, | 669 | 0x41, 0x84, 0x3f, 0x3f, 0x54, 0x00, 0x00, 0x05, |
668 | 0x41,0x84,0x3f,0x3f,0x54,0x00,0x00,0x05, | 670 | 0x41}}, |
669 | 0x41}}, | 671 | {{0x2d, 0x27, 0x28, 0x90, 0x2c, 0x80, 0x0b, 0x3e, |
670 | {{0x2d,0x27,0x28,0x90,0x2c,0x80,0x0b,0x3e, | 672 | 0xe9, 0x8b, 0xdf, 0xe7, 0x04, 0x00, 0x00, 0x00, |
671 | 0xe9,0x8b,0xdf,0xe7,0x04,0x00,0x00,0x00, | 673 | 0x00}}, /* 0x4e */ |
672 | 0x00}}, /* 0x4e */ | 674 | {{0xcd, 0x9f, 0x9f, 0x91, 0xab, 0x1c, 0x3a, 0xff, |
673 | {{0xcd,0x9f,0x9f,0x91,0xab,0x1c,0x3a,0xff, | 675 | 0x20, 0x83, 0x1f, 0x1f, 0x3b, 0x10, 0x00, 0x07, |
674 | 0x20,0x83,0x1f,0x1f,0x3b,0x10,0x00,0x07, | 676 | 0x21}}, /* 0x4f */ |
675 | 0x21}}, /* 0x4f */ | 677 | {{0x15, 0xd1, 0xd1, 0x99, 0xe2, 0x19, 0x3d, 0x10, |
676 | {{0x15,0xd1,0xd1,0x99,0xe2,0x19,0x3d,0x10, | 678 | 0x1a, 0x8d, 0x19, 0x19, 0x3e, 0x2f, 0x01, 0x0c, |
677 | 0x1a,0x8d,0x19,0x19,0x3e,0x2f,0x01,0x0c, | 679 | 0x20}}, /* 0x50 */ |
678 | 0x20}}, /* 0x50 */ | 680 | {{0x0e, 0xef, 0xef, 0x92, 0xfe, 0x03, 0x30, 0xf0, |
679 | {{0x0e,0xef,0xef,0x92,0xfe,0x03,0x30,0xf0, | 681 | 0x1e, 0x83, 0x1b, 0x1c, 0x31, 0x00, 0x01, 0x00, |
680 | 0x1e,0x83,0x1b,0x1c,0x31,0x00,0x01,0x00, | 682 | 0x61}}, /* 0x51 */ |
681 | 0x61}}, /* 0x51 */ | 683 | {{0x85, 0x77, 0x77, 0x89, 0x7d, 0x01, 0x31, 0xf0, |
682 | {{0x85,0x77,0x77,0x89,0x7d,0x01,0x31,0xf0, | 684 | 0x1e, 0x84, 0x1b, 0x1c, 0x32, 0x00, 0x00, 0x02, |
683 | 0x1e,0x84,0x1b,0x1c,0x32,0x00,0x00,0x02, | 685 | 0x41}}, /* 0x52 */ |
684 | 0x41}}, /* 0x52 */ | 686 | {{0x87, 0x77, 0x77, 0x8b, 0x81, 0x0b, 0x68, 0xf0, |
685 | {{0x87,0x77,0x77,0x8b,0x81,0x0b,0x68,0xf0, | 687 | 0x5a, 0x80, 0x57, 0x57, 0x69, 0x00, 0x00, 0x02, |
686 | 0x5a,0x80,0x57,0x57,0x69,0x00,0x00,0x02, | 688 | 0x01}}, /* 0x53 */ |
687 | 0x01}}, /* 0x53 */ | 689 | {{0xcd, 0x8f, 0x8f, 0x91, 0x9b, 0x1b, 0x7a, 0xff, |
688 | {{0xcd,0x8f,0x8f,0x91,0x9b,0x1b,0x7a,0xff, | 690 | 0x64, 0x8c, 0x5f, 0x62, 0x7b, 0x10, 0x00, 0x07, |
689 | 0x64,0x8c,0x5f,0x62,0x7b,0x10,0x00,0x07, | 691 | 0x41}} /* 0x54 */ |
690 | 0x41}} /* 0x54 */ | ||
691 | }; | 692 | }; |
692 | 693 | ||
693 | static const struct SiS_VCLKData SiSUSB_VCLKData[] = | 694 | static const struct SiS_VCLKData SiSUSB_VCLKData[] = { |
694 | { | 695 | {0x1b, 0xe1, 25}, /* 0x00 */ |
695 | { 0x1b,0xe1, 25}, /* 0x00 */ | 696 | {0x4e, 0xe4, 28}, /* 0x01 */ |
696 | { 0x4e,0xe4, 28}, /* 0x01 */ | 697 | {0x57, 0xe4, 31}, /* 0x02 */ |
697 | { 0x57,0xe4, 31}, /* 0x02 */ | 698 | {0xc3, 0xc8, 36}, /* 0x03 */ |
698 | { 0xc3,0xc8, 36}, /* 0x03 */ | 699 | {0x42, 0xe2, 40}, /* 0x04 */ |
699 | { 0x42,0xe2, 40}, /* 0x04 */ | 700 | {0xfe, 0xcd, 43}, /* 0x05 */ |
700 | { 0xfe,0xcd, 43}, /* 0x05 */ | 701 | {0x5d, 0xc4, 44}, /* 0x06 */ |
701 | { 0x5d,0xc4, 44}, /* 0x06 */ | 702 | {0x52, 0xe2, 49}, /* 0x07 */ |
702 | { 0x52,0xe2, 49}, /* 0x07 */ | 703 | {0x53, 0xe2, 50}, /* 0x08 */ |
703 | { 0x53,0xe2, 50}, /* 0x08 */ | 704 | {0x74, 0x67, 52}, /* 0x09 */ |
704 | { 0x74,0x67, 52}, /* 0x09 */ | 705 | {0x6d, 0x66, 56}, /* 0x0a */ |
705 | { 0x6d,0x66, 56}, /* 0x0a */ | 706 | {0x5a, 0x64, 65}, /* 0x0b */ |
706 | { 0x5a,0x64, 65}, /* 0x0b */ | 707 | {0x46, 0x44, 67}, /* 0x0c */ |
707 | { 0x46,0x44, 67}, /* 0x0c */ | 708 | {0xb1, 0x46, 68}, /* 0x0d */ |
708 | { 0xb1,0x46, 68}, /* 0x0d */ | 709 | {0xd3, 0x4a, 72}, /* 0x0e */ |
709 | { 0xd3,0x4a, 72}, /* 0x0e */ | 710 | {0x29, 0x61, 75}, /* 0x0f */ |
710 | { 0x29,0x61, 75}, /* 0x0f */ | 711 | {0x6e, 0x46, 76}, /* 0x10 */ |
711 | { 0x6e,0x46, 76}, /* 0x10 */ | 712 | {0x2b, 0x61, 78}, /* 0x11 */ |
712 | { 0x2b,0x61, 78}, /* 0x11 */ | 713 | {0x31, 0x42, 79}, /* 0x12 */ |
713 | { 0x31,0x42, 79}, /* 0x12 */ | 714 | {0xab, 0x44, 83}, /* 0x13 */ |
714 | { 0xab,0x44, 83}, /* 0x13 */ | 715 | {0x46, 0x25, 84}, /* 0x14 */ |
715 | { 0x46,0x25, 84}, /* 0x14 */ | 716 | {0x78, 0x29, 86}, /* 0x15 */ |
716 | { 0x78,0x29, 86}, /* 0x15 */ | 717 | {0x62, 0x44, 94}, /* 0x16 */ |
717 | { 0x62,0x44, 94}, /* 0x16 */ | 718 | {0x2b, 0x41, 104}, /* 0x17 */ |
718 | { 0x2b,0x41,104}, /* 0x17 */ | 719 | {0x3a, 0x23, 105}, /* 0x18 */ |
719 | { 0x3a,0x23,105}, /* 0x18 */ | 720 | {0x70, 0x44, 108}, /* 0x19 */ |
720 | { 0x70,0x44,108}, /* 0x19 */ | 721 | {0x3c, 0x23, 109}, /* 0x1a */ |
721 | { 0x3c,0x23,109}, /* 0x1a */ | 722 | {0x5e, 0x43, 113}, /* 0x1b */ |
722 | { 0x5e,0x43,113}, /* 0x1b */ | 723 | {0xbc, 0x44, 116}, /* 0x1c */ |
723 | { 0xbc,0x44,116}, /* 0x1c */ | 724 | {0xe0, 0x46, 132}, /* 0x1d */ |
724 | { 0xe0,0x46,132}, /* 0x1d */ | 725 | {0x54, 0x42, 135}, /* 0x1e */ |
725 | { 0x54,0x42,135}, /* 0x1e */ | 726 | {0xea, 0x2a, 139}, /* 0x1f */ |
726 | { 0xea,0x2a,139}, /* 0x1f */ | 727 | {0x41, 0x22, 157}, /* 0x20 */ |
727 | { 0x41,0x22,157}, /* 0x20 */ | 728 | {0x70, 0x24, 162}, /* 0x21 */ |
728 | { 0x70,0x24,162}, /* 0x21 */ | 729 | {0x30, 0x21, 175}, /* 0x22 */ |
729 | { 0x30,0x21,175}, /* 0x22 */ | 730 | {0x4e, 0x22, 189}, /* 0x23 */ |
730 | { 0x4e,0x22,189}, /* 0x23 */ | 731 | {0xde, 0x26, 194}, /* 0x24 */ |
731 | { 0xde,0x26,194}, /* 0x24 */ | 732 | {0x62, 0x06, 202}, /* 0x25 */ |
732 | { 0x62,0x06,202}, /* 0x25 */ | 733 | {0x3f, 0x03, 229}, /* 0x26 */ |
733 | { 0x3f,0x03,229}, /* 0x26 */ | 734 | {0xb8, 0x06, 234}, /* 0x27 */ |
734 | { 0xb8,0x06,234}, /* 0x27 */ | 735 | {0x34, 0x02, 253}, /* 0x28 */ |
735 | { 0x34,0x02,253}, /* 0x28 */ | 736 | {0x58, 0x04, 255}, /* 0x29 */ |
736 | { 0x58,0x04,255}, /* 0x29 */ | 737 | {0x24, 0x01, 265}, /* 0x2a */ |
737 | { 0x24,0x01,265}, /* 0x2a */ | 738 | {0x9b, 0x02, 267}, /* 0x2b */ |
738 | { 0x9b,0x02,267}, /* 0x2b */ | 739 | {0x70, 0x05, 270}, /* 0x2c */ |
739 | { 0x70,0x05,270}, /* 0x2c */ | 740 | {0x25, 0x01, 272}, /* 0x2d */ |
740 | { 0x25,0x01,272}, /* 0x2d */ | 741 | {0x9c, 0x02, 277}, /* 0x2e */ |
741 | { 0x9c,0x02,277}, /* 0x2e */ | 742 | {0x27, 0x01, 286}, /* 0x2f */ |
742 | { 0x27,0x01,286}, /* 0x2f */ | 743 | {0x3c, 0x02, 291}, /* 0x30 */ |
743 | { 0x3c,0x02,291}, /* 0x30 */ | 744 | {0xef, 0x0a, 292}, /* 0x31 */ |
744 | { 0xef,0x0a,292}, /* 0x31 */ | 745 | {0xf6, 0x0a, 310}, /* 0x32 */ |
745 | { 0xf6,0x0a,310}, /* 0x32 */ | 746 | {0x95, 0x01, 315}, /* 0x33 */ |
746 | { 0x95,0x01,315}, /* 0x33 */ | 747 | {0xf0, 0x09, 324}, /* 0x34 */ |
747 | { 0xf0,0x09,324}, /* 0x34 */ | 748 | {0xfe, 0x0a, 331}, /* 0x35 */ |
748 | { 0xfe,0x0a,331}, /* 0x35 */ | 749 | {0xf3, 0x09, 332}, /* 0x36 */ |
749 | { 0xf3,0x09,332}, /* 0x36 */ | 750 | {0xea, 0x08, 340}, /* 0x37 */ |
750 | { 0xea,0x08,340}, /* 0x37 */ | 751 | {0xe8, 0x07, 376}, /* 0x38 */ |
751 | { 0xe8,0x07,376}, /* 0x38 */ | 752 | {0xde, 0x06, 389}, /* 0x39 */ |
752 | { 0xde,0x06,389}, /* 0x39 */ | 753 | {0x52, 0x2a, 54}, /* 0x3a 301 TV */ |
753 | { 0x52,0x2a, 54}, /* 0x3a 301 TV */ | 754 | {0x52, 0x6a, 27}, /* 0x3b 301 TV */ |
754 | { 0x52,0x6a, 27}, /* 0x3b 301 TV */ | 755 | {0x62, 0x24, 70}, /* 0x3c 301 TV */ |
755 | { 0x62,0x24, 70}, /* 0x3c 301 TV */ | 756 | {0x62, 0x64, 70}, /* 0x3d 301 TV */ |
756 | { 0x62,0x64, 70}, /* 0x3d 301 TV */ | 757 | {0xa8, 0x4c, 30}, /* 0x3e 301 TV */ |
757 | { 0xa8,0x4c, 30}, /* 0x3e 301 TV */ | 758 | {0x20, 0x26, 33}, /* 0x3f 301 TV */ |
758 | { 0x20,0x26, 33}, /* 0x3f 301 TV */ | 759 | {0x31, 0xc2, 39}, /* 0x40 */ |
759 | { 0x31,0xc2, 39}, /* 0x40 */ | 760 | {0x60, 0x36, 30}, /* 0x41 Chrontel */ |
760 | { 0x60,0x36, 30}, /* 0x41 Chrontel */ | 761 | {0x40, 0x4a, 28}, /* 0x42 Chrontel */ |
761 | { 0x40,0x4a, 28}, /* 0x42 Chrontel */ | 762 | {0x9f, 0x46, 44}, /* 0x43 Chrontel */ |
762 | { 0x9f,0x46, 44}, /* 0x43 Chrontel */ | 763 | {0x97, 0x2c, 26}, /* 0x44 */ |
763 | { 0x97,0x2c, 26}, /* 0x44 */ | 764 | {0x44, 0xe4, 25}, /* 0x45 Chrontel */ |
764 | { 0x44,0xe4, 25}, /* 0x45 Chrontel */ | 765 | {0x7e, 0x32, 47}, /* 0x46 Chrontel */ |
765 | { 0x7e,0x32, 47}, /* 0x46 Chrontel */ | 766 | {0x8a, 0x24, 31}, /* 0x47 Chrontel */ |
766 | { 0x8a,0x24, 31}, /* 0x47 Chrontel */ | 767 | {0x97, 0x2c, 26}, /* 0x48 Chrontel */ |
767 | { 0x97,0x2c, 26}, /* 0x48 Chrontel */ | 768 | {0xce, 0x3c, 39}, /* 0x49 */ |
768 | { 0xce,0x3c, 39}, /* 0x49 */ | 769 | {0x52, 0x4a, 36}, /* 0x4a Chrontel */ |
769 | { 0x52,0x4a, 36}, /* 0x4a Chrontel */ | 770 | {0x34, 0x61, 95}, /* 0x4b */ |
770 | { 0x34,0x61, 95}, /* 0x4b */ | 771 | {0x78, 0x27, 108}, /* 0x4c - was 102 */ |
771 | { 0x78,0x27,108}, /* 0x4c - was 102 */ | 772 | {0x66, 0x43, 123}, /* 0x4d Modes 0x26-0x28 (1400x1050) */ |
772 | { 0x66,0x43,123}, /* 0x4d Modes 0x26-0x28 (1400x1050) */ | 773 | {0x41, 0x4e, 21}, /* 0x4e */ |
773 | { 0x41,0x4e, 21}, /* 0x4e */ | 774 | {0xa1, 0x4a, 29}, /* 0x4f Chrontel */ |
774 | { 0xa1,0x4a, 29}, /* 0x4f Chrontel */ | 775 | {0x19, 0x42, 42}, /* 0x50 */ |
775 | { 0x19,0x42, 42}, /* 0x50 */ | 776 | {0x54, 0x46, 58}, /* 0x51 Chrontel */ |
776 | { 0x54,0x46, 58}, /* 0x51 Chrontel */ | 777 | {0x25, 0x42, 61}, /* 0x52 */ |
777 | { 0x25,0x42, 61}, /* 0x52 */ | 778 | {0x44, 0x44, 66}, /* 0x53 Chrontel */ |
778 | { 0x44,0x44, 66}, /* 0x53 Chrontel */ | 779 | {0x3a, 0x62, 70}, /* 0x54 Chrontel */ |
779 | { 0x3a,0x62, 70}, /* 0x54 Chrontel */ | 780 | {0x62, 0xc6, 34}, /* 0x55 848x480-60 */ |
780 | { 0x62,0xc6, 34}, /* 0x55 848x480-60 */ | 781 | {0x6a, 0xc6, 37}, /* 0x56 848x480-75 - TEMP */ |
781 | { 0x6a,0xc6, 37}, /* 0x56 848x480-75 - TEMP */ | 782 | {0xbf, 0xc8, 35}, /* 0x57 856x480-38i,60 */ |
782 | { 0xbf,0xc8, 35}, /* 0x57 856x480-38i,60 */ | 783 | {0x30, 0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) */ |
783 | { 0x30,0x23, 88}, /* 0x58 1360x768-62 (is 60Hz!) */ | 784 | {0x52, 0x07, 149}, /* 0x59 1280x960-85 */ |
784 | { 0x52,0x07,149}, /* 0x59 1280x960-85 */ | 785 | {0x56, 0x07, 156}, /* 0x5a 1400x1050-75 */ |
785 | { 0x56,0x07,156}, /* 0x5a 1400x1050-75 */ | 786 | {0x70, 0x29, 81}, /* 0x5b 1280x768 LCD */ |
786 | { 0x70,0x29, 81}, /* 0x5b 1280x768 LCD */ | 787 | {0x45, 0x25, 83}, /* 0x5c 1280x800 */ |
787 | { 0x45,0x25, 83}, /* 0x5c 1280x800 */ | 788 | {0x70, 0x0a, 147}, /* 0x5d 1680x1050 */ |
788 | { 0x70,0x0a,147}, /* 0x5d 1680x1050 */ | 789 | {0x70, 0x24, 162}, /* 0x5e 1600x1200 */ |
789 | { 0x70,0x24,162}, /* 0x5e 1600x1200 */ | 790 | {0x5a, 0x64, 65}, /* 0x5f 1280x720 - temp */ |
790 | { 0x5a,0x64, 65}, /* 0x5f 1280x720 - temp */ | 791 | {0x63, 0x46, 68}, /* 0x60 1280x768_2 */ |
791 | { 0x63,0x46, 68}, /* 0x60 1280x768_2 */ | 792 | {0x31, 0x42, 79}, /* 0x61 1280x768_3 - temp */ |
792 | { 0x31,0x42, 79}, /* 0x61 1280x768_3 - temp */ | 793 | {0, 0, 0}, /* 0x62 - custom (will be filled out at run-time) */ |
793 | { 0, 0, 0}, /* 0x62 - custom (will be filled out at run-time) */ | 794 | {0x5a, 0x64, 65}, /* 0x63 1280x720 (LCD LVDS) */ |
794 | { 0x5a,0x64, 65}, /* 0x63 1280x720 (LCD LVDS) */ | 795 | {0x70, 0x28, 90}, /* 0x64 1152x864@60 */ |
795 | { 0x70,0x28, 90}, /* 0x64 1152x864@60 */ | 796 | {0x41, 0xc4, 32}, /* 0x65 848x480@60 */ |
796 | { 0x41,0xc4, 32}, /* 0x65 848x480@60 */ | 797 | {0x5c, 0xc6, 32}, /* 0x66 856x480@60 */ |
797 | { 0x5c,0xc6, 32}, /* 0x66 856x480@60 */ | 798 | {0x76, 0xe7, 27}, /* 0x67 720x480@60 */ |
798 | { 0x76,0xe7, 27}, /* 0x67 720x480@60 */ | 799 | {0x5f, 0xc6, 33}, /* 0x68 720/768x576@60 */ |
799 | { 0x5f,0xc6, 33}, /* 0x68 720/768x576@60 */ | 800 | {0x52, 0x27, 75}, /* 0x69 1920x1080i 60Hz interlaced */ |
800 | { 0x52,0x27, 75}, /* 0x69 1920x1080i 60Hz interlaced */ | 801 | {0x7c, 0x6b, 38}, /* 0x6a 960x540@60 */ |
801 | { 0x7c,0x6b, 38}, /* 0x6a 960x540@60 */ | 802 | {0xe3, 0x56, 41}, /* 0x6b 960x600@60 */ |
802 | { 0xe3,0x56, 41}, /* 0x6b 960x600@60 */ | 803 | {0x45, 0x25, 83}, /* 0x6c 1280x800 */ |
803 | { 0x45,0x25, 83}, /* 0x6c 1280x800 */ | 804 | {0x70, 0x28, 90}, /* 0x6d 1152x864@60 */ |
804 | { 0x70,0x28, 90}, /* 0x6d 1152x864@60 */ | 805 | {0x15, 0xe1, 20}, /* 0x6e 640x400@60 (fake, not actually used) */ |
805 | { 0x15,0xe1, 20}, /* 0x6e 640x400@60 (fake, not actually used) */ | 806 | {0x5f, 0xc6, 33}, /* 0x6f 720x576@60 */ |
806 | { 0x5f,0xc6, 33}, /* 0x6f 720x576@60 */ | 807 | {0x37, 0x5a, 10}, /* 0x70 320x200@60 (fake, not actually used) */ |
807 | { 0x37,0x5a, 10}, /* 0x70 320x200@60 (fake, not actually used) */ | 808 | {0x2b, 0xc2, 35} /* 0x71 768@576@60 */ |
808 | { 0x2b,0xc2, 35} /* 0x71 768@576@60 */ | ||
809 | }; | 809 | }; |
810 | 810 | ||
811 | int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo); | 811 | int SiSUSBSetMode(struct SiS_Private *SiS_Pr, unsigned short ModeNo); |
812 | int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo); | 812 | int SiSUSBSetVESAMode(struct SiS_Private *SiS_Pr, unsigned short VModeNo); |
813 | 813 | ||
814 | extern int sisusb_setreg(struct sisusb_usb_data *sisusb, int port, u8 data); | 814 | extern int sisusb_setreg(struct sisusb_usb_data *sisusb, int port, u8 data); |
815 | extern int sisusb_getreg(struct sisusb_usb_data *sisusb, int port, u8 *data); | 815 | extern int sisusb_getreg(struct sisusb_usb_data *sisusb, int port, u8 * data); |
816 | extern int sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port, | 816 | extern int sisusb_setidxreg(struct sisusb_usb_data *sisusb, int port, |
817 | u8 index, u8 data); | 817 | u8 index, u8 data); |
818 | extern int sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port, | 818 | extern int sisusb_getidxreg(struct sisusb_usb_data *sisusb, int port, |
819 | u8 index, u8 *data); | 819 | u8 index, u8 * data); |
820 | extern int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, | 820 | extern int sisusb_setidxregandor(struct sisusb_usb_data *sisusb, int port, |
821 | u8 idx, u8 myand, u8 myor); | 821 | u8 idx, u8 myand, u8 myor); |
822 | extern int sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port, | 822 | extern int sisusb_setidxregor(struct sisusb_usb_data *sisusb, int port, |
823 | u8 index, u8 myor); | 823 | u8 index, u8 myor); |
824 | extern int sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port, | 824 | extern int sisusb_setidxregand(struct sisusb_usb_data *sisusb, int port, |
825 | u8 idx, u8 myand); | 825 | u8 idx, u8 myand); |
826 | 826 | ||
827 | void sisusb_delete(struct kref *kref); | 827 | void sisusb_delete(struct kref *kref); |
828 | int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data); | 828 | int sisusb_writeb(struct sisusb_usb_data *sisusb, u32 adr, u8 data); |
829 | int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 *data); | 829 | int sisusb_readb(struct sisusb_usb_data *sisusb, u32 adr, u8 * data); |
830 | int sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src, | 830 | int sisusb_copy_memory(struct sisusb_usb_data *sisusb, char *src, |
831 | u32 dest, int length, size_t *bytes_written); | 831 | u32 dest, int length, size_t * bytes_written); |
832 | int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init); | 832 | int sisusb_reset_text_mode(struct sisusb_usb_data *sisusb, int init); |
833 | int sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot, | 833 | int sisusbcon_do_font_op(struct sisusb_usb_data *sisusb, int set, int slot, |
834 | u8 *arg, int cmapsz, int ch512, int dorecalc, | 834 | u8 * arg, int cmapsz, int ch512, int dorecalc, |
835 | struct vc_data *c, int fh, int uplock); | 835 | struct vc_data *c, int fh, int uplock); |
836 | void sisusb_set_cursor(struct sisusb_usb_data *sisusb, unsigned int location); | 836 | void sisusb_set_cursor(struct sisusb_usb_data *sisusb, unsigned int location); |
837 | int sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last); | 837 | int sisusb_console_init(struct sisusb_usb_data *sisusb, int first, int last); |
@@ -839,4 +839,3 @@ void sisusb_console_exit(struct sisusb_usb_data *sisusb); | |||
839 | void sisusb_init_concode(void); | 839 | void sisusb_init_concode(void); |
840 | 840 | ||
841 | #endif | 841 | #endif |
842 | |||
diff --git a/drivers/usb/misc/sisusbvga/sisusb_struct.h b/drivers/usb/misc/sisusbvga/sisusb_struct.h index f325ecb29a6..1c4240e802c 100644 --- a/drivers/usb/misc/sisusbvga/sisusb_struct.h +++ b/drivers/usb/misc/sisusbvga/sisusb_struct.h | |||
@@ -44,7 +44,7 @@ | |||
44 | * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 44 | * * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
45 | * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 45 | * * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
46 | * | 46 | * |
47 | * Author: Thomas Winischhofer <thomas@winischhofer.net> | 47 | * Author: Thomas Winischhofer <thomas@winischhofer.net> |
48 | * | 48 | * |
49 | */ | 49 | */ |
50 | 50 | ||
@@ -52,85 +52,78 @@ | |||
52 | #define _SISUSB_STRUCT_H_ | 52 | #define _SISUSB_STRUCT_H_ |
53 | 53 | ||
54 | struct SiS_St { | 54 | struct SiS_St { |
55 | unsigned char St_ModeID; | 55 | unsigned char St_ModeID; |
56 | unsigned short St_ModeFlag; | 56 | unsigned short St_ModeFlag; |
57 | unsigned char St_StTableIndex; | 57 | unsigned char St_StTableIndex; |
58 | unsigned char St_CRT2CRTC; | 58 | unsigned char St_CRT2CRTC; |
59 | unsigned char St_ResInfo; | 59 | unsigned char St_ResInfo; |
60 | unsigned char VB_StTVFlickerIndex; | 60 | unsigned char VB_StTVFlickerIndex; |
61 | unsigned char VB_StTVEdgeIndex; | 61 | unsigned char VB_StTVEdgeIndex; |
62 | unsigned char VB_StTVYFilterIndex; | 62 | unsigned char VB_StTVYFilterIndex; |
63 | unsigned char St_PDC; | 63 | unsigned char St_PDC; |
64 | }; | 64 | }; |
65 | 65 | ||
66 | struct SiS_StandTable | 66 | struct SiS_StandTable { |
67 | { | 67 | unsigned char CRT_COLS; |
68 | unsigned char CRT_COLS; | 68 | unsigned char ROWS; |
69 | unsigned char ROWS; | 69 | unsigned char CHAR_HEIGHT; |
70 | unsigned char CHAR_HEIGHT; | 70 | unsigned short CRT_LEN; |
71 | unsigned short CRT_LEN; | 71 | unsigned char SR[4]; |
72 | unsigned char SR[4]; | 72 | unsigned char MISC; |
73 | unsigned char MISC; | 73 | unsigned char CRTC[0x19]; |
74 | unsigned char CRTC[0x19]; | 74 | unsigned char ATTR[0x14]; |
75 | unsigned char ATTR[0x14]; | 75 | unsigned char GRC[9]; |
76 | unsigned char GRC[9]; | ||
77 | }; | 76 | }; |
78 | 77 | ||
79 | struct SiS_StResInfo_S { | 78 | struct SiS_StResInfo_S { |
80 | unsigned short HTotal; | 79 | unsigned short HTotal; |
81 | unsigned short VTotal; | 80 | unsigned short VTotal; |
82 | }; | 81 | }; |
83 | 82 | ||
84 | struct SiS_Ext | 83 | struct SiS_Ext { |
85 | { | 84 | unsigned char Ext_ModeID; |
86 | unsigned char Ext_ModeID; | 85 | unsigned short Ext_ModeFlag; |
87 | unsigned short Ext_ModeFlag; | 86 | unsigned short Ext_VESAID; |
88 | unsigned short Ext_VESAID; | 87 | unsigned char Ext_RESINFO; |
89 | unsigned char Ext_RESINFO; | 88 | unsigned char VB_ExtTVFlickerIndex; |
90 | unsigned char VB_ExtTVFlickerIndex; | 89 | unsigned char VB_ExtTVEdgeIndex; |
91 | unsigned char VB_ExtTVEdgeIndex; | 90 | unsigned char VB_ExtTVYFilterIndex; |
92 | unsigned char VB_ExtTVYFilterIndex; | 91 | unsigned char VB_ExtTVYFilterIndexROM661; |
93 | unsigned char VB_ExtTVYFilterIndexROM661; | 92 | unsigned char REFindex; |
94 | unsigned char REFindex; | 93 | char ROMMODEIDX661; |
95 | char ROMMODEIDX661; | ||
96 | }; | 94 | }; |
97 | 95 | ||
98 | struct SiS_Ext2 | 96 | struct SiS_Ext2 { |
99 | { | 97 | unsigned short Ext_InfoFlag; |
100 | unsigned short Ext_InfoFlag; | 98 | unsigned char Ext_CRT1CRTC; |
101 | unsigned char Ext_CRT1CRTC; | 99 | unsigned char Ext_CRTVCLK; |
102 | unsigned char Ext_CRTVCLK; | 100 | unsigned char Ext_CRT2CRTC; |
103 | unsigned char Ext_CRT2CRTC; | 101 | unsigned char Ext_CRT2CRTC_NS; |
104 | unsigned char Ext_CRT2CRTC_NS; | 102 | unsigned char ModeID; |
105 | unsigned char ModeID; | 103 | unsigned short XRes; |
106 | unsigned short XRes; | 104 | unsigned short YRes; |
107 | unsigned short YRes; | 105 | unsigned char Ext_PDC; |
108 | unsigned char Ext_PDC; | 106 | unsigned char Ext_FakeCRT2CRTC; |
109 | unsigned char Ext_FakeCRT2CRTC; | 107 | unsigned char Ext_FakeCRT2Clk; |
110 | unsigned char Ext_FakeCRT2Clk; | ||
111 | }; | 108 | }; |
112 | 109 | ||
113 | struct SiS_CRT1Table | 110 | struct SiS_CRT1Table { |
114 | { | 111 | unsigned char CR[17]; |
115 | unsigned char CR[17]; | ||
116 | }; | 112 | }; |
117 | 113 | ||
118 | struct SiS_VCLKData | 114 | struct SiS_VCLKData { |
119 | { | 115 | unsigned char SR2B, SR2C; |
120 | unsigned char SR2B,SR2C; | 116 | unsigned short CLOCK; |
121 | unsigned short CLOCK; | ||
122 | }; | 117 | }; |
123 | 118 | ||
124 | struct SiS_ModeResInfo | 119 | struct SiS_ModeResInfo { |
125 | { | 120 | unsigned short HTotal; |
126 | unsigned short HTotal; | 121 | unsigned short VTotal; |
127 | unsigned short VTotal; | 122 | unsigned char XChar; |
128 | unsigned char XChar; | 123 | unsigned char YChar; |
129 | unsigned char YChar; | ||
130 | }; | 124 | }; |
131 | 125 | ||
132 | struct SiS_Private | 126 | struct SiS_Private { |
133 | { | ||
134 | void *sisusb; | 127 | void *sisusb; |
135 | 128 | ||
136 | unsigned long IOAddress; | 129 | unsigned long IOAddress; |
@@ -151,19 +144,18 @@ struct SiS_Private | |||
151 | unsigned long SiS_P3da; | 144 | unsigned long SiS_P3da; |
152 | unsigned long SiS_Part1Port; | 145 | unsigned long SiS_Part1Port; |
153 | 146 | ||
154 | unsigned char SiS_MyCR63; | 147 | unsigned char SiS_MyCR63; |
155 | unsigned short SiS_CRT1Mode; | 148 | unsigned short SiS_CRT1Mode; |
156 | unsigned short SiS_ModeType; | 149 | unsigned short SiS_ModeType; |
157 | unsigned short SiS_SetFlag; | 150 | unsigned short SiS_SetFlag; |
158 | 151 | ||
159 | const struct SiS_StandTable *SiS_StandTable; | 152 | const struct SiS_StandTable *SiS_StandTable; |
160 | const struct SiS_St *SiS_SModeIDTable; | 153 | const struct SiS_St *SiS_SModeIDTable; |
161 | const struct SiS_Ext *SiS_EModeIDTable; | 154 | const struct SiS_Ext *SiS_EModeIDTable; |
162 | const struct SiS_Ext2 *SiS_RefIndex; | 155 | const struct SiS_Ext2 *SiS_RefIndex; |
163 | const struct SiS_CRT1Table *SiS_CRT1Table; | 156 | const struct SiS_CRT1Table *SiS_CRT1Table; |
164 | const struct SiS_VCLKData *SiS_VCLKData; | 157 | const struct SiS_VCLKData *SiS_VCLKData; |
165 | const struct SiS_ModeResInfo *SiS_ModeResInfo; | 158 | const struct SiS_ModeResInfo *SiS_ModeResInfo; |
166 | }; | 159 | }; |
167 | 160 | ||
168 | #endif | 161 | #endif |
169 | |||
diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index 504f7221b0d..71984203271 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c | |||
@@ -176,16 +176,17 @@ static int lcd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, u | |||
176 | static void lcd_write_bulk_callback(struct urb *urb) | 176 | static void lcd_write_bulk_callback(struct urb *urb) |
177 | { | 177 | { |
178 | struct usb_lcd *dev; | 178 | struct usb_lcd *dev; |
179 | int status = urb->status; | ||
179 | 180 | ||
180 | dev = (struct usb_lcd *)urb->context; | 181 | dev = (struct usb_lcd *)urb->context; |
181 | 182 | ||
182 | /* sync/async unlink faults aren't errors */ | 183 | /* sync/async unlink faults aren't errors */ |
183 | if (urb->status && | 184 | if (status && |
184 | !(urb->status == -ENOENT || | 185 | !(status == -ENOENT || |
185 | urb->status == -ECONNRESET || | 186 | status == -ECONNRESET || |
186 | urb->status == -ESHUTDOWN)) { | 187 | status == -ESHUTDOWN)) { |
187 | dbg("USBLCD: %s - nonzero write bulk status received: %d", | 188 | dbg("USBLCD: %s - nonzero write bulk status received: %d", |
188 | __FUNCTION__, urb->status); | 189 | __FUNCTION__, status); |
189 | } | 190 | } |
190 | 191 | ||
191 | /* free up our allocated buffer */ | 192 | /* free up our allocated buffer */ |
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index fb321864a92..e901d31e051 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c | |||
@@ -768,8 +768,8 @@ static void ctrl_complete (struct urb *urb) | |||
768 | 768 | ||
769 | /* some faults are allowed, not required */ | 769 | /* some faults are allowed, not required */ |
770 | if (subcase->expected > 0 && ( | 770 | if (subcase->expected > 0 && ( |
771 | ((urb->status == -subcase->expected /* happened */ | 771 | ((status == -subcase->expected /* happened */ |
772 | || urb->status == 0)))) /* didn't */ | 772 | || status == 0)))) /* didn't */ |
773 | status = 0; | 773 | status = 0; |
774 | /* sometimes more than one fault is allowed */ | 774 | /* sometimes more than one fault is allowed */ |
775 | else if (subcase->number == 12 && status == -EPIPE) | 775 | else if (subcase->number == 12 && status == -EPIPE) |
diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index 1a60f9c473a..2734fe2b9c4 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c | |||
@@ -111,12 +111,13 @@ static void async_complete(struct urb *urb) | |||
111 | struct uss720_async_request *rq; | 111 | struct uss720_async_request *rq; |
112 | struct parport *pp; | 112 | struct parport *pp; |
113 | struct parport_uss720_private *priv; | 113 | struct parport_uss720_private *priv; |
114 | int status = urb->status; | ||
114 | 115 | ||
115 | rq = urb->context; | 116 | rq = urb->context; |
116 | priv = rq->priv; | 117 | priv = rq->priv; |
117 | pp = priv->pp; | 118 | pp = priv->pp; |
118 | if (urb->status) { | 119 | if (status) { |
119 | err("async_complete: urb error %d", urb->status); | 120 | err("async_complete: urb error %d", status); |
120 | } else if (rq->dr.bRequest == 3) { | 121 | } else if (rq->dr.bRequest == 3) { |
121 | memcpy(priv->reg, rq->reg, sizeof(priv->reg)); | 122 | memcpy(priv->reg, rq->reg, sizeof(priv->reg)); |
122 | #if 0 | 123 | #if 0 |
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c index c03dfd7a9d3..f06e4e2b49d 100644 --- a/drivers/usb/mon/mon_bin.c +++ b/drivers/usb/mon/mon_bin.c | |||
@@ -172,6 +172,10 @@ static inline struct mon_bin_hdr *MON_OFF2HDR(const struct mon_reader_bin *rp, | |||
172 | 172 | ||
173 | #define MON_RING_EMPTY(rp) ((rp)->b_cnt == 0) | 173 | #define MON_RING_EMPTY(rp) ((rp)->b_cnt == 0) |
174 | 174 | ||
175 | static unsigned char xfer_to_pipe[4] = { | ||
176 | PIPE_CONTROL, PIPE_ISOCHRONOUS, PIPE_BULK, PIPE_INTERRUPT | ||
177 | }; | ||
178 | |||
175 | static struct class *mon_bin_class; | 179 | static struct class *mon_bin_class; |
176 | static dev_t mon_bin_dev0; | 180 | static dev_t mon_bin_dev0; |
177 | static struct cdev mon_bin_cdev; | 181 | static struct cdev mon_bin_cdev; |
@@ -354,13 +358,9 @@ static inline char mon_bin_get_setup(unsigned char *setupb, | |||
354 | const struct urb *urb, char ev_type) | 358 | const struct urb *urb, char ev_type) |
355 | { | 359 | { |
356 | 360 | ||
357 | if (!usb_pipecontrol(urb->pipe) || ev_type != 'S') | 361 | if (!usb_endpoint_xfer_control(&urb->ep->desc) || ev_type != 'S') |
358 | return '-'; | 362 | return '-'; |
359 | 363 | ||
360 | if (urb->dev->bus->uses_dma && | ||
361 | (urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) { | ||
362 | return mon_dmapeek(setupb, urb->setup_dma, SETUP_LEN); | ||
363 | } | ||
364 | if (urb->setup_packet == NULL) | 364 | if (urb->setup_packet == NULL) |
365 | return 'Z'; | 365 | return 'Z'; |
366 | 366 | ||
@@ -386,13 +386,15 @@ static char mon_bin_get_data(const struct mon_reader_bin *rp, | |||
386 | } | 386 | } |
387 | 387 | ||
388 | static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | 388 | static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, |
389 | char ev_type) | 389 | char ev_type, int status) |
390 | { | 390 | { |
391 | const struct usb_endpoint_descriptor *epd = &urb->ep->desc; | ||
391 | unsigned long flags; | 392 | unsigned long flags; |
392 | struct timeval ts; | 393 | struct timeval ts; |
393 | unsigned int urb_length; | 394 | unsigned int urb_length; |
394 | unsigned int offset; | 395 | unsigned int offset; |
395 | unsigned int length; | 396 | unsigned int length; |
397 | unsigned char dir; | ||
396 | struct mon_bin_hdr *ep; | 398 | struct mon_bin_hdr *ep; |
397 | char data_tag = 0; | 399 | char data_tag = 0; |
398 | 400 | ||
@@ -410,16 +412,19 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
410 | if (length >= rp->b_size/5) | 412 | if (length >= rp->b_size/5) |
411 | length = rp->b_size/5; | 413 | length = rp->b_size/5; |
412 | 414 | ||
413 | if (usb_pipein(urb->pipe)) { | 415 | if (usb_urb_dir_in(urb)) { |
414 | if (ev_type == 'S') { | 416 | if (ev_type == 'S') { |
415 | length = 0; | 417 | length = 0; |
416 | data_tag = '<'; | 418 | data_tag = '<'; |
417 | } | 419 | } |
420 | /* Cannot rely on endpoint number in case of control ep.0 */ | ||
421 | dir = USB_DIR_IN; | ||
418 | } else { | 422 | } else { |
419 | if (ev_type == 'C') { | 423 | if (ev_type == 'C') { |
420 | length = 0; | 424 | length = 0; |
421 | data_tag = '>'; | 425 | data_tag = '>'; |
422 | } | 426 | } |
427 | dir = 0; | ||
423 | } | 428 | } |
424 | 429 | ||
425 | if (rp->mmap_active) | 430 | if (rp->mmap_active) |
@@ -440,15 +445,14 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
440 | */ | 445 | */ |
441 | memset(ep, 0, PKT_SIZE); | 446 | memset(ep, 0, PKT_SIZE); |
442 | ep->type = ev_type; | 447 | ep->type = ev_type; |
443 | ep->xfer_type = usb_pipetype(urb->pipe); | 448 | ep->xfer_type = xfer_to_pipe[usb_endpoint_type(epd)]; |
444 | /* We use the fact that usb_pipein() returns 0x80 */ | 449 | ep->epnum = dir | usb_endpoint_num(epd); |
445 | ep->epnum = usb_pipeendpoint(urb->pipe) | usb_pipein(urb->pipe); | 450 | ep->devnum = urb->dev->devnum; |
446 | ep->devnum = usb_pipedevice(urb->pipe); | ||
447 | ep->busnum = urb->dev->bus->busnum; | 451 | ep->busnum = urb->dev->bus->busnum; |
448 | ep->id = (unsigned long) urb; | 452 | ep->id = (unsigned long) urb; |
449 | ep->ts_sec = ts.tv_sec; | 453 | ep->ts_sec = ts.tv_sec; |
450 | ep->ts_usec = ts.tv_usec; | 454 | ep->ts_usec = ts.tv_usec; |
451 | ep->status = urb->status; | 455 | ep->status = status; |
452 | ep->len_urb = urb_length; | 456 | ep->len_urb = urb_length; |
453 | ep->len_cap = length; | 457 | ep->len_cap = length; |
454 | 458 | ||
@@ -471,13 +475,13 @@ static void mon_bin_event(struct mon_reader_bin *rp, struct urb *urb, | |||
471 | static void mon_bin_submit(void *data, struct urb *urb) | 475 | static void mon_bin_submit(void *data, struct urb *urb) |
472 | { | 476 | { |
473 | struct mon_reader_bin *rp = data; | 477 | struct mon_reader_bin *rp = data; |
474 | mon_bin_event(rp, urb, 'S'); | 478 | mon_bin_event(rp, urb, 'S', -EINPROGRESS); |
475 | } | 479 | } |
476 | 480 | ||
477 | static void mon_bin_complete(void *data, struct urb *urb) | 481 | static void mon_bin_complete(void *data, struct urb *urb, int status) |
478 | { | 482 | { |
479 | struct mon_reader_bin *rp = data; | 483 | struct mon_reader_bin *rp = data; |
480 | mon_bin_event(rp, urb, 'C'); | 484 | mon_bin_event(rp, urb, 'C', status); |
481 | } | 485 | } |
482 | 486 | ||
483 | static void mon_bin_error(void *data, struct urb *urb, int error) | 487 | static void mon_bin_error(void *data, struct urb *urb, int error) |
@@ -500,10 +504,10 @@ static void mon_bin_error(void *data, struct urb *urb, int error) | |||
500 | 504 | ||
501 | memset(ep, 0, PKT_SIZE); | 505 | memset(ep, 0, PKT_SIZE); |
502 | ep->type = 'E'; | 506 | ep->type = 'E'; |
503 | ep->xfer_type = usb_pipetype(urb->pipe); | 507 | ep->xfer_type = xfer_to_pipe[usb_endpoint_type(&urb->ep->desc)]; |
504 | /* We use the fact that usb_pipein() returns 0x80 */ | 508 | ep->epnum = usb_urb_dir_in(urb) ? USB_DIR_IN : 0; |
505 | ep->epnum = usb_pipeendpoint(urb->pipe) | usb_pipein(urb->pipe); | 509 | ep->epnum |= usb_endpoint_num(&urb->ep->desc); |
506 | ep->devnum = usb_pipedevice(urb->pipe); | 510 | ep->devnum = urb->dev->devnum; |
507 | ep->busnum = urb->dev->bus->busnum; | 511 | ep->busnum = urb->dev->bus->busnum; |
508 | ep->id = (unsigned long) urb; | 512 | ep->id = (unsigned long) urb; |
509 | ep->status = error; | 513 | ep->status = error; |
diff --git a/drivers/usb/mon/mon_main.c b/drivers/usb/mon/mon_main.c index ce61d8b0fd8..b371ffd39d3 100644 --- a/drivers/usb/mon/mon_main.c +++ b/drivers/usb/mon/mon_main.c | |||
@@ -129,7 +129,8 @@ static void mon_submit_error(struct usb_bus *ubus, struct urb *urb, int error) | |||
129 | 129 | ||
130 | /* | 130 | /* |
131 | */ | 131 | */ |
132 | static void mon_bus_complete(struct mon_bus *mbus, struct urb *urb) | 132 | static void mon_bus_complete(struct mon_bus *mbus, struct urb *urb, |
133 | int status) | ||
133 | { | 134 | { |
134 | unsigned long flags; | 135 | unsigned long flags; |
135 | struct list_head *pos; | 136 | struct list_head *pos; |
@@ -139,28 +140,18 @@ static void mon_bus_complete(struct mon_bus *mbus, struct urb *urb) | |||
139 | mbus->cnt_events++; | 140 | mbus->cnt_events++; |
140 | list_for_each (pos, &mbus->r_list) { | 141 | list_for_each (pos, &mbus->r_list) { |
141 | r = list_entry(pos, struct mon_reader, r_link); | 142 | r = list_entry(pos, struct mon_reader, r_link); |
142 | r->rnf_complete(r->r_data, urb); | 143 | r->rnf_complete(r->r_data, urb, status); |
143 | } | 144 | } |
144 | spin_unlock_irqrestore(&mbus->lock, flags); | 145 | spin_unlock_irqrestore(&mbus->lock, flags); |
145 | } | 146 | } |
146 | 147 | ||
147 | static void mon_complete(struct usb_bus *ubus, struct urb *urb) | 148 | static void mon_complete(struct usb_bus *ubus, struct urb *urb, int status) |
148 | { | 149 | { |
149 | struct mon_bus *mbus; | 150 | struct mon_bus *mbus; |
150 | 151 | ||
151 | mbus = ubus->mon_bus; | 152 | if ((mbus = ubus->mon_bus) != NULL) |
152 | if (mbus == NULL) { | 153 | mon_bus_complete(mbus, urb, status); |
153 | /* | 154 | mon_bus_complete(&mon_bus0, urb, status); |
154 | * This should not happen. | ||
155 | * At this point we do not even know the bus number... | ||
156 | */ | ||
157 | printk(KERN_ERR TAG ": Null mon bus in URB, pipe 0x%x\n", | ||
158 | urb->pipe); | ||
159 | return; | ||
160 | } | ||
161 | |||
162 | mon_bus_complete(mbus, urb); | ||
163 | mon_bus_complete(&mon_bus0, urb); | ||
164 | } | 155 | } |
165 | 156 | ||
166 | /* int (*unlink_urb) (struct urb *urb, int status); */ | 157 | /* int (*unlink_urb) (struct urb *urb, int status); */ |
@@ -170,7 +161,7 @@ static void mon_complete(struct usb_bus *ubus, struct urb *urb) | |||
170 | */ | 161 | */ |
171 | static void mon_stop(struct mon_bus *mbus) | 162 | static void mon_stop(struct mon_bus *mbus) |
172 | { | 163 | { |
173 | struct usb_bus *ubus = mbus->u_bus; | 164 | struct usb_bus *ubus; |
174 | struct list_head *p; | 165 | struct list_head *p; |
175 | 166 | ||
176 | if (mbus == &mon_bus0) { | 167 | if (mbus == &mon_bus0) { |
diff --git a/drivers/usb/mon/mon_text.c b/drivers/usb/mon/mon_text.c index 982b773d71e..ebb04ac4857 100644 --- a/drivers/usb/mon/mon_text.c +++ b/drivers/usb/mon/mon_text.c | |||
@@ -50,10 +50,13 @@ struct mon_iso_desc { | |||
50 | struct mon_event_text { | 50 | struct mon_event_text { |
51 | struct list_head e_link; | 51 | struct list_head e_link; |
52 | int type; /* submit, complete, etc. */ | 52 | int type; /* submit, complete, etc. */ |
53 | unsigned int pipe; /* Pipe */ | ||
54 | unsigned long id; /* From pointer, most of the time */ | 53 | unsigned long id; /* From pointer, most of the time */ |
55 | unsigned int tstamp; | 54 | unsigned int tstamp; |
56 | int busnum; | 55 | int busnum; |
56 | char devnum; | ||
57 | char epnum; | ||
58 | char is_in; | ||
59 | char xfertype; | ||
57 | int length; /* Depends on type: xfer length or act length */ | 60 | int length; /* Depends on type: xfer length or act length */ |
58 | int status; | 61 | int status; |
59 | int interval; | 62 | int interval; |
@@ -121,13 +124,9 @@ static inline char mon_text_get_setup(struct mon_event_text *ep, | |||
121 | struct urb *urb, char ev_type, struct mon_bus *mbus) | 124 | struct urb *urb, char ev_type, struct mon_bus *mbus) |
122 | { | 125 | { |
123 | 126 | ||
124 | if (!usb_pipecontrol(urb->pipe) || ev_type != 'S') | 127 | if (ep->xfertype != USB_ENDPOINT_XFER_CONTROL || ev_type != 'S') |
125 | return '-'; | 128 | return '-'; |
126 | 129 | ||
127 | if (urb->dev->bus->uses_dma && | ||
128 | (urb->transfer_flags & URB_NO_SETUP_DMA_MAP)) { | ||
129 | return mon_dmapeek(ep->setup, urb->setup_dma, SETUP_MAX); | ||
130 | } | ||
131 | if (urb->setup_packet == NULL) | 130 | if (urb->setup_packet == NULL) |
132 | return 'Z'; /* '0' would be not as pretty. */ | 131 | return 'Z'; /* '0' would be not as pretty. */ |
133 | 132 | ||
@@ -138,14 +137,12 @@ static inline char mon_text_get_setup(struct mon_event_text *ep, | |||
138 | static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb, | 137 | static inline char mon_text_get_data(struct mon_event_text *ep, struct urb *urb, |
139 | int len, char ev_type, struct mon_bus *mbus) | 138 | int len, char ev_type, struct mon_bus *mbus) |
140 | { | 139 | { |
141 | int pipe = urb->pipe; | ||
142 | |||
143 | if (len <= 0) | 140 | if (len <= 0) |
144 | return 'L'; | 141 | return 'L'; |
145 | if (len >= DATA_MAX) | 142 | if (len >= DATA_MAX) |
146 | len = DATA_MAX; | 143 | len = DATA_MAX; |
147 | 144 | ||
148 | if (usb_pipein(pipe)) { | 145 | if (ep->is_in) { |
149 | if (ev_type != 'C') | 146 | if (ev_type != 'C') |
150 | return '<'; | 147 | return '<'; |
151 | } else { | 148 | } else { |
@@ -186,7 +183,7 @@ static inline unsigned int mon_get_timestamp(void) | |||
186 | } | 183 | } |
187 | 184 | ||
188 | static void mon_text_event(struct mon_reader_text *rp, struct urb *urb, | 185 | static void mon_text_event(struct mon_reader_text *rp, struct urb *urb, |
189 | char ev_type) | 186 | char ev_type, int status) |
190 | { | 187 | { |
191 | struct mon_event_text *ep; | 188 | struct mon_event_text *ep; |
192 | unsigned int stamp; | 189 | unsigned int stamp; |
@@ -203,24 +200,28 @@ static void mon_text_event(struct mon_reader_text *rp, struct urb *urb, | |||
203 | } | 200 | } |
204 | 201 | ||
205 | ep->type = ev_type; | 202 | ep->type = ev_type; |
206 | ep->pipe = urb->pipe; | ||
207 | ep->id = (unsigned long) urb; | 203 | ep->id = (unsigned long) urb; |
208 | ep->busnum = urb->dev->bus->busnum; | 204 | ep->busnum = urb->dev->bus->busnum; |
205 | ep->devnum = urb->dev->devnum; | ||
206 | ep->epnum = usb_endpoint_num(&urb->ep->desc); | ||
207 | ep->xfertype = usb_endpoint_type(&urb->ep->desc); | ||
208 | ep->is_in = usb_urb_dir_in(urb); | ||
209 | ep->tstamp = stamp; | 209 | ep->tstamp = stamp; |
210 | ep->length = (ev_type == 'S') ? | 210 | ep->length = (ev_type == 'S') ? |
211 | urb->transfer_buffer_length : urb->actual_length; | 211 | urb->transfer_buffer_length : urb->actual_length; |
212 | /* Collecting status makes debugging sense for submits, too */ | 212 | /* Collecting status makes debugging sense for submits, too */ |
213 | ep->status = urb->status; | 213 | ep->status = status; |
214 | 214 | ||
215 | if (usb_pipeint(urb->pipe)) { | 215 | if (ep->xfertype == USB_ENDPOINT_XFER_INT) { |
216 | ep->interval = urb->interval; | 216 | ep->interval = urb->interval; |
217 | } else if (usb_pipeisoc(urb->pipe)) { | 217 | } else if (ep->xfertype == USB_ENDPOINT_XFER_ISOC) { |
218 | ep->interval = urb->interval; | 218 | ep->interval = urb->interval; |
219 | ep->start_frame = urb->start_frame; | 219 | ep->start_frame = urb->start_frame; |
220 | ep->error_count = urb->error_count; | 220 | ep->error_count = urb->error_count; |
221 | } | 221 | } |
222 | ep->numdesc = urb->number_of_packets; | 222 | ep->numdesc = urb->number_of_packets; |
223 | if (usb_pipeisoc(urb->pipe) && urb->number_of_packets > 0) { | 223 | if (ep->xfertype == USB_ENDPOINT_XFER_ISOC && |
224 | urb->number_of_packets > 0) { | ||
224 | if ((ndesc = urb->number_of_packets) > ISODESC_MAX) | 225 | if ((ndesc = urb->number_of_packets) > ISODESC_MAX) |
225 | ndesc = ISODESC_MAX; | 226 | ndesc = ISODESC_MAX; |
226 | fp = urb->iso_frame_desc; | 227 | fp = urb->iso_frame_desc; |
@@ -247,13 +248,13 @@ static void mon_text_event(struct mon_reader_text *rp, struct urb *urb, | |||
247 | static void mon_text_submit(void *data, struct urb *urb) | 248 | static void mon_text_submit(void *data, struct urb *urb) |
248 | { | 249 | { |
249 | struct mon_reader_text *rp = data; | 250 | struct mon_reader_text *rp = data; |
250 | mon_text_event(rp, urb, 'S'); | 251 | mon_text_event(rp, urb, 'S', -EINPROGRESS); |
251 | } | 252 | } |
252 | 253 | ||
253 | static void mon_text_complete(void *data, struct urb *urb) | 254 | static void mon_text_complete(void *data, struct urb *urb, int status) |
254 | { | 255 | { |
255 | struct mon_reader_text *rp = data; | 256 | struct mon_reader_text *rp = data; |
256 | mon_text_event(rp, urb, 'C'); | 257 | mon_text_event(rp, urb, 'C', status); |
257 | } | 258 | } |
258 | 259 | ||
259 | static void mon_text_error(void *data, struct urb *urb, int error) | 260 | static void mon_text_error(void *data, struct urb *urb, int error) |
@@ -268,9 +269,12 @@ static void mon_text_error(void *data, struct urb *urb, int error) | |||
268 | } | 269 | } |
269 | 270 | ||
270 | ep->type = 'E'; | 271 | ep->type = 'E'; |
271 | ep->pipe = urb->pipe; | ||
272 | ep->id = (unsigned long) urb; | 272 | ep->id = (unsigned long) urb; |
273 | ep->busnum = 0; | 273 | ep->busnum = 0; |
274 | ep->devnum = urb->dev->devnum; | ||
275 | ep->epnum = usb_endpoint_num(&urb->ep->desc); | ||
276 | ep->xfertype = usb_endpoint_type(&urb->ep->desc); | ||
277 | ep->is_in = usb_urb_dir_in(urb); | ||
274 | ep->tstamp = 0; | 278 | ep->tstamp = 0; |
275 | ep->length = 0; | 279 | ep->length = 0; |
276 | ep->status = error; | 280 | ep->status = error; |
@@ -340,7 +344,7 @@ static int mon_text_open(struct inode *inode, struct file *file) | |||
340 | snprintf(rp->slab_name, SLAB_NAME_SZ, "mon_text_%p", rp); | 344 | snprintf(rp->slab_name, SLAB_NAME_SZ, "mon_text_%p", rp); |
341 | rp->e_slab = kmem_cache_create(rp->slab_name, | 345 | rp->e_slab = kmem_cache_create(rp->slab_name, |
342 | sizeof(struct mon_event_text), sizeof(long), 0, | 346 | sizeof(struct mon_event_text), sizeof(long), 0, |
343 | mon_text_ctor, NULL); | 347 | mon_text_ctor); |
344 | if (rp->e_slab == NULL) { | 348 | if (rp->e_slab == NULL) { |
345 | rc = -ENOMEM; | 349 | rc = -ENOMEM; |
346 | goto err_slab; | 350 | goto err_slab; |
@@ -413,10 +417,10 @@ static ssize_t mon_text_read_u(struct file *file, char __user *buf, | |||
413 | mon_text_read_head_u(rp, &ptr, ep); | 417 | mon_text_read_head_u(rp, &ptr, ep); |
414 | if (ep->type == 'E') { | 418 | if (ep->type == 'E') { |
415 | mon_text_read_statset(rp, &ptr, ep); | 419 | mon_text_read_statset(rp, &ptr, ep); |
416 | } else if (usb_pipeisoc(ep->pipe)) { | 420 | } else if (ep->xfertype == USB_ENDPOINT_XFER_ISOC) { |
417 | mon_text_read_isostat(rp, &ptr, ep); | 421 | mon_text_read_isostat(rp, &ptr, ep); |
418 | mon_text_read_isodesc(rp, &ptr, ep); | 422 | mon_text_read_isodesc(rp, &ptr, ep); |
419 | } else if (usb_pipeint(ep->pipe)) { | 423 | } else if (ep->xfertype == USB_ENDPOINT_XFER_INT) { |
420 | mon_text_read_intstat(rp, &ptr, ep); | 424 | mon_text_read_intstat(rp, &ptr, ep); |
421 | } else { | 425 | } else { |
422 | mon_text_read_statset(rp, &ptr, ep); | 426 | mon_text_read_statset(rp, &ptr, ep); |
@@ -468,18 +472,17 @@ static void mon_text_read_head_t(struct mon_reader_text *rp, | |||
468 | { | 472 | { |
469 | char udir, utype; | 473 | char udir, utype; |
470 | 474 | ||
471 | udir = usb_pipein(ep->pipe) ? 'i' : 'o'; | 475 | udir = (ep->is_in ? 'i' : 'o'); |
472 | switch (usb_pipetype(ep->pipe)) { | 476 | switch (ep->xfertype) { |
473 | case PIPE_ISOCHRONOUS: utype = 'Z'; break; | 477 | case USB_ENDPOINT_XFER_ISOC: utype = 'Z'; break; |
474 | case PIPE_INTERRUPT: utype = 'I'; break; | 478 | case USB_ENDPOINT_XFER_INT: utype = 'I'; break; |
475 | case PIPE_CONTROL: utype = 'C'; break; | 479 | case USB_ENDPOINT_XFER_CONTROL: utype = 'C'; break; |
476 | default: /* PIPE_BULK */ utype = 'B'; | 480 | default: /* PIPE_BULK */ utype = 'B'; |
477 | } | 481 | } |
478 | p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, | 482 | p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, |
479 | "%lx %u %c %c%c:%03u:%02u", | 483 | "%lx %u %c %c%c:%03u:%02u", |
480 | ep->id, ep->tstamp, ep->type, | 484 | ep->id, ep->tstamp, ep->type, |
481 | utype, udir, | 485 | utype, udir, ep->devnum, ep->epnum); |
482 | usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe)); | ||
483 | } | 486 | } |
484 | 487 | ||
485 | static void mon_text_read_head_u(struct mon_reader_text *rp, | 488 | static void mon_text_read_head_u(struct mon_reader_text *rp, |
@@ -487,18 +490,17 @@ static void mon_text_read_head_u(struct mon_reader_text *rp, | |||
487 | { | 490 | { |
488 | char udir, utype; | 491 | char udir, utype; |
489 | 492 | ||
490 | udir = usb_pipein(ep->pipe) ? 'i' : 'o'; | 493 | udir = (ep->is_in ? 'i' : 'o'); |
491 | switch (usb_pipetype(ep->pipe)) { | 494 | switch (ep->xfertype) { |
492 | case PIPE_ISOCHRONOUS: utype = 'Z'; break; | 495 | case USB_ENDPOINT_XFER_ISOC: utype = 'Z'; break; |
493 | case PIPE_INTERRUPT: utype = 'I'; break; | 496 | case USB_ENDPOINT_XFER_INT: utype = 'I'; break; |
494 | case PIPE_CONTROL: utype = 'C'; break; | 497 | case USB_ENDPOINT_XFER_CONTROL: utype = 'C'; break; |
495 | default: /* PIPE_BULK */ utype = 'B'; | 498 | default: /* PIPE_BULK */ utype = 'B'; |
496 | } | 499 | } |
497 | p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, | 500 | p->cnt += snprintf(p->pbuf + p->cnt, p->limit - p->cnt, |
498 | "%lx %u %c %c%c:%d:%03u:%u", | 501 | "%lx %u %c %c%c:%d:%03u:%u", |
499 | ep->id, ep->tstamp, ep->type, | 502 | ep->id, ep->tstamp, ep->type, |
500 | utype, udir, | 503 | utype, udir, ep->busnum, ep->devnum, ep->epnum); |
501 | ep->busnum, usb_pipedevice(ep->pipe), usb_pipeendpoint(ep->pipe)); | ||
502 | } | 504 | } |
503 | 505 | ||
504 | static void mon_text_read_statset(struct mon_reader_text *rp, | 506 | static void mon_text_read_statset(struct mon_reader_text *rp, |
diff --git a/drivers/usb/mon/usb_mon.h b/drivers/usb/mon/usb_mon.h index f68ad6d99ad..f5d84ff8c10 100644 --- a/drivers/usb/mon/usb_mon.h +++ b/drivers/usb/mon/usb_mon.h | |||
@@ -46,7 +46,7 @@ struct mon_reader { | |||
46 | 46 | ||
47 | void (*rnf_submit)(void *data, struct urb *urb); | 47 | void (*rnf_submit)(void *data, struct urb *urb); |
48 | void (*rnf_error)(void *data, struct urb *urb, int error); | 48 | void (*rnf_error)(void *data, struct urb *urb, int error); |
49 | void (*rnf_complete)(void *data, struct urb *urb); | 49 | void (*rnf_complete)(void *data, struct urb *urb, int status); |
50 | }; | 50 | }; |
51 | 51 | ||
52 | void mon_reader_add(struct mon_bus *mbus, struct mon_reader *r); | 52 | void mon_reader_add(struct mon_bus *mbus, struct mon_reader *r); |
diff --git a/drivers/usb/serial/Kconfig b/drivers/usb/serial/Kconfig index 43d6db696f9..99fefed7791 100644 --- a/drivers/usb/serial/Kconfig +++ b/drivers/usb/serial/Kconfig | |||
@@ -92,6 +92,16 @@ config USB_SERIAL_BELKIN | |||
92 | To compile this driver as a module, choose M here: the | 92 | To compile this driver as a module, choose M here: the |
93 | module will be called belkin_sa. | 93 | module will be called belkin_sa. |
94 | 94 | ||
95 | config USB_SERIAL_CH341 | ||
96 | tristate "USB Winchiphead CH341 Single Port Serial Driver" | ||
97 | depends on USB_SERIAL | ||
98 | help | ||
99 | Say Y here if you want to use a Winchiphead CH341 single port | ||
100 | USB to serial adapter. | ||
101 | |||
102 | To compile this driver as a module, choose M here: the | ||
103 | module will be called ch341. | ||
104 | |||
95 | config USB_SERIAL_WHITEHEAT | 105 | config USB_SERIAL_WHITEHEAT |
96 | tristate "USB ConnectTech WhiteHEAT Serial Driver" | 106 | tristate "USB ConnectTech WhiteHEAT Serial Driver" |
97 | depends on USB_SERIAL | 107 | depends on USB_SERIAL |
diff --git a/drivers/usb/serial/Makefile b/drivers/usb/serial/Makefile index 07a976eca6b..d6fb384e52b 100644 --- a/drivers/usb/serial/Makefile +++ b/drivers/usb/serial/Makefile | |||
@@ -15,6 +15,7 @@ obj-$(CONFIG_USB_SERIAL_AIRCABLE) += aircable.o | |||
15 | obj-$(CONFIG_USB_SERIAL_AIRPRIME) += airprime.o | 15 | obj-$(CONFIG_USB_SERIAL_AIRPRIME) += airprime.o |
16 | obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o | 16 | obj-$(CONFIG_USB_SERIAL_ARK3116) += ark3116.o |
17 | obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o | 17 | obj-$(CONFIG_USB_SERIAL_BELKIN) += belkin_sa.o |
18 | obj-$(CONFIG_USB_SERIAL_CH341) += ch341.o | ||
18 | obj-$(CONFIG_USB_SERIAL_CP2101) += cp2101.o | 19 | obj-$(CONFIG_USB_SERIAL_CP2101) += cp2101.o |
19 | obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o | 20 | obj-$(CONFIG_USB_SERIAL_CYBERJACK) += cyberjack.o |
20 | obj-$(CONFIG_USB_SERIAL_CYPRESS_M8) += cypress_m8.o | 21 | obj-$(CONFIG_USB_SERIAL_CYPRESS_M8) += cypress_m8.o |
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index cff6fd190a2..77bb893bf2e 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c | |||
@@ -18,7 +18,6 @@ | |||
18 | 18 | ||
19 | static struct usb_device_id id_table [] = { | 19 | static struct usb_device_id id_table [] = { |
20 | { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */ | 20 | { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */ |
21 | { USB_DEVICE(0x413c, 0x8115) }, /* Dell Wireless HSDPA 5500 */ | ||
22 | { }, | 21 | { }, |
23 | }; | 22 | }; |
24 | MODULE_DEVICE_TABLE(usb, id_table); | 23 | MODULE_DEVICE_TABLE(usb, id_table); |
diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index c9fd486c1c7..2a8e537cb04 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c | |||
@@ -172,11 +172,6 @@ static void ark3116_set_termios(struct usb_serial_port *port, | |||
172 | 172 | ||
173 | dbg("%s - port %d", __FUNCTION__, port->number); | 173 | dbg("%s - port %d", __FUNCTION__, port->number); |
174 | 174 | ||
175 | if (!port->tty || !port->tty->termios) { | ||
176 | dbg("%s - no tty structures", __FUNCTION__); | ||
177 | return; | ||
178 | } | ||
179 | |||
180 | spin_lock_irqsave(&priv->lock, flags); | 175 | spin_lock_irqsave(&priv->lock, flags); |
181 | if (!priv->termios_initialized) { | 176 | if (!priv->termios_initialized) { |
182 | *(port->tty->termios) = tty_std_termios; | 177 | *(port->tty->termios) = tty_std_termios; |
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index e67ce25f751..86724e88570 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c | |||
@@ -383,6 +383,10 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios | |||
383 | } | 383 | } |
384 | 384 | ||
385 | baud = tty_get_baud_rate(port->tty); | 385 | baud = tty_get_baud_rate(port->tty); |
386 | if (baud == 0) { | ||
387 | dbg("%s - tty_get_baud_rate says 0 baud", __FUNCTION__); | ||
388 | return; | ||
389 | } | ||
386 | urb_value = BELKIN_SA_BAUD(baud); | 390 | urb_value = BELKIN_SA_BAUD(baud); |
387 | /* Clip to maximum speed */ | 391 | /* Clip to maximum speed */ |
388 | if (urb_value == 0) | 392 | if (urb_value == 0) |
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index c08a38402b9..0b14aea8ebd 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c | |||
@@ -36,6 +36,16 @@ static int usb_serial_device_match (struct device *dev, struct device_driver *dr | |||
36 | return 0; | 36 | return 0; |
37 | } | 37 | } |
38 | 38 | ||
39 | static ssize_t show_port_number(struct device *dev, | ||
40 | struct device_attribute *attr, char *buf) | ||
41 | { | ||
42 | struct usb_serial_port *port = to_usb_serial_port(dev); | ||
43 | |||
44 | return sprintf(buf, "%d\n", port->number - port->serial->minor); | ||
45 | } | ||
46 | |||
47 | static DEVICE_ATTR(port_number, S_IRUGO, show_port_number, NULL); | ||
48 | |||
39 | static int usb_serial_device_probe (struct device *dev) | 49 | static int usb_serial_device_probe (struct device *dev) |
40 | { | 50 | { |
41 | struct usb_serial_driver *driver; | 51 | struct usb_serial_driver *driver; |
@@ -62,6 +72,10 @@ static int usb_serial_device_probe (struct device *dev) | |||
62 | goto exit; | 72 | goto exit; |
63 | } | 73 | } |
64 | 74 | ||
75 | retval = device_create_file(dev, &dev_attr_port_number); | ||
76 | if (retval) | ||
77 | goto exit; | ||
78 | |||
65 | minor = port->number; | 79 | minor = port->number; |
66 | tty_register_device (usb_serial_tty_driver, minor, dev); | 80 | tty_register_device (usb_serial_tty_driver, minor, dev); |
67 | dev_info(&port->serial->dev->dev, | 81 | dev_info(&port->serial->dev->dev, |
@@ -84,6 +98,8 @@ static int usb_serial_device_remove (struct device *dev) | |||
84 | return -ENODEV; | 98 | return -ENODEV; |
85 | } | 99 | } |
86 | 100 | ||
101 | device_remove_file(&port->dev, &dev_attr_port_number); | ||
102 | |||
87 | driver = port->serial->type; | 103 | driver = port->serial->type; |
88 | if (driver->port_remove) { | 104 | if (driver->port_remove) { |
89 | if (!try_module_get(driver->driver.owner)) { | 105 | if (!try_module_get(driver->driver.owner)) { |
@@ -138,7 +154,7 @@ static void free_dynids(struct usb_serial_driver *drv) | |||
138 | static struct driver_attribute drv_attrs[] = { | 154 | static struct driver_attribute drv_attrs[] = { |
139 | __ATTR_NULL, | 155 | __ATTR_NULL, |
140 | }; | 156 | }; |
141 | static inline void free_dynids(struct usb_driver *drv) | 157 | static inline void free_dynids(struct usb_serial_driver *drv) |
142 | { | 158 | { |
143 | } | 159 | } |
144 | #endif | 160 | #endif |
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c new file mode 100644 index 00000000000..6b252ceb39a --- /dev/null +++ b/drivers/usb/serial/ch341.c | |||
@@ -0,0 +1,354 @@ | |||
1 | /* | ||
2 | * Copyright 2007, Frank A Kingswood <frank@kingswood-consulting.co.uk> | ||
3 | * | ||
4 | * ch341.c implements a serial port driver for the Winchiphead CH341. | ||
5 | * | ||
6 | * The CH341 device can be used to implement an RS232 asynchronous | ||
7 | * serial port, an IEEE-1284 parallel printer port or a memory-like | ||
8 | * interface. In all cases the CH341 supports an I2C interface as well. | ||
9 | * This driver only supports the asynchronous serial interface. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or | ||
12 | * modify it under the terms of the GNU General Public License version | ||
13 | * 2 as published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/tty.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/usb.h> | ||
21 | #include <linux/usb/serial.h> | ||
22 | #include <linux/serial.h> | ||
23 | |||
24 | #define DEFAULT_BAUD_RATE 2400 | ||
25 | #define DEFAULT_TIMEOUT 1000 | ||
26 | |||
27 | static int debug; | ||
28 | |||
29 | static struct usb_device_id id_table [] = { | ||
30 | { USB_DEVICE(0x4348, 0x5523) }, | ||
31 | { }, | ||
32 | }; | ||
33 | MODULE_DEVICE_TABLE(usb, id_table); | ||
34 | |||
35 | struct ch341_private { | ||
36 | unsigned baud_rate; | ||
37 | u8 dtr; | ||
38 | u8 rts; | ||
39 | }; | ||
40 | |||
41 | static int ch341_control_out(struct usb_device *dev, u8 request, | ||
42 | u16 value, u16 index) | ||
43 | { | ||
44 | int r; | ||
45 | dbg("ch341_control_out(%02x,%02x,%04x,%04x)", USB_DIR_OUT|0x40, | ||
46 | (int)request, (int)value, (int)index); | ||
47 | |||
48 | r = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), request, | ||
49 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, | ||
50 | value, index, NULL, 0, DEFAULT_TIMEOUT); | ||
51 | |||
52 | return r; | ||
53 | } | ||
54 | |||
55 | static int ch341_control_in(struct usb_device *dev, | ||
56 | u8 request, u16 value, u16 index, | ||
57 | char *buf, unsigned bufsize) | ||
58 | { | ||
59 | int r; | ||
60 | dbg("ch341_control_in(%02x,%02x,%04x,%04x,%p,%u)", USB_DIR_IN|0x40, | ||
61 | (int)request, (int)value, (int)index, buf, (int)bufsize); | ||
62 | |||
63 | r = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), request, | ||
64 | USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, | ||
65 | value, index, buf, bufsize, DEFAULT_TIMEOUT); | ||
66 | return r; | ||
67 | } | ||
68 | |||
69 | static int ch341_set_baudrate(struct usb_device *dev, | ||
70 | struct ch341_private *priv) | ||
71 | { | ||
72 | short a, b; | ||
73 | int r; | ||
74 | |||
75 | dbg("ch341_set_baudrate(%d)", priv->baud_rate); | ||
76 | switch (priv->baud_rate) { | ||
77 | case 2400: | ||
78 | a = 0xd901; | ||
79 | b = 0x0038; | ||
80 | break; | ||
81 | case 4800: | ||
82 | a = 0x6402; | ||
83 | b = 0x001f; | ||
84 | break; | ||
85 | case 9600: | ||
86 | a = 0xb202; | ||
87 | b = 0x0013; | ||
88 | break; | ||
89 | case 19200: | ||
90 | a = 0xd902; | ||
91 | b = 0x000d; | ||
92 | break; | ||
93 | case 38400: | ||
94 | a = 0x6403; | ||
95 | b = 0x000a; | ||
96 | break; | ||
97 | case 115200: | ||
98 | a = 0xcc03; | ||
99 | b = 0x0008; | ||
100 | break; | ||
101 | default: | ||
102 | return -EINVAL; | ||
103 | } | ||
104 | |||
105 | r = ch341_control_out(dev, 0x9a, 0x1312, a); | ||
106 | if (!r) | ||
107 | r = ch341_control_out(dev, 0x9a, 0x0f2c, b); | ||
108 | |||
109 | return r; | ||
110 | } | ||
111 | |||
112 | static int ch341_set_handshake(struct usb_device *dev, | ||
113 | struct ch341_private *priv) | ||
114 | { | ||
115 | dbg("ch341_set_handshake(%d,%d)", priv->dtr, priv->rts); | ||
116 | return ch341_control_out(dev, 0xa4, | ||
117 | ~((priv->dtr?1<<5:0)|(priv->rts?1<<6:0)), 0); | ||
118 | } | ||
119 | |||
120 | static int ch341_get_status(struct usb_device *dev) | ||
121 | { | ||
122 | char *buffer; | ||
123 | int r; | ||
124 | const unsigned size = 8; | ||
125 | |||
126 | dbg("ch341_get_status()"); | ||
127 | |||
128 | buffer = kmalloc(size, GFP_KERNEL); | ||
129 | if (!buffer) | ||
130 | return -ENOMEM; | ||
131 | |||
132 | r = ch341_control_in(dev, 0x95, 0x0706, 0, buffer, size); | ||
133 | if ( r < 0) | ||
134 | goto out; | ||
135 | |||
136 | /* Not having the datasheet for the CH341, we ignore the bytes returned | ||
137 | * from the device. Return error if the device did not respond in time. | ||
138 | */ | ||
139 | r = 0; | ||
140 | |||
141 | out: kfree(buffer); | ||
142 | return r; | ||
143 | } | ||
144 | |||
145 | /* -------------------------------------------------------------------------- */ | ||
146 | |||
147 | static int ch341_configure(struct usb_device *dev, struct ch341_private *priv) | ||
148 | { | ||
149 | char *buffer; | ||
150 | int r; | ||
151 | const unsigned size = 8; | ||
152 | |||
153 | dbg("ch341_configure()"); | ||
154 | |||
155 | buffer = kmalloc(size, GFP_KERNEL); | ||
156 | if (!buffer) | ||
157 | return -ENOMEM; | ||
158 | |||
159 | /* expect two bytes 0x27 0x00 */ | ||
160 | r = ch341_control_in(dev, 0x5f, 0, 0, buffer, size); | ||
161 | if (r < 0) | ||
162 | goto out; | ||
163 | |||
164 | r = ch341_control_out(dev, 0xa1, 0, 0); | ||
165 | if (r < 0) | ||
166 | goto out; | ||
167 | |||
168 | r = ch341_set_baudrate(dev, priv); | ||
169 | if (r < 0) | ||
170 | goto out; | ||
171 | |||
172 | /* expect two bytes 0x56 0x00 */ | ||
173 | r = ch341_control_in(dev, 0x95, 0x2518, 0, buffer, size); | ||
174 | if (r < 0) | ||
175 | goto out; | ||
176 | |||
177 | r = ch341_control_out(dev, 0x9a, 0x2518, 0x0050); | ||
178 | if (r < 0) | ||
179 | goto out; | ||
180 | |||
181 | /* expect 0xff 0xee */ | ||
182 | r = ch341_get_status(dev); | ||
183 | if (r < 0) | ||
184 | goto out; | ||
185 | |||
186 | r = ch341_control_out(dev, 0xa1, 0x501f, 0xd90a); | ||
187 | if (r < 0) | ||
188 | goto out; | ||
189 | |||
190 | r = ch341_set_baudrate(dev, priv); | ||
191 | if (r < 0) | ||
192 | goto out; | ||
193 | |||
194 | r = ch341_set_handshake(dev, priv); | ||
195 | if (r < 0) | ||
196 | goto out; | ||
197 | |||
198 | /* expect 0x9f 0xee */ | ||
199 | r = ch341_get_status(dev); | ||
200 | |||
201 | out: kfree(buffer); | ||
202 | return r; | ||
203 | } | ||
204 | |||
205 | /* allocate private data */ | ||
206 | static int ch341_attach(struct usb_serial *serial) | ||
207 | { | ||
208 | struct ch341_private *priv; | ||
209 | int r; | ||
210 | |||
211 | dbg("ch341_attach()"); | ||
212 | |||
213 | /* private data */ | ||
214 | priv = kzalloc(sizeof(struct ch341_private), GFP_KERNEL); | ||
215 | if (!priv) | ||
216 | return -ENOMEM; | ||
217 | |||
218 | priv->baud_rate = DEFAULT_BAUD_RATE; | ||
219 | priv->dtr = 1; | ||
220 | priv->rts = 1; | ||
221 | |||
222 | r = ch341_configure(serial->dev, priv); | ||
223 | if (r < 0) | ||
224 | goto error; | ||
225 | |||
226 | usb_set_serial_port_data(serial->port[0], priv); | ||
227 | return 0; | ||
228 | |||
229 | error: kfree(priv); | ||
230 | return r; | ||
231 | } | ||
232 | |||
233 | /* open this device, set default parameters */ | ||
234 | static int ch341_open(struct usb_serial_port *port, struct file *filp) | ||
235 | { | ||
236 | struct usb_serial *serial = port->serial; | ||
237 | struct ch341_private *priv = usb_get_serial_port_data(serial->port[0]); | ||
238 | int r; | ||
239 | |||
240 | dbg("ch341_open()"); | ||
241 | |||
242 | priv->baud_rate = DEFAULT_BAUD_RATE; | ||
243 | priv->dtr = 1; | ||
244 | priv->rts = 1; | ||
245 | |||
246 | r = ch341_configure(serial->dev, priv); | ||
247 | if (r) | ||
248 | goto out; | ||
249 | |||
250 | r = ch341_set_handshake(serial->dev, priv); | ||
251 | if (r) | ||
252 | goto out; | ||
253 | |||
254 | r = ch341_set_baudrate(serial->dev, priv); | ||
255 | if (r) | ||
256 | goto out; | ||
257 | |||
258 | r = usb_serial_generic_open(port, filp); | ||
259 | |||
260 | out: return r; | ||
261 | } | ||
262 | |||
263 | /* Old_termios contains the original termios settings and | ||
264 | * tty->termios contains the new setting to be used. | ||
265 | */ | ||
266 | static void ch341_set_termios(struct usb_serial_port *port, | ||
267 | struct ktermios *old_termios) | ||
268 | { | ||
269 | struct ch341_private *priv = usb_get_serial_port_data(port); | ||
270 | struct tty_struct *tty = port->tty; | ||
271 | unsigned baud_rate; | ||
272 | |||
273 | dbg("ch341_set_termios()"); | ||
274 | |||
275 | if (!tty || !tty->termios) | ||
276 | return; | ||
277 | |||
278 | baud_rate = tty_get_baud_rate(tty); | ||
279 | |||
280 | switch (baud_rate) { | ||
281 | case 2400: | ||
282 | case 4800: | ||
283 | case 9600: | ||
284 | case 19200: | ||
285 | case 38400: | ||
286 | case 115200: | ||
287 | priv->baud_rate = baud_rate; | ||
288 | break; | ||
289 | default: | ||
290 | dbg("Rate %d not supported, using %d", | ||
291 | baud_rate, DEFAULT_BAUD_RATE); | ||
292 | priv->baud_rate = DEFAULT_BAUD_RATE; | ||
293 | } | ||
294 | |||
295 | ch341_set_baudrate(port->serial->dev, priv); | ||
296 | |||
297 | /* Unimplemented: | ||
298 | * (cflag & CSIZE) : data bits [5, 8] | ||
299 | * (cflag & PARENB) : parity {NONE, EVEN, ODD} | ||
300 | * (cflag & CSTOPB) : stop bits [1, 2] | ||
301 | */ | ||
302 | } | ||
303 | |||
304 | static struct usb_driver ch341_driver = { | ||
305 | .name = "ch341", | ||
306 | .probe = usb_serial_probe, | ||
307 | .disconnect = usb_serial_disconnect, | ||
308 | .id_table = id_table, | ||
309 | .no_dynamic_id = 1, | ||
310 | }; | ||
311 | |||
312 | static struct usb_serial_driver ch341_device = { | ||
313 | .driver = { | ||
314 | .owner = THIS_MODULE, | ||
315 | .name = "ch341-uart", | ||
316 | }, | ||
317 | .id_table = id_table, | ||
318 | .usb_driver = &ch341_driver, | ||
319 | .num_interrupt_in = NUM_DONT_CARE, | ||
320 | .num_bulk_in = 1, | ||
321 | .num_bulk_out = 1, | ||
322 | .num_ports = 1, | ||
323 | .open = ch341_open, | ||
324 | .set_termios = ch341_set_termios, | ||
325 | .attach = ch341_attach, | ||
326 | }; | ||
327 | |||
328 | static int __init ch341_init(void) | ||
329 | { | ||
330 | int retval; | ||
331 | |||
332 | retval = usb_serial_register(&ch341_device); | ||
333 | if (retval) | ||
334 | return retval; | ||
335 | retval = usb_register(&ch341_driver); | ||
336 | if (retval) | ||
337 | usb_serial_deregister(&ch341_device); | ||
338 | return retval; | ||
339 | } | ||
340 | |||
341 | static void __exit ch341_exit(void) | ||
342 | { | ||
343 | usb_deregister(&ch341_driver); | ||
344 | usb_serial_deregister(&ch341_device); | ||
345 | } | ||
346 | |||
347 | module_init(ch341_init); | ||
348 | module_exit(ch341_exit); | ||
349 | MODULE_LICENSE("GPL"); | ||
350 | |||
351 | module_param(debug, bool, S_IRUGO | S_IWUSR); | ||
352 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | ||
353 | |||
354 | /* EOF ch341.c */ | ||
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c index e831cb7f64f..eb7df1835c1 100644 --- a/drivers/usb/serial/cp2101.c +++ b/drivers/usb/serial/cp2101.c | |||
@@ -53,6 +53,7 @@ static void cp2101_shutdown(struct usb_serial*); | |||
53 | static int debug; | 53 | static int debug; |
54 | 54 | ||
55 | static struct usb_device_id id_table [] = { | 55 | static struct usb_device_id id_table [] = { |
56 | { USB_DEVICE(0x08e6, 0x5501) }, /* Gemalto Prox-PU/CU contactless smartcard reader */ | ||
56 | { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ | 57 | { USB_DEVICE(0x0FCF, 0x1003) }, /* Dynastream ANT development board */ |
57 | { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */ | 58 | { USB_DEVICE(0x10A6, 0xAA26) }, /* Knock-off DCU-11 cable */ |
58 | { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ | 59 | { USB_DEVICE(0x10AB, 0x10C5) }, /* Siemens MC60 Cable */ |
@@ -356,7 +357,7 @@ static void cp2101_get_termios (struct usb_serial_port *port) | |||
356 | 357 | ||
357 | dbg("%s - port %d", __FUNCTION__, port->number); | 358 | dbg("%s - port %d", __FUNCTION__, port->number); |
358 | 359 | ||
359 | if ((!port->tty) || (!port->tty->termios)) { | 360 | if (!port->tty || !port->tty->termios) { |
360 | dbg("%s - no tty structures", __FUNCTION__); | 361 | dbg("%s - no tty structures", __FUNCTION__); |
361 | return; | 362 | return; |
362 | } | 363 | } |
@@ -521,55 +522,40 @@ static void cp2101_set_termios (struct usb_serial_port *port, | |||
521 | 522 | ||
522 | dbg("%s - port %d", __FUNCTION__, port->number); | 523 | dbg("%s - port %d", __FUNCTION__, port->number); |
523 | 524 | ||
524 | if ((!port->tty) || (!port->tty->termios)) { | 525 | if (!port->tty || !port->tty->termios) { |
525 | dbg("%s - no tty structures", __FUNCTION__); | 526 | dbg("%s - no tty structures", __FUNCTION__); |
526 | return; | 527 | return; |
527 | } | 528 | } |
528 | cflag = port->tty->termios->c_cflag; | 529 | cflag = port->tty->termios->c_cflag; |
529 | 530 | old_cflag = old_termios->c_cflag; | |
530 | /* Check that they really want us to change something */ | 531 | baud = tty_get_baud_rate(port->tty); |
531 | if (old_termios) { | ||
532 | if ((cflag == old_termios->c_cflag) && | ||
533 | (RELEVANT_IFLAG(port->tty->termios->c_iflag) | ||
534 | == RELEVANT_IFLAG(old_termios->c_iflag))) { | ||
535 | dbg("%s - nothing to change...", __FUNCTION__); | ||
536 | return; | ||
537 | } | ||
538 | |||
539 | old_cflag = old_termios->c_cflag; | ||
540 | } | ||
541 | 532 | ||
542 | /* If the baud rate is to be updated*/ | 533 | /* If the baud rate is to be updated*/ |
543 | if ((cflag & CBAUD) != (old_cflag & CBAUD)) { | 534 | if (baud != tty_termios_baud_rate(old_termios)) { |
544 | switch (cflag & CBAUD) { | 535 | switch (baud) { |
545 | /* | 536 | case 0: |
546 | * The baud rates which are commented out below | 537 | case 600: |
547 | * appear to be supported by the device | 538 | case 1200: |
548 | * but are non-standard | 539 | case 1800: |
549 | */ | 540 | case 2400: |
550 | case B0: baud = 0; break; | 541 | case 4800: |
551 | case B600: baud = 600; break; | 542 | case 7200: |
552 | case B1200: baud = 1200; break; | 543 | case 9600: |
553 | case B1800: baud = 1800; break; | 544 | case 14400: |
554 | case B2400: baud = 2400; break; | 545 | case 19200: |
555 | case B4800: baud = 4800; break; | 546 | case 28800: |
556 | /*case B7200: baud = 7200; break;*/ | 547 | case 38400: |
557 | case B9600: baud = 9600; break; | 548 | case 55854: |
558 | /*ase B14400: baud = 14400; break;*/ | 549 | case 57600: |
559 | case B19200: baud = 19200; break; | 550 | case 115200: |
560 | /*case B28800: baud = 28800; break;*/ | 551 | case 127117: |
561 | case B38400: baud = 38400; break; | 552 | case 230400: |
562 | /*case B55854: baud = 55054; break;*/ | 553 | case 460800: |
563 | case B57600: baud = 57600; break; | 554 | case 921600: |
564 | case B115200: baud = 115200; break; | 555 | case 3686400: |
565 | /*case B127117: baud = 127117; break;*/ | 556 | break; |
566 | case B230400: baud = 230400; break; | ||
567 | case B460800: baud = 460800; break; | ||
568 | case B921600: baud = 921600; break; | ||
569 | /*case B3686400: baud = 3686400; break;*/ | ||
570 | default: | 557 | default: |
571 | dev_err(&port->dev, "cp2101 driver does not " | 558 | baud = 9600; |
572 | "support the baudrate requested\n"); | ||
573 | break; | 559 | break; |
574 | } | 560 | } |
575 | 561 | ||
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c index 976f54ec26e..dab2e66d111 100644 --- a/drivers/usb/serial/digi_acceleport.c +++ b/drivers/usb/serial/digi_acceleport.c | |||
@@ -433,38 +433,38 @@ struct digi_port { | |||
433 | 433 | ||
434 | /* Local Function Declarations */ | 434 | /* Local Function Declarations */ |
435 | 435 | ||
436 | static void digi_wakeup_write( struct usb_serial_port *port ); | 436 | static void digi_wakeup_write(struct usb_serial_port *port); |
437 | static void digi_wakeup_write_lock(struct work_struct *work); | 437 | static void digi_wakeup_write_lock(struct work_struct *work); |
438 | static int digi_write_oob_command( struct usb_serial_port *port, | 438 | static int digi_write_oob_command(struct usb_serial_port *port, |
439 | unsigned char *buf, int count, int interruptible ); | 439 | unsigned char *buf, int count, int interruptible); |
440 | static int digi_write_inb_command( struct usb_serial_port *port, | 440 | static int digi_write_inb_command(struct usb_serial_port *port, |
441 | unsigned char *buf, int count, unsigned long timeout ); | 441 | unsigned char *buf, int count, unsigned long timeout); |
442 | static int digi_set_modem_signals( struct usb_serial_port *port, | 442 | static int digi_set_modem_signals(struct usb_serial_port *port, |
443 | unsigned int modem_signals, int interruptible ); | 443 | unsigned int modem_signals, int interruptible); |
444 | static int digi_transmit_idle( struct usb_serial_port *port, | 444 | static int digi_transmit_idle(struct usb_serial_port *port, |
445 | unsigned long timeout ); | 445 | unsigned long timeout); |
446 | static void digi_rx_throttle (struct usb_serial_port *port); | 446 | static void digi_rx_throttle (struct usb_serial_port *port); |
447 | static void digi_rx_unthrottle (struct usb_serial_port *port); | 447 | static void digi_rx_unthrottle (struct usb_serial_port *port); |
448 | static void digi_set_termios( struct usb_serial_port *port, | 448 | static void digi_set_termios(struct usb_serial_port *port, |
449 | struct ktermios *old_termios ); | 449 | struct ktermios *old_termios); |
450 | static void digi_break_ctl( struct usb_serial_port *port, int break_state ); | 450 | static void digi_break_ctl(struct usb_serial_port *port, int break_state); |
451 | static int digi_ioctl( struct usb_serial_port *port, struct file *file, | 451 | static int digi_ioctl(struct usb_serial_port *port, struct file *file, |
452 | unsigned int cmd, unsigned long arg ); | 452 | unsigned int cmd, unsigned long arg); |
453 | static int digi_tiocmget( struct usb_serial_port *port, struct file *file ); | 453 | static int digi_tiocmget(struct usb_serial_port *port, struct file *file); |
454 | static int digi_tiocmset( struct usb_serial_port *port, struct file *file, | 454 | static int digi_tiocmset(struct usb_serial_port *port, struct file *file, |
455 | unsigned int set, unsigned int clear ); | 455 | unsigned int set, unsigned int clear); |
456 | static int digi_write( struct usb_serial_port *port, const unsigned char *buf, int count ); | 456 | static int digi_write(struct usb_serial_port *port, const unsigned char *buf, int count); |
457 | static void digi_write_bulk_callback( struct urb *urb ); | 457 | static void digi_write_bulk_callback(struct urb *urb); |
458 | static int digi_write_room( struct usb_serial_port *port ); | 458 | static int digi_write_room(struct usb_serial_port *port); |
459 | static int digi_chars_in_buffer( struct usb_serial_port *port ); | 459 | static int digi_chars_in_buffer(struct usb_serial_port *port); |
460 | static int digi_open( struct usb_serial_port *port, struct file *filp ); | 460 | static int digi_open(struct usb_serial_port *port, struct file *filp); |
461 | static void digi_close( struct usb_serial_port *port, struct file *filp ); | 461 | static void digi_close(struct usb_serial_port *port, struct file *filp); |
462 | static int digi_startup_device( struct usb_serial *serial ); | 462 | static int digi_startup_device(struct usb_serial *serial); |
463 | static int digi_startup( struct usb_serial *serial ); | 463 | static int digi_startup(struct usb_serial *serial); |
464 | static void digi_shutdown( struct usb_serial *serial ); | 464 | static void digi_shutdown(struct usb_serial *serial); |
465 | static void digi_read_bulk_callback( struct urb *urb ); | 465 | static void digi_read_bulk_callback(struct urb *urb); |
466 | static int digi_read_inb_callback( struct urb *urb ); | 466 | static int digi_read_inb_callback(struct urb *urb); |
467 | static int digi_read_oob_callback( struct urb *urb ); | 467 | static int digi_read_oob_callback(struct urb *urb); |
468 | 468 | ||
469 | 469 | ||
470 | /* Statics */ | 470 | /* Statics */ |
@@ -576,9 +576,9 @@ static struct usb_serial_driver digi_acceleport_4_device = { | |||
576 | * with the equivalent code. | 576 | * with the equivalent code. |
577 | */ | 577 | */ |
578 | 578 | ||
579 | static inline long cond_wait_interruptible_timeout_irqrestore( | 579 | static long cond_wait_interruptible_timeout_irqrestore( |
580 | wait_queue_head_t *q, long timeout, | 580 | wait_queue_head_t *q, long timeout, |
581 | spinlock_t *lock, unsigned long flags ) | 581 | spinlock_t *lock, unsigned long flags) |
582 | { | 582 | { |
583 | DEFINE_WAIT(wait); | 583 | DEFINE_WAIT(wait); |
584 | 584 | ||
@@ -600,18 +600,16 @@ static inline long cond_wait_interruptible_timeout_irqrestore( | |||
600 | 600 | ||
601 | static void digi_wakeup_write_lock(struct work_struct *work) | 601 | static void digi_wakeup_write_lock(struct work_struct *work) |
602 | { | 602 | { |
603 | struct digi_port *priv = | 603 | struct digi_port *priv = container_of(work, struct digi_port, dp_wakeup_work); |
604 | container_of(work, struct digi_port, dp_wakeup_work); | ||
605 | struct usb_serial_port *port = priv->dp_port; | 604 | struct usb_serial_port *port = priv->dp_port; |
606 | unsigned long flags; | 605 | unsigned long flags; |
607 | 606 | ||
608 | 607 | spin_lock_irqsave(&priv->dp_port_lock, flags); | |
609 | spin_lock_irqsave( &priv->dp_port_lock, flags ); | 608 | digi_wakeup_write(port); |
610 | digi_wakeup_write( port ); | 609 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); |
611 | spin_unlock_irqrestore( &priv->dp_port_lock, flags ); | ||
612 | } | 610 | } |
613 | 611 | ||
614 | static void digi_wakeup_write( struct usb_serial_port *port ) | 612 | static void digi_wakeup_write(struct usb_serial_port *port) |
615 | { | 613 | { |
616 | tty_wakeup(port->tty); | 614 | tty_wakeup(port->tty); |
617 | } | 615 | } |
@@ -628,8 +626,8 @@ static void digi_wakeup_write( struct usb_serial_port *port ) | |||
628 | * returned by usb_submit_urb. | 626 | * returned by usb_submit_urb. |
629 | */ | 627 | */ |
630 | 628 | ||
631 | static int digi_write_oob_command( struct usb_serial_port *port, | 629 | static int digi_write_oob_command(struct usb_serial_port *port, |
632 | unsigned char *buf, int count, int interruptible ) | 630 | unsigned char *buf, int count, int interruptible) |
633 | { | 631 | { |
634 | 632 | ||
635 | int ret = 0; | 633 | int ret = 0; |
@@ -638,49 +636,37 @@ static int digi_write_oob_command( struct usb_serial_port *port, | |||
638 | struct digi_port *oob_priv = usb_get_serial_port_data(oob_port); | 636 | struct digi_port *oob_priv = usb_get_serial_port_data(oob_port); |
639 | unsigned long flags = 0; | 637 | unsigned long flags = 0; |
640 | 638 | ||
639 | dbg("digi_write_oob_command: TOP: port=%d, count=%d", oob_priv->dp_port_num, count); | ||
641 | 640 | ||
642 | dbg( "digi_write_oob_command: TOP: port=%d, count=%d", oob_priv->dp_port_num, count ); | 641 | spin_lock_irqsave(&oob_priv->dp_port_lock, flags); |
643 | 642 | while(count > 0) { | |
644 | spin_lock_irqsave( &oob_priv->dp_port_lock, flags ); | 643 | while(oob_port->write_urb->status == -EINPROGRESS |
645 | 644 | || oob_priv->dp_write_urb_in_use) { | |
646 | while( count > 0 ) { | ||
647 | |||
648 | while( oob_port->write_urb->status == -EINPROGRESS | ||
649 | || oob_priv->dp_write_urb_in_use ) { | ||
650 | cond_wait_interruptible_timeout_irqrestore( | 645 | cond_wait_interruptible_timeout_irqrestore( |
651 | &oob_port->write_wait, DIGI_RETRY_TIMEOUT, | 646 | &oob_port->write_wait, DIGI_RETRY_TIMEOUT, |
652 | &oob_priv->dp_port_lock, flags ); | 647 | &oob_priv->dp_port_lock, flags); |
653 | if( interruptible && signal_pending(current) ) { | 648 | if (interruptible && signal_pending(current)) |
654 | return( -EINTR ); | 649 | return -EINTR; |
655 | } | 650 | spin_lock_irqsave(&oob_priv->dp_port_lock, flags); |
656 | spin_lock_irqsave( &oob_priv->dp_port_lock, flags ); | ||
657 | } | 651 | } |
658 | 652 | ||
659 | /* len must be a multiple of 4, so commands are not split */ | 653 | /* len must be a multiple of 4, so commands are not split */ |
660 | len = min(count, oob_port->bulk_out_size ); | 654 | len = min(count, oob_port->bulk_out_size); |
661 | if( len > 4 ) | 655 | if (len > 4) |
662 | len &= ~3; | 656 | len &= ~3; |
663 | 657 | memcpy(oob_port->write_urb->transfer_buffer, buf, len); | |
664 | memcpy( oob_port->write_urb->transfer_buffer, buf, len ); | ||
665 | oob_port->write_urb->transfer_buffer_length = len; | 658 | oob_port->write_urb->transfer_buffer_length = len; |
666 | oob_port->write_urb->dev = port->serial->dev; | 659 | oob_port->write_urb->dev = port->serial->dev; |
667 | 660 | if ((ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC)) == 0) { | |
668 | if( (ret=usb_submit_urb(oob_port->write_urb, GFP_ATOMIC)) == 0 ) { | ||
669 | oob_priv->dp_write_urb_in_use = 1; | 661 | oob_priv->dp_write_urb_in_use = 1; |
670 | count -= len; | 662 | count -= len; |
671 | buf += len; | 663 | buf += len; |
672 | } | 664 | } |
673 | |||
674 | } | ||
675 | |||
676 | spin_unlock_irqrestore( &oob_priv->dp_port_lock, flags ); | ||
677 | |||
678 | if( ret ) { | ||
679 | err("%s: usb_submit_urb failed, ret=%d", __FUNCTION__, | ||
680 | ret ); | ||
681 | } | 665 | } |
682 | 666 | spin_unlock_irqrestore(&oob_priv->dp_port_lock, flags); | |
683 | return( ret ); | 667 | if (ret) |
668 | err("%s: usb_submit_urb failed, ret=%d", __FUNCTION__, ret); | ||
669 | return ret; | ||
684 | 670 | ||
685 | } | 671 | } |
686 | 672 | ||
@@ -697,63 +683,58 @@ dbg( "digi_write_oob_command: TOP: port=%d, count=%d", oob_priv->dp_port_num, co | |||
697 | * error returned by digi_write. | 683 | * error returned by digi_write. |
698 | */ | 684 | */ |
699 | 685 | ||
700 | static int digi_write_inb_command( struct usb_serial_port *port, | 686 | static int digi_write_inb_command(struct usb_serial_port *port, |
701 | unsigned char *buf, int count, unsigned long timeout ) | 687 | unsigned char *buf, int count, unsigned long timeout) |
702 | { | 688 | { |
703 | |||
704 | int ret = 0; | 689 | int ret = 0; |
705 | int len; | 690 | int len; |
706 | struct digi_port *priv = usb_get_serial_port_data(port); | 691 | struct digi_port *priv = usb_get_serial_port_data(port); |
707 | unsigned char *data = port->write_urb->transfer_buffer; | 692 | unsigned char *data = port->write_urb->transfer_buffer; |
708 | unsigned long flags = 0; | 693 | unsigned long flags = 0; |
709 | 694 | ||
695 | dbg("digi_write_inb_command: TOP: port=%d, count=%d", | ||
696 | priv->dp_port_num, count); | ||
710 | 697 | ||
711 | dbg( "digi_write_inb_command: TOP: port=%d, count=%d", priv->dp_port_num, | 698 | if (timeout) |
712 | count ); | ||
713 | |||
714 | if( timeout ) | ||
715 | timeout += jiffies; | 699 | timeout += jiffies; |
716 | else | 700 | else |
717 | timeout = ULONG_MAX; | 701 | timeout = ULONG_MAX; |
718 | 702 | ||
719 | spin_lock_irqsave( &priv->dp_port_lock, flags ); | 703 | spin_lock_irqsave(&priv->dp_port_lock, flags); |
720 | 704 | while(count > 0 && ret == 0) { | |
721 | while( count > 0 && ret == 0 ) { | 705 | while((port->write_urb->status == -EINPROGRESS |
722 | 706 | || priv->dp_write_urb_in_use) && time_before(jiffies, timeout)) { | |
723 | while( (port->write_urb->status == -EINPROGRESS | ||
724 | || priv->dp_write_urb_in_use) && time_before(jiffies, timeout)) { | ||
725 | cond_wait_interruptible_timeout_irqrestore( | 707 | cond_wait_interruptible_timeout_irqrestore( |
726 | &port->write_wait, DIGI_RETRY_TIMEOUT, | 708 | &port->write_wait, DIGI_RETRY_TIMEOUT, |
727 | &priv->dp_port_lock, flags ); | 709 | &priv->dp_port_lock, flags); |
728 | if( signal_pending(current) ) { | 710 | if (signal_pending(current)) |
729 | return( -EINTR ); | 711 | return -EINTR; |
730 | } | 712 | spin_lock_irqsave(&priv->dp_port_lock, flags); |
731 | spin_lock_irqsave( &priv->dp_port_lock, flags ); | ||
732 | } | 713 | } |
733 | 714 | ||
734 | /* len must be a multiple of 4 and small enough to */ | 715 | /* len must be a multiple of 4 and small enough to */ |
735 | /* guarantee the write will send buffered data first, */ | 716 | /* guarantee the write will send buffered data first, */ |
736 | /* so commands are in order with data and not split */ | 717 | /* so commands are in order with data and not split */ |
737 | len = min(count, port->bulk_out_size-2-priv->dp_out_buf_len ); | 718 | len = min(count, port->bulk_out_size-2-priv->dp_out_buf_len); |
738 | if( len > 4 ) | 719 | if (len > 4) |
739 | len &= ~3; | 720 | len &= ~3; |
740 | 721 | ||
741 | /* write any buffered data first */ | 722 | /* write any buffered data first */ |
742 | if( priv->dp_out_buf_len > 0 ) { | 723 | if (priv->dp_out_buf_len > 0) { |
743 | data[0] = DIGI_CMD_SEND_DATA; | 724 | data[0] = DIGI_CMD_SEND_DATA; |
744 | data[1] = priv->dp_out_buf_len; | 725 | data[1] = priv->dp_out_buf_len; |
745 | memcpy( data+2, priv->dp_out_buf, | 726 | memcpy(data + 2, priv->dp_out_buf, |
746 | priv->dp_out_buf_len ); | 727 | priv->dp_out_buf_len); |
747 | memcpy( data+2+priv->dp_out_buf_len, buf, len ); | 728 | memcpy(data + 2 + priv->dp_out_buf_len, buf, len); |
748 | port->write_urb->transfer_buffer_length | 729 | port->write_urb->transfer_buffer_length |
749 | = priv->dp_out_buf_len+2+len; | 730 | = priv->dp_out_buf_len + 2 + len; |
750 | } else { | 731 | } else { |
751 | memcpy( data, buf, len ); | 732 | memcpy(data, buf, len); |
752 | port->write_urb->transfer_buffer_length = len; | 733 | port->write_urb->transfer_buffer_length = len; |
753 | } | 734 | } |
754 | port->write_urb->dev = port->serial->dev; | 735 | port->write_urb->dev = port->serial->dev; |
755 | 736 | ||
756 | if( (ret=usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0 ) { | 737 | if ((ret = usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0) { |
757 | priv->dp_write_urb_in_use = 1; | 738 | priv->dp_write_urb_in_use = 1; |
758 | priv->dp_out_buf_len = 0; | 739 | priv->dp_out_buf_len = 0; |
759 | count -= len; | 740 | count -= len; |
@@ -761,16 +742,12 @@ count ); | |||
761 | } | 742 | } |
762 | 743 | ||
763 | } | 744 | } |
745 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); | ||
764 | 746 | ||
765 | spin_unlock_irqrestore( &priv->dp_port_lock, flags ); | 747 | if (ret) |
766 | 748 | err("%s: usb_submit_urb failed, ret=%d, port=%d", | |
767 | if( ret ) { | 749 | __FUNCTION__, ret, priv->dp_port_num); |
768 | err("%s: usb_submit_urb failed, ret=%d, port=%d", __FUNCTION__, | 750 | return ret; |
769 | ret, priv->dp_port_num ); | ||
770 | } | ||
771 | |||
772 | return( ret ); | ||
773 | |||
774 | } | 751 | } |
775 | 752 | ||
776 | 753 | ||
@@ -784,8 +761,8 @@ count ); | |||
784 | * returned by usb_submit_urb. | 761 | * returned by usb_submit_urb. |
785 | */ | 762 | */ |
786 | 763 | ||
787 | static int digi_set_modem_signals( struct usb_serial_port *port, | 764 | static int digi_set_modem_signals(struct usb_serial_port *port, |
788 | unsigned int modem_signals, int interruptible ) | 765 | unsigned int modem_signals, int interruptible) |
789 | { | 766 | { |
790 | 767 | ||
791 | int ret; | 768 | int ret; |
@@ -796,60 +773,47 @@ static int digi_set_modem_signals( struct usb_serial_port *port, | |||
796 | unsigned long flags = 0; | 773 | unsigned long flags = 0; |
797 | 774 | ||
798 | 775 | ||
799 | dbg( "digi_set_modem_signals: TOP: port=%d, modem_signals=0x%x", | 776 | dbg("digi_set_modem_signals: TOP: port=%d, modem_signals=0x%x", |
800 | port_priv->dp_port_num, modem_signals ); | 777 | port_priv->dp_port_num, modem_signals); |
801 | 778 | ||
802 | spin_lock_irqsave( &oob_priv->dp_port_lock, flags ); | 779 | spin_lock_irqsave(&oob_priv->dp_port_lock, flags); |
803 | spin_lock( &port_priv->dp_port_lock ); | 780 | spin_lock(&port_priv->dp_port_lock); |
804 | 781 | ||
805 | while( oob_port->write_urb->status == -EINPROGRESS | 782 | while(oob_port->write_urb->status == -EINPROGRESS || oob_priv->dp_write_urb_in_use) { |
806 | || oob_priv->dp_write_urb_in_use ) { | 783 | spin_unlock(&port_priv->dp_port_lock); |
807 | spin_unlock( &port_priv->dp_port_lock ); | ||
808 | cond_wait_interruptible_timeout_irqrestore( | 784 | cond_wait_interruptible_timeout_irqrestore( |
809 | &oob_port->write_wait, DIGI_RETRY_TIMEOUT, | 785 | &oob_port->write_wait, DIGI_RETRY_TIMEOUT, |
810 | &oob_priv->dp_port_lock, flags ); | 786 | &oob_priv->dp_port_lock, flags); |
811 | if( interruptible && signal_pending(current) ) { | 787 | if (interruptible && signal_pending(current)) |
812 | return( -EINTR ); | 788 | return -EINTR; |
813 | } | 789 | spin_lock_irqsave(&oob_priv->dp_port_lock, flags); |
814 | spin_lock_irqsave( &oob_priv->dp_port_lock, flags ); | 790 | spin_lock(&port_priv->dp_port_lock); |
815 | spin_lock( &port_priv->dp_port_lock ); | ||
816 | } | 791 | } |
817 | |||
818 | data[0] = DIGI_CMD_SET_DTR_SIGNAL; | 792 | data[0] = DIGI_CMD_SET_DTR_SIGNAL; |
819 | data[1] = port_priv->dp_port_num; | 793 | data[1] = port_priv->dp_port_num; |
820 | data[2] = (modem_signals&TIOCM_DTR) ? | 794 | data[2] = (modem_signals&TIOCM_DTR) ? DIGI_DTR_ACTIVE : DIGI_DTR_INACTIVE; |
821 | DIGI_DTR_ACTIVE : DIGI_DTR_INACTIVE; | ||
822 | data[3] = 0; | 795 | data[3] = 0; |
823 | |||
824 | data[4] = DIGI_CMD_SET_RTS_SIGNAL; | 796 | data[4] = DIGI_CMD_SET_RTS_SIGNAL; |
825 | data[5] = port_priv->dp_port_num; | 797 | data[5] = port_priv->dp_port_num; |
826 | data[6] = (modem_signals&TIOCM_RTS) ? | 798 | data[6] = (modem_signals&TIOCM_RTS) ? DIGI_RTS_ACTIVE : DIGI_RTS_INACTIVE; |
827 | DIGI_RTS_ACTIVE : DIGI_RTS_INACTIVE; | ||
828 | data[7] = 0; | 799 | data[7] = 0; |
829 | 800 | ||
830 | oob_port->write_urb->transfer_buffer_length = 8; | 801 | oob_port->write_urb->transfer_buffer_length = 8; |
831 | oob_port->write_urb->dev = port->serial->dev; | 802 | oob_port->write_urb->dev = port->serial->dev; |
832 | 803 | ||
833 | if( (ret=usb_submit_urb(oob_port->write_urb, GFP_ATOMIC)) == 0 ) { | 804 | if ((ret = usb_submit_urb(oob_port->write_urb, GFP_ATOMIC)) == 0) { |
834 | oob_priv->dp_write_urb_in_use = 1; | 805 | oob_priv->dp_write_urb_in_use = 1; |
835 | port_priv->dp_modem_signals = | 806 | port_priv->dp_modem_signals = |
836 | (port_priv->dp_modem_signals&~(TIOCM_DTR|TIOCM_RTS)) | 807 | (port_priv->dp_modem_signals&~(TIOCM_DTR|TIOCM_RTS)) |
837 | | (modem_signals&(TIOCM_DTR|TIOCM_RTS)); | 808 | | (modem_signals&(TIOCM_DTR|TIOCM_RTS)); |
838 | } | 809 | } |
839 | 810 | spin_unlock(&port_priv->dp_port_lock); | |
840 | spin_unlock( &port_priv->dp_port_lock ); | 811 | spin_unlock_irqrestore(&oob_priv->dp_port_lock, flags); |
841 | spin_unlock_irqrestore( &oob_priv->dp_port_lock, flags ); | 812 | if (ret) |
842 | 813 | err("%s: usb_submit_urb failed, ret=%d", __FUNCTION__, ret); | |
843 | if( ret ) { | 814 | return ret; |
844 | err("%s: usb_submit_urb failed, ret=%d", __FUNCTION__, | ||
845 | ret ); | ||
846 | } | ||
847 | |||
848 | return( ret ); | ||
849 | |||
850 | } | 815 | } |
851 | 816 | ||
852 | |||
853 | /* | 817 | /* |
854 | * Digi Transmit Idle | 818 | * Digi Transmit Idle |
855 | * | 819 | * |
@@ -862,203 +826,182 @@ port_priv->dp_port_num, modem_signals ); | |||
862 | * port at a time, so its ok. | 826 | * port at a time, so its ok. |
863 | */ | 827 | */ |
864 | 828 | ||
865 | static int digi_transmit_idle( struct usb_serial_port *port, | 829 | static int digi_transmit_idle(struct usb_serial_port *port, |
866 | unsigned long timeout ) | 830 | unsigned long timeout) |
867 | { | 831 | { |
868 | |||
869 | int ret; | 832 | int ret; |
870 | unsigned char buf[2]; | 833 | unsigned char buf[2]; |
871 | struct digi_port *priv = usb_get_serial_port_data(port); | 834 | struct digi_port *priv = usb_get_serial_port_data(port); |
872 | unsigned long flags = 0; | 835 | unsigned long flags = 0; |
873 | 836 | ||
874 | 837 | spin_lock_irqsave(&priv->dp_port_lock, flags); | |
875 | spin_lock_irqsave( &priv->dp_port_lock, flags ); | ||
876 | priv->dp_transmit_idle = 0; | 838 | priv->dp_transmit_idle = 0; |
877 | spin_unlock_irqrestore( &priv->dp_port_lock, flags ); | 839 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); |
878 | 840 | ||
879 | buf[0] = DIGI_CMD_TRANSMIT_IDLE; | 841 | buf[0] = DIGI_CMD_TRANSMIT_IDLE; |
880 | buf[1] = 0; | 842 | buf[1] = 0; |
881 | 843 | ||
882 | timeout += jiffies; | 844 | timeout += jiffies; |
883 | 845 | ||
884 | if( (ret=digi_write_inb_command( port, buf, 2, timeout-jiffies )) != 0 ) | 846 | if ((ret = digi_write_inb_command(port, buf, 2, timeout - jiffies)) != 0) |
885 | return( ret ); | 847 | return ret; |
886 | 848 | ||
887 | spin_lock_irqsave( &priv->dp_port_lock, flags ); | 849 | spin_lock_irqsave(&priv->dp_port_lock, flags); |
888 | 850 | ||
889 | while( time_before(jiffies, timeout) && !priv->dp_transmit_idle ) { | 851 | while(time_before(jiffies, timeout) && !priv->dp_transmit_idle) { |
890 | cond_wait_interruptible_timeout_irqrestore( | 852 | cond_wait_interruptible_timeout_irqrestore( |
891 | &priv->dp_transmit_idle_wait, DIGI_RETRY_TIMEOUT, | 853 | &priv->dp_transmit_idle_wait, DIGI_RETRY_TIMEOUT, |
892 | &priv->dp_port_lock, flags ); | 854 | &priv->dp_port_lock, flags); |
893 | if( signal_pending(current) ) { | 855 | if (signal_pending(current)) |
894 | return( -EINTR ); | 856 | return -EINTR; |
895 | } | 857 | spin_lock_irqsave(&priv->dp_port_lock, flags); |
896 | spin_lock_irqsave( &priv->dp_port_lock, flags ); | ||
897 | } | 858 | } |
898 | |||
899 | priv->dp_transmit_idle = 0; | 859 | priv->dp_transmit_idle = 0; |
900 | spin_unlock_irqrestore( &priv->dp_port_lock, flags ); | 860 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); |
901 | 861 | return 0; | |
902 | return( 0 ); | ||
903 | 862 | ||
904 | } | 863 | } |
905 | 864 | ||
906 | 865 | ||
907 | static void digi_rx_throttle( struct usb_serial_port *port ) | 866 | static void digi_rx_throttle(struct usb_serial_port *port) |
908 | { | 867 | { |
909 | |||
910 | unsigned long flags; | 868 | unsigned long flags; |
911 | struct digi_port *priv = usb_get_serial_port_data(port); | 869 | struct digi_port *priv = usb_get_serial_port_data(port); |
912 | 870 | ||
913 | 871 | ||
914 | dbg( "digi_rx_throttle: TOP: port=%d", priv->dp_port_num ); | 872 | dbg("digi_rx_throttle: TOP: port=%d", priv->dp_port_num); |
915 | 873 | ||
916 | /* stop receiving characters by not resubmitting the read urb */ | 874 | /* stop receiving characters by not resubmitting the read urb */ |
917 | spin_lock_irqsave( &priv->dp_port_lock, flags ); | 875 | spin_lock_irqsave(&priv->dp_port_lock, flags); |
918 | priv->dp_throttled = 1; | 876 | priv->dp_throttled = 1; |
919 | priv->dp_throttle_restart = 0; | 877 | priv->dp_throttle_restart = 0; |
920 | spin_unlock_irqrestore( &priv->dp_port_lock, flags ); | 878 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); |
921 | |||
922 | } | 879 | } |
923 | 880 | ||
924 | 881 | ||
925 | static void digi_rx_unthrottle( struct usb_serial_port *port ) | 882 | static void digi_rx_unthrottle(struct usb_serial_port *port) |
926 | { | 883 | { |
927 | |||
928 | int ret = 0; | 884 | int ret = 0; |
929 | unsigned long flags; | 885 | unsigned long flags; |
930 | struct digi_port *priv = usb_get_serial_port_data(port); | 886 | struct digi_port *priv = usb_get_serial_port_data(port); |
931 | 887 | ||
932 | dbg( "digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num ); | 888 | dbg("digi_rx_unthrottle: TOP: port=%d", priv->dp_port_num); |
933 | 889 | ||
934 | spin_lock_irqsave( &priv->dp_port_lock, flags ); | 890 | spin_lock_irqsave(&priv->dp_port_lock, flags); |
935 | 891 | ||
936 | /* turn throttle off */ | 892 | /* turn throttle off */ |
937 | priv->dp_throttled = 0; | 893 | priv->dp_throttled = 0; |
938 | priv->dp_throttle_restart = 0; | 894 | priv->dp_throttle_restart = 0; |
939 | 895 | ||
940 | /* restart read chain */ | 896 | /* restart read chain */ |
941 | if( priv->dp_throttle_restart ) { | 897 | if (priv->dp_throttle_restart) { |
942 | port->read_urb->dev = port->serial->dev; | 898 | port->read_urb->dev = port->serial->dev; |
943 | ret = usb_submit_urb( port->read_urb, GFP_ATOMIC ); | 899 | ret = usb_submit_urb(port->read_urb, GFP_ATOMIC); |
944 | } | 900 | } |
945 | 901 | ||
946 | spin_unlock_irqrestore( &priv->dp_port_lock, flags ); | 902 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); |
947 | |||
948 | if( ret ) { | ||
949 | err("%s: usb_submit_urb failed, ret=%d, port=%d", __FUNCTION__, | ||
950 | ret, priv->dp_port_num ); | ||
951 | } | ||
952 | 903 | ||
904 | if (ret) | ||
905 | err("%s: usb_submit_urb failed, ret=%d, port=%d", | ||
906 | __FUNCTION__, ret, priv->dp_port_num); | ||
953 | } | 907 | } |
954 | 908 | ||
955 | 909 | ||
956 | static void digi_set_termios( struct usb_serial_port *port, | 910 | static void digi_set_termios(struct usb_serial_port *port, |
957 | struct ktermios *old_termios ) | 911 | struct ktermios *old_termios) |
958 | { | 912 | { |
959 | 913 | ||
960 | struct digi_port *priv = usb_get_serial_port_data(port); | 914 | struct digi_port *priv = usb_get_serial_port_data(port); |
961 | unsigned int iflag = port->tty->termios->c_iflag; | 915 | struct tty_struct *tty = port->tty; |
962 | unsigned int cflag = port->tty->termios->c_cflag; | 916 | unsigned int iflag = tty->termios->c_iflag; |
917 | unsigned int cflag = tty->termios->c_cflag; | ||
963 | unsigned int old_iflag = old_termios->c_iflag; | 918 | unsigned int old_iflag = old_termios->c_iflag; |
964 | unsigned int old_cflag = old_termios->c_cflag; | 919 | unsigned int old_cflag = old_termios->c_cflag; |
965 | unsigned char buf[32]; | 920 | unsigned char buf[32]; |
966 | unsigned int modem_signals; | 921 | unsigned int modem_signals; |
967 | int arg,ret; | 922 | int arg,ret; |
968 | int i = 0; | 923 | int i = 0; |
924 | speed_t baud; | ||
969 | 925 | ||
970 | 926 | dbg("digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, old_cflag=0x%x", priv->dp_port_num, iflag, old_iflag, cflag, old_cflag); | |
971 | dbg( "digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, old_cflag=0x%x", priv->dp_port_num, iflag, old_iflag, cflag, old_cflag ); | ||
972 | 927 | ||
973 | /* set baud rate */ | 928 | /* set baud rate */ |
974 | if( (cflag&CBAUD) != (old_cflag&CBAUD) ) { | 929 | if ((baud = tty_get_baud_rate(tty)) != tty_termios_baud_rate(old_termios)) { |
975 | |||
976 | arg = -1; | 930 | arg = -1; |
977 | 931 | ||
978 | /* reassert DTR and (maybe) RTS on transition from B0 */ | 932 | /* reassert DTR and (maybe) RTS on transition from B0 */ |
979 | if( (old_cflag&CBAUD) == B0 ) { | 933 | if ((old_cflag&CBAUD) == B0) { |
980 | /* don't set RTS if using hardware flow control */ | 934 | /* don't set RTS if using hardware flow control */ |
981 | /* and throttling input */ | 935 | /* and throttling input */ |
982 | modem_signals = TIOCM_DTR; | 936 | modem_signals = TIOCM_DTR; |
983 | if( !(port->tty->termios->c_cflag & CRTSCTS) || | 937 | if (!(tty->termios->c_cflag & CRTSCTS) || |
984 | !test_bit(TTY_THROTTLED, &port->tty->flags) ) { | 938 | !test_bit(TTY_THROTTLED, &tty->flags)) |
985 | modem_signals |= TIOCM_RTS; | 939 | modem_signals |= TIOCM_RTS; |
986 | } | 940 | digi_set_modem_signals(port, modem_signals, 1); |
987 | digi_set_modem_signals( port, modem_signals, 1 ); | ||
988 | } | 941 | } |
989 | 942 | switch (baud) { | |
990 | switch( (cflag&CBAUD) ) { | ||
991 | /* drop DTR and RTS on transition to B0 */ | 943 | /* drop DTR and RTS on transition to B0 */ |
992 | case B0: digi_set_modem_signals( port, 0, 1 ); break; | 944 | case 0: digi_set_modem_signals(port, 0, 1); break; |
993 | case B50: arg = DIGI_BAUD_50; break; | 945 | case 50: arg = DIGI_BAUD_50; break; |
994 | case B75: arg = DIGI_BAUD_75; break; | 946 | case 75: arg = DIGI_BAUD_75; break; |
995 | case B110: arg = DIGI_BAUD_110; break; | 947 | case 110: arg = DIGI_BAUD_110; break; |
996 | case B150: arg = DIGI_BAUD_150; break; | 948 | case 150: arg = DIGI_BAUD_150; break; |
997 | case B200: arg = DIGI_BAUD_200; break; | 949 | case 200: arg = DIGI_BAUD_200; break; |
998 | case B300: arg = DIGI_BAUD_300; break; | 950 | case 300: arg = DIGI_BAUD_300; break; |
999 | case B600: arg = DIGI_BAUD_600; break; | 951 | case 600: arg = DIGI_BAUD_600; break; |
1000 | case B1200: arg = DIGI_BAUD_1200; break; | 952 | case 1200: arg = DIGI_BAUD_1200; break; |
1001 | case B1800: arg = DIGI_BAUD_1800; break; | 953 | case 1800: arg = DIGI_BAUD_1800; break; |
1002 | case B2400: arg = DIGI_BAUD_2400; break; | 954 | case 2400: arg = DIGI_BAUD_2400; break; |
1003 | case B4800: arg = DIGI_BAUD_4800; break; | 955 | case 4800: arg = DIGI_BAUD_4800; break; |
1004 | case B9600: arg = DIGI_BAUD_9600; break; | 956 | case 9600: arg = DIGI_BAUD_9600; break; |
1005 | case B19200: arg = DIGI_BAUD_19200; break; | 957 | case 19200: arg = DIGI_BAUD_19200; break; |
1006 | case B38400: arg = DIGI_BAUD_38400; break; | 958 | case 38400: arg = DIGI_BAUD_38400; break; |
1007 | case B57600: arg = DIGI_BAUD_57600; break; | 959 | case 57600: arg = DIGI_BAUD_57600; break; |
1008 | case B115200: arg = DIGI_BAUD_115200; break; | 960 | case 115200: arg = DIGI_BAUD_115200; break; |
1009 | case B230400: arg = DIGI_BAUD_230400; break; | 961 | case 230400: arg = DIGI_BAUD_230400; break; |
1010 | case B460800: arg = DIGI_BAUD_460800; break; | 962 | case 460800: arg = DIGI_BAUD_460800; break; |
1011 | default: | 963 | default: |
1012 | dbg( "digi_set_termios: can't handle baud rate 0x%x", | 964 | arg = DIGI_BAUD_9600; |
1013 | (cflag&CBAUD) ); | 965 | baud = 9600; |
1014 | break; | 966 | break; |
1015 | } | 967 | } |
1016 | 968 | if (arg != -1) { | |
1017 | if( arg != -1 ) { | ||
1018 | buf[i++] = DIGI_CMD_SET_BAUD_RATE; | 969 | buf[i++] = DIGI_CMD_SET_BAUD_RATE; |
1019 | buf[i++] = priv->dp_port_num; | 970 | buf[i++] = priv->dp_port_num; |
1020 | buf[i++] = arg; | 971 | buf[i++] = arg; |
1021 | buf[i++] = 0; | 972 | buf[i++] = 0; |
1022 | } | 973 | } |
1023 | |||
1024 | } | 974 | } |
1025 | |||
1026 | /* set parity */ | 975 | /* set parity */ |
1027 | if( (cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD)) ) { | 976 | if ((cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD))) { |
1028 | 977 | if (cflag&PARENB) { | |
1029 | if( (cflag&PARENB) ) { | 978 | if (cflag&PARODD) |
1030 | if( (cflag&PARODD) ) | ||
1031 | arg = DIGI_PARITY_ODD; | 979 | arg = DIGI_PARITY_ODD; |
1032 | else | 980 | else |
1033 | arg = DIGI_PARITY_EVEN; | 981 | arg = DIGI_PARITY_EVEN; |
1034 | } else { | 982 | } else { |
1035 | arg = DIGI_PARITY_NONE; | 983 | arg = DIGI_PARITY_NONE; |
1036 | } | 984 | } |
1037 | |||
1038 | buf[i++] = DIGI_CMD_SET_PARITY; | 985 | buf[i++] = DIGI_CMD_SET_PARITY; |
1039 | buf[i++] = priv->dp_port_num; | 986 | buf[i++] = priv->dp_port_num; |
1040 | buf[i++] = arg; | 987 | buf[i++] = arg; |
1041 | buf[i++] = 0; | 988 | buf[i++] = 0; |
1042 | |||
1043 | } | 989 | } |
1044 | |||
1045 | /* set word size */ | 990 | /* set word size */ |
1046 | if( (cflag&CSIZE) != (old_cflag&CSIZE) ) { | 991 | if ((cflag&CSIZE) != (old_cflag&CSIZE)) { |
1047 | |||
1048 | arg = -1; | 992 | arg = -1; |
1049 | 993 | switch (cflag&CSIZE) { | |
1050 | switch( (cflag&CSIZE) ) { | ||
1051 | case CS5: arg = DIGI_WORD_SIZE_5; break; | 994 | case CS5: arg = DIGI_WORD_SIZE_5; break; |
1052 | case CS6: arg = DIGI_WORD_SIZE_6; break; | 995 | case CS6: arg = DIGI_WORD_SIZE_6; break; |
1053 | case CS7: arg = DIGI_WORD_SIZE_7; break; | 996 | case CS7: arg = DIGI_WORD_SIZE_7; break; |
1054 | case CS8: arg = DIGI_WORD_SIZE_8; break; | 997 | case CS8: arg = DIGI_WORD_SIZE_8; break; |
1055 | default: | 998 | default: |
1056 | dbg( "digi_set_termios: can't handle word size %d", | 999 | dbg("digi_set_termios: can't handle word size %d", |
1057 | (cflag&CSIZE) ); | 1000 | (cflag&CSIZE)); |
1058 | break; | 1001 | break; |
1059 | } | 1002 | } |
1060 | 1003 | ||
1061 | if( arg != -1 ) { | 1004 | if (arg != -1) { |
1062 | buf[i++] = DIGI_CMD_SET_WORD_SIZE; | 1005 | buf[i++] = DIGI_CMD_SET_WORD_SIZE; |
1063 | buf[i++] = priv->dp_port_num; | 1006 | buf[i++] = priv->dp_port_num; |
1064 | buf[i++] = arg; | 1007 | buf[i++] = arg; |
@@ -1068,9 +1011,9 @@ dbg( "digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, ol | |||
1068 | } | 1011 | } |
1069 | 1012 | ||
1070 | /* set stop bits */ | 1013 | /* set stop bits */ |
1071 | if( (cflag&CSTOPB) != (old_cflag&CSTOPB) ) { | 1014 | if ((cflag&CSTOPB) != (old_cflag&CSTOPB)) { |
1072 | 1015 | ||
1073 | if( (cflag&CSTOPB) ) | 1016 | if ((cflag&CSTOPB)) |
1074 | arg = DIGI_STOP_BITS_2; | 1017 | arg = DIGI_STOP_BITS_2; |
1075 | else | 1018 | else |
1076 | arg = DIGI_STOP_BITS_1; | 1019 | arg = DIGI_STOP_BITS_1; |
@@ -1083,18 +1026,15 @@ dbg( "digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, ol | |||
1083 | } | 1026 | } |
1084 | 1027 | ||
1085 | /* set input flow control */ | 1028 | /* set input flow control */ |
1086 | if( (iflag&IXOFF) != (old_iflag&IXOFF) | 1029 | if ((iflag&IXOFF) != (old_iflag&IXOFF) |
1087 | || (cflag&CRTSCTS) != (old_cflag&CRTSCTS) ) { | 1030 | || (cflag&CRTSCTS) != (old_cflag&CRTSCTS)) { |
1088 | |||
1089 | arg = 0; | 1031 | arg = 0; |
1090 | 1032 | if (iflag&IXOFF) | |
1091 | if( (iflag&IXOFF) ) | ||
1092 | arg |= DIGI_INPUT_FLOW_CONTROL_XON_XOFF; | 1033 | arg |= DIGI_INPUT_FLOW_CONTROL_XON_XOFF; |
1093 | else | 1034 | else |
1094 | arg &= ~DIGI_INPUT_FLOW_CONTROL_XON_XOFF; | 1035 | arg &= ~DIGI_INPUT_FLOW_CONTROL_XON_XOFF; |
1095 | 1036 | ||
1096 | if( (cflag&CRTSCTS) ) { | 1037 | if (cflag&CRTSCTS) { |
1097 | |||
1098 | arg |= DIGI_INPUT_FLOW_CONTROL_RTS; | 1038 | arg |= DIGI_INPUT_FLOW_CONTROL_RTS; |
1099 | 1039 | ||
1100 | /* On USB-4 it is necessary to assert RTS prior */ | 1040 | /* On USB-4 it is necessary to assert RTS prior */ |
@@ -1107,43 +1047,37 @@ dbg( "digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, ol | |||
1107 | } else { | 1047 | } else { |
1108 | arg &= ~DIGI_INPUT_FLOW_CONTROL_RTS; | 1048 | arg &= ~DIGI_INPUT_FLOW_CONTROL_RTS; |
1109 | } | 1049 | } |
1110 | |||
1111 | buf[i++] = DIGI_CMD_SET_INPUT_FLOW_CONTROL; | 1050 | buf[i++] = DIGI_CMD_SET_INPUT_FLOW_CONTROL; |
1112 | buf[i++] = priv->dp_port_num; | 1051 | buf[i++] = priv->dp_port_num; |
1113 | buf[i++] = arg; | 1052 | buf[i++] = arg; |
1114 | buf[i++] = 0; | 1053 | buf[i++] = 0; |
1115 | |||
1116 | } | 1054 | } |
1117 | 1055 | ||
1118 | /* set output flow control */ | 1056 | /* set output flow control */ |
1119 | if( (iflag&IXON) != (old_iflag&IXON) | 1057 | if ((iflag&IXON) != (old_iflag&IXON) |
1120 | || (cflag&CRTSCTS) != (old_cflag&CRTSCTS) ) { | 1058 | || (cflag&CRTSCTS) != (old_cflag&CRTSCTS)) { |
1121 | |||
1122 | arg = 0; | 1059 | arg = 0; |
1123 | 1060 | if (iflag&IXON) | |
1124 | if( (iflag&IXON) ) | ||
1125 | arg |= DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF; | 1061 | arg |= DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF; |
1126 | else | 1062 | else |
1127 | arg &= ~DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF; | 1063 | arg &= ~DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF; |
1128 | 1064 | ||
1129 | if( (cflag&CRTSCTS) ) { | 1065 | if (cflag&CRTSCTS) { |
1130 | arg |= DIGI_OUTPUT_FLOW_CONTROL_CTS; | 1066 | arg |= DIGI_OUTPUT_FLOW_CONTROL_CTS; |
1131 | } else { | 1067 | } else { |
1132 | arg &= ~DIGI_OUTPUT_FLOW_CONTROL_CTS; | 1068 | arg &= ~DIGI_OUTPUT_FLOW_CONTROL_CTS; |
1133 | port->tty->hw_stopped = 0; | 1069 | tty->hw_stopped = 0; |
1134 | } | 1070 | } |
1135 | 1071 | ||
1136 | buf[i++] = DIGI_CMD_SET_OUTPUT_FLOW_CONTROL; | 1072 | buf[i++] = DIGI_CMD_SET_OUTPUT_FLOW_CONTROL; |
1137 | buf[i++] = priv->dp_port_num; | 1073 | buf[i++] = priv->dp_port_num; |
1138 | buf[i++] = arg; | 1074 | buf[i++] = arg; |
1139 | buf[i++] = 0; | 1075 | buf[i++] = 0; |
1140 | |||
1141 | } | 1076 | } |
1142 | 1077 | ||
1143 | /* set receive enable/disable */ | 1078 | /* set receive enable/disable */ |
1144 | if( (cflag&CREAD) != (old_cflag&CREAD) ) { | 1079 | if ((cflag&CREAD) != (old_cflag&CREAD)) { |
1145 | 1080 | if (cflag&CREAD) | |
1146 | if( (cflag&CREAD) ) | ||
1147 | arg = DIGI_ENABLE; | 1081 | arg = DIGI_ENABLE; |
1148 | else | 1082 | else |
1149 | arg = DIGI_DISABLE; | 1083 | arg = DIGI_DISABLE; |
@@ -1152,32 +1086,26 @@ dbg( "digi_set_termios: TOP: port=%d, iflag=0x%x, old_iflag=0x%x, cflag=0x%x, ol | |||
1152 | buf[i++] = priv->dp_port_num; | 1086 | buf[i++] = priv->dp_port_num; |
1153 | buf[i++] = arg; | 1087 | buf[i++] = arg; |
1154 | buf[i++] = 0; | 1088 | buf[i++] = 0; |
1155 | |||
1156 | } | 1089 | } |
1157 | 1090 | if ((ret = digi_write_oob_command(port, buf, i, 1)) != 0) | |
1158 | if( (ret=digi_write_oob_command( port, buf, i, 1 )) != 0 ) | 1091 | dbg("digi_set_termios: write oob failed, ret=%d", ret); |
1159 | dbg( "digi_set_termios: write oob failed, ret=%d", ret ); | ||
1160 | 1092 | ||
1161 | } | 1093 | } |
1162 | 1094 | ||
1163 | 1095 | ||
1164 | static void digi_break_ctl( struct usb_serial_port *port, int break_state ) | 1096 | static void digi_break_ctl(struct usb_serial_port *port, int break_state) |
1165 | { | 1097 | { |
1166 | |||
1167 | unsigned char buf[4]; | 1098 | unsigned char buf[4]; |
1168 | 1099 | ||
1169 | |||
1170 | buf[0] = DIGI_CMD_BREAK_CONTROL; | 1100 | buf[0] = DIGI_CMD_BREAK_CONTROL; |
1171 | buf[1] = 2; /* length */ | 1101 | buf[1] = 2; /* length */ |
1172 | buf[2] = break_state ? 1 : 0; | 1102 | buf[2] = break_state ? 1 : 0; |
1173 | buf[3] = 0; /* pad */ | 1103 | buf[3] = 0; /* pad */ |
1174 | 1104 | digi_write_inb_command(port, buf, 4, 0); | |
1175 | digi_write_inb_command( port, buf, 4, 0 ); | ||
1176 | |||
1177 | } | 1105 | } |
1178 | 1106 | ||
1179 | 1107 | ||
1180 | static int digi_tiocmget( struct usb_serial_port *port, struct file *file ) | 1108 | static int digi_tiocmget(struct usb_serial_port *port, struct file *file) |
1181 | { | 1109 | { |
1182 | struct digi_port *priv = usb_get_serial_port_data(port); | 1110 | struct digi_port *priv = usb_get_serial_port_data(port); |
1183 | unsigned int val; | 1111 | unsigned int val; |
@@ -1185,15 +1113,15 @@ static int digi_tiocmget( struct usb_serial_port *port, struct file *file ) | |||
1185 | 1113 | ||
1186 | dbg("%s: TOP: port=%d", __FUNCTION__, priv->dp_port_num); | 1114 | dbg("%s: TOP: port=%d", __FUNCTION__, priv->dp_port_num); |
1187 | 1115 | ||
1188 | spin_lock_irqsave( &priv->dp_port_lock, flags ); | 1116 | spin_lock_irqsave(&priv->dp_port_lock, flags); |
1189 | val = priv->dp_modem_signals; | 1117 | val = priv->dp_modem_signals; |
1190 | spin_unlock_irqrestore( &priv->dp_port_lock, flags ); | 1118 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); |
1191 | return val; | 1119 | return val; |
1192 | } | 1120 | } |
1193 | 1121 | ||
1194 | 1122 | ||
1195 | static int digi_tiocmset( struct usb_serial_port *port, struct file *file, | 1123 | static int digi_tiocmset(struct usb_serial_port *port, struct file *file, |
1196 | unsigned int set, unsigned int clear ) | 1124 | unsigned int set, unsigned int clear) |
1197 | { | 1125 | { |
1198 | struct digi_port *priv = usb_get_serial_port_data(port); | 1126 | struct digi_port *priv = usb_get_serial_port_data(port); |
1199 | unsigned int val; | 1127 | unsigned int val; |
@@ -1201,41 +1129,34 @@ static int digi_tiocmset( struct usb_serial_port *port, struct file *file, | |||
1201 | 1129 | ||
1202 | dbg("%s: TOP: port=%d", __FUNCTION__, priv->dp_port_num); | 1130 | dbg("%s: TOP: port=%d", __FUNCTION__, priv->dp_port_num); |
1203 | 1131 | ||
1204 | spin_lock_irqsave( &priv->dp_port_lock, flags ); | 1132 | spin_lock_irqsave(&priv->dp_port_lock, flags); |
1205 | val = (priv->dp_modem_signals & ~clear) | set; | 1133 | val = (priv->dp_modem_signals & ~clear) | set; |
1206 | spin_unlock_irqrestore( &priv->dp_port_lock, flags ); | 1134 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); |
1207 | return digi_set_modem_signals( port, val, 1 ); | 1135 | return digi_set_modem_signals(port, val, 1); |
1208 | } | 1136 | } |
1209 | 1137 | ||
1210 | 1138 | ||
1211 | static int digi_ioctl( struct usb_serial_port *port, struct file *file, | 1139 | static int digi_ioctl(struct usb_serial_port *port, struct file *file, |
1212 | unsigned int cmd, unsigned long arg ) | 1140 | unsigned int cmd, unsigned long arg) |
1213 | { | 1141 | { |
1214 | |||
1215 | struct digi_port *priv = usb_get_serial_port_data(port); | 1142 | struct digi_port *priv = usb_get_serial_port_data(port); |
1216 | 1143 | dbg("digi_ioctl: TOP: port=%d, cmd=0x%x", priv->dp_port_num, cmd); | |
1217 | dbg( "digi_ioctl: TOP: port=%d, cmd=0x%x", priv->dp_port_num, cmd ); | ||
1218 | 1144 | ||
1219 | switch (cmd) { | 1145 | switch (cmd) { |
1220 | |||
1221 | case TIOCMIWAIT: | 1146 | case TIOCMIWAIT: |
1222 | /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/ | 1147 | /* wait for any of the 4 modem inputs (DCD,RI,DSR,CTS)*/ |
1223 | /* TODO */ | 1148 | /* TODO */ |
1224 | return( 0 ); | 1149 | return 0; |
1225 | |||
1226 | case TIOCGICOUNT: | 1150 | case TIOCGICOUNT: |
1227 | /* return count of modemline transitions */ | 1151 | /* return count of modemline transitions */ |
1228 | /* TODO */ | 1152 | /* TODO */ |
1229 | return 0; | 1153 | return 0; |
1230 | |||
1231 | } | 1154 | } |
1232 | 1155 | return -ENOIOCTLCMD; | |
1233 | return( -ENOIOCTLCMD ); | ||
1234 | 1156 | ||
1235 | } | 1157 | } |
1236 | 1158 | ||
1237 | 1159 | static int digi_write(struct usb_serial_port *port, const unsigned char *buf, int count) | |
1238 | static int digi_write( struct usb_serial_port *port, const unsigned char *buf, int count ) | ||
1239 | { | 1160 | { |
1240 | 1161 | ||
1241 | int ret,data_len,new_len; | 1162 | int ret,data_len,new_len; |
@@ -1243,35 +1164,29 @@ static int digi_write( struct usb_serial_port *port, const unsigned char *buf, i | |||
1243 | unsigned char *data = port->write_urb->transfer_buffer; | 1164 | unsigned char *data = port->write_urb->transfer_buffer; |
1244 | unsigned long flags = 0; | 1165 | unsigned long flags = 0; |
1245 | 1166 | ||
1246 | 1167 | dbg("digi_write: TOP: port=%d, count=%d, in_interrupt=%ld", | |
1247 | dbg( "digi_write: TOP: port=%d, count=%d, in_interrupt=%ld", | 1168 | priv->dp_port_num, count, in_interrupt()); |
1248 | priv->dp_port_num, count, in_interrupt() ); | ||
1249 | 1169 | ||
1250 | /* copy user data (which can sleep) before getting spin lock */ | 1170 | /* copy user data (which can sleep) before getting spin lock */ |
1251 | count = min( count, port->bulk_out_size-2 ); | 1171 | count = min(count, port->bulk_out_size-2); |
1252 | count = min( 64, count); | 1172 | count = min(64, count); |
1253 | 1173 | ||
1254 | /* be sure only one write proceeds at a time */ | 1174 | /* be sure only one write proceeds at a time */ |
1255 | /* there are races on the port private buffer */ | 1175 | /* there are races on the port private buffer */ |
1256 | /* and races to check write_urb->status */ | 1176 | /* and races to check write_urb->status */ |
1257 | spin_lock_irqsave( &priv->dp_port_lock, flags ); | 1177 | spin_lock_irqsave(&priv->dp_port_lock, flags); |
1258 | 1178 | ||
1259 | /* wait for urb status clear to submit another urb */ | 1179 | /* wait for urb status clear to submit another urb */ |
1260 | if( port->write_urb->status == -EINPROGRESS | 1180 | if (port->write_urb->status == -EINPROGRESS || priv->dp_write_urb_in_use) { |
1261 | || priv->dp_write_urb_in_use ) { | ||
1262 | |||
1263 | /* buffer data if count is 1 (probably put_char) if possible */ | 1181 | /* buffer data if count is 1 (probably put_char) if possible */ |
1264 | if( count == 1 && priv->dp_out_buf_len < DIGI_OUT_BUF_SIZE ) { | 1182 | if (count == 1 && priv->dp_out_buf_len < DIGI_OUT_BUF_SIZE) { |
1265 | priv->dp_out_buf[priv->dp_out_buf_len++] = *buf; | 1183 | priv->dp_out_buf[priv->dp_out_buf_len++] = *buf; |
1266 | new_len = 1; | 1184 | new_len = 1; |
1267 | } else { | 1185 | } else { |
1268 | new_len = 0; | 1186 | new_len = 0; |
1269 | } | 1187 | } |
1270 | 1188 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); | |
1271 | spin_unlock_irqrestore( &priv->dp_port_lock, flags ); | 1189 | return new_len; |
1272 | |||
1273 | return( new_len ); | ||
1274 | |||
1275 | } | 1190 | } |
1276 | 1191 | ||
1277 | /* allow space for any buffered data and for new data, up to */ | 1192 | /* allow space for any buffered data and for new data, up to */ |
@@ -1279,9 +1194,9 @@ priv->dp_port_num, count, in_interrupt() ); | |||
1279 | new_len = min(count, port->bulk_out_size-2-priv->dp_out_buf_len); | 1194 | new_len = min(count, port->bulk_out_size-2-priv->dp_out_buf_len); |
1280 | data_len = new_len + priv->dp_out_buf_len; | 1195 | data_len = new_len + priv->dp_out_buf_len; |
1281 | 1196 | ||
1282 | if( data_len == 0 ) { | 1197 | if (data_len == 0) { |
1283 | spin_unlock_irqrestore( &priv->dp_port_lock, flags ); | 1198 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); |
1284 | return( 0 ); | 1199 | return 0; |
1285 | } | 1200 | } |
1286 | 1201 | ||
1287 | port->write_urb->transfer_buffer_length = data_len+2; | 1202 | port->write_urb->transfer_buffer_length = data_len+2; |
@@ -1291,32 +1206,29 @@ priv->dp_port_num, count, in_interrupt() ); | |||
1291 | *data++ = data_len; | 1206 | *data++ = data_len; |
1292 | 1207 | ||
1293 | /* copy in buffered data first */ | 1208 | /* copy in buffered data first */ |
1294 | memcpy( data, priv->dp_out_buf, priv->dp_out_buf_len ); | 1209 | memcpy(data, priv->dp_out_buf, priv->dp_out_buf_len); |
1295 | data += priv->dp_out_buf_len; | 1210 | data += priv->dp_out_buf_len; |
1296 | 1211 | ||
1297 | /* copy in new data */ | 1212 | /* copy in new data */ |
1298 | memcpy( data, buf, new_len ); | 1213 | memcpy(data, buf, new_len); |
1299 | 1214 | ||
1300 | if( (ret=usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0 ) { | 1215 | if ((ret = usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0) { |
1301 | priv->dp_write_urb_in_use = 1; | 1216 | priv->dp_write_urb_in_use = 1; |
1302 | ret = new_len; | 1217 | ret = new_len; |
1303 | priv->dp_out_buf_len = 0; | 1218 | priv->dp_out_buf_len = 0; |
1304 | } | 1219 | } |
1305 | 1220 | ||
1306 | /* return length of new data written, or error */ | 1221 | /* return length of new data written, or error */ |
1307 | spin_unlock_irqrestore( &priv->dp_port_lock, flags ); | 1222 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); |
1308 | if( ret < 0 ) { | 1223 | if (ret < 0) |
1309 | err("%s: usb_submit_urb failed, ret=%d, port=%d", __FUNCTION__, | 1224 | err("%s: usb_submit_urb failed, ret=%d, port=%d", |
1310 | ret, priv->dp_port_num ); | 1225 | __FUNCTION__, ret, priv->dp_port_num); |
1311 | } | 1226 | dbg("digi_write: returning %d", ret); |
1312 | 1227 | return ret; | |
1313 | dbg( "digi_write: returning %d", ret ); | ||
1314 | return( ret ); | ||
1315 | 1228 | ||
1316 | } | 1229 | } |
1317 | 1230 | ||
1318 | 1231 | static void digi_write_bulk_callback(struct urb *urb) | |
1319 | static void digi_write_bulk_callback( struct urb *urb ) | ||
1320 | { | 1232 | { |
1321 | 1233 | ||
1322 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | 1234 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; |
@@ -1326,153 +1238,136 @@ static void digi_write_bulk_callback( struct urb *urb ) | |||
1326 | int ret = 0; | 1238 | int ret = 0; |
1327 | int status = urb->status; | 1239 | int status = urb->status; |
1328 | 1240 | ||
1329 | 1241 | dbg("digi_write_bulk_callback: TOP, urb->status=%d", status); | |
1330 | dbg("digi_write_bulk_callback: TOP, urb status=%d", status); | ||
1331 | 1242 | ||
1332 | /* port and serial sanity check */ | 1243 | /* port and serial sanity check */ |
1333 | if( port == NULL || (priv=usb_get_serial_port_data(port)) == NULL ) { | 1244 | if (port == NULL || (priv=usb_get_serial_port_data(port)) == NULL) { |
1334 | err("%s: port or port->private is NULL, status=%d", | 1245 | err("%s: port or port->private is NULL, status=%d", |
1335 | __FUNCTION__, status); | 1246 | __FUNCTION__, status); |
1336 | return; | 1247 | return; |
1337 | } | 1248 | } |
1338 | serial = port->serial; | 1249 | serial = port->serial; |
1339 | if( serial == NULL || (serial_priv=usb_get_serial_data(serial)) == NULL ) { | 1250 | if (serial == NULL || (serial_priv=usb_get_serial_data(serial)) == NULL) { |
1340 | err("%s: serial or serial->private is NULL, status=%d", | 1251 | err("%s: serial or serial->private is NULL, status=%d", |
1341 | __FUNCTION__, status); | 1252 | __FUNCTION__, status); |
1342 | return; | 1253 | return; |
1343 | } | 1254 | } |
1344 | 1255 | ||
1345 | /* handle oob callback */ | 1256 | /* handle oob callback */ |
1346 | if( priv->dp_port_num == serial_priv->ds_oob_port_num ) { | 1257 | if (priv->dp_port_num == serial_priv->ds_oob_port_num) { |
1347 | dbg( "digi_write_bulk_callback: oob callback" ); | 1258 | dbg("digi_write_bulk_callback: oob callback"); |
1348 | spin_lock( &priv->dp_port_lock ); | 1259 | spin_lock(&priv->dp_port_lock); |
1349 | priv->dp_write_urb_in_use = 0; | 1260 | priv->dp_write_urb_in_use = 0; |
1350 | wake_up_interruptible( &port->write_wait ); | 1261 | wake_up_interruptible(&port->write_wait); |
1351 | spin_unlock( &priv->dp_port_lock ); | 1262 | spin_unlock(&priv->dp_port_lock); |
1352 | return; | 1263 | return; |
1353 | } | 1264 | } |
1354 | 1265 | ||
1355 | /* try to send any buffered data on this port, if it is open */ | 1266 | /* try to send any buffered data on this port, if it is open */ |
1356 | spin_lock( &priv->dp_port_lock ); | 1267 | spin_lock(&priv->dp_port_lock); |
1357 | priv->dp_write_urb_in_use = 0; | 1268 | priv->dp_write_urb_in_use = 0; |
1358 | if( port->open_count && port->write_urb->status != -EINPROGRESS | 1269 | if (port->open_count && port->write_urb->status != -EINPROGRESS |
1359 | && priv->dp_out_buf_len > 0 ) { | 1270 | && priv->dp_out_buf_len > 0) { |
1360 | |||
1361 | *((unsigned char *)(port->write_urb->transfer_buffer)) | 1271 | *((unsigned char *)(port->write_urb->transfer_buffer)) |
1362 | = (unsigned char)DIGI_CMD_SEND_DATA; | 1272 | = (unsigned char)DIGI_CMD_SEND_DATA; |
1363 | *((unsigned char *)(port->write_urb->transfer_buffer)+1) | 1273 | *((unsigned char *)(port->write_urb->transfer_buffer)+1) |
1364 | = (unsigned char)priv->dp_out_buf_len; | 1274 | = (unsigned char)priv->dp_out_buf_len; |
1365 | 1275 | port->write_urb->transfer_buffer_length = priv->dp_out_buf_len+2; | |
1366 | port->write_urb->transfer_buffer_length | ||
1367 | = priv->dp_out_buf_len+2; | ||
1368 | port->write_urb->dev = serial->dev; | 1276 | port->write_urb->dev = serial->dev; |
1369 | 1277 | memcpy(port->write_urb->transfer_buffer+2, priv->dp_out_buf, | |
1370 | memcpy( port->write_urb->transfer_buffer+2, priv->dp_out_buf, | 1278 | priv->dp_out_buf_len); |
1371 | priv->dp_out_buf_len ); | 1279 | if ((ret = usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0) { |
1372 | |||
1373 | if( (ret=usb_submit_urb(port->write_urb, GFP_ATOMIC)) == 0 ) { | ||
1374 | priv->dp_write_urb_in_use = 1; | 1280 | priv->dp_write_urb_in_use = 1; |
1375 | priv->dp_out_buf_len = 0; | 1281 | priv->dp_out_buf_len = 0; |
1376 | } | 1282 | } |
1377 | |||
1378 | } | 1283 | } |
1379 | |||
1380 | /* wake up processes sleeping on writes immediately */ | 1284 | /* wake up processes sleeping on writes immediately */ |
1381 | digi_wakeup_write( port ); | 1285 | digi_wakeup_write(port); |
1382 | |||
1383 | /* also queue up a wakeup at scheduler time, in case we */ | 1286 | /* also queue up a wakeup at scheduler time, in case we */ |
1384 | /* lost the race in write_chan(). */ | 1287 | /* lost the race in write_chan(). */ |
1385 | schedule_work(&priv->dp_wakeup_work); | 1288 | schedule_work(&priv->dp_wakeup_work); |
1386 | 1289 | ||
1387 | spin_unlock( &priv->dp_port_lock ); | 1290 | spin_unlock(&priv->dp_port_lock); |
1388 | 1291 | if (ret) | |
1389 | if( ret ) { | 1292 | err("%s: usb_submit_urb failed, ret=%d, port=%d", |
1390 | err("%s: usb_submit_urb failed, ret=%d, port=%d", __FUNCTION__, | 1293 | __FUNCTION__, ret, priv->dp_port_num); |
1391 | ret, priv->dp_port_num ); | ||
1392 | } | ||
1393 | |||
1394 | } | 1294 | } |
1395 | 1295 | ||
1396 | 1296 | static int digi_write_room(struct usb_serial_port *port) | |
1397 | static int digi_write_room( struct usb_serial_port *port ) | ||
1398 | { | 1297 | { |
1399 | 1298 | ||
1400 | int room; | 1299 | int room; |
1401 | struct digi_port *priv = usb_get_serial_port_data(port); | 1300 | struct digi_port *priv = usb_get_serial_port_data(port); |
1402 | unsigned long flags = 0; | 1301 | unsigned long flags = 0; |
1403 | 1302 | ||
1303 | spin_lock_irqsave(&priv->dp_port_lock, flags); | ||
1404 | 1304 | ||
1405 | spin_lock_irqsave( &priv->dp_port_lock, flags ); | 1305 | if (port->write_urb->status == -EINPROGRESS || priv->dp_write_urb_in_use) |
1406 | |||
1407 | if( port->write_urb->status == -EINPROGRESS | ||
1408 | || priv->dp_write_urb_in_use ) | ||
1409 | room = 0; | 1306 | room = 0; |
1410 | else | 1307 | else |
1411 | room = port->bulk_out_size - 2 - priv->dp_out_buf_len; | 1308 | room = port->bulk_out_size - 2 - priv->dp_out_buf_len; |
1412 | 1309 | ||
1413 | spin_unlock_irqrestore( &priv->dp_port_lock, flags ); | 1310 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); |
1414 | 1311 | dbg("digi_write_room: port=%d, room=%d", priv->dp_port_num, room); | |
1415 | dbg( "digi_write_room: port=%d, room=%d", priv->dp_port_num, room ); | 1312 | return room; |
1416 | return( room ); | ||
1417 | 1313 | ||
1418 | } | 1314 | } |
1419 | 1315 | ||
1420 | 1316 | static int digi_chars_in_buffer(struct usb_serial_port *port) | |
1421 | static int digi_chars_in_buffer( struct usb_serial_port *port ) | ||
1422 | { | 1317 | { |
1423 | 1318 | ||
1424 | struct digi_port *priv = usb_get_serial_port_data(port); | 1319 | struct digi_port *priv = usb_get_serial_port_data(port); |
1425 | 1320 | ||
1426 | 1321 | ||
1427 | if( port->write_urb->status == -EINPROGRESS | 1322 | if (port->write_urb->status == -EINPROGRESS |
1428 | || priv->dp_write_urb_in_use ) { | 1323 | || priv->dp_write_urb_in_use) { |
1429 | dbg( "digi_chars_in_buffer: port=%d, chars=%d", priv->dp_port_num, port->bulk_out_size - 2 ); | 1324 | dbg("digi_chars_in_buffer: port=%d, chars=%d", |
1430 | /* return( port->bulk_out_size - 2 ); */ | 1325 | priv->dp_port_num, port->bulk_out_size - 2); |
1431 | return( 256 ); | 1326 | /* return(port->bulk_out_size - 2); */ |
1327 | return 256; | ||
1432 | } else { | 1328 | } else { |
1433 | dbg( "digi_chars_in_buffer: port=%d, chars=%d", priv->dp_port_num, priv->dp_out_buf_len ); | 1329 | dbg("digi_chars_in_buffer: port=%d, chars=%d", |
1434 | return( priv->dp_out_buf_len ); | 1330 | priv->dp_port_num, priv->dp_out_buf_len); |
1331 | return priv->dp_out_buf_len; | ||
1435 | } | 1332 | } |
1436 | 1333 | ||
1437 | } | 1334 | } |
1438 | 1335 | ||
1439 | 1336 | ||
1440 | static int digi_open( struct usb_serial_port *port, struct file *filp ) | 1337 | static int digi_open(struct usb_serial_port *port, struct file *filp) |
1441 | { | 1338 | { |
1442 | |||
1443 | int ret; | 1339 | int ret; |
1444 | unsigned char buf[32]; | 1340 | unsigned char buf[32]; |
1445 | struct digi_port *priv = usb_get_serial_port_data(port); | 1341 | struct digi_port *priv = usb_get_serial_port_data(port); |
1446 | struct ktermios not_termios; | 1342 | struct ktermios not_termios; |
1447 | unsigned long flags = 0; | 1343 | unsigned long flags = 0; |
1448 | 1344 | ||
1449 | 1345 | dbg("digi_open: TOP: port=%d, open_count=%d", | |
1450 | dbg( "digi_open: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_count ); | 1346 | priv->dp_port_num, port->open_count); |
1451 | 1347 | ||
1452 | /* be sure the device is started up */ | 1348 | /* be sure the device is started up */ |
1453 | if( digi_startup_device( port->serial ) != 0 ) | 1349 | if (digi_startup_device(port->serial) != 0) |
1454 | return( -ENXIO ); | 1350 | return -ENXIO; |
1455 | 1351 | ||
1456 | spin_lock_irqsave( &priv->dp_port_lock, flags ); | 1352 | spin_lock_irqsave(&priv->dp_port_lock, flags); |
1457 | 1353 | ||
1458 | /* don't wait on a close in progress for non-blocking opens */ | 1354 | /* don't wait on a close in progress for non-blocking opens */ |
1459 | if( priv->dp_in_close && (filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0 ) { | 1355 | if (priv->dp_in_close && (filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0) { |
1460 | spin_unlock_irqrestore( &priv->dp_port_lock, flags ); | 1356 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); |
1461 | return( -EAGAIN ); | 1357 | return -EAGAIN; |
1462 | } | 1358 | } |
1463 | 1359 | ||
1464 | /* wait for a close in progress to finish */ | 1360 | /* wait for a close in progress to finish */ |
1465 | while( priv->dp_in_close ) { | 1361 | while(priv->dp_in_close) { |
1466 | cond_wait_interruptible_timeout_irqrestore( | 1362 | cond_wait_interruptible_timeout_irqrestore( |
1467 | &priv->dp_close_wait, DIGI_RETRY_TIMEOUT, | 1363 | &priv->dp_close_wait, DIGI_RETRY_TIMEOUT, |
1468 | &priv->dp_port_lock, flags ); | 1364 | &priv->dp_port_lock, flags); |
1469 | if( signal_pending(current) ) { | 1365 | if (signal_pending(current)) |
1470 | return( -EINTR ); | 1366 | return -EINTR; |
1471 | } | 1367 | spin_lock_irqsave(&priv->dp_port_lock, flags); |
1472 | spin_lock_irqsave( &priv->dp_port_lock, flags ); | ||
1473 | } | 1368 | } |
1474 | 1369 | ||
1475 | spin_unlock_irqrestore( &priv->dp_port_lock, flags ); | 1370 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); |
1476 | 1371 | ||
1477 | /* read modem signals automatically whenever they change */ | 1372 | /* read modem signals automatically whenever they change */ |
1478 | buf[0] = DIGI_CMD_READ_INPUT_SIGNALS; | 1373 | buf[0] = DIGI_CMD_READ_INPUT_SIGNALS; |
@@ -1486,23 +1381,22 @@ dbg( "digi_open: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_cou | |||
1486 | buf[6] = DIGI_FLUSH_TX | DIGI_FLUSH_RX; | 1381 | buf[6] = DIGI_FLUSH_TX | DIGI_FLUSH_RX; |
1487 | buf[7] = 0; | 1382 | buf[7] = 0; |
1488 | 1383 | ||
1489 | if( (ret=digi_write_oob_command( port, buf, 8, 1 )) != 0 ) | 1384 | if ((ret = digi_write_oob_command(port, buf, 8, 1)) != 0) |
1490 | dbg( "digi_open: write oob failed, ret=%d", ret ); | 1385 | dbg("digi_open: write oob failed, ret=%d", ret); |
1491 | 1386 | ||
1492 | /* set termios settings */ | 1387 | /* set termios settings */ |
1493 | not_termios.c_cflag = ~port->tty->termios->c_cflag; | 1388 | not_termios.c_cflag = ~port->tty->termios->c_cflag; |
1494 | not_termios.c_iflag = ~port->tty->termios->c_iflag; | 1389 | not_termios.c_iflag = ~port->tty->termios->c_iflag; |
1495 | digi_set_termios( port, ¬_termios ); | 1390 | digi_set_termios(port, ¬_termios); |
1496 | 1391 | ||
1497 | /* set DTR and RTS */ | 1392 | /* set DTR and RTS */ |
1498 | digi_set_modem_signals( port, TIOCM_DTR|TIOCM_RTS, 1 ); | 1393 | digi_set_modem_signals(port, TIOCM_DTR|TIOCM_RTS, 1); |
1499 | |||
1500 | return( 0 ); | ||
1501 | 1394 | ||
1395 | return 0; | ||
1502 | } | 1396 | } |
1503 | 1397 | ||
1504 | 1398 | ||
1505 | static void digi_close( struct usb_serial_port *port, struct file *filp ) | 1399 | static void digi_close(struct usb_serial_port *port, struct file *filp) |
1506 | { | 1400 | { |
1507 | DEFINE_WAIT(wait); | 1401 | DEFINE_WAIT(wait); |
1508 | int ret; | 1402 | int ret; |
@@ -1511,40 +1405,37 @@ static void digi_close( struct usb_serial_port *port, struct file *filp ) | |||
1511 | struct digi_port *priv = usb_get_serial_port_data(port); | 1405 | struct digi_port *priv = usb_get_serial_port_data(port); |
1512 | unsigned long flags = 0; | 1406 | unsigned long flags = 0; |
1513 | 1407 | ||
1514 | 1408 | dbg("digi_close: TOP: port=%d, open_count=%d", | |
1515 | dbg( "digi_close: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_count ); | 1409 | priv->dp_port_num, port->open_count); |
1516 | |||
1517 | 1410 | ||
1518 | /* if disconnected, just clear flags */ | 1411 | /* if disconnected, just clear flags */ |
1519 | if (!usb_get_intfdata(port->serial->interface)) | 1412 | if (!usb_get_intfdata(port->serial->interface)) |
1520 | goto exit; | 1413 | goto exit; |
1521 | 1414 | ||
1522 | /* do cleanup only after final close on this port */ | 1415 | /* do cleanup only after final close on this port */ |
1523 | spin_lock_irqsave( &priv->dp_port_lock, flags ); | 1416 | spin_lock_irqsave(&priv->dp_port_lock, flags); |
1524 | priv->dp_in_close = 1; | 1417 | priv->dp_in_close = 1; |
1525 | spin_unlock_irqrestore( &priv->dp_port_lock, flags ); | 1418 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); |
1526 | 1419 | ||
1527 | /* tell line discipline to process only XON/XOFF */ | 1420 | /* tell line discipline to process only XON/XOFF */ |
1528 | tty->closing = 1; | 1421 | tty->closing = 1; |
1529 | 1422 | ||
1530 | /* wait for output to drain */ | 1423 | /* wait for output to drain */ |
1531 | if( (filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0 ) { | 1424 | if ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0) |
1532 | tty_wait_until_sent( tty, DIGI_CLOSE_TIMEOUT ); | 1425 | tty_wait_until_sent(tty, DIGI_CLOSE_TIMEOUT); |
1533 | } | ||
1534 | 1426 | ||
1535 | /* flush driver and line discipline buffers */ | 1427 | /* flush driver and line discipline buffers */ |
1536 | if( tty->driver->flush_buffer ) | 1428 | if (tty->driver->flush_buffer) |
1537 | tty->driver->flush_buffer( tty ); | 1429 | tty->driver->flush_buffer(tty); |
1538 | tty_ldisc_flush(tty); | 1430 | tty_ldisc_flush(tty); |
1539 | 1431 | ||
1540 | if (port->serial->dev) { | 1432 | if (port->serial->dev) { |
1541 | /* wait for transmit idle */ | 1433 | /* wait for transmit idle */ |
1542 | if( (filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0 ) { | 1434 | if ((filp->f_flags&(O_NDELAY|O_NONBLOCK)) == 0) { |
1543 | digi_transmit_idle( port, DIGI_CLOSE_TIMEOUT ); | 1435 | digi_transmit_idle(port, DIGI_CLOSE_TIMEOUT); |
1544 | } | 1436 | } |
1545 | |||
1546 | /* drop DTR and RTS */ | 1437 | /* drop DTR and RTS */ |
1547 | digi_set_modem_signals( port, 0, 0 ); | 1438 | digi_set_modem_signals(port, 0, 0); |
1548 | 1439 | ||
1549 | /* disable input flow control */ | 1440 | /* disable input flow control */ |
1550 | buf[0] = DIGI_CMD_SET_INPUT_FLOW_CONTROL; | 1441 | buf[0] = DIGI_CMD_SET_INPUT_FLOW_CONTROL; |
@@ -1576,8 +1467,8 @@ dbg( "digi_close: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_co | |||
1576 | buf[18] = DIGI_FLUSH_TX | DIGI_FLUSH_RX; | 1467 | buf[18] = DIGI_FLUSH_TX | DIGI_FLUSH_RX; |
1577 | buf[19] = 0; | 1468 | buf[19] = 0; |
1578 | 1469 | ||
1579 | if( (ret=digi_write_oob_command( port, buf, 20, 0 )) != 0 ) | 1470 | if ((ret = digi_write_oob_command(port, buf, 20, 0)) != 0) |
1580 | dbg( "digi_close: write oob failed, ret=%d", ret ); | 1471 | dbg("digi_close: write oob failed, ret=%d", ret); |
1581 | 1472 | ||
1582 | /* wait for final commands on oob port to complete */ | 1473 | /* wait for final commands on oob port to complete */ |
1583 | prepare_to_wait(&priv->dp_flush_wait, &wait, TASK_INTERRUPTIBLE); | 1474 | prepare_to_wait(&priv->dp_flush_wait, &wait, TASK_INTERRUPTIBLE); |
@@ -1587,17 +1478,14 @@ dbg( "digi_close: TOP: port=%d, open_count=%d", priv->dp_port_num, port->open_co | |||
1587 | /* shutdown any outstanding bulk writes */ | 1478 | /* shutdown any outstanding bulk writes */ |
1588 | usb_kill_urb(port->write_urb); | 1479 | usb_kill_urb(port->write_urb); |
1589 | } | 1480 | } |
1590 | |||
1591 | tty->closing = 0; | 1481 | tty->closing = 0; |
1592 | |||
1593 | exit: | 1482 | exit: |
1594 | spin_lock_irqsave( &priv->dp_port_lock, flags ); | 1483 | spin_lock_irqsave(&priv->dp_port_lock, flags); |
1595 | priv->dp_write_urb_in_use = 0; | 1484 | priv->dp_write_urb_in_use = 0; |
1596 | priv->dp_in_close = 0; | 1485 | priv->dp_in_close = 0; |
1597 | wake_up_interruptible( &priv->dp_close_wait ); | 1486 | wake_up_interruptible(&priv->dp_close_wait); |
1598 | spin_unlock_irqrestore( &priv->dp_port_lock, flags ); | 1487 | spin_unlock_irqrestore(&priv->dp_port_lock, flags); |
1599 | 1488 | dbg("digi_close: done"); | |
1600 | dbg( "digi_close: done" ); | ||
1601 | } | 1489 | } |
1602 | 1490 | ||
1603 | 1491 | ||
@@ -1608,155 +1496,136 @@ dbg( "digi_close: done" ); | |||
1608 | * urbs initialized. Returns 0 if successful, non-zero error otherwise. | 1496 | * urbs initialized. Returns 0 if successful, non-zero error otherwise. |
1609 | */ | 1497 | */ |
1610 | 1498 | ||
1611 | static int digi_startup_device( struct usb_serial *serial ) | 1499 | static int digi_startup_device(struct usb_serial *serial) |
1612 | { | 1500 | { |
1613 | |||
1614 | int i,ret = 0; | 1501 | int i,ret = 0; |
1615 | struct digi_serial *serial_priv = usb_get_serial_data(serial); | 1502 | struct digi_serial *serial_priv = usb_get_serial_data(serial); |
1616 | struct usb_serial_port *port; | 1503 | struct usb_serial_port *port; |
1617 | 1504 | ||
1618 | |||
1619 | /* be sure this happens exactly once */ | 1505 | /* be sure this happens exactly once */ |
1620 | spin_lock( &serial_priv->ds_serial_lock ); | 1506 | spin_lock(&serial_priv->ds_serial_lock); |
1621 | if( serial_priv->ds_device_started ) { | 1507 | if (serial_priv->ds_device_started) { |
1622 | spin_unlock( &serial_priv->ds_serial_lock ); | 1508 | spin_unlock(&serial_priv->ds_serial_lock); |
1623 | return( 0 ); | 1509 | return 0; |
1624 | } | 1510 | } |
1625 | serial_priv->ds_device_started = 1; | 1511 | serial_priv->ds_device_started = 1; |
1626 | spin_unlock( &serial_priv->ds_serial_lock ); | 1512 | spin_unlock(&serial_priv->ds_serial_lock); |
1627 | 1513 | ||
1628 | /* start reading from each bulk in endpoint for the device */ | 1514 | /* start reading from each bulk in endpoint for the device */ |
1629 | /* set USB_DISABLE_SPD flag for write bulk urbs */ | 1515 | /* set USB_DISABLE_SPD flag for write bulk urbs */ |
1630 | for( i=0; i<serial->type->num_ports+1; i++ ) { | 1516 | for (i = 0; i < serial->type->num_ports + 1; i++) { |
1631 | |||
1632 | port = serial->port[i]; | 1517 | port = serial->port[i]; |
1633 | |||
1634 | port->write_urb->dev = port->serial->dev; | 1518 | port->write_urb->dev = port->serial->dev; |
1635 | 1519 | if ((ret = usb_submit_urb(port->read_urb, GFP_KERNEL)) != 0) { | |
1636 | if( (ret=usb_submit_urb(port->read_urb, GFP_KERNEL)) != 0 ) { | 1520 | err("%s: usb_submit_urb failed, ret=%d, port=%d", |
1637 | err("%s: usb_submit_urb failed, ret=%d, port=%d", __FUNCTION__, | 1521 | __FUNCTION__, ret, i); |
1638 | ret, i ); | ||
1639 | break; | 1522 | break; |
1640 | } | 1523 | } |
1641 | |||
1642 | } | 1524 | } |
1643 | 1525 | return ret; | |
1644 | return( ret ); | ||
1645 | |||
1646 | } | 1526 | } |
1647 | 1527 | ||
1648 | 1528 | ||
1649 | static int digi_startup( struct usb_serial *serial ) | 1529 | static int digi_startup(struct usb_serial *serial) |
1650 | { | 1530 | { |
1651 | 1531 | ||
1652 | int i; | 1532 | int i; |
1653 | struct digi_port *priv; | 1533 | struct digi_port *priv; |
1654 | struct digi_serial *serial_priv; | 1534 | struct digi_serial *serial_priv; |
1655 | 1535 | ||
1656 | 1536 | dbg("digi_startup: TOP"); | |
1657 | dbg( "digi_startup: TOP" ); | ||
1658 | 1537 | ||
1659 | /* allocate the private data structures for all ports */ | 1538 | /* allocate the private data structures for all ports */ |
1660 | /* number of regular ports + 1 for the out-of-band port */ | 1539 | /* number of regular ports + 1 for the out-of-band port */ |
1661 | for( i=0; i<serial->type->num_ports+1; i++ ) { | 1540 | for(i = 0; i < serial->type->num_ports + 1; i++) { |
1662 | |||
1663 | /* allocate port private structure */ | 1541 | /* allocate port private structure */ |
1664 | priv = kmalloc( sizeof(struct digi_port), | 1542 | priv = kmalloc(sizeof(struct digi_port), GFP_KERNEL); |
1665 | GFP_KERNEL ); | 1543 | if (priv == NULL) { |
1666 | if( priv == (struct digi_port *)0 ) { | 1544 | while (--i >= 0) |
1667 | while( --i >= 0 ) | 1545 | kfree(usb_get_serial_port_data(serial->port[i])); |
1668 | kfree( usb_get_serial_port_data(serial->port[i]) ); | 1546 | return 1; /* error */ |
1669 | return( 1 ); /* error */ | ||
1670 | } | 1547 | } |
1671 | 1548 | ||
1672 | /* initialize port private structure */ | 1549 | /* initialize port private structure */ |
1673 | spin_lock_init( &priv->dp_port_lock ); | 1550 | spin_lock_init(&priv->dp_port_lock); |
1674 | priv->dp_port_num = i; | 1551 | priv->dp_port_num = i; |
1675 | priv->dp_out_buf_len = 0; | 1552 | priv->dp_out_buf_len = 0; |
1676 | priv->dp_write_urb_in_use = 0; | 1553 | priv->dp_write_urb_in_use = 0; |
1677 | priv->dp_modem_signals = 0; | 1554 | priv->dp_modem_signals = 0; |
1678 | init_waitqueue_head( &priv->dp_modem_change_wait ); | 1555 | init_waitqueue_head(&priv->dp_modem_change_wait); |
1679 | priv->dp_transmit_idle = 0; | 1556 | priv->dp_transmit_idle = 0; |
1680 | init_waitqueue_head( &priv->dp_transmit_idle_wait ); | 1557 | init_waitqueue_head(&priv->dp_transmit_idle_wait); |
1681 | priv->dp_throttled = 0; | 1558 | priv->dp_throttled = 0; |
1682 | priv->dp_throttle_restart = 0; | 1559 | priv->dp_throttle_restart = 0; |
1683 | init_waitqueue_head( &priv->dp_flush_wait ); | 1560 | init_waitqueue_head(&priv->dp_flush_wait); |
1684 | priv->dp_in_close = 0; | 1561 | priv->dp_in_close = 0; |
1685 | init_waitqueue_head( &priv->dp_close_wait ); | 1562 | init_waitqueue_head(&priv->dp_close_wait); |
1686 | INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock); | 1563 | INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock); |
1687 | priv->dp_port = serial->port[i]; | 1564 | priv->dp_port = serial->port[i]; |
1688 | |||
1689 | /* initialize write wait queue for this port */ | 1565 | /* initialize write wait queue for this port */ |
1690 | init_waitqueue_head( &serial->port[i]->write_wait ); | 1566 | init_waitqueue_head(&serial->port[i]->write_wait); |
1691 | 1567 | ||
1692 | usb_set_serial_port_data(serial->port[i], priv); | 1568 | usb_set_serial_port_data(serial->port[i], priv); |
1693 | } | 1569 | } |
1694 | 1570 | ||
1695 | /* allocate serial private structure */ | 1571 | /* allocate serial private structure */ |
1696 | serial_priv = kmalloc( sizeof(struct digi_serial), | 1572 | serial_priv = kmalloc(sizeof(struct digi_serial), GFP_KERNEL); |
1697 | GFP_KERNEL ); | 1573 | if (serial_priv == NULL) { |
1698 | if( serial_priv == (struct digi_serial *)0 ) { | 1574 | for (i = 0; i < serial->type->num_ports + 1; i++) |
1699 | for( i=0; i<serial->type->num_ports+1; i++ ) | 1575 | kfree(usb_get_serial_port_data(serial->port[i])); |
1700 | kfree( usb_get_serial_port_data(serial->port[i]) ); | 1576 | return 1; /* error */ |
1701 | return( 1 ); /* error */ | ||
1702 | } | 1577 | } |
1703 | 1578 | ||
1704 | /* initialize serial private structure */ | 1579 | /* initialize serial private structure */ |
1705 | spin_lock_init( &serial_priv->ds_serial_lock ); | 1580 | spin_lock_init(&serial_priv->ds_serial_lock); |
1706 | serial_priv->ds_oob_port_num = serial->type->num_ports; | 1581 | serial_priv->ds_oob_port_num = serial->type->num_ports; |
1707 | serial_priv->ds_oob_port = serial->port[serial_priv->ds_oob_port_num]; | 1582 | serial_priv->ds_oob_port = serial->port[serial_priv->ds_oob_port_num]; |
1708 | serial_priv->ds_device_started = 0; | 1583 | serial_priv->ds_device_started = 0; |
1709 | usb_set_serial_data(serial, serial_priv); | 1584 | usb_set_serial_data(serial, serial_priv); |
1710 | 1585 | ||
1711 | return( 0 ); | 1586 | return 0; |
1712 | |||
1713 | } | 1587 | } |
1714 | 1588 | ||
1715 | 1589 | ||
1716 | static void digi_shutdown( struct usb_serial *serial ) | 1590 | static void digi_shutdown(struct usb_serial *serial) |
1717 | { | 1591 | { |
1718 | |||
1719 | int i; | 1592 | int i; |
1720 | 1593 | dbg("digi_shutdown: TOP, in_interrupt()=%ld", in_interrupt()); | |
1721 | |||
1722 | dbg( "digi_shutdown: TOP, in_interrupt()=%ld", in_interrupt() ); | ||
1723 | 1594 | ||
1724 | /* stop reads and writes on all ports */ | 1595 | /* stop reads and writes on all ports */ |
1725 | for( i=0; i<serial->type->num_ports+1; i++ ) { | 1596 | for (i = 0; i < serial->type->num_ports + 1; i++) { |
1726 | usb_kill_urb(serial->port[i]->read_urb); | 1597 | usb_kill_urb(serial->port[i]->read_urb); |
1727 | usb_kill_urb(serial->port[i]->write_urb); | 1598 | usb_kill_urb(serial->port[i]->write_urb); |
1728 | } | 1599 | } |
1729 | 1600 | ||
1730 | /* free the private data structures for all ports */ | 1601 | /* free the private data structures for all ports */ |
1731 | /* number of regular ports + 1 for the out-of-band port */ | 1602 | /* number of regular ports + 1 for the out-of-band port */ |
1732 | for( i=0; i<serial->type->num_ports+1; i++ ) | 1603 | for(i = 0; i < serial->type->num_ports + 1; i++) |
1733 | kfree( usb_get_serial_port_data(serial->port[i]) ); | 1604 | kfree(usb_get_serial_port_data(serial->port[i])); |
1734 | kfree( usb_get_serial_data(serial) ); | 1605 | kfree(usb_get_serial_data(serial)); |
1735 | } | 1606 | } |
1736 | 1607 | ||
1737 | 1608 | ||
1738 | static void digi_read_bulk_callback( struct urb *urb ) | 1609 | static void digi_read_bulk_callback(struct urb *urb) |
1739 | { | 1610 | { |
1740 | |||
1741 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | 1611 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; |
1742 | struct digi_port *priv; | 1612 | struct digi_port *priv; |
1743 | struct digi_serial *serial_priv; | 1613 | struct digi_serial *serial_priv; |
1744 | int ret; | 1614 | int ret; |
1745 | int status = urb->status; | 1615 | int status = urb->status; |
1746 | 1616 | ||
1747 | 1617 | dbg("digi_read_bulk_callback: TOP"); | |
1748 | dbg( "digi_read_bulk_callback: TOP" ); | ||
1749 | 1618 | ||
1750 | /* port sanity check, do not resubmit if port is not valid */ | 1619 | /* port sanity check, do not resubmit if port is not valid */ |
1751 | if( port == NULL || (priv=usb_get_serial_port_data(port)) == NULL ) { | 1620 | if (port == NULL || (priv = usb_get_serial_port_data(port)) == NULL) { |
1752 | err("%s: port or port->private is NULL, status=%d", | 1621 | err("%s: port or port->private is NULL, status=%d", |
1753 | __FUNCTION__, status); | 1622 | __FUNCTION__, status); |
1754 | return; | 1623 | return; |
1755 | } | 1624 | } |
1756 | if( port->serial == NULL | 1625 | if (port->serial == NULL || |
1757 | || (serial_priv=usb_get_serial_data(port->serial)) == NULL ) { | 1626 | (serial_priv=usb_get_serial_data(port->serial)) == NULL) { |
1758 | err("%s: serial is bad or serial->private is NULL, status=%d", | 1627 | err("%s: serial is bad or serial->private is NULL, status=%d", |
1759 | __FUNCTION__, status); | 1628 | __FUNCTION__, status); |
1760 | return; | 1629 | return; |
1761 | } | 1630 | } |
1762 | 1631 | ||
@@ -1768,24 +1637,23 @@ dbg( "digi_read_bulk_callback: TOP" ); | |||
1768 | } | 1637 | } |
1769 | 1638 | ||
1770 | /* handle oob or inb callback, do not resubmit if error */ | 1639 | /* handle oob or inb callback, do not resubmit if error */ |
1771 | if( priv->dp_port_num == serial_priv->ds_oob_port_num ) { | 1640 | if (priv->dp_port_num == serial_priv->ds_oob_port_num) { |
1772 | if( digi_read_oob_callback( urb ) != 0 ) | 1641 | if (digi_read_oob_callback(urb) != 0) |
1773 | return; | 1642 | return; |
1774 | } else { | 1643 | } else { |
1775 | if( digi_read_inb_callback( urb ) != 0 ) | 1644 | if (digi_read_inb_callback(urb) != 0) |
1776 | return; | 1645 | return; |
1777 | } | 1646 | } |
1778 | 1647 | ||
1779 | /* continue read */ | 1648 | /* continue read */ |
1780 | urb->dev = port->serial->dev; | 1649 | urb->dev = port->serial->dev; |
1781 | if( (ret=usb_submit_urb(urb, GFP_ATOMIC)) != 0 ) { | 1650 | if ((ret = usb_submit_urb(urb, GFP_ATOMIC)) != 0) { |
1782 | err("%s: failed resubmitting urb, ret=%d, port=%d", __FUNCTION__, | 1651 | err("%s: failed resubmitting urb, ret=%d, port=%d", |
1783 | ret, priv->dp_port_num ); | 1652 | __FUNCTION__, ret, priv->dp_port_num); |
1784 | } | 1653 | } |
1785 | 1654 | ||
1786 | } | 1655 | } |
1787 | 1656 | ||
1788 | |||
1789 | /* | 1657 | /* |
1790 | * Digi Read INB Callback | 1658 | * Digi Read INB Callback |
1791 | * | 1659 | * |
@@ -1796,7 +1664,7 @@ dbg( "digi_read_bulk_callback: TOP" ); | |||
1796 | * throttled, and -1 if the sanity checks failed. | 1664 | * throttled, and -1 if the sanity checks failed. |
1797 | */ | 1665 | */ |
1798 | 1666 | ||
1799 | static int digi_read_inb_callback( struct urb *urb ) | 1667 | static int digi_read_inb_callback(struct urb *urb) |
1800 | { | 1668 | { |
1801 | 1669 | ||
1802 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | 1670 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; |
@@ -1812,72 +1680,67 @@ static int digi_read_inb_callback( struct urb *urb ) | |||
1812 | 1680 | ||
1813 | /* do not process callbacks on closed ports */ | 1681 | /* do not process callbacks on closed ports */ |
1814 | /* but do continue the read chain */ | 1682 | /* but do continue the read chain */ |
1815 | if( port->open_count == 0 ) | 1683 | if (port->open_count == 0) |
1816 | return( 0 ); | 1684 | return 0; |
1817 | 1685 | ||
1818 | /* short/multiple packet check */ | 1686 | /* short/multiple packet check */ |
1819 | if( urb->actual_length != len + 2 ) { | 1687 | if (urb->actual_length != len + 2) { |
1820 | err("%s: INCOMPLETE OR MULTIPLE PACKET, urb status=%d, " | 1688 | err("%s: INCOMPLETE OR MULTIPLE PACKET, urb->status=%d, " |
1821 | "port=%d, opcode=%d, len=%d, actual_length=%d, " | 1689 | "port=%d, opcode=%d, len=%d, actual_length=%d, " |
1822 | "port_status=%d", __FUNCTION__, status, priv->dp_port_num, | 1690 | "status=%d", __FUNCTION__, status, priv->dp_port_num, |
1823 | opcode, len, urb->actual_length, port_status); | 1691 | opcode, len, urb->actual_length, port_status); |
1824 | return( -1 ); | 1692 | return -1; |
1825 | } | 1693 | } |
1826 | 1694 | ||
1827 | spin_lock( &priv->dp_port_lock ); | 1695 | spin_lock(&priv->dp_port_lock); |
1828 | 1696 | ||
1829 | /* check for throttle; if set, do not resubmit read urb */ | 1697 | /* check for throttle; if set, do not resubmit read urb */ |
1830 | /* indicate the read chain needs to be restarted on unthrottle */ | 1698 | /* indicate the read chain needs to be restarted on unthrottle */ |
1831 | throttled = priv->dp_throttled; | 1699 | throttled = priv->dp_throttled; |
1832 | if( throttled ) | 1700 | if (throttled) |
1833 | priv->dp_throttle_restart = 1; | 1701 | priv->dp_throttle_restart = 1; |
1834 | 1702 | ||
1835 | /* receive data */ | 1703 | /* receive data */ |
1836 | if( opcode == DIGI_CMD_RECEIVE_DATA ) { | 1704 | if (opcode == DIGI_CMD_RECEIVE_DATA) { |
1837 | |||
1838 | /* get flag from port_status */ | 1705 | /* get flag from port_status */ |
1839 | flag = 0; | 1706 | flag = 0; |
1840 | 1707 | ||
1841 | /* overrun is special, not associated with a char */ | 1708 | /* overrun is special, not associated with a char */ |
1842 | if (port_status & DIGI_OVERRUN_ERROR) { | 1709 | if (port_status & DIGI_OVERRUN_ERROR) |
1843 | tty_insert_flip_char( tty, 0, TTY_OVERRUN ); | 1710 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); |
1844 | } | ||
1845 | 1711 | ||
1846 | /* break takes precedence over parity, */ | 1712 | /* break takes precedence over parity, */ |
1847 | /* which takes precedence over framing errors */ | 1713 | /* which takes precedence over framing errors */ |
1848 | if (port_status & DIGI_BREAK_ERROR) { | 1714 | if (port_status & DIGI_BREAK_ERROR) |
1849 | flag = TTY_BREAK; | 1715 | flag = TTY_BREAK; |
1850 | } else if (port_status & DIGI_PARITY_ERROR) { | 1716 | else if (port_status & DIGI_PARITY_ERROR) |
1851 | flag = TTY_PARITY; | 1717 | flag = TTY_PARITY; |
1852 | } else if (port_status & DIGI_FRAMING_ERROR) { | 1718 | else if (port_status & DIGI_FRAMING_ERROR) |
1853 | flag = TTY_FRAME; | 1719 | flag = TTY_FRAME; |
1854 | } | ||
1855 | 1720 | ||
1856 | /* data length is len-1 (one byte of len is port_status) */ | 1721 | /* data length is len-1 (one byte of len is port_status) */ |
1857 | --len; | 1722 | --len; |
1858 | 1723 | ||
1859 | len = tty_buffer_request_room(tty, len); | 1724 | len = tty_buffer_request_room(tty, len); |
1860 | if( len > 0 ) { | 1725 | if (len > 0) { |
1861 | /* Hot path */ | 1726 | /* Hot path */ |
1862 | if(flag == TTY_NORMAL) | 1727 | if (flag == TTY_NORMAL) |
1863 | tty_insert_flip_string(tty, data, len); | 1728 | tty_insert_flip_string(tty, data, len); |
1864 | else { | 1729 | else { |
1865 | for(i = 0; i < len; i++) | 1730 | for(i = 0; i < len; i++) |
1866 | tty_insert_flip_char(tty, data[i], flag); | 1731 | tty_insert_flip_char(tty, data[i], flag); |
1867 | } | 1732 | } |
1868 | tty_flip_buffer_push( tty ); | 1733 | tty_flip_buffer_push(tty); |
1869 | } | 1734 | } |
1870 | } | 1735 | } |
1736 | spin_unlock(&priv->dp_port_lock); | ||
1871 | 1737 | ||
1872 | spin_unlock( &priv->dp_port_lock ); | 1738 | if (opcode == DIGI_CMD_RECEIVE_DISABLE) |
1873 | 1739 | dbg("%s: got RECEIVE_DISABLE", __FUNCTION__); | |
1874 | if( opcode == DIGI_CMD_RECEIVE_DISABLE ) { | 1740 | else if (opcode != DIGI_CMD_RECEIVE_DATA) |
1875 | dbg("%s: got RECEIVE_DISABLE", __FUNCTION__ ); | 1741 | dbg("%s: unknown opcode: %d", __FUNCTION__, opcode); |
1876 | } else if( opcode != DIGI_CMD_RECEIVE_DATA ) { | ||
1877 | dbg("%s: unknown opcode: %d", __FUNCTION__, opcode ); | ||
1878 | } | ||
1879 | 1742 | ||
1880 | return( throttled ? 1 : 0 ); | 1743 | return(throttled ? 1 : 0); |
1881 | 1744 | ||
1882 | } | 1745 | } |
1883 | 1746 | ||
@@ -1891,7 +1754,7 @@ static int digi_read_inb_callback( struct urb *urb ) | |||
1891 | * -1 if the sanity checks failed. | 1754 | * -1 if the sanity checks failed. |
1892 | */ | 1755 | */ |
1893 | 1756 | ||
1894 | static int digi_read_oob_callback( struct urb *urb ) | 1757 | static int digi_read_oob_callback(struct urb *urb) |
1895 | { | 1758 | { |
1896 | 1759 | ||
1897 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | 1760 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; |
@@ -1900,87 +1763,75 @@ static int digi_read_oob_callback( struct urb *urb ) | |||
1900 | int opcode, line, status, val; | 1763 | int opcode, line, status, val; |
1901 | int i; | 1764 | int i; |
1902 | 1765 | ||
1903 | 1766 | dbg("digi_read_oob_callback: port=%d, len=%d", | |
1904 | dbg( "digi_read_oob_callback: port=%d, len=%d", priv->dp_port_num, | 1767 | priv->dp_port_num, urb->actual_length); |
1905 | urb->actual_length ); | ||
1906 | 1768 | ||
1907 | /* handle each oob command */ | 1769 | /* handle each oob command */ |
1908 | for( i=0; i<urb->actual_length-3; ) { | 1770 | for(i = 0; i < urb->actual_length - 3;) { |
1909 | |||
1910 | opcode = ((unsigned char *)urb->transfer_buffer)[i++]; | 1771 | opcode = ((unsigned char *)urb->transfer_buffer)[i++]; |
1911 | line = ((unsigned char *)urb->transfer_buffer)[i++]; | 1772 | line = ((unsigned char *)urb->transfer_buffer)[i++]; |
1912 | status = ((unsigned char *)urb->transfer_buffer)[i++]; | 1773 | status = ((unsigned char *)urb->transfer_buffer)[i++]; |
1913 | val = ((unsigned char *)urb->transfer_buffer)[i++]; | 1774 | val = ((unsigned char *)urb->transfer_buffer)[i++]; |
1914 | 1775 | ||
1915 | dbg( "digi_read_oob_callback: opcode=%d, line=%d, status=%d, val=%d", | 1776 | dbg("digi_read_oob_callback: opcode=%d, line=%d, status=%d, val=%d", |
1916 | opcode, line, status, val ); | 1777 | opcode, line, status, val); |
1917 | 1778 | ||
1918 | if( status != 0 || line >= serial->type->num_ports ) | 1779 | if (status != 0 || line >= serial->type->num_ports) |
1919 | continue; | 1780 | continue; |
1920 | 1781 | ||
1921 | port = serial->port[line]; | 1782 | port = serial->port[line]; |
1922 | 1783 | ||
1923 | if ((priv=usb_get_serial_port_data(port)) == NULL ) | 1784 | if ((priv=usb_get_serial_port_data(port)) == NULL) |
1924 | return -1; | 1785 | return -1; |
1925 | 1786 | ||
1926 | if( opcode == DIGI_CMD_READ_INPUT_SIGNALS ) { | 1787 | if (opcode == DIGI_CMD_READ_INPUT_SIGNALS) { |
1927 | 1788 | spin_lock(&priv->dp_port_lock); | |
1928 | spin_lock( &priv->dp_port_lock ); | ||
1929 | |||
1930 | /* convert from digi flags to termiox flags */ | 1789 | /* convert from digi flags to termiox flags */ |
1931 | if( val & DIGI_READ_INPUT_SIGNALS_CTS ) { | 1790 | if (val & DIGI_READ_INPUT_SIGNALS_CTS) { |
1932 | priv->dp_modem_signals |= TIOCM_CTS; | 1791 | priv->dp_modem_signals |= TIOCM_CTS; |
1933 | /* port must be open to use tty struct */ | 1792 | /* port must be open to use tty struct */ |
1934 | if( port->open_count | 1793 | if (port->open_count |
1935 | && port->tty->termios->c_cflag & CRTSCTS ) { | 1794 | && port->tty->termios->c_cflag & CRTSCTS) { |
1936 | port->tty->hw_stopped = 0; | 1795 | port->tty->hw_stopped = 0; |
1937 | digi_wakeup_write( port ); | 1796 | digi_wakeup_write(port); |
1938 | } | 1797 | } |
1939 | } else { | 1798 | } else { |
1940 | priv->dp_modem_signals &= ~TIOCM_CTS; | 1799 | priv->dp_modem_signals &= ~TIOCM_CTS; |
1941 | /* port must be open to use tty struct */ | 1800 | /* port must be open to use tty struct */ |
1942 | if( port->open_count | 1801 | if (port->open_count |
1943 | && port->tty->termios->c_cflag & CRTSCTS ) { | 1802 | && port->tty->termios->c_cflag & CRTSCTS) { |
1944 | port->tty->hw_stopped = 1; | 1803 | port->tty->hw_stopped = 1; |
1945 | } | 1804 | } |
1946 | } | 1805 | } |
1947 | if( val & DIGI_READ_INPUT_SIGNALS_DSR ) | 1806 | if (val & DIGI_READ_INPUT_SIGNALS_DSR) |
1948 | priv->dp_modem_signals |= TIOCM_DSR; | 1807 | priv->dp_modem_signals |= TIOCM_DSR; |
1949 | else | 1808 | else |
1950 | priv->dp_modem_signals &= ~TIOCM_DSR; | 1809 | priv->dp_modem_signals &= ~TIOCM_DSR; |
1951 | if( val & DIGI_READ_INPUT_SIGNALS_RI ) | 1810 | if (val & DIGI_READ_INPUT_SIGNALS_RI) |
1952 | priv->dp_modem_signals |= TIOCM_RI; | 1811 | priv->dp_modem_signals |= TIOCM_RI; |
1953 | else | 1812 | else |
1954 | priv->dp_modem_signals &= ~TIOCM_RI; | 1813 | priv->dp_modem_signals &= ~TIOCM_RI; |
1955 | if( val & DIGI_READ_INPUT_SIGNALS_DCD ) | 1814 | if (val & DIGI_READ_INPUT_SIGNALS_DCD) |
1956 | priv->dp_modem_signals |= TIOCM_CD; | 1815 | priv->dp_modem_signals |= TIOCM_CD; |
1957 | else | 1816 | else |
1958 | priv->dp_modem_signals &= ~TIOCM_CD; | 1817 | priv->dp_modem_signals &= ~TIOCM_CD; |
1959 | 1818 | ||
1960 | wake_up_interruptible( &priv->dp_modem_change_wait ); | 1819 | wake_up_interruptible(&priv->dp_modem_change_wait); |
1961 | spin_unlock( &priv->dp_port_lock ); | 1820 | spin_unlock(&priv->dp_port_lock); |
1962 | 1821 | } else if (opcode == DIGI_CMD_TRANSMIT_IDLE) { | |
1963 | } else if( opcode == DIGI_CMD_TRANSMIT_IDLE ) { | 1822 | spin_lock(&priv->dp_port_lock); |
1964 | |||
1965 | spin_lock( &priv->dp_port_lock ); | ||
1966 | priv->dp_transmit_idle = 1; | 1823 | priv->dp_transmit_idle = 1; |
1967 | wake_up_interruptible( &priv->dp_transmit_idle_wait ); | 1824 | wake_up_interruptible(&priv->dp_transmit_idle_wait); |
1968 | spin_unlock( &priv->dp_port_lock ); | 1825 | spin_unlock(&priv->dp_port_lock); |
1969 | 1826 | } else if (opcode == DIGI_CMD_IFLUSH_FIFO) { | |
1970 | } else if( opcode == DIGI_CMD_IFLUSH_FIFO ) { | 1827 | wake_up_interruptible(&priv->dp_flush_wait); |
1971 | |||
1972 | wake_up_interruptible( &priv->dp_flush_wait ); | ||
1973 | |||
1974 | } | 1828 | } |
1975 | |||
1976 | } | 1829 | } |
1977 | 1830 | return 0; | |
1978 | return( 0 ); | ||
1979 | 1831 | ||
1980 | } | 1832 | } |
1981 | 1833 | ||
1982 | 1834 | static int __init digi_init(void) | |
1983 | static int __init digi_init (void) | ||
1984 | { | 1835 | { |
1985 | int retval; | 1836 | int retval; |
1986 | retval = usb_serial_register(&digi_acceleport_2_device); | 1837 | retval = usb_serial_register(&digi_acceleport_2_device); |
@@ -2002,12 +1853,11 @@ failed_acceleport_2_device: | |||
2002 | return retval; | 1853 | return retval; |
2003 | } | 1854 | } |
2004 | 1855 | ||
2005 | |||
2006 | static void __exit digi_exit (void) | 1856 | static void __exit digi_exit (void) |
2007 | { | 1857 | { |
2008 | usb_deregister (&digi_driver); | 1858 | usb_deregister(&digi_driver); |
2009 | usb_serial_deregister (&digi_acceleport_2_device); | 1859 | usb_serial_deregister(&digi_acceleport_2_device); |
2010 | usb_serial_deregister (&digi_acceleport_4_device); | 1860 | usb_serial_deregister(&digi_acceleport_4_device); |
2011 | } | 1861 | } |
2012 | 1862 | ||
2013 | 1863 | ||
@@ -2015,8 +1865,8 @@ module_init(digi_init); | |||
2015 | module_exit(digi_exit); | 1865 | module_exit(digi_exit); |
2016 | 1866 | ||
2017 | 1867 | ||
2018 | MODULE_AUTHOR( DRIVER_AUTHOR ); | 1868 | MODULE_AUTHOR(DRIVER_AUTHOR); |
2019 | MODULE_DESCRIPTION( DRIVER_DESC ); | 1869 | MODULE_DESCRIPTION(DRIVER_DESC); |
2020 | MODULE_LICENSE("GPL"); | 1870 | MODULE_LICENSE("GPL"); |
2021 | 1871 | ||
2022 | module_param(debug, bool, S_IRUGO | S_IWUSR); | 1872 | module_param(debug, bool, S_IRUGO | S_IWUSR); |
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 7b1673a4407..e4c248c98e8 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -538,6 +538,8 @@ static struct usb_device_id id_table_combined [] = { | |||
538 | { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_VCP_PID) }, | 538 | { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_VCP_PID) }, |
539 | { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_D2XX_PID) }, | 539 | { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_D2XX_PID) }, |
540 | { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, | 540 | { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) }, |
541 | { USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) }, | ||
542 | { USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) }, | ||
541 | { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, | 543 | { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) }, |
542 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, | 544 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) }, |
543 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) }, | 545 | { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) }, |
@@ -566,6 +568,7 @@ static struct usb_device_id id_table_combined [] = { | |||
566 | { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, | 568 | { USB_DEVICE(ELEKTOR_VID, ELEKTOR_FT323R_PID) }, |
567 | { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, | 569 | { USB_DEVICE(TELLDUS_VID, TELLDUS_TELLSTICK_PID) }, |
568 | { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, | 570 | { USB_DEVICE(FTDI_VID, FTDI_MAXSTREAM_PID) }, |
571 | { USB_DEVICE(TML_VID, TML_USB_SERIAL_PID) }, | ||
569 | { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID), | 572 | { USB_DEVICE(OLIMEX_VID, OLIMEX_ARM_USB_OCD_PID), |
570 | .driver_info = (kernel_ulong_t)&ftdi_olimex_quirk }, | 573 | .driver_info = (kernel_ulong_t)&ftdi_olimex_quirk }, |
571 | { }, /* Optional parameter entry */ | 574 | { }, /* Optional parameter entry */ |
@@ -1166,7 +1169,9 @@ static void remove_sysfs_attrs(struct usb_serial_port *port) | |||
1166 | /* XXX see create_sysfs_attrs */ | 1169 | /* XXX see create_sysfs_attrs */ |
1167 | if (priv->chip_type != SIO) { | 1170 | if (priv->chip_type != SIO) { |
1168 | device_remove_file(&port->dev, &dev_attr_event_char); | 1171 | device_remove_file(&port->dev, &dev_attr_event_char); |
1169 | if (priv->chip_type == FT232BM || priv->chip_type == FT2232C) { | 1172 | if (priv->chip_type == FT232BM || |
1173 | priv->chip_type == FT2232C || | ||
1174 | priv->chip_type == FT232RL) { | ||
1170 | device_remove_file(&port->dev, &dev_attr_latency_timer); | 1175 | device_remove_file(&port->dev, &dev_attr_latency_timer); |
1171 | } | 1176 | } |
1172 | } | 1177 | } |
@@ -2099,6 +2104,7 @@ static int ftdi_tiocmget (struct usb_serial_port *port, struct file *file) | |||
2099 | case FT8U232AM: | 2104 | case FT8U232AM: |
2100 | case FT232BM: | 2105 | case FT232BM: |
2101 | case FT2232C: | 2106 | case FT2232C: |
2107 | case FT232RL: | ||
2102 | /* the 8U232AM returns a two byte value (the sio is a 1 byte value) - in the same | 2108 | /* the 8U232AM returns a two byte value (the sio is a 1 byte value) - in the same |
2103 | format as the data returned from the in point */ | 2109 | format as the data returned from the in point */ |
2104 | if ((ret = usb_control_msg(port->serial->dev, | 2110 | if ((ret = usb_control_msg(port->serial->dev, |
diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index d9e49716db1..b57b90ae9f9 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h | |||
@@ -430,6 +430,9 @@ | |||
430 | */ | 430 | */ |
431 | #define EVOLUTION_VID 0xDEEE /* Vendor ID */ | 431 | #define EVOLUTION_VID 0xDEEE /* Vendor ID */ |
432 | #define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */ | 432 | #define EVOLUTION_ER1_PID 0x0300 /* ER1 Control Module */ |
433 | #define EVO_8U232AM_PID 0x02FF /* Evolution robotics RCM2 (FT232AM)*/ | ||
434 | #define EVO_HYBRID_PID 0x0302 /* Evolution robotics RCM4 PID (FT232BM)*/ | ||
435 | #define EVO_RCM4_PID 0x0303 /* Evolution robotics RCM4 PID */ | ||
433 | 436 | ||
434 | /* Pyramid Computer GmbH */ | 437 | /* Pyramid Computer GmbH */ |
435 | #define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ | 438 | #define FTDI_PYRAMID_PID 0xE6C8 /* Pyramid Appliance Display */ |
@@ -531,6 +534,14 @@ | |||
531 | #define OLIMEX_VID 0x15BA | 534 | #define OLIMEX_VID 0x15BA |
532 | #define OLIMEX_ARM_USB_OCD_PID 0x0003 | 535 | #define OLIMEX_ARM_USB_OCD_PID 0x0003 |
533 | 536 | ||
537 | |||
538 | /* | ||
539 | * The Mobility Lab (TML) | ||
540 | * Submitted by Pierre Castella | ||
541 | */ | ||
542 | #define TML_VID 0x1B91 /* Vendor ID */ | ||
543 | #define TML_USB_SERIAL_PID 0x0064 /* USB - Serial Converter */ | ||
544 | |||
534 | /* Commands */ | 545 | /* Commands */ |
535 | #define FTDI_SIO_RESET 0 /* Reset the port */ | 546 | #define FTDI_SIO_RESET 0 /* Reset the port */ |
536 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ | 547 | #define FTDI_SIO_MODEM_CTRL 1 /* Set the modem control register */ |
diff --git a/drivers/usb/serial/funsoft.c b/drivers/usb/serial/funsoft.c index 4092f6dc9ef..b5194dc7d3b 100644 --- a/drivers/usb/serial/funsoft.c +++ b/drivers/usb/serial/funsoft.c | |||
@@ -24,26 +24,6 @@ static struct usb_device_id id_table [] = { | |||
24 | }; | 24 | }; |
25 | MODULE_DEVICE_TABLE(usb, id_table); | 25 | MODULE_DEVICE_TABLE(usb, id_table); |
26 | 26 | ||
27 | static int funsoft_ioctl(struct usb_serial_port *port, struct file *file, | ||
28 | unsigned int cmd, unsigned long arg) | ||
29 | { | ||
30 | struct ktermios t; | ||
31 | |||
32 | dbg("%s - port %d, cmd 0x%04x", __FUNCTION__, port->number, cmd); | ||
33 | |||
34 | if (cmd == TCSETSF) { | ||
35 | if (user_termios_to_kernel_termios(&t, (struct termios __user *)arg)) | ||
36 | return -EFAULT; | ||
37 | |||
38 | dbg("%s - iflag:%x oflag:%x cflag:%x lflag:%x", __FUNCTION__, | ||
39 | t.c_iflag, t.c_oflag, t.c_cflag, t.c_lflag); | ||
40 | |||
41 | if (!(t.c_lflag & ICANON)) | ||
42 | return -EINVAL; | ||
43 | } | ||
44 | return -ENOIOCTLCMD; | ||
45 | } | ||
46 | |||
47 | static struct usb_driver funsoft_driver = { | 27 | static struct usb_driver funsoft_driver = { |
48 | .name = "funsoft", | 28 | .name = "funsoft", |
49 | .probe = usb_serial_probe, | 29 | .probe = usb_serial_probe, |
@@ -63,7 +43,6 @@ static struct usb_serial_driver funsoft_device = { | |||
63 | .num_bulk_in = NUM_DONT_CARE, | 43 | .num_bulk_in = NUM_DONT_CARE, |
64 | .num_bulk_out = NUM_DONT_CARE, | 44 | .num_bulk_out = NUM_DONT_CARE, |
65 | .num_ports = 1, | 45 | .num_ports = 1, |
66 | .ioctl = funsoft_ioctl, | ||
67 | }; | 46 | }; |
68 | 47 | ||
69 | static int __init funsoft_init(void) | 48 | static int __init funsoft_init(void) |
diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 04bd3b7a298..f1c90cfe725 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Garmin GPS driver | 2 | * Garmin GPS driver |
3 | * | 3 | * |
4 | * Copyright (C) 2006 Hermann Kneissel herkne@users.sourceforge.net | 4 | * Copyright (C) 2006,2007 Hermann Kneissel herkne@users.sourceforge.net |
5 | * | 5 | * |
6 | * The latest version of the driver can be found at | 6 | * The latest version of the driver can be found at |
7 | * http://sourceforge.net/projects/garmin-gps/ | 7 | * http://sourceforge.net/projects/garmin-gps/ |
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
35 | #include <linux/spinlock.h> | 35 | #include <linux/spinlock.h> |
36 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
37 | #include <asm/atomic.h> | ||
37 | #include <linux/usb.h> | 38 | #include <linux/usb.h> |
38 | #include <linux/usb/serial.h> | 39 | #include <linux/usb/serial.h> |
39 | 40 | ||
@@ -52,7 +53,7 @@ static int debug = 0; | |||
52 | */ | 53 | */ |
53 | 54 | ||
54 | #define VERSION_MAJOR 0 | 55 | #define VERSION_MAJOR 0 |
55 | #define VERSION_MINOR 28 | 56 | #define VERSION_MINOR 31 |
56 | 57 | ||
57 | #define _STR(s) #s | 58 | #define _STR(s) #s |
58 | #define _DRIVER_VERSION(a,b) "v" _STR(a) "." _STR(b) | 59 | #define _DRIVER_VERSION(a,b) "v" _STR(a) "." _STR(b) |
@@ -141,6 +142,8 @@ struct garmin_data { | |||
141 | __u8 inbuffer [GPS_IN_BUFSIZ]; /* tty -> usb */ | 142 | __u8 inbuffer [GPS_IN_BUFSIZ]; /* tty -> usb */ |
142 | __u8 outbuffer[GPS_OUT_BUFSIZ]; /* usb -> tty */ | 143 | __u8 outbuffer[GPS_OUT_BUFSIZ]; /* usb -> tty */ |
143 | __u8 privpkt[4*6]; | 144 | __u8 privpkt[4*6]; |
145 | atomic_t req_count; | ||
146 | atomic_t resp_count; | ||
144 | spinlock_t lock; | 147 | spinlock_t lock; |
145 | struct list_head pktlist; | 148 | struct list_head pktlist; |
146 | }; | 149 | }; |
@@ -171,8 +174,6 @@ struct garmin_data { | |||
171 | #define CLEAR_HALT_REQUIRED 0x0001 | 174 | #define CLEAR_HALT_REQUIRED 0x0001 |
172 | 175 | ||
173 | #define FLAGS_QUEUING 0x0100 | 176 | #define FLAGS_QUEUING 0x0100 |
174 | #define FLAGS_APP_RESP_SEEN 0x0200 | ||
175 | #define FLAGS_APP_REQ_SEEN 0x0400 | ||
176 | #define FLAGS_DROP_DATA 0x0800 | 177 | #define FLAGS_DROP_DATA 0x0800 |
177 | 178 | ||
178 | #define FLAGS_GSP_SKIP 0x1000 | 179 | #define FLAGS_GSP_SKIP 0x1000 |
@@ -186,7 +187,8 @@ struct garmin_data { | |||
186 | /* function prototypes */ | 187 | /* function prototypes */ |
187 | static void gsp_next_packet(struct garmin_data * garmin_data_p); | 188 | static void gsp_next_packet(struct garmin_data * garmin_data_p); |
188 | static int garmin_write_bulk(struct usb_serial_port *port, | 189 | static int garmin_write_bulk(struct usb_serial_port *port, |
189 | const unsigned char *buf, int count); | 190 | const unsigned char *buf, int count, |
191 | int dismiss_ack); | ||
190 | 192 | ||
191 | /* some special packets to be send or received */ | 193 | /* some special packets to be send or received */ |
192 | static unsigned char const GARMIN_START_SESSION_REQ[] | 194 | static unsigned char const GARMIN_START_SESSION_REQ[] |
@@ -233,9 +235,7 @@ static struct usb_driver garmin_driver = { | |||
233 | 235 | ||
234 | static inline int noResponseFromAppLayer(struct garmin_data * garmin_data_p) | 236 | static inline int noResponseFromAppLayer(struct garmin_data * garmin_data_p) |
235 | { | 237 | { |
236 | return ((garmin_data_p->flags | 238 | return atomic_read(&garmin_data_p->req_count) == atomic_read(&garmin_data_p->resp_count); |
237 | & (FLAGS_APP_REQ_SEEN|FLAGS_APP_RESP_SEEN)) | ||
238 | == FLAGS_APP_REQ_SEEN); | ||
239 | } | 239 | } |
240 | 240 | ||
241 | 241 | ||
@@ -463,7 +463,7 @@ static int gsp_rec_packet(struct garmin_data * garmin_data_p, int count) | |||
463 | usbdata[2] = __cpu_to_le32(size); | 463 | usbdata[2] = __cpu_to_le32(size); |
464 | 464 | ||
465 | garmin_write_bulk (garmin_data_p->port, garmin_data_p->inbuffer, | 465 | garmin_write_bulk (garmin_data_p->port, garmin_data_p->inbuffer, |
466 | GARMIN_PKTHDR_LENGTH+size); | 466 | GARMIN_PKTHDR_LENGTH+size, 0); |
467 | 467 | ||
468 | /* if this was an abort-transfer command, flush all | 468 | /* if this was an abort-transfer command, flush all |
469 | queued data. */ | 469 | queued data. */ |
@@ -818,7 +818,7 @@ static int nat_receive(struct garmin_data * garmin_data_p, | |||
818 | if (garmin_data_p->insize >= len) { | 818 | if (garmin_data_p->insize >= len) { |
819 | garmin_write_bulk (garmin_data_p->port, | 819 | garmin_write_bulk (garmin_data_p->port, |
820 | garmin_data_p->inbuffer, | 820 | garmin_data_p->inbuffer, |
821 | len); | 821 | len, 0); |
822 | garmin_data_p->insize = 0; | 822 | garmin_data_p->insize = 0; |
823 | 823 | ||
824 | /* if this was an abort-transfer command, | 824 | /* if this was an abort-transfer command, |
@@ -893,10 +893,11 @@ static int garmin_clear(struct garmin_data * garmin_data_p) | |||
893 | 893 | ||
894 | struct usb_serial_port *port = garmin_data_p->port; | 894 | struct usb_serial_port *port = garmin_data_p->port; |
895 | 895 | ||
896 | if (port != NULL && garmin_data_p->flags & FLAGS_APP_RESP_SEEN) { | 896 | if (port != NULL && atomic_read(&garmin_data_p->resp_count)) { |
897 | /* send a terminate command */ | 897 | /* send a terminate command */ |
898 | status = garmin_write_bulk(port, GARMIN_STOP_TRANSFER_REQ, | 898 | status = garmin_write_bulk(port, GARMIN_STOP_TRANSFER_REQ, |
899 | sizeof(GARMIN_STOP_TRANSFER_REQ)); | 899 | sizeof(GARMIN_STOP_TRANSFER_REQ), |
900 | 1); | ||
900 | } | 901 | } |
901 | 902 | ||
902 | /* flush all queued data */ | 903 | /* flush all queued data */ |
@@ -939,7 +940,8 @@ static int garmin_init_session(struct usb_serial_port *port) | |||
939 | dbg("%s - starting session ...", __FUNCTION__); | 940 | dbg("%s - starting session ...", __FUNCTION__); |
940 | garmin_data_p->state = STATE_ACTIVE; | 941 | garmin_data_p->state = STATE_ACTIVE; |
941 | status = garmin_write_bulk(port, GARMIN_START_SESSION_REQ, | 942 | status = garmin_write_bulk(port, GARMIN_START_SESSION_REQ, |
942 | sizeof(GARMIN_START_SESSION_REQ)); | 943 | sizeof(GARMIN_START_SESSION_REQ), |
944 | 0); | ||
943 | 945 | ||
944 | if (status >= 0) { | 946 | if (status >= 0) { |
945 | 947 | ||
@@ -950,7 +952,8 @@ static int garmin_init_session(struct usb_serial_port *port) | |||
950 | /* not needed, but the win32 driver does it too ... */ | 952 | /* not needed, but the win32 driver does it too ... */ |
951 | status = garmin_write_bulk(port, | 953 | status = garmin_write_bulk(port, |
952 | GARMIN_START_SESSION_REQ2, | 954 | GARMIN_START_SESSION_REQ2, |
953 | sizeof(GARMIN_START_SESSION_REQ2)); | 955 | sizeof(GARMIN_START_SESSION_REQ2), |
956 | 0); | ||
954 | if (status >= 0) { | 957 | if (status >= 0) { |
955 | status = 0; | 958 | status = 0; |
956 | spin_lock_irqsave(&garmin_data_p->lock, flags); | 959 | spin_lock_irqsave(&garmin_data_p->lock, flags); |
@@ -987,6 +990,8 @@ static int garmin_open (struct usb_serial_port *port, struct file *filp) | |||
987 | garmin_data_p->mode = initial_mode; | 990 | garmin_data_p->mode = initial_mode; |
988 | garmin_data_p->count = 0; | 991 | garmin_data_p->count = 0; |
989 | garmin_data_p->flags = 0; | 992 | garmin_data_p->flags = 0; |
993 | atomic_set(&garmin_data_p->req_count, 0); | ||
994 | atomic_set(&garmin_data_p->resp_count, 0); | ||
990 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | 995 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); |
991 | 996 | ||
992 | /* shutdown any bulk reads that might be going on */ | 997 | /* shutdown any bulk reads that might be going on */ |
@@ -1035,28 +1040,39 @@ static void garmin_write_bulk_callback (struct urb *urb) | |||
1035 | { | 1040 | { |
1036 | unsigned long flags; | 1041 | unsigned long flags; |
1037 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; | 1042 | struct usb_serial_port *port = (struct usb_serial_port *)urb->context; |
1038 | struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); | ||
1039 | int status = urb->status; | 1043 | int status = urb->status; |
1040 | 1044 | ||
1041 | /* free up the transfer buffer, as usb_free_urb() does not do this */ | 1045 | if (port) { |
1042 | kfree (urb->transfer_buffer); | 1046 | struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); |
1043 | 1047 | ||
1044 | dbg("%s - port %d", __FUNCTION__, port->number); | 1048 | dbg("%s - port %d", __FUNCTION__, port->number); |
1045 | 1049 | ||
1046 | if (status) { | 1050 | if (GARMIN_LAYERID_APPL == getLayerId(urb->transfer_buffer) |
1047 | dbg("%s - nonzero write bulk status received: %d", | 1051 | && (garmin_data_p->mode == MODE_GARMIN_SERIAL)) { |
1048 | __FUNCTION__, status); | 1052 | gsp_send_ack(garmin_data_p, ((__u8 *)urb->transfer_buffer)[4]); |
1049 | spin_lock_irqsave(&garmin_data_p->lock, flags); | 1053 | } |
1050 | garmin_data_p->flags |= CLEAR_HALT_REQUIRED; | 1054 | |
1051 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | 1055 | if (status) { |
1056 | dbg("%s - nonzero write bulk status received: %d", | ||
1057 | __FUNCTION__, urb->status); | ||
1058 | spin_lock_irqsave(&garmin_data_p->lock, flags); | ||
1059 | garmin_data_p->flags |= CLEAR_HALT_REQUIRED; | ||
1060 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | ||
1061 | } | ||
1062 | |||
1063 | usb_serial_port_softint(port); | ||
1052 | } | 1064 | } |
1053 | 1065 | ||
1054 | usb_serial_port_softint(port); | 1066 | /* Ignore errors that resulted from garmin_write_bulk with dismiss_ack=1 */ |
1067 | |||
1068 | /* free up the transfer buffer, as usb_free_urb() does not do this */ | ||
1069 | kfree (urb->transfer_buffer); | ||
1055 | } | 1070 | } |
1056 | 1071 | ||
1057 | 1072 | ||
1058 | static int garmin_write_bulk (struct usb_serial_port *port, | 1073 | static int garmin_write_bulk (struct usb_serial_port *port, |
1059 | const unsigned char *buf, int count) | 1074 | const unsigned char *buf, int count, |
1075 | int dismiss_ack) | ||
1060 | { | 1076 | { |
1061 | unsigned long flags; | 1077 | unsigned long flags; |
1062 | struct usb_serial *serial = port->serial; | 1078 | struct usb_serial *serial = port->serial; |
@@ -1093,13 +1109,12 @@ static int garmin_write_bulk (struct usb_serial_port *port, | |||
1093 | usb_sndbulkpipe (serial->dev, | 1109 | usb_sndbulkpipe (serial->dev, |
1094 | port->bulk_out_endpointAddress), | 1110 | port->bulk_out_endpointAddress), |
1095 | buffer, count, | 1111 | buffer, count, |
1096 | garmin_write_bulk_callback, port); | 1112 | garmin_write_bulk_callback, |
1113 | dismiss_ack ? NULL : port); | ||
1097 | urb->transfer_flags |= URB_ZERO_PACKET; | 1114 | urb->transfer_flags |= URB_ZERO_PACKET; |
1098 | 1115 | ||
1099 | if (GARMIN_LAYERID_APPL == getLayerId(buffer)) { | 1116 | if (GARMIN_LAYERID_APPL == getLayerId(buffer)) { |
1100 | spin_lock_irqsave(&garmin_data_p->lock, flags); | 1117 | atomic_inc(&garmin_data_p->req_count); |
1101 | garmin_data_p->flags |= FLAGS_APP_REQ_SEEN; | ||
1102 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | ||
1103 | if (garmin_data_p->mode == MODE_GARMIN_SERIAL) { | 1118 | if (garmin_data_p->mode == MODE_GARMIN_SERIAL) { |
1104 | pkt_clear(garmin_data_p); | 1119 | pkt_clear(garmin_data_p); |
1105 | garmin_data_p->state = STATE_GSP_WAIT_DATA; | 1120 | garmin_data_p->state = STATE_GSP_WAIT_DATA; |
@@ -1114,13 +1129,6 @@ static int garmin_write_bulk (struct usb_serial_port *port, | |||
1114 | "failed with status = %d\n", | 1129 | "failed with status = %d\n", |
1115 | __FUNCTION__, status); | 1130 | __FUNCTION__, status); |
1116 | count = status; | 1131 | count = status; |
1117 | } else { | ||
1118 | |||
1119 | if (GARMIN_LAYERID_APPL == getLayerId(buffer) | ||
1120 | && (garmin_data_p->mode == MODE_GARMIN_SERIAL)) { | ||
1121 | |||
1122 | gsp_send_ack(garmin_data_p, buffer[4]); | ||
1123 | } | ||
1124 | } | 1132 | } |
1125 | 1133 | ||
1126 | /* we are done with this urb, so let the host driver | 1134 | /* we are done with this urb, so let the host driver |
@@ -1135,7 +1143,6 @@ static int garmin_write_bulk (struct usb_serial_port *port, | |||
1135 | static int garmin_write (struct usb_serial_port *port, | 1143 | static int garmin_write (struct usb_serial_port *port, |
1136 | const unsigned char *buf, int count) | 1144 | const unsigned char *buf, int count) |
1137 | { | 1145 | { |
1138 | unsigned long flags; | ||
1139 | int pktid, pktsiz, len; | 1146 | int pktid, pktsiz, len; |
1140 | struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); | 1147 | struct garmin_data * garmin_data_p = usb_get_serial_port_data(port); |
1141 | __le32 *privpkt = (__le32 *)garmin_data_p->privpkt; | 1148 | __le32 *privpkt = (__le32 *)garmin_data_p->privpkt; |
@@ -1186,9 +1193,7 @@ static int garmin_write (struct usb_serial_port *port, | |||
1186 | break; | 1193 | break; |
1187 | 1194 | ||
1188 | case PRIV_PKTID_RESET_REQ: | 1195 | case PRIV_PKTID_RESET_REQ: |
1189 | spin_lock_irqsave(&garmin_data_p->lock, flags); | 1196 | atomic_inc(&garmin_data_p->req_count); |
1190 | garmin_data_p->flags |= FLAGS_APP_REQ_SEEN; | ||
1191 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | ||
1192 | break; | 1197 | break; |
1193 | 1198 | ||
1194 | case PRIV_PKTID_SET_DEF_MODE: | 1199 | case PRIV_PKTID_SET_DEF_MODE: |
@@ -1241,8 +1246,6 @@ static int garmin_chars_in_buffer (struct usb_serial_port *port) | |||
1241 | static void garmin_read_process(struct garmin_data * garmin_data_p, | 1246 | static void garmin_read_process(struct garmin_data * garmin_data_p, |
1242 | unsigned char *data, unsigned data_length) | 1247 | unsigned char *data, unsigned data_length) |
1243 | { | 1248 | { |
1244 | unsigned long flags; | ||
1245 | |||
1246 | if (garmin_data_p->flags & FLAGS_DROP_DATA) { | 1249 | if (garmin_data_p->flags & FLAGS_DROP_DATA) { |
1247 | /* abort-transfer cmd is actice */ | 1250 | /* abort-transfer cmd is actice */ |
1248 | dbg("%s - pkt dropped", __FUNCTION__); | 1251 | dbg("%s - pkt dropped", __FUNCTION__); |
@@ -1254,9 +1257,7 @@ static void garmin_read_process(struct garmin_data * garmin_data_p, | |||
1254 | the device */ | 1257 | the device */ |
1255 | if (0 == memcmp(data, GARMIN_APP_LAYER_REPLY, | 1258 | if (0 == memcmp(data, GARMIN_APP_LAYER_REPLY, |
1256 | sizeof(GARMIN_APP_LAYER_REPLY))) { | 1259 | sizeof(GARMIN_APP_LAYER_REPLY))) { |
1257 | spin_lock_irqsave(&garmin_data_p->lock, flags); | 1260 | atomic_inc(&garmin_data_p->resp_count); |
1258 | garmin_data_p->flags |= FLAGS_APP_RESP_SEEN; | ||
1259 | spin_unlock_irqrestore(&garmin_data_p->lock, flags); | ||
1260 | } | 1261 | } |
1261 | 1262 | ||
1262 | /* if throttling is active or postprecessing is required | 1263 | /* if throttling is active or postprecessing is required |
diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index dd42f57089f..2ecb1d2a034 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c | |||
@@ -2366,9 +2366,8 @@ static int send_cmd_write_baud_rate (struct edgeport_port *edge_port, int baudRa | |||
2366 | int status; | 2366 | int status; |
2367 | unsigned char number = edge_port->port->number - edge_port->port->serial->minor; | 2367 | unsigned char number = edge_port->port->number - edge_port->port->serial->minor; |
2368 | 2368 | ||
2369 | if ((!edge_serial->is_epic) || | 2369 | if (edge_serial->is_epic && |
2370 | ((edge_serial->is_epic) && | 2370 | !edge_serial->epic_descriptor.Supports.IOSPSetBaudRate) { |
2371 | (!edge_serial->epic_descriptor.Supports.IOSPSetBaudRate))) { | ||
2372 | dbg("SendCmdWriteBaudRate - NOT Setting baud rate for port = %d, baud = %d", | 2371 | dbg("SendCmdWriteBaudRate - NOT Setting baud rate for port = %d, baud = %d", |
2373 | edge_port->port->number, baudRate); | 2372 | edge_port->port->number, baudRate); |
2374 | return 0; | 2373 | return 0; |
@@ -2461,18 +2460,16 @@ static int send_cmd_write_uart_register (struct edgeport_port *edge_port, __u8 r | |||
2461 | 2460 | ||
2462 | dbg("%s - write to %s register 0x%02x", (regNum == MCR) ? "MCR" : "LCR", __FUNCTION__, regValue); | 2461 | dbg("%s - write to %s register 0x%02x", (regNum == MCR) ? "MCR" : "LCR", __FUNCTION__, regValue); |
2463 | 2462 | ||
2464 | if ((!edge_serial->is_epic) || | 2463 | if (edge_serial->is_epic && |
2465 | ((edge_serial->is_epic) && | 2464 | !edge_serial->epic_descriptor.Supports.IOSPWriteMCR && |
2466 | (!edge_serial->epic_descriptor.Supports.IOSPWriteMCR) && | 2465 | regNum == MCR) { |
2467 | (regNum == MCR))) { | ||
2468 | dbg("SendCmdWriteUartReg - Not writing to MCR Register"); | 2466 | dbg("SendCmdWriteUartReg - Not writing to MCR Register"); |
2469 | return 0; | 2467 | return 0; |
2470 | } | 2468 | } |
2471 | 2469 | ||
2472 | if ((!edge_serial->is_epic) || | 2470 | if (edge_serial->is_epic && |
2473 | ((edge_serial->is_epic) && | 2471 | !edge_serial->epic_descriptor.Supports.IOSPWriteLCR && |
2474 | (!edge_serial->epic_descriptor.Supports.IOSPWriteLCR) && | 2472 | regNum == LCR) { |
2475 | (regNum == LCR))) { | ||
2476 | dbg ("SendCmdWriteUartReg - Not writing to LCR Register"); | 2473 | dbg ("SendCmdWriteUartReg - Not writing to LCR Register"); |
2477 | return 0; | 2474 | return 0; |
2478 | } | 2475 | } |
diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index 0d3903691e8..b8670905bc3 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c | |||
@@ -2794,16 +2794,14 @@ static void edge_shutdown (struct usb_serial *serial) | |||
2794 | 2794 | ||
2795 | dbg ("%s", __FUNCTION__); | 2795 | dbg ("%s", __FUNCTION__); |
2796 | 2796 | ||
2797 | for (i=0; i < serial->num_ports; ++i) { | 2797 | for (i = 0; i < serial->num_ports; ++i) { |
2798 | edge_port = usb_get_serial_port_data(serial->port[i]); | 2798 | edge_port = usb_get_serial_port_data(serial->port[i]); |
2799 | edge_remove_sysfs_attrs(edge_port->port); | 2799 | edge_remove_sysfs_attrs(edge_port->port); |
2800 | if (edge_port) { | 2800 | edge_buf_free(edge_port->ep_out_buf); |
2801 | edge_buf_free(edge_port->ep_out_buf); | 2801 | kfree(edge_port); |
2802 | kfree(edge_port); | ||
2803 | } | ||
2804 | usb_set_serial_port_data(serial->port[i], NULL); | 2802 | usb_set_serial_port_data(serial->port[i], NULL); |
2805 | } | 2803 | } |
2806 | kfree (usb_get_serial_data(serial)); | 2804 | kfree(usb_get_serial_data(serial)); |
2807 | usb_set_serial_data(serial, NULL); | 2805 | usb_set_serial_data(serial, NULL); |
2808 | } | 2806 | } |
2809 | 2807 | ||
diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 0455c1552ae..e836ad07fdb 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c | |||
@@ -256,6 +256,7 @@ static struct usb_device_id ipaq_id_table [] = { | |||
256 | { USB_DEVICE(0x04DD, 0x9121) }, /* SHARP WS004SH USB Modem */ | 256 | { USB_DEVICE(0x04DD, 0x9121) }, /* SHARP WS004SH USB Modem */ |
257 | { USB_DEVICE(0x04DD, 0x9123) }, /* SHARP WS007SH USB Modem */ | 257 | { USB_DEVICE(0x04DD, 0x9123) }, /* SHARP WS007SH USB Modem */ |
258 | { USB_DEVICE(0x04DD, 0x9151) }, /* SHARP S01SH USB Modem */ | 258 | { USB_DEVICE(0x04DD, 0x9151) }, /* SHARP S01SH USB Modem */ |
259 | { USB_DEVICE(0x04DD, 0x91AC) }, /* SHARP WS011SH USB Modem */ | ||
259 | { USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */ | 260 | { USB_DEVICE(0x04E8, 0x5F00) }, /* Samsung NEXiO USB Sync */ |
260 | { USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */ | 261 | { USB_DEVICE(0x04E8, 0x5F01) }, /* Samsung NEXiO USB Sync */ |
261 | { USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */ | 262 | { USB_DEVICE(0x04E8, 0x5F02) }, /* Samsung NEXiO USB Sync */ |
@@ -545,6 +546,7 @@ static struct usb_device_id ipaq_id_table [] = { | |||
545 | { USB_DEVICE(0x413C, 0x4009) }, /* Dell Axim USB Sync */ | 546 | { USB_DEVICE(0x413C, 0x4009) }, /* Dell Axim USB Sync */ |
546 | { USB_DEVICE(0x4505, 0x0010) }, /* Smartphone */ | 547 | { USB_DEVICE(0x4505, 0x0010) }, /* Smartphone */ |
547 | { USB_DEVICE(0x5E04, 0xCE00) }, /* SAGEM Wireless Assistant */ | 548 | { USB_DEVICE(0x5E04, 0xCE00) }, /* SAGEM Wireless Assistant */ |
549 | { USB_DEVICE(0x0BB4, 0x00CF) }, /* HTC smartphone modems */ | ||
548 | { } /* Terminating entry */ | 550 | { } /* Terminating entry */ |
549 | }; | 551 | }; |
550 | 552 | ||
@@ -645,11 +647,13 @@ static int ipaq_open(struct usb_serial_port *port, struct file *filp) | |||
645 | kfree(port->bulk_out_buffer); | 647 | kfree(port->bulk_out_buffer); |
646 | port->bulk_in_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL); | 648 | port->bulk_in_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL); |
647 | if (port->bulk_in_buffer == NULL) { | 649 | if (port->bulk_in_buffer == NULL) { |
650 | port->bulk_out_buffer = NULL; /* prevent double free */ | ||
648 | goto enomem; | 651 | goto enomem; |
649 | } | 652 | } |
650 | port->bulk_out_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL); | 653 | port->bulk_out_buffer = kmalloc(URBDATA_SIZE, GFP_KERNEL); |
651 | if (port->bulk_out_buffer == NULL) { | 654 | if (port->bulk_out_buffer == NULL) { |
652 | kfree(port->bulk_in_buffer); | 655 | kfree(port->bulk_in_buffer); |
656 | port->bulk_in_buffer = NULL; | ||
653 | goto enomem; | 657 | goto enomem; |
654 | } | 658 | } |
655 | port->read_urb->transfer_buffer = port->bulk_in_buffer; | 659 | port->read_urb->transfer_buffer = port->bulk_in_buffer; |
diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 5a4127e62c4..90e3216abd1 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c | |||
@@ -728,24 +728,32 @@ static void klsi_105_set_termios (struct usb_serial_port *port, | |||
728 | #endif | 728 | #endif |
729 | } | 729 | } |
730 | 730 | ||
731 | switch(cflag & CBAUD) { | 731 | switch(tty_get_baud_rate(port->tty)) { |
732 | case B0: /* handled below */ | 732 | case 0: /* handled below */ |
733 | break; | 733 | break; |
734 | case B1200: priv->cfg.baudrate = kl5kusb105a_sio_b1200; | 734 | case 1200: |
735 | priv->cfg.baudrate = kl5kusb105a_sio_b1200; | ||
735 | break; | 736 | break; |
736 | case B2400: priv->cfg.baudrate = kl5kusb105a_sio_b2400; | 737 | case 2400: |
738 | priv->cfg.baudrate = kl5kusb105a_sio_b2400; | ||
737 | break; | 739 | break; |
738 | case B4800: priv->cfg.baudrate = kl5kusb105a_sio_b4800; | 740 | case 4800: |
741 | priv->cfg.baudrate = kl5kusb105a_sio_b4800; | ||
739 | break; | 742 | break; |
740 | case B9600: priv->cfg.baudrate = kl5kusb105a_sio_b9600; | 743 | case 9600: |
744 | priv->cfg.baudrate = kl5kusb105a_sio_b9600; | ||
741 | break; | 745 | break; |
742 | case B19200: priv->cfg.baudrate = kl5kusb105a_sio_b19200; | 746 | case 19200: |
747 | priv->cfg.baudrate = kl5kusb105a_sio_b19200; | ||
743 | break; | 748 | break; |
744 | case B38400: priv->cfg.baudrate = kl5kusb105a_sio_b38400; | 749 | case 38400: |
750 | priv->cfg.baudrate = kl5kusb105a_sio_b38400; | ||
745 | break; | 751 | break; |
746 | case B57600: priv->cfg.baudrate = kl5kusb105a_sio_b57600; | 752 | case 57600: |
753 | priv->cfg.baudrate = kl5kusb105a_sio_b57600; | ||
747 | break; | 754 | break; |
748 | case B115200: priv->cfg.baudrate = kl5kusb105a_sio_b115200; | 755 | case 115200: |
756 | priv->cfg.baudrate = kl5kusb105a_sio_b115200; | ||
749 | break; | 757 | break; |
750 | default: | 758 | default: |
751 | err("KLSI USB->Serial converter:" | 759 | err("KLSI USB->Serial converter:" |
diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 02a86dbc0e9..6f224195bd2 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c | |||
@@ -82,6 +82,7 @@ static int kobil_tiocmset(struct usb_serial_port *port, struct file *file, | |||
82 | unsigned int set, unsigned int clear); | 82 | unsigned int set, unsigned int clear); |
83 | static void kobil_read_int_callback( struct urb *urb ); | 83 | static void kobil_read_int_callback( struct urb *urb ); |
84 | static void kobil_write_callback( struct urb *purb ); | 84 | static void kobil_write_callback( struct urb *purb ); |
85 | static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old); | ||
85 | 86 | ||
86 | 87 | ||
87 | static struct usb_device_id id_table [] = { | 88 | static struct usb_device_id id_table [] = { |
@@ -119,6 +120,7 @@ static struct usb_serial_driver kobil_device = { | |||
119 | .attach = kobil_startup, | 120 | .attach = kobil_startup, |
120 | .shutdown = kobil_shutdown, | 121 | .shutdown = kobil_shutdown, |
121 | .ioctl = kobil_ioctl, | 122 | .ioctl = kobil_ioctl, |
123 | .set_termios = kobil_set_termios, | ||
122 | .tiocmget = kobil_tiocmget, | 124 | .tiocmget = kobil_tiocmget, |
123 | .tiocmset = kobil_tiocmset, | 125 | .tiocmset = kobil_tiocmset, |
124 | .open = kobil_open, | 126 | .open = kobil_open, |
@@ -137,7 +139,6 @@ struct kobil_private { | |||
137 | int cur_pos; // index of the next char to send in buf | 139 | int cur_pos; // index of the next char to send in buf |
138 | __u16 device_type; | 140 | __u16 device_type; |
139 | int line_state; | 141 | int line_state; |
140 | struct ktermios internal_termios; | ||
141 | }; | 142 | }; |
142 | 143 | ||
143 | 144 | ||
@@ -216,7 +217,7 @@ static void kobil_shutdown (struct usb_serial *serial) | |||
216 | 217 | ||
217 | static int kobil_open (struct usb_serial_port *port, struct file *filp) | 218 | static int kobil_open (struct usb_serial_port *port, struct file *filp) |
218 | { | 219 | { |
219 | int i, result = 0; | 220 | int result = 0; |
220 | struct kobil_private *priv; | 221 | struct kobil_private *priv; |
221 | unsigned char *transfer_buffer; | 222 | unsigned char *transfer_buffer; |
222 | int transfer_buffer_length = 8; | 223 | int transfer_buffer_length = 8; |
@@ -242,16 +243,6 @@ static int kobil_open (struct usb_serial_port *port, struct file *filp) | |||
242 | port->tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF; | 243 | port->tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF; |
243 | port->tty->termios->c_oflag &= ~ONLCR; // do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) | 244 | port->tty->termios->c_oflag &= ~ONLCR; // do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) |
244 | 245 | ||
245 | // set up internal termios structure | ||
246 | priv->internal_termios.c_iflag = port->tty->termios->c_iflag; | ||
247 | priv->internal_termios.c_oflag = port->tty->termios->c_oflag; | ||
248 | priv->internal_termios.c_cflag = port->tty->termios->c_cflag; | ||
249 | priv->internal_termios.c_lflag = port->tty->termios->c_lflag; | ||
250 | |||
251 | for (i=0; i<NCCS; i++) { | ||
252 | priv->internal_termios.c_cc[i] = port->tty->termios->c_cc[i]; | ||
253 | } | ||
254 | |||
255 | // allocate memory for transfer buffer | 246 | // allocate memory for transfer buffer |
256 | transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); | 247 | transfer_buffer = kzalloc(transfer_buffer_length, GFP_KERNEL); |
257 | if (! transfer_buffer) { | 248 | if (! transfer_buffer) { |
@@ -607,102 +598,79 @@ static int kobil_tiocmset(struct usb_serial_port *port, struct file *file, | |||
607 | return (result < 0) ? result : 0; | 598 | return (result < 0) ? result : 0; |
608 | } | 599 | } |
609 | 600 | ||
610 | 601 | static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old) | |
611 | static int kobil_ioctl(struct usb_serial_port *port, struct file *file, | ||
612 | unsigned int cmd, unsigned long arg) | ||
613 | { | 602 | { |
614 | struct kobil_private * priv; | 603 | struct kobil_private * priv; |
615 | int result; | 604 | int result; |
616 | unsigned short urb_val = 0; | 605 | unsigned short urb_val = 0; |
617 | unsigned char *transfer_buffer; | 606 | int c_cflag = port->tty->termios->c_cflag; |
618 | int transfer_buffer_length = 8; | 607 | speed_t speed; |
619 | char *settings; | 608 | void * settings; |
620 | void __user *user_arg = (void __user *)arg; | ||
621 | 609 | ||
622 | priv = usb_get_serial_port_data(port); | 610 | priv = usb_get_serial_port_data(port); |
623 | if ((priv->device_type == KOBIL_USBTWIN_PRODUCT_ID) || (priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID)) { | 611 | if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) |
624 | // This device doesn't support ioctl calls | 612 | // This device doesn't support ioctl calls |
625 | return 0; | 613 | return; |
626 | } | ||
627 | |||
628 | switch (cmd) { | ||
629 | case TCGETS: // 0x5401 | ||
630 | if (!access_ok(VERIFY_WRITE, user_arg, sizeof(struct ktermios))) { | ||
631 | dbg("%s - port %d Error in access_ok", __FUNCTION__, port->number); | ||
632 | return -EFAULT; | ||
633 | } | ||
634 | if (kernel_termios_to_user_termios((struct ktermios __user *)arg, | ||
635 | &priv->internal_termios)) | ||
636 | return -EFAULT; | ||
637 | return 0; | ||
638 | |||
639 | case TCSETS: // 0x5402 | ||
640 | if (!(port->tty->termios)) { | ||
641 | dbg("%s - port %d Error: port->tty->termios is NULL", __FUNCTION__, port->number); | ||
642 | return -ENOTTY; | ||
643 | } | ||
644 | if (!access_ok(VERIFY_READ, user_arg, sizeof(struct ktermios))) { | ||
645 | dbg("%s - port %d Error in access_ok", __FUNCTION__, port->number); | ||
646 | return -EFAULT; | ||
647 | } | ||
648 | if (user_termios_to_kernel_termios(&priv->internal_termios, | ||
649 | (struct ktermios __user *)arg)) | ||
650 | return -EFAULT; | ||
651 | |||
652 | settings = kzalloc(50, GFP_KERNEL); | ||
653 | if (! settings) { | ||
654 | return -ENOBUFS; | ||
655 | } | ||
656 | 614 | ||
657 | switch (priv->internal_termios.c_cflag & CBAUD) { | 615 | switch (speed = tty_get_baud_rate(port->tty)) { |
658 | case B1200: | 616 | case 1200: |
659 | urb_val = SUSBCR_SBR_1200; | 617 | urb_val = SUSBCR_SBR_1200; |
660 | strcat(settings, "1200 "); | ||
661 | break; | 618 | break; |
662 | case B9600: | 619 | case 9600: |
663 | default: | 620 | default: |
664 | urb_val = SUSBCR_SBR_9600; | 621 | urb_val = SUSBCR_SBR_9600; |
665 | strcat(settings, "9600 "); | ||
666 | break; | 622 | break; |
667 | } | 623 | } |
624 | urb_val |= (c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : SUSBCR_SPASB_1StopBit; | ||
625 | |||
626 | settings = kzalloc(50, GFP_KERNEL); | ||
627 | if (! settings) | ||
628 | return; | ||
668 | 629 | ||
669 | urb_val |= (priv->internal_termios.c_cflag & CSTOPB) ? SUSBCR_SPASB_2StopBits : SUSBCR_SPASB_1StopBit; | 630 | sprintf(settings, "%d ", speed); |
670 | strcat(settings, (priv->internal_termios.c_cflag & CSTOPB) ? "2 StopBits " : "1 StopBit "); | ||
671 | 631 | ||
672 | if (priv->internal_termios.c_cflag & PARENB) { | 632 | if (c_cflag & PARENB) { |
673 | if (priv->internal_termios.c_cflag & PARODD) { | 633 | if (c_cflag & PARODD) { |
674 | urb_val |= SUSBCR_SPASB_OddParity; | 634 | urb_val |= SUSBCR_SPASB_OddParity; |
675 | strcat(settings, "Odd Parity"); | 635 | strcat(settings, "Odd Parity"); |
676 | } else { | ||
677 | urb_val |= SUSBCR_SPASB_EvenParity; | ||
678 | strcat(settings, "Even Parity"); | ||
679 | } | ||
680 | } else { | 636 | } else { |
681 | urb_val |= SUSBCR_SPASB_NoParity; | 637 | urb_val |= SUSBCR_SPASB_EvenParity; |
682 | strcat(settings, "No Parity"); | 638 | strcat(settings, "Even Parity"); |
683 | } | 639 | } |
684 | dbg("%s - port %d setting port to: %s", __FUNCTION__, port->number, settings ); | 640 | } else { |
641 | urb_val |= SUSBCR_SPASB_NoParity; | ||
642 | strcat(settings, "No Parity"); | ||
643 | } | ||
685 | 644 | ||
686 | result = usb_control_msg( port->serial->dev, | 645 | result = usb_control_msg( port->serial->dev, |
687 | usb_rcvctrlpipe(port->serial->dev, 0 ), | 646 | usb_rcvctrlpipe(port->serial->dev, 0 ), |
688 | SUSBCRequest_SetBaudRateParityAndStopBits, | 647 | SUSBCRequest_SetBaudRateParityAndStopBits, |
689 | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, | 648 | USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, |
690 | urb_val, | 649 | urb_val, |
691 | 0, | 650 | 0, |
692 | settings, | 651 | settings, |
693 | 0, | 652 | 0, |
694 | KOBIL_TIMEOUT | 653 | KOBIL_TIMEOUT |
695 | ); | 654 | ); |
655 | kfree(settings); | ||
656 | } | ||
696 | 657 | ||
697 | dbg("%s - port %d Send set_baudrate URB returns: %i", __FUNCTION__, port->number, result); | 658 | static int kobil_ioctl(struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg) |
698 | kfree(settings); | 659 | { |
660 | struct kobil_private * priv = usb_get_serial_port_data(port); | ||
661 | unsigned char *transfer_buffer; | ||
662 | int transfer_buffer_length = 8; | ||
663 | int result; | ||
664 | |||
665 | if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID || priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) | ||
666 | // This device doesn't support ioctl calls | ||
699 | return 0; | 667 | return 0; |
700 | 668 | ||
669 | switch (cmd) { | ||
701 | case TCFLSH: // 0x540B | 670 | case TCFLSH: // 0x540B |
702 | transfer_buffer = kmalloc(transfer_buffer_length, GFP_KERNEL); | 671 | transfer_buffer = kmalloc(transfer_buffer_length, GFP_KERNEL); |
703 | if (! transfer_buffer) { | 672 | if (! transfer_buffer) |
704 | return -ENOBUFS; | 673 | return -ENOBUFS; |
705 | } | ||
706 | 674 | ||
707 | result = usb_control_msg( port->serial->dev, | 675 | result = usb_control_msg( port->serial->dev, |
708 | usb_rcvctrlpipe(port->serial->dev, 0 ), | 676 | usb_rcvctrlpipe(port->serial->dev, 0 ), |
@@ -716,15 +684,13 @@ static int kobil_ioctl(struct usb_serial_port *port, struct file *file, | |||
716 | ); | 684 | ); |
717 | 685 | ||
718 | dbg("%s - port %d Send reset_all_queues (FLUSH) URB returns: %i", __FUNCTION__, port->number, result); | 686 | dbg("%s - port %d Send reset_all_queues (FLUSH) URB returns: %i", __FUNCTION__, port->number, result); |
719 | |||
720 | kfree(transfer_buffer); | 687 | kfree(transfer_buffer); |
721 | return ((result < 0) ? -EFAULT : 0); | 688 | return (result < 0) ? -EFAULT : 0; |
722 | 689 | default: | |
690 | return -ENOIOCTLCMD; | ||
723 | } | 691 | } |
724 | return -ENOIOCTLCMD; | ||
725 | } | 692 | } |
726 | 693 | ||
727 | |||
728 | static int __init kobil_init (void) | 694 | static int __init kobil_init (void) |
729 | { | 695 | { |
730 | int retval; | 696 | int retval; |
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c index 2a3fabcf518..0dc99f75bb0 100644 --- a/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
@@ -184,21 +184,21 @@ struct mct_u232_private { | |||
184 | * we do not know how to support. We ignore them for the moment. | 184 | * we do not know how to support. We ignore them for the moment. |
185 | * XXX Rate-limit the error message, it's user triggerable. | 185 | * XXX Rate-limit the error message, it's user triggerable. |
186 | */ | 186 | */ |
187 | static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value) | 187 | static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value) |
188 | { | 188 | { |
189 | if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID | 189 | if (le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_SITECOM_PID |
190 | || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) { | 190 | || le16_to_cpu(serial->dev->descriptor.idProduct) == MCT_U232_BELKIN_F5U109_PID) { |
191 | switch (value) { | 191 | switch (value) { |
192 | case B300: return 0x01; | 192 | case 300: return 0x01; |
193 | case B600: return 0x02; /* this one not tested */ | 193 | case 600: return 0x02; /* this one not tested */ |
194 | case B1200: return 0x03; | 194 | case 1200: return 0x03; |
195 | case B2400: return 0x04; | 195 | case 2400: return 0x04; |
196 | case B4800: return 0x06; | 196 | case 4800: return 0x06; |
197 | case B9600: return 0x08; | 197 | case 9600: return 0x08; |
198 | case B19200: return 0x09; | 198 | case 19200: return 0x09; |
199 | case B38400: return 0x0a; | 199 | case 38400: return 0x0a; |
200 | case B57600: return 0x0b; | 200 | case 57600: return 0x0b; |
201 | case B115200: return 0x0c; | 201 | case 115200: return 0x0c; |
202 | default: | 202 | default: |
203 | err("MCT USB-RS232: unsupported baudrate request 0x%x," | 203 | err("MCT USB-RS232: unsupported baudrate request 0x%x," |
204 | " using default of B9600", value); | 204 | " using default of B9600", value); |
@@ -206,16 +206,16 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value) | |||
206 | } | 206 | } |
207 | } else { | 207 | } else { |
208 | switch (value) { | 208 | switch (value) { |
209 | case B300: value = 300; break; | 209 | case 300: break; |
210 | case B600: value = 600; break; | 210 | case 600: break; |
211 | case B1200: value = 1200; break; | 211 | case 1200: break; |
212 | case B2400: value = 2400; break; | 212 | case 2400: break; |
213 | case B4800: value = 4800; break; | 213 | case 4800: break; |
214 | case B9600: value = 9600; break; | 214 | case 9600: break; |
215 | case B19200: value = 19200; break; | 215 | case 19200: break; |
216 | case B38400: value = 38400; break; | 216 | case 38400: break; |
217 | case B57600: value = 57600; break; | 217 | case 57600: break; |
218 | case B115200: value = 115200; break; | 218 | case 115200: break; |
219 | default: | 219 | default: |
220 | err("MCT USB-RS232: unsupported baudrate request 0x%x," | 220 | err("MCT USB-RS232: unsupported baudrate request 0x%x," |
221 | " using default of B9600", value); | 221 | " using default of B9600", value); |
@@ -226,7 +226,7 @@ static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value) | |||
226 | } | 226 | } |
227 | 227 | ||
228 | static int mct_u232_set_baud_rate(struct usb_serial *serial, struct usb_serial_port *port, | 228 | static int mct_u232_set_baud_rate(struct usb_serial *serial, struct usb_serial_port *port, |
229 | int value) | 229 | speed_t value) |
230 | { | 230 | { |
231 | __le32 divisor; | 231 | __le32 divisor; |
232 | int rc; | 232 | int rc; |
@@ -634,7 +634,7 @@ static void mct_u232_set_termios (struct usb_serial_port *port, | |||
634 | mct_u232_set_modem_ctrl(serial, control_state); | 634 | mct_u232_set_modem_ctrl(serial, control_state); |
635 | } | 635 | } |
636 | 636 | ||
637 | mct_u232_set_baud_rate(serial, port, cflag & CBAUD); | 637 | mct_u232_set_baud_rate(serial, port, tty_get_baud_rate(port->tty)); |
638 | 638 | ||
639 | if ((cflag & CBAUD) == B0 ) { | 639 | if ((cflag & CBAUD) == B0 ) { |
640 | dbg("%s: baud is B0", __FUNCTION__); | 640 | dbg("%s: baud is B0", __FUNCTION__); |
diff --git a/drivers/usb/serial/mct_u232.h b/drivers/usb/serial/mct_u232.h index a61bac8f224..aae10c8174d 100644 --- a/drivers/usb/serial/mct_u232.h +++ b/drivers/usb/serial/mct_u232.h | |||
@@ -79,7 +79,7 @@ | |||
79 | * and "Intel solution". They are the regular MCT and "Sitecom" for us. | 79 | * and "Intel solution". They are the regular MCT and "Sitecom" for us. |
80 | * This is pointless to document in the header, see the code for the bits. | 80 | * This is pointless to document in the header, see the code for the bits. |
81 | */ | 81 | */ |
82 | static int mct_u232_calculate_baud_rate(struct usb_serial *serial, int value); | 82 | static int mct_u232_calculate_baud_rate(struct usb_serial *serial, speed_t value); |
83 | 83 | ||
84 | /* | 84 | /* |
85 | * Line Control Register (LCR) | 85 | * Line Control Register (LCR) |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 231b584f6d0..01e811becec 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
@@ -110,11 +110,6 @@ static void mos7720_interrupt_callback(struct urb *urb) | |||
110 | 110 | ||
111 | dbg("%s"," : Entering\n"); | 111 | dbg("%s"," : Entering\n"); |
112 | 112 | ||
113 | if (!urb) { | ||
114 | dbg("%s","Invalid Pointer !!!!:\n"); | ||
115 | return; | ||
116 | } | ||
117 | |||
118 | switch (status) { | 113 | switch (status) { |
119 | case 0: | 114 | case 0: |
120 | /* success */ | 115 | /* success */ |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 37f41f576d3..f76480f1455 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -436,11 +436,6 @@ static void mos7840_control_callback(struct urb *urb) | |||
436 | int result = 0; | 436 | int result = 0; |
437 | int status = urb->status; | 437 | int status = urb->status; |
438 | 438 | ||
439 | if (!urb) { | ||
440 | dbg("%s", "Invalid Pointer !!!!:\n"); | ||
441 | return; | ||
442 | } | ||
443 | |||
444 | mos7840_port = (struct moschip_port *)urb->context; | 439 | mos7840_port = (struct moschip_port *)urb->context; |
445 | 440 | ||
446 | switch (status) { | 441 | switch (status) { |
@@ -525,10 +520,6 @@ static void mos7840_interrupt_callback(struct urb *urb) | |||
525 | int status = urb->status; | 520 | int status = urb->status; |
526 | 521 | ||
527 | dbg("%s", " : Entering\n"); | 522 | dbg("%s", " : Entering\n"); |
528 | if (!urb) { | ||
529 | dbg("%s", "Invalid Pointer !!!!:\n"); | ||
530 | return; | ||
531 | } | ||
532 | 523 | ||
533 | switch (status) { | 524 | switch (status) { |
534 | case 0: | 525 | case 0: |
@@ -676,11 +667,6 @@ static void mos7840_bulk_in_callback(struct urb *urb) | |||
676 | struct tty_struct *tty; | 667 | struct tty_struct *tty; |
677 | int status = urb->status; | 668 | int status = urb->status; |
678 | 669 | ||
679 | if (!urb) { | ||
680 | dbg("%s", "Invalid Pointer !!!!:\n"); | ||
681 | return; | ||
682 | } | ||
683 | |||
684 | if (status) { | 670 | if (status) { |
685 | dbg("nonzero read bulk status received: %d", status); | 671 | dbg("nonzero read bulk status received: %d", status); |
686 | return; | 672 | return; |
@@ -753,11 +739,6 @@ static void mos7840_bulk_out_data_callback(struct urb *urb) | |||
753 | int status = urb->status; | 739 | int status = urb->status; |
754 | int i; | 740 | int i; |
755 | 741 | ||
756 | if (!urb) { | ||
757 | dbg("%s", "Invalid Pointer !!!!:\n"); | ||
758 | return; | ||
759 | } | ||
760 | |||
761 | mos7840_port = (struct moschip_port *)urb->context; | 742 | mos7840_port = (struct moschip_port *)urb->context; |
762 | spin_lock(&mos7840_port->pool_lock); | 743 | spin_lock(&mos7840_port->pool_lock); |
763 | for (i = 0; i < NUM_URBS; i++) { | 744 | for (i = 0; i < NUM_URBS; i++) { |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 84c12b5f127..a18659e0700 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -108,8 +108,10 @@ static int option_send_setup(struct usb_serial_port *port); | |||
108 | #define HUAWEI_VENDOR_ID 0x12D1 | 108 | #define HUAWEI_VENDOR_ID 0x12D1 |
109 | #define HUAWEI_PRODUCT_E600 0x1001 | 109 | #define HUAWEI_PRODUCT_E600 0x1001 |
110 | #define HUAWEI_PRODUCT_E220 0x1003 | 110 | #define HUAWEI_PRODUCT_E220 0x1003 |
111 | #define HUAWEI_PRODUCT_E220BIS 0x1004 | ||
111 | 112 | ||
112 | #define NOVATELWIRELESS_VENDOR_ID 0x1410 | 113 | #define NOVATELWIRELESS_VENDOR_ID 0x1410 |
114 | #define DELL_VENDOR_ID 0x413C | ||
113 | 115 | ||
114 | #define ANYDATA_VENDOR_ID 0x16d5 | 116 | #define ANYDATA_VENDOR_ID 0x16d5 |
115 | #define ANYDATA_PRODUCT_ADU_E100A 0x6501 | 117 | #define ANYDATA_PRODUCT_ADU_E100A 0x6501 |
@@ -119,8 +121,6 @@ static int option_send_setup(struct usb_serial_port *port); | |||
119 | #define BANDRICH_PRODUCT_C100_1 0x1002 | 121 | #define BANDRICH_PRODUCT_C100_1 0x1002 |
120 | #define BANDRICH_PRODUCT_C100_2 0x1003 | 122 | #define BANDRICH_PRODUCT_C100_2 0x1003 |
121 | 123 | ||
122 | #define DELL_VENDOR_ID 0x413C | ||
123 | |||
124 | static struct usb_device_id option_ids[] = { | 124 | static struct usb_device_id option_ids[] = { |
125 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, | 125 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, |
126 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, | 126 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, |
@@ -159,6 +159,7 @@ static struct usb_device_id option_ids[] = { | |||
159 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_NETWORK) }, | 159 | { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_ETNA_KOI_NETWORK) }, |
160 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, | 160 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, |
161 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) }, | 161 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) }, |
162 | { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS) }, | ||
162 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1100) }, /* Novatel Merlin XS620/S640 */ | 163 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1100) }, /* Novatel Merlin XS620/S640 */ |
163 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1110) }, /* Novatel Merlin S620 */ | 164 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1110) }, /* Novatel Merlin S620 */ |
164 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1120) }, /* Novatel Merlin EX720 */ | 165 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x1120) }, /* Novatel Merlin EX720 */ |
@@ -171,11 +172,17 @@ static struct usb_device_id option_ids[] = { | |||
171 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */ | 172 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */ |
172 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */ | 173 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */ |
173 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */ | 174 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */ |
175 | { USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */ | ||
176 | { USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ | ||
177 | { USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */ | ||
178 | { USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */ | ||
179 | { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */ | ||
180 | { USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */ | ||
181 | { USB_DEVICE(DELL_VENDOR_ID, 0x8137) }, /* Dell Wireless HSDPA 5520 */ | ||
174 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, | 182 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, |
175 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, | 183 | { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) }, |
176 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, | 184 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) }, |
177 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, | 185 | { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) }, |
178 | { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard */ | ||
179 | { } /* Terminating entry */ | 186 | { } /* Terminating entry */ |
180 | }; | 187 | }; |
181 | MODULE_DEVICE_TABLE(usb, option_ids); | 188 | MODULE_DEVICE_TABLE(usb, option_ids); |
diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index d7db71eca52..d19861166b5 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c | |||
@@ -817,23 +817,6 @@ static int oti6858_ioctl(struct usb_serial_port *port, struct file *file, | |||
817 | __FUNCTION__, port->number, cmd, arg); | 817 | __FUNCTION__, port->number, cmd, arg); |
818 | 818 | ||
819 | switch (cmd) { | 819 | switch (cmd) { |
820 | case TCGETS: | ||
821 | if (copy_to_user(user_arg, port->tty->termios, | ||
822 | sizeof(struct ktermios))) { | ||
823 | return -EFAULT; | ||
824 | } | ||
825 | return 0; | ||
826 | |||
827 | case TCSETS: | ||
828 | case TCSETSW: /* FIXME: this is not the same! */ | ||
829 | case TCSETSF: /* FIXME: this is not the same! */ | ||
830 | if (copy_from_user(port->tty->termios, user_arg, | ||
831 | sizeof(struct ktermios))) { | ||
832 | return -EFAULT; | ||
833 | } | ||
834 | oti6858_set_termios(port, NULL); | ||
835 | return 0; | ||
836 | |||
837 | case TCFLSH: | 820 | case TCFLSH: |
838 | /* FIXME */ | 821 | /* FIXME */ |
839 | return 0; | 822 | return 0; |
@@ -1161,7 +1144,7 @@ static struct pl2303_buf *pl2303_buf_alloc(unsigned int size) | |||
1161 | if (size == 0) | 1144 | if (size == 0) |
1162 | return NULL; | 1145 | return NULL; |
1163 | 1146 | ||
1164 | pb = (struct pl2303_buf *)kmalloc(sizeof(struct pl2303_buf), GFP_KERNEL); | 1147 | pb = kmalloc(sizeof(struct pl2303_buf), GFP_KERNEL); |
1165 | if (pb == NULL) | 1148 | if (pb == NULL) |
1166 | return NULL; | 1149 | return NULL; |
1167 | 1150 | ||
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index f9f85f56f0d..1da57fd9ea2 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c | |||
@@ -73,6 +73,7 @@ static struct usb_device_id id_table [] = { | |||
73 | { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_SX1) }, | 73 | { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_SX1) }, |
74 | { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65) }, | 74 | { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X65) }, |
75 | { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X75) }, | 75 | { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_X75) }, |
76 | { USB_DEVICE(SIEMENS_VENDOR_ID, SIEMENS_PRODUCT_ID_EF81) }, | ||
76 | { USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) }, | 77 | { USB_DEVICE(SYNTECH_VENDOR_ID, SYNTECH_PRODUCT_ID) }, |
77 | { USB_DEVICE(NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID) }, | 78 | { USB_DEVICE(NOKIA_CA42_VENDOR_ID, NOKIA_CA42_PRODUCT_ID) }, |
78 | { USB_DEVICE(CA_42_CA42_VENDOR_ID, CA_42_CA42_PRODUCT_ID) }, | 79 | { USB_DEVICE(CA_42_CA42_VENDOR_ID, CA_42_CA42_PRODUCT_ID) }, |
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h index f9a71d0c102..c39bace5cbc 100644 --- a/drivers/usb/serial/pl2303.h +++ b/drivers/usb/serial/pl2303.h | |||
@@ -59,6 +59,7 @@ | |||
59 | #define SIEMENS_PRODUCT_ID_SX1 0x0001 | 59 | #define SIEMENS_PRODUCT_ID_SX1 0x0001 |
60 | #define SIEMENS_PRODUCT_ID_X65 0x0003 | 60 | #define SIEMENS_PRODUCT_ID_X65 0x0003 |
61 | #define SIEMENS_PRODUCT_ID_X75 0x0004 | 61 | #define SIEMENS_PRODUCT_ID_X75 0x0004 |
62 | #define SIEMENS_PRODUCT_ID_EF81 0x0005 | ||
62 | 63 | ||
63 | #define SYNTECH_VENDOR_ID 0x0745 | 64 | #define SYNTECH_VENDOR_ID 0x0745 |
64 | #define SYNTECH_PRODUCT_ID 0x0001 | 65 | #define SYNTECH_PRODUCT_ID 0x0001 |
diff --git a/drivers/usb/serial/safe_serial.c b/drivers/usb/serial/safe_serial.c index 86899d55d8d..4e6dcc199be 100644 --- a/drivers/usb/serial/safe_serial.c +++ b/drivers/usb/serial/safe_serial.c | |||
@@ -74,13 +74,13 @@ | |||
74 | #include <linux/usb/serial.h> | 74 | #include <linux/usb/serial.h> |
75 | 75 | ||
76 | 76 | ||
77 | #ifndef CONFIG_USB_SAFE_PADDED | 77 | #ifndef CONFIG_USB_SERIAL_SAFE_PADDED |
78 | #define CONFIG_USB_SAFE_PADDED 0 | 78 | #define CONFIG_USB_SERIAL_SAFE_PADDED 0 |
79 | #endif | 79 | #endif |
80 | 80 | ||
81 | static int debug; | 81 | static int debug; |
82 | static int safe = 1; | 82 | static int safe = 1; |
83 | static int padded = CONFIG_USB_SAFE_PADDED; | 83 | static int padded = CONFIG_USB_SERIAL_SAFE_PADDED; |
84 | 84 | ||
85 | #define DRIVER_VERSION "v0.0b" | 85 | #define DRIVER_VERSION "v0.0b" |
86 | #define DRIVER_AUTHOR "sl@lineo.com, tbr@lineo.com" | 86 | #define DRIVER_AUTHOR "sl@lineo.com, tbr@lineo.com" |
@@ -90,18 +90,12 @@ MODULE_AUTHOR (DRIVER_AUTHOR); | |||
90 | MODULE_DESCRIPTION (DRIVER_DESC); | 90 | MODULE_DESCRIPTION (DRIVER_DESC); |
91 | MODULE_LICENSE("GPL"); | 91 | MODULE_LICENSE("GPL"); |
92 | 92 | ||
93 | #if defined(CONFIG_USBD_SAFE_SERIAL_VENDOR) && !defined(CONFIG_USBD_SAFE_SERIAL_PRODUCT) | ||
94 | #error "SAFE_SERIAL_VENDOR defined without SAFE_SERIAL_PRODUCT" | ||
95 | #endif | ||
96 | |||
97 | #if ! defined(CONFIG_USBD_SAFE_SERIAL_VENDOR) | ||
98 | static __u16 vendor; // no default | 93 | static __u16 vendor; // no default |
99 | static __u16 product; // no default | 94 | static __u16 product; // no default |
100 | module_param(vendor, ushort, 0); | 95 | module_param(vendor, ushort, 0); |
101 | MODULE_PARM_DESC(vendor, "User specified USB idVendor (required)"); | 96 | MODULE_PARM_DESC(vendor, "User specified USB idVendor (required)"); |
102 | module_param(product, ushort, 0); | 97 | module_param(product, ushort, 0); |
103 | MODULE_PARM_DESC(product, "User specified USB idProduct (required)"); | 98 | MODULE_PARM_DESC(product, "User specified USB idProduct (required)"); |
104 | #endif | ||
105 | 99 | ||
106 | module_param(debug, bool, S_IRUGO | S_IWUSR); | 100 | module_param(debug, bool, S_IRUGO | S_IWUSR); |
107 | MODULE_PARM_DESC(debug, "Debug enabled or not"); | 101 | MODULE_PARM_DESC(debug, "Debug enabled or not"); |
@@ -145,11 +139,6 @@ static struct usb_device_id id_table[] = { | |||
145 | {MY_USB_DEVICE (0x4dd, 0x8003, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, // Collie | 139 | {MY_USB_DEVICE (0x4dd, 0x8003, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, // Collie |
146 | {MY_USB_DEVICE (0x4dd, 0x8004, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, // Collie | 140 | {MY_USB_DEVICE (0x4dd, 0x8004, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, // Collie |
147 | {MY_USB_DEVICE (0x5f9, 0xffff, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, // Sharp tmp | 141 | {MY_USB_DEVICE (0x5f9, 0xffff, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, // Sharp tmp |
148 | #if defined(CONFIG_USB_SAFE_SERIAL_VENDOR) | ||
149 | {MY_USB_DEVICE | ||
150 | (CONFIG_USB_SAFE_SERIAL_VENDOR, CONFIG_USB_SAFE_SERIAL_PRODUCT, CDC_DEVICE_CLASS, | ||
151 | LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, | ||
152 | #endif | ||
153 | // extra null entry for module | 142 | // extra null entry for module |
154 | // vendor/produc parameters | 143 | // vendor/produc parameters |
155 | {MY_USB_DEVICE (0, 0, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, | 144 | {MY_USB_DEVICE (0, 0, CDC_DEVICE_CLASS, LINEO_INTERFACE_CLASS, LINEO_INTERFACE_SUBCLASS_SAFESERIAL)}, |
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index e7db20343d1..0bb8de4cc52 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | USB Driver for Sierra Wireless | 2 | USB Driver for Sierra Wireless |
3 | 3 | ||
4 | Copyright (C) 2006 Kevin Lloyd <linux@sierrawireless.com> | 4 | Copyright (C) 2006, 2007 Kevin Lloyd <linux@sierrawireless.com> |
5 | 5 | ||
6 | IMPORTANT DISCLAIMER: This driver is not commercially supported by | 6 | IMPORTANT DISCLAIMER: This driver is not commercially supported by |
7 | Sierra Wireless. Use at your own risk. | 7 | Sierra Wireless. Use at your own risk. |
@@ -12,10 +12,9 @@ | |||
12 | 12 | ||
13 | Portions based on the option driver by Matthias Urlichs <smurf@smurf.noris.de> | 13 | Portions based on the option driver by Matthias Urlichs <smurf@smurf.noris.de> |
14 | Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> | 14 | Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org> |
15 | |||
16 | */ | 15 | */ |
17 | 16 | ||
18 | #define DRIVER_VERSION "v.1.0.6" | 17 | #define DRIVER_VERSION "v.1.2.5b" |
19 | #define DRIVER_AUTHOR "Kevin Lloyd <linux@sierrawireless.com>" | 18 | #define DRIVER_AUTHOR "Kevin Lloyd <linux@sierrawireless.com>" |
20 | #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" | 19 | #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems" |
21 | 20 | ||
@@ -28,23 +27,99 @@ | |||
28 | #include <linux/usb.h> | 27 | #include <linux/usb.h> |
29 | #include <linux/usb/serial.h> | 28 | #include <linux/usb/serial.h> |
30 | 29 | ||
30 | #define SWIMS_USB_REQUEST_SetMode 0x0B | ||
31 | #define SWIMS_USB_REQUEST_TYPE_SetMode 0x40 | ||
32 | #define SWIMS_USB_INDEX_SetMode 0x0000 | ||
33 | #define SWIMS_SET_MODE_Modem 0x0001 | ||
34 | |||
35 | /* per port private data */ | ||
36 | #define N_IN_URB 4 | ||
37 | #define N_OUT_URB 4 | ||
38 | #define IN_BUFLEN 4096 | ||
39 | |||
40 | static int debug; | ||
41 | |||
42 | enum devicetype { | ||
43 | DEVICE_3_PORT = 0, | ||
44 | DEVICE_1_PORT = 1, | ||
45 | DEVICE_INSTALLER = 2, | ||
46 | }; | ||
47 | |||
48 | static int sierra_set_power_state(struct usb_device *udev, __u16 swiState) | ||
49 | { | ||
50 | int result; | ||
51 | dev_dbg(&udev->dev, "%s", "SET POWER STATE"); | ||
52 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
53 | 0x00, /* __u8 request */ | ||
54 | 0x40, /* __u8 request type */ | ||
55 | swiState, /* __u16 value */ | ||
56 | 0, /* __u16 index */ | ||
57 | NULL, /* void *data */ | ||
58 | 0, /* __u16 size */ | ||
59 | USB_CTRL_SET_TIMEOUT); /* int timeout */ | ||
60 | return result; | ||
61 | } | ||
62 | |||
63 | static int sierra_set_ms_mode(struct usb_device *udev, __u16 eSocMode) | ||
64 | { | ||
65 | int result; | ||
66 | dev_dbg(&udev->dev, "%s", "DEVICE MODE SWITCH"); | ||
67 | result = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), | ||
68 | SWIMS_USB_REQUEST_SetMode, /* __u8 request */ | ||
69 | SWIMS_USB_REQUEST_TYPE_SetMode, /* __u8 request type */ | ||
70 | eSocMode, /* __u16 value */ | ||
71 | SWIMS_USB_INDEX_SetMode, /* __u16 index */ | ||
72 | NULL, /* void *data */ | ||
73 | 0, /* __u16 size */ | ||
74 | USB_CTRL_SET_TIMEOUT); /* int timeout */ | ||
75 | return result; | ||
76 | } | ||
77 | |||
78 | static int sierra_probe(struct usb_interface *iface, | ||
79 | const struct usb_device_id *id) | ||
80 | { | ||
81 | int result; | ||
82 | struct usb_device *udev; | ||
83 | |||
84 | udev = usb_get_dev(interface_to_usbdev(iface)); | ||
85 | |||
86 | /* Check if in installer mode */ | ||
87 | if (id->driver_info == DEVICE_INSTALLER) { | ||
88 | dev_dbg(&udev->dev, "%s", "FOUND DEVICE(SW)\n"); | ||
89 | result = sierra_set_ms_mode(udev, SWIMS_SET_MODE_Modem); | ||
90 | /*We do not want to bind to the device when in installer mode*/ | ||
91 | return -EIO; | ||
92 | } | ||
93 | |||
94 | return usb_serial_probe(iface, id); | ||
95 | } | ||
31 | 96 | ||
32 | static struct usb_device_id id_table [] = { | 97 | static struct usb_device_id id_table [] = { |
33 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ | 98 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ |
34 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ | 99 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ |
35 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ | 100 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ |
101 | { USB_DEVICE(0x0f30, 0x1b1d) }, /* Sierra Wireless MC5720 */ | ||
36 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ | 102 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ |
37 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ | 103 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ |
38 | { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless AirCard 595U */ | ||
39 | { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ | 104 | { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ |
105 | { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U */ | ||
106 | |||
40 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ | 107 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ |
41 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ | 108 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ |
42 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ | 109 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ |
43 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ | 110 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ |
44 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ | 111 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ |
112 | { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780*/ | ||
113 | { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781*/ | ||
114 | { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */ | ||
115 | { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */ | ||
116 | { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880 E */ | ||
117 | { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881 E */ | ||
45 | 118 | ||
46 | { USB_DEVICE(0x1199, 0x0112) }, /* Sierra Wireless AirCard 580 */ | 119 | { USB_DEVICE(0x1199, 0x0112), .driver_info = DEVICE_1_PORT }, /* Sierra Wireless AirCard 580 */ |
47 | { USB_DEVICE(0x0F3D, 0x0112) }, /* AirPrime/Sierra PC 5220 */ | 120 | { USB_DEVICE(0x0F3D, 0x0112), .driver_info = DEVICE_1_PORT }, /* Airprime/Sierra PC 5220 */ |
121 | |||
122 | { USB_DEVICE(0x1199, 0x0FFF), .driver_info = DEVICE_INSTALLER}, | ||
48 | { } | 123 | { } |
49 | }; | 124 | }; |
50 | MODULE_DEVICE_TABLE(usb, id_table); | 125 | MODULE_DEVICE_TABLE(usb, id_table); |
@@ -58,35 +133,36 @@ static struct usb_device_id id_table_1port [] = { | |||
58 | static struct usb_device_id id_table_3port [] = { | 133 | static struct usb_device_id id_table_3port [] = { |
59 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ | 134 | { USB_DEVICE(0x1199, 0x0017) }, /* Sierra Wireless EM5625 */ |
60 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ | 135 | { USB_DEVICE(0x1199, 0x0018) }, /* Sierra Wireless MC5720 */ |
136 | { USB_DEVICE(0x0f30, 0x1b1d) }, /* Sierra Wireless MC5720 */ | ||
61 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ | 137 | { USB_DEVICE(0x1199, 0x0218) }, /* Sierra Wireless MC5720 */ |
62 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ | 138 | { USB_DEVICE(0x1199, 0x0020) }, /* Sierra Wireless MC5725 */ |
63 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ | 139 | { USB_DEVICE(0x1199, 0x0019) }, /* Sierra Wireless AirCard 595 */ |
64 | { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless AirCard 595U */ | ||
65 | { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ | 140 | { USB_DEVICE(0x1199, 0x0021) }, /* Sierra Wireless AirCard 597E */ |
141 | { USB_DEVICE(0x1199, 0x0120) }, /* Sierra Wireless USB Dongle 595U*/ | ||
142 | |||
66 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ | 143 | { USB_DEVICE(0x1199, 0x6802) }, /* Sierra Wireless MC8755 */ |
67 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ | 144 | { USB_DEVICE(0x1199, 0x6804) }, /* Sierra Wireless MC8755 */ |
68 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ | 145 | { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */ |
69 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 */ | 146 | { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */ |
70 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ | 147 | { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */ |
148 | { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780*/ | ||
149 | { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781*/ | ||
150 | { USB_DEVICE(0x1199, 0x6850) }, /* Sierra Wireless AirCard 880 */ | ||
151 | { USB_DEVICE(0x1199, 0x6851) }, /* Sierra Wireless AirCard 881 */ | ||
152 | { USB_DEVICE(0x1199, 0x6852) }, /* Sierra Wireless AirCard 880E */ | ||
153 | { USB_DEVICE(0x1199, 0x6853) }, /* Sierra Wireless AirCard 881E */ | ||
71 | { } | 154 | { } |
72 | }; | 155 | }; |
73 | 156 | ||
74 | static struct usb_driver sierra_driver = { | 157 | static struct usb_driver sierra_driver = { |
75 | .name = "sierra", | 158 | .name = "sierra", |
76 | .probe = usb_serial_probe, | 159 | .probe = sierra_probe, |
77 | .disconnect = usb_serial_disconnect, | 160 | .disconnect = usb_serial_disconnect, |
78 | .id_table = id_table, | 161 | .id_table = id_table, |
79 | .no_dynamic_id = 1, | 162 | .no_dynamic_id = 1, |
80 | }; | 163 | }; |
81 | 164 | ||
82 | 165 | ||
83 | static int debug; | ||
84 | |||
85 | /* per port private data */ | ||
86 | #define N_IN_URB 4 | ||
87 | #define N_OUT_URB 4 | ||
88 | #define IN_BUFLEN 4096 | ||
89 | |||
90 | struct sierra_port_private { | 166 | struct sierra_port_private { |
91 | spinlock_t lock; /* lock the structure */ | 167 | spinlock_t lock; /* lock the structure */ |
92 | int outstanding_urbs; /* number of out urbs in flight */ | 168 | int outstanding_urbs; /* number of out urbs in flight */ |
@@ -421,7 +497,6 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp) | |||
421 | int i; | 497 | int i; |
422 | struct urb *urb; | 498 | struct urb *urb; |
423 | int result; | 499 | int result; |
424 | __u16 set_mode_dzero = 0x0000; | ||
425 | 500 | ||
426 | portdata = usb_get_serial_port_data(port); | 501 | portdata = usb_get_serial_port_data(port); |
427 | 502 | ||
@@ -457,12 +532,6 @@ static int sierra_open(struct usb_serial_port *port, struct file *filp) | |||
457 | 532 | ||
458 | port->tty->low_latency = 1; | 533 | port->tty->low_latency = 1; |
459 | 534 | ||
460 | /* set mode to D0 */ | ||
461 | result = usb_control_msg(serial->dev, | ||
462 | usb_rcvctrlpipe(serial->dev, 0), | ||
463 | 0x00, 0x40, set_mode_dzero, 0, NULL, | ||
464 | 0, USB_CTRL_SET_TIMEOUT); | ||
465 | |||
466 | sierra_send_setup(port); | 535 | sierra_send_setup(port); |
467 | 536 | ||
468 | /* start up the interrupt endpoint if we have one */ | 537 | /* start up the interrupt endpoint if we have one */ |
@@ -510,6 +579,9 @@ static int sierra_startup(struct usb_serial *serial) | |||
510 | 579 | ||
511 | dbg("%s", __FUNCTION__); | 580 | dbg("%s", __FUNCTION__); |
512 | 581 | ||
582 | /*Set Device mode to D0 */ | ||
583 | sierra_set_power_state(serial->dev, 0x0000); | ||
584 | |||
513 | /* Now setup per port private data */ | 585 | /* Now setup per port private data */ |
514 | for (i = 0; i < serial->num_ports; i++) { | 586 | for (i = 0; i < serial->num_ports; i++) { |
515 | port = serial->port[i]; | 587 | port = serial->port[i]; |
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index a3665659d13..4b1bd7def4a 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c | |||
@@ -60,19 +60,19 @@ static struct usb_driver usb_serial_driver = { | |||
60 | 60 | ||
61 | static int debug; | 61 | static int debug; |
62 | static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */ | 62 | static struct usb_serial *serial_table[SERIAL_TTY_MINORS]; /* initially all NULL */ |
63 | static spinlock_t table_lock; | 63 | static DEFINE_MUTEX(table_lock); |
64 | static LIST_HEAD(usb_serial_driver_list); | 64 | static LIST_HEAD(usb_serial_driver_list); |
65 | 65 | ||
66 | struct usb_serial *usb_serial_get_by_index(unsigned index) | 66 | struct usb_serial *usb_serial_get_by_index(unsigned index) |
67 | { | 67 | { |
68 | struct usb_serial *serial; | 68 | struct usb_serial *serial; |
69 | 69 | ||
70 | spin_lock(&table_lock); | 70 | mutex_lock(&table_lock); |
71 | serial = serial_table[index]; | 71 | serial = serial_table[index]; |
72 | 72 | ||
73 | if (serial) | 73 | if (serial) |
74 | kref_get(&serial->kref); | 74 | kref_get(&serial->kref); |
75 | spin_unlock(&table_lock); | 75 | mutex_unlock(&table_lock); |
76 | return serial; | 76 | return serial; |
77 | } | 77 | } |
78 | 78 | ||
@@ -84,7 +84,7 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po | |||
84 | dbg("%s %d", __FUNCTION__, num_ports); | 84 | dbg("%s %d", __FUNCTION__, num_ports); |
85 | 85 | ||
86 | *minor = 0; | 86 | *minor = 0; |
87 | spin_lock(&table_lock); | 87 | mutex_lock(&table_lock); |
88 | for (i = 0; i < SERIAL_TTY_MINORS; ++i) { | 88 | for (i = 0; i < SERIAL_TTY_MINORS; ++i) { |
89 | if (serial_table[i]) | 89 | if (serial_table[i]) |
90 | continue; | 90 | continue; |
@@ -106,10 +106,10 @@ static struct usb_serial *get_free_serial (struct usb_serial *serial, int num_po | |||
106 | serial_table[i] = serial; | 106 | serial_table[i] = serial; |
107 | serial->port[j++]->number = i; | 107 | serial->port[j++]->number = i; |
108 | } | 108 | } |
109 | spin_unlock(&table_lock); | 109 | mutex_unlock(&table_lock); |
110 | return serial; | 110 | return serial; |
111 | } | 111 | } |
112 | spin_unlock(&table_lock); | 112 | mutex_unlock(&table_lock); |
113 | return NULL; | 113 | return NULL; |
114 | } | 114 | } |
115 | 115 | ||
@@ -172,9 +172,9 @@ static void destroy_serial(struct kref *kref) | |||
172 | 172 | ||
173 | void usb_serial_put(struct usb_serial *serial) | 173 | void usb_serial_put(struct usb_serial *serial) |
174 | { | 174 | { |
175 | spin_lock(&table_lock); | 175 | mutex_lock(&table_lock); |
176 | kref_put(&serial->kref, destroy_serial); | 176 | kref_put(&serial->kref, destroy_serial); |
177 | spin_unlock(&table_lock); | 177 | mutex_unlock(&table_lock); |
178 | } | 178 | } |
179 | 179 | ||
180 | /***************************************************************************** | 180 | /***************************************************************************** |
@@ -578,6 +578,17 @@ static void kill_traffic(struct usb_serial_port *port) | |||
578 | { | 578 | { |
579 | usb_kill_urb(port->read_urb); | 579 | usb_kill_urb(port->read_urb); |
580 | usb_kill_urb(port->write_urb); | 580 | usb_kill_urb(port->write_urb); |
581 | /* | ||
582 | * This is tricky. | ||
583 | * Some drivers submit the read_urb in the | ||
584 | * handler for the write_urb or vice versa | ||
585 | * this order determines the order in which | ||
586 | * usb_kill_urb() must be used to reliably | ||
587 | * kill the URBs. As it is unknown here, | ||
588 | * both orders must be used in turn. | ||
589 | * The call below is not redundant. | ||
590 | */ | ||
591 | usb_kill_urb(port->read_urb); | ||
581 | usb_kill_urb(port->interrupt_in_urb); | 592 | usb_kill_urb(port->interrupt_in_urb); |
582 | usb_kill_urb(port->interrupt_out_urb); | 593 | usb_kill_urb(port->interrupt_out_urb); |
583 | } | 594 | } |
@@ -651,16 +662,14 @@ exit: | |||
651 | 662 | ||
652 | static struct usb_serial_driver *search_serial_device(struct usb_interface *iface) | 663 | static struct usb_serial_driver *search_serial_device(struct usb_interface *iface) |
653 | { | 664 | { |
654 | struct list_head *p; | ||
655 | const struct usb_device_id *id; | 665 | const struct usb_device_id *id; |
656 | struct usb_serial_driver *t; | 666 | struct usb_serial_driver *drv; |
657 | 667 | ||
658 | /* Check if the usb id matches a known device */ | 668 | /* Check if the usb id matches a known device */ |
659 | list_for_each(p, &usb_serial_driver_list) { | 669 | list_for_each_entry(drv, &usb_serial_driver_list, driver_list) { |
660 | t = list_entry(p, struct usb_serial_driver, driver_list); | 670 | id = get_iface_id(drv, iface); |
661 | id = get_iface_id(t, iface); | ||
662 | if (id) | 671 | if (id) |
663 | return t; | 672 | return drv; |
664 | } | 673 | } |
665 | 674 | ||
666 | return NULL; | 675 | return NULL; |
@@ -800,9 +809,6 @@ int usb_serial_probe(struct usb_interface *interface, | |||
800 | /* END HORRIBLE HACK FOR PL2303 */ | 809 | /* END HORRIBLE HACK FOR PL2303 */ |
801 | #endif | 810 | #endif |
802 | 811 | ||
803 | /* found all that we need */ | ||
804 | dev_info(&interface->dev, "%s converter detected\n", type->description); | ||
805 | |||
806 | #ifdef CONFIG_USB_SERIAL_GENERIC | 812 | #ifdef CONFIG_USB_SERIAL_GENERIC |
807 | if (type == &usb_serial_generic_device) { | 813 | if (type == &usb_serial_generic_device) { |
808 | num_ports = num_bulk_out; | 814 | num_ports = num_bulk_out; |
@@ -836,6 +842,24 @@ int usb_serial_probe(struct usb_interface *interface, | |||
836 | serial->num_interrupt_in = num_interrupt_in; | 842 | serial->num_interrupt_in = num_interrupt_in; |
837 | serial->num_interrupt_out = num_interrupt_out; | 843 | serial->num_interrupt_out = num_interrupt_out; |
838 | 844 | ||
845 | /* check that the device meets the driver's requirements */ | ||
846 | if ((type->num_interrupt_in != NUM_DONT_CARE && | ||
847 | type->num_interrupt_in != num_interrupt_in) | ||
848 | || (type->num_interrupt_out != NUM_DONT_CARE && | ||
849 | type->num_interrupt_out != num_interrupt_out) | ||
850 | || (type->num_bulk_in != NUM_DONT_CARE && | ||
851 | type->num_bulk_in != num_bulk_in) | ||
852 | || (type->num_bulk_out != NUM_DONT_CARE && | ||
853 | type->num_bulk_out != num_bulk_out)) { | ||
854 | dbg("wrong number of endpoints"); | ||
855 | kfree(serial); | ||
856 | return -EIO; | ||
857 | } | ||
858 | |||
859 | /* found all that we need */ | ||
860 | dev_info(&interface->dev, "%s converter detected\n", | ||
861 | type->description); | ||
862 | |||
839 | /* create our ports, we need as many as the max endpoints */ | 863 | /* create our ports, we need as many as the max endpoints */ |
840 | /* we don't use num_ports here cauz some devices have more endpoint pairs than ports */ | 864 | /* we don't use num_ports here cauz some devices have more endpoint pairs than ports */ |
841 | max_endpoints = max(num_bulk_in, num_bulk_out); | 865 | max_endpoints = max(num_bulk_in, num_bulk_out); |
@@ -1077,16 +1101,17 @@ int usb_serial_suspend(struct usb_interface *intf, pm_message_t message) | |||
1077 | struct usb_serial_port *port; | 1101 | struct usb_serial_port *port; |
1078 | int i, r = 0; | 1102 | int i, r = 0; |
1079 | 1103 | ||
1080 | if (serial) { | 1104 | if (!serial) /* device has been disconnected */ |
1081 | for (i = 0; i < serial->num_ports; ++i) { | 1105 | return 0; |
1082 | port = serial->port[i]; | 1106 | |
1083 | if (port) | 1107 | for (i = 0; i < serial->num_ports; ++i) { |
1084 | kill_traffic(port); | 1108 | port = serial->port[i]; |
1085 | } | 1109 | if (port) |
1110 | kill_traffic(port); | ||
1086 | } | 1111 | } |
1087 | 1112 | ||
1088 | if (serial->type->suspend) | 1113 | if (serial->type->suspend) |
1089 | serial->type->suspend(serial, message); | 1114 | r = serial->type->suspend(serial, message); |
1090 | 1115 | ||
1091 | return r; | 1116 | return r; |
1092 | } | 1117 | } |
@@ -1128,7 +1153,6 @@ static int __init usb_serial_init(void) | |||
1128 | return -ENOMEM; | 1153 | return -ENOMEM; |
1129 | 1154 | ||
1130 | /* Initialize our global data */ | 1155 | /* Initialize our global data */ |
1131 | spin_lock_init(&table_lock); | ||
1132 | for (i = 0; i < SERIAL_TTY_MINORS; ++i) { | 1156 | for (i = 0; i < SERIAL_TTY_MINORS; ++i) { |
1133 | serial_table[i] = NULL; | 1157 | serial_table[i] = NULL; |
1134 | } | 1158 | } |
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 7d84a7647e8..7ee087fed91 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c | |||
@@ -46,7 +46,6 @@ static int visor_probe (struct usb_serial *serial, const struct usb_device_id | |||
46 | static int visor_calc_num_ports(struct usb_serial *serial); | 46 | static int visor_calc_num_ports(struct usb_serial *serial); |
47 | static void visor_shutdown (struct usb_serial *serial); | 47 | static void visor_shutdown (struct usb_serial *serial); |
48 | static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); | 48 | static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsigned int cmd, unsigned long arg); |
49 | static void visor_set_termios (struct usb_serial_port *port, struct ktermios *old_termios); | ||
50 | static void visor_write_bulk_callback (struct urb *urb); | 49 | static void visor_write_bulk_callback (struct urb *urb); |
51 | static void visor_read_bulk_callback (struct urb *urb); | 50 | static void visor_read_bulk_callback (struct urb *urb); |
52 | static void visor_read_int_callback (struct urb *urb); | 51 | static void visor_read_int_callback (struct urb *urb); |
@@ -104,6 +103,8 @@ static struct usb_device_id id_table [] = { | |||
104 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, | 103 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, |
105 | { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID), | 104 | { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID), |
106 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, | 105 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, |
106 | { USB_DEVICE(ACER_VENDOR_ID, ACER_S10_ID), | ||
107 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, | ||
107 | { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID), | 108 | { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID), |
108 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, | 109 | .driver_info = (kernel_ulong_t)&palm_os_4_probe }, |
109 | { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID), | 110 | { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID), |
@@ -201,7 +202,6 @@ static struct usb_serial_driver handspring_device = { | |||
201 | .calc_num_ports = visor_calc_num_ports, | 202 | .calc_num_ports = visor_calc_num_ports, |
202 | .shutdown = visor_shutdown, | 203 | .shutdown = visor_shutdown, |
203 | .ioctl = visor_ioctl, | 204 | .ioctl = visor_ioctl, |
204 | .set_termios = visor_set_termios, | ||
205 | .write = visor_write, | 205 | .write = visor_write, |
206 | .write_room = visor_write_room, | 206 | .write_room = visor_write_room, |
207 | .chars_in_buffer = visor_chars_in_buffer, | 207 | .chars_in_buffer = visor_chars_in_buffer, |
@@ -232,7 +232,6 @@ static struct usb_serial_driver clie_5_device = { | |||
232 | .calc_num_ports = visor_calc_num_ports, | 232 | .calc_num_ports = visor_calc_num_ports, |
233 | .shutdown = visor_shutdown, | 233 | .shutdown = visor_shutdown, |
234 | .ioctl = visor_ioctl, | 234 | .ioctl = visor_ioctl, |
235 | .set_termios = visor_set_termios, | ||
236 | .write = visor_write, | 235 | .write = visor_write, |
237 | .write_room = visor_write_room, | 236 | .write_room = visor_write_room, |
238 | .chars_in_buffer = visor_chars_in_buffer, | 237 | .chars_in_buffer = visor_chars_in_buffer, |
@@ -260,7 +259,6 @@ static struct usb_serial_driver clie_3_5_device = { | |||
260 | .unthrottle = visor_unthrottle, | 259 | .unthrottle = visor_unthrottle, |
261 | .attach = clie_3_5_startup, | 260 | .attach = clie_3_5_startup, |
262 | .ioctl = visor_ioctl, | 261 | .ioctl = visor_ioctl, |
263 | .set_termios = visor_set_termios, | ||
264 | .write = visor_write, | 262 | .write = visor_write, |
265 | .write_room = visor_write_room, | 263 | .write_room = visor_write_room, |
266 | .chars_in_buffer = visor_chars_in_buffer, | 264 | .chars_in_buffer = visor_chars_in_buffer, |
@@ -934,66 +932,6 @@ static int visor_ioctl (struct usb_serial_port *port, struct file * file, unsign | |||
934 | return -ENOIOCTLCMD; | 932 | return -ENOIOCTLCMD; |
935 | } | 933 | } |
936 | 934 | ||
937 | |||
938 | /* This function is all nice and good, but we don't change anything based on it :) */ | ||
939 | static void visor_set_termios (struct usb_serial_port *port, struct ktermios *old_termios) | ||
940 | { | ||
941 | unsigned int cflag; | ||
942 | |||
943 | dbg("%s - port %d", __FUNCTION__, port->number); | ||
944 | |||
945 | if ((!port->tty) || (!port->tty->termios)) { | ||
946 | dbg("%s - no tty structures", __FUNCTION__); | ||
947 | return; | ||
948 | } | ||
949 | |||
950 | cflag = port->tty->termios->c_cflag; | ||
951 | |||
952 | /* get the byte size */ | ||
953 | switch (cflag & CSIZE) { | ||
954 | case CS5: dbg("%s - data bits = 5", __FUNCTION__); break; | ||
955 | case CS6: dbg("%s - data bits = 6", __FUNCTION__); break; | ||
956 | case CS7: dbg("%s - data bits = 7", __FUNCTION__); break; | ||
957 | default: | ||
958 | case CS8: dbg("%s - data bits = 8", __FUNCTION__); break; | ||
959 | } | ||
960 | |||
961 | /* determine the parity */ | ||
962 | if (cflag & PARENB) | ||
963 | if (cflag & PARODD) | ||
964 | dbg("%s - parity = odd", __FUNCTION__); | ||
965 | else | ||
966 | dbg("%s - parity = even", __FUNCTION__); | ||
967 | else | ||
968 | dbg("%s - parity = none", __FUNCTION__); | ||
969 | |||
970 | /* figure out the stop bits requested */ | ||
971 | if (cflag & CSTOPB) | ||
972 | dbg("%s - stop bits = 2", __FUNCTION__); | ||
973 | else | ||
974 | dbg("%s - stop bits = 1", __FUNCTION__); | ||
975 | |||
976 | |||
977 | /* figure out the flow control settings */ | ||
978 | if (cflag & CRTSCTS) | ||
979 | dbg("%s - RTS/CTS is enabled", __FUNCTION__); | ||
980 | else | ||
981 | dbg("%s - RTS/CTS is disabled", __FUNCTION__); | ||
982 | |||
983 | /* determine software flow control */ | ||
984 | if (I_IXOFF(port->tty)) | ||
985 | dbg("%s - XON/XOFF is enabled, XON = %2x, XOFF = %2x", | ||
986 | __FUNCTION__, START_CHAR(port->tty), STOP_CHAR(port->tty)); | ||
987 | else | ||
988 | dbg("%s - XON/XOFF is disabled", __FUNCTION__); | ||
989 | |||
990 | /* get the baud rate wanted */ | ||
991 | dbg("%s - baud rate = %d", __FUNCTION__, tty_get_baud_rate(port->tty)); | ||
992 | |||
993 | return; | ||
994 | } | ||
995 | |||
996 | |||
997 | static int __init visor_init (void) | 935 | static int __init visor_init (void) |
998 | { | 936 | { |
999 | int i, retval; | 937 | int i, retval; |
diff --git a/drivers/usb/serial/visor.h b/drivers/usb/serial/visor.h index 4ce6f62a6f3..57229cf6647 100644 --- a/drivers/usb/serial/visor.h +++ b/drivers/usb/serial/visor.h | |||
@@ -48,6 +48,9 @@ | |||
48 | #define SONY_CLIE_UX50_ID 0x0144 | 48 | #define SONY_CLIE_UX50_ID 0x0144 |
49 | #define SONY_CLIE_TJ25_ID 0x0169 | 49 | #define SONY_CLIE_TJ25_ID 0x0169 |
50 | 50 | ||
51 | #define ACER_VENDOR_ID 0x0502 | ||
52 | #define ACER_S10_ID 0x0001 | ||
53 | |||
51 | #define SAMSUNG_VENDOR_ID 0x04E8 | 54 | #define SAMSUNG_VENDOR_ID 0x04E8 |
52 | #define SAMSUNG_SCH_I330_ID 0x8001 | 55 | #define SAMSUNG_SCH_I330_ID 0x8001 |
53 | #define SAMSUNG_SPH_I500_ID 0x6601 | 56 | #define SAMSUNG_SPH_I500_ID 0x6601 |
diff --git a/drivers/usb/storage/dpcm.c b/drivers/usb/storage/dpcm.c index 1628cb25856..9a410b5a6e5 100644 --- a/drivers/usb/storage/dpcm.c +++ b/drivers/usb/storage/dpcm.c | |||
@@ -46,43 +46,43 @@ | |||
46 | */ | 46 | */ |
47 | int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us) | 47 | int dpcm_transport(struct scsi_cmnd *srb, struct us_data *us) |
48 | { | 48 | { |
49 | int ret; | 49 | int ret; |
50 | 50 | ||
51 | if(srb == NULL) | 51 | if (srb == NULL) |
52 | return USB_STOR_TRANSPORT_ERROR; | 52 | return USB_STOR_TRANSPORT_ERROR; |
53 | 53 | ||
54 | US_DEBUGP("dpcm_transport: LUN=%d\n", srb->device->lun); | 54 | US_DEBUGP("dpcm_transport: LUN=%d\n", srb->device->lun); |
55 | 55 | ||
56 | switch(srb->device->lun) { | 56 | switch (srb->device->lun) { |
57 | case 0: | 57 | case 0: |
58 | 58 | ||
59 | /* | 59 | /* |
60 | * LUN 0 corresponds to the CompactFlash card reader. | 60 | * LUN 0 corresponds to the CompactFlash card reader. |
61 | */ | 61 | */ |
62 | ret = usb_stor_CB_transport(srb, us); | 62 | ret = usb_stor_CB_transport(srb, us); |
63 | break; | 63 | break; |
64 | 64 | ||
65 | #ifdef CONFIG_USB_STORAGE_SDDR09 | 65 | #ifdef CONFIG_USB_STORAGE_SDDR09 |
66 | case 1: | 66 | case 1: |
67 | 67 | ||
68 | /* | 68 | /* |
69 | * LUN 1 corresponds to the SmartMedia card reader. | 69 | * LUN 1 corresponds to the SmartMedia card reader. |
70 | */ | 70 | */ |
71 | 71 | ||
72 | /* | 72 | /* |
73 | * Set the LUN to 0 (just in case). | 73 | * Set the LUN to 0 (just in case). |
74 | */ | 74 | */ |
75 | srb->device->lun = 0; us->srb->device->lun = 0; | 75 | srb->device->lun = 0; us->srb->device->lun = 0; |
76 | ret = sddr09_transport(srb, us); | 76 | ret = sddr09_transport(srb, us); |
77 | srb->device->lun = 1; us->srb->device->lun = 1; | 77 | srb->device->lun = 1; us->srb->device->lun = 1; |
78 | break; | 78 | break; |
79 | 79 | ||
80 | #endif | 80 | #endif |
81 | 81 | ||
82 | default: | 82 | default: |
83 | US_DEBUGP("dpcm_transport: Invalid LUN %d\n", srb->device->lun); | 83 | US_DEBUGP("dpcm_transport: Invalid LUN %d\n", srb->device->lun); |
84 | ret = USB_STOR_TRANSPORT_ERROR; | 84 | ret = USB_STOR_TRANSPORT_ERROR; |
85 | break; | 85 | break; |
86 | } | 86 | } |
87 | return ret; | 87 | return ret; |
88 | } | 88 | } |
diff --git a/drivers/usb/storage/initializers.c b/drivers/usb/storage/initializers.c index 3a41740cad9..ee5b42aa536 100644 --- a/drivers/usb/storage/initializers.c +++ b/drivers/usb/storage/initializers.c | |||
@@ -90,3 +90,17 @@ int usb_stor_ucr61s2b_init(struct us_data *us) | |||
90 | 90 | ||
91 | return (res ? -1 : 0); | 91 | return (res ? -1 : 0); |
92 | } | 92 | } |
93 | |||
94 | /* This places the HUAWEI E220 devices in multi-port mode */ | ||
95 | int usb_stor_huawei_e220_init(struct us_data *us) | ||
96 | { | ||
97 | int result; | ||
98 | |||
99 | us->iobuf[0] = 0x1; | ||
100 | result = usb_stor_control_msg(us, us->send_ctrl_pipe, | ||
101 | USB_REQ_SET_FEATURE, | ||
102 | USB_TYPE_STANDARD | USB_RECIP_DEVICE, | ||
103 | 0x01, 0x0, us->iobuf, 0x1, 1000); | ||
104 | US_DEBUGP("usb_control_msg performing result is %d\n", result); | ||
105 | return (result ? 0 : -1); | ||
106 | } | ||
diff --git a/drivers/usb/storage/initializers.h b/drivers/usb/storage/initializers.h index e2967a4d48a..ad3ffd4236c 100644 --- a/drivers/usb/storage/initializers.h +++ b/drivers/usb/storage/initializers.h | |||
@@ -47,3 +47,6 @@ int usb_stor_euscsi_init(struct us_data *us); | |||
47 | /* This function is required to activate all four slots on the UCR-61S2B | 47 | /* This function is required to activate all four slots on the UCR-61S2B |
48 | * flash reader */ | 48 | * flash reader */ |
49 | int usb_stor_ucr61s2b_init(struct us_data *us); | 49 | int usb_stor_ucr61s2b_init(struct us_data *us); |
50 | |||
51 | /* This places the HUAWEI E220 devices in multi-port mode */ | ||
52 | int usb_stor_huawei_e220_init(struct us_data *us); | ||
diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index d35369392fe..dfd42fe9e5f 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c | |||
@@ -57,9 +57,10 @@ static void usb_onetouch_irq(struct urb *urb) | |||
57 | struct usb_onetouch *onetouch = urb->context; | 57 | struct usb_onetouch *onetouch = urb->context; |
58 | signed char *data = onetouch->data; | 58 | signed char *data = onetouch->data; |
59 | struct input_dev *dev = onetouch->dev; | 59 | struct input_dev *dev = onetouch->dev; |
60 | int status; | 60 | int status = urb->status; |
61 | int retval; | ||
61 | 62 | ||
62 | switch (urb->status) { | 63 | switch (status) { |
63 | case 0: /* success */ | 64 | case 0: /* success */ |
64 | break; | 65 | break; |
65 | case -ECONNRESET: /* unlink */ | 66 | case -ECONNRESET: /* unlink */ |
@@ -75,11 +76,11 @@ static void usb_onetouch_irq(struct urb *urb) | |||
75 | input_sync(dev); | 76 | input_sync(dev); |
76 | 77 | ||
77 | resubmit: | 78 | resubmit: |
78 | status = usb_submit_urb (urb, GFP_ATOMIC); | 79 | retval = usb_submit_urb (urb, GFP_ATOMIC); |
79 | if (status) | 80 | if (retval) |
80 | err ("can't resubmit intr, %s-%s/input0, status %d", | 81 | err ("can't resubmit intr, %s-%s/input0, retval %d", |
81 | onetouch->udev->bus->bus_name, | 82 | onetouch->udev->bus->bus_name, |
82 | onetouch->udev->devpath, status); | 83 | onetouch->udev->devpath, retval); |
83 | } | 84 | } |
84 | 85 | ||
85 | static int usb_onetouch_open(struct input_dev *dev) | 86 | static int usb_onetouch_open(struct input_dev *dev) |
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 47e56079925..1ba19eaa197 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c | |||
@@ -285,15 +285,10 @@ static int device_reset(struct scsi_cmnd *srb) | |||
285 | 285 | ||
286 | US_DEBUGP("%s called\n", __FUNCTION__); | 286 | US_DEBUGP("%s called\n", __FUNCTION__); |
287 | 287 | ||
288 | result = usb_autopm_get_interface(us->pusb_intf); | 288 | /* lock the device pointers and do the reset */ |
289 | if (result == 0) { | 289 | mutex_lock(&(us->dev_mutex)); |
290 | 290 | result = us->transport_reset(us); | |
291 | /* lock the device pointers and do the reset */ | 291 | mutex_unlock(&us->dev_mutex); |
292 | mutex_lock(&(us->dev_mutex)); | ||
293 | result = us->transport_reset(us); | ||
294 | mutex_unlock(&us->dev_mutex); | ||
295 | usb_autopm_put_interface(us->pusb_intf); | ||
296 | } | ||
297 | 292 | ||
298 | return result < 0 ? FAILED : SUCCESS; | 293 | return result < 0 ? FAILED : SUCCESS; |
299 | } | 294 | } |
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index 5e27297c017..17ca4d73577 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c | |||
@@ -190,9 +190,6 @@ static int usbat_check_status(struct us_data *us) | |||
190 | unsigned char *reply = us->iobuf; | 190 | unsigned char *reply = us->iobuf; |
191 | int rc; | 191 | int rc; |
192 | 192 | ||
193 | if (!us) | ||
194 | return USB_STOR_TRANSPORT_ERROR; | ||
195 | |||
196 | rc = usbat_get_status(us, reply); | 193 | rc = usbat_get_status(us, reply); |
197 | if (rc != USB_STOR_XFER_GOOD) | 194 | if (rc != USB_STOR_XFER_GOOD) |
198 | return USB_STOR_TRANSPORT_FAILED; | 195 | return USB_STOR_TRANSPORT_FAILED; |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index b6bf31a97b6..9b656ec427d 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -198,7 +198,7 @@ UNUSUAL_DEV( 0x0421, 0x044e, 0x0100, 0x0100, | |||
198 | US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), | 198 | US_FL_IGNORE_RESIDUE | US_FL_FIX_CAPACITY ), |
199 | 199 | ||
200 | /* Reported by Bardur Arantsson <bardur@scientician.net> */ | 200 | /* Reported by Bardur Arantsson <bardur@scientician.net> */ |
201 | UNUSUAL_DEV( 0x0421, 0x047c, 0x0370, 0x0370, | 201 | UNUSUAL_DEV( 0x0421, 0x047c, 0x0370, 0x0610, |
202 | "Nokia", | 202 | "Nokia", |
203 | "6131", | 203 | "6131", |
204 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 204 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
@@ -313,6 +313,20 @@ UNUSUAL_DEV( 0x04b0, 0x0301, 0x0010, 0x0010, | |||
313 | US_SC_DEVICE, US_PR_DEVICE,NULL, | 313 | US_SC_DEVICE, US_PR_DEVICE,NULL, |
314 | US_FL_NOT_LOCKABLE ), | 314 | US_FL_NOT_LOCKABLE ), |
315 | 315 | ||
316 | /* Reported by Stefan de Konink <skinkie@xs4all.nl> */ | ||
317 | UNUSUAL_DEV( 0x04b0, 0x0401, 0x0200, 0x0200, | ||
318 | "NIKON", | ||
319 | "NIKON DSC D100", | ||
320 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
321 | US_FL_FIX_CAPACITY), | ||
322 | |||
323 | /* Reported by Milinevsky Dmitry <niam.niam@gmail.com> */ | ||
324 | UNUSUAL_DEV( 0x04b0, 0x0409, 0x0100, 0x0100, | ||
325 | "NIKON", | ||
326 | "NIKON DSC D50", | ||
327 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
328 | US_FL_FIX_CAPACITY), | ||
329 | |||
316 | /* Reported by Andreas Bockhold <andreas@bockionline.de> */ | 330 | /* Reported by Andreas Bockhold <andreas@bockionline.de> */ |
317 | UNUSUAL_DEV( 0x04b0, 0x0405, 0x0100, 0x0100, | 331 | UNUSUAL_DEV( 0x04b0, 0x0405, 0x0100, 0x0100, |
318 | "NIKON", | 332 | "NIKON", |
@@ -327,13 +341,41 @@ UNUSUAL_DEV( 0x04b0, 0x040d, 0x0100, 0x0100, | |||
327 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 341 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
328 | US_FL_FIX_CAPACITY), | 342 | US_FL_FIX_CAPACITY), |
329 | 343 | ||
344 | /* Reported by Graber and Mike Pagano <mpagano-kernel@mpagano.com> */ | ||
345 | UNUSUAL_DEV( 0x04b0, 0x040f, 0x0200, 0x0200, | ||
346 | "NIKON", | ||
347 | "NIKON DSC D200", | ||
348 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
349 | US_FL_FIX_CAPACITY), | ||
350 | |||
330 | /* Reported by Emil Larsson <emil@swip.net> */ | 351 | /* Reported by Emil Larsson <emil@swip.net> */ |
331 | UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0100, | 352 | UNUSUAL_DEV( 0x04b0, 0x0411, 0x0100, 0x0101, |
332 | "NIKON", | 353 | "NIKON", |
333 | "NIKON DSC D80", | 354 | "NIKON DSC D80", |
334 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 355 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
335 | US_FL_FIX_CAPACITY), | 356 | US_FL_FIX_CAPACITY), |
336 | 357 | ||
358 | /* Reported by Ortwin Glueck <odi@odi.ch> */ | ||
359 | UNUSUAL_DEV( 0x04b0, 0x0413, 0x0110, 0x0110, | ||
360 | "NIKON", | ||
361 | "NIKON DSC D40", | ||
362 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
363 | US_FL_FIX_CAPACITY), | ||
364 | |||
365 | /* Reported by Paul Check <paul@openstreet.com> */ | ||
366 | UNUSUAL_DEV( 0x04b0, 0x0415, 0x0100, 0x0100, | ||
367 | "NIKON", | ||
368 | "NIKON DSC D2Xs", | ||
369 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
370 | US_FL_FIX_CAPACITY), | ||
371 | |||
372 | /* Reported by Shan Destromp (shansan@gmail.com) */ | ||
373 | UNUSUAL_DEV( 0x04b0, 0x0417, 0x0100, 0x0100, | ||
374 | "NIKON", | ||
375 | "NIKON DSC D40X", | ||
376 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
377 | US_FL_FIX_CAPACITY), | ||
378 | |||
337 | /* BENQ DC5330 | 379 | /* BENQ DC5330 |
338 | * Reported by Manuel Fombuena <mfombuena@ya.com> and | 380 | * Reported by Manuel Fombuena <mfombuena@ya.com> and |
339 | * Frank Copeland <fjc@thingy.apana.org.au> */ | 381 | * Frank Copeland <fjc@thingy.apana.org.au> */ |
@@ -883,6 +925,22 @@ UNUSUAL_DEV( 0x069b, 0x3004, 0x0001, 0x0001, | |||
883 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 925 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
884 | US_FL_FIX_CAPACITY ), | 926 | US_FL_FIX_CAPACITY ), |
885 | 927 | ||
928 | /* Reported by Massimiliano Ghilardi <massimiliano.ghilardi@gmail.com> | ||
929 | * This USB MP3/AVI player device fails and disconnects if more than 128 | ||
930 | * sectors (64kB) are read/written in a single command, and may be present | ||
931 | * at least in the following products: | ||
932 | * "Magnex Digital Video Panel DVP 1800" | ||
933 | * "MP4 AIGO 4GB SLOT SD" | ||
934 | * "Teclast TL-C260 MP3" | ||
935 | * "i.Meizu PMP MP3/MP4" | ||
936 | * "Speed MV8 MP4 Audio Player" | ||
937 | */ | ||
938 | UNUSUAL_DEV( 0x071b, 0x3203, 0x0100, 0x0100, | ||
939 | "RockChip", | ||
940 | "ROCK MP3", | ||
941 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
942 | US_FL_MAX_SECTORS_64), | ||
943 | |||
886 | /* Reported by Olivier Blondeau <zeitoun@gmail.com> */ | 944 | /* Reported by Olivier Blondeau <zeitoun@gmail.com> */ |
887 | UNUSUAL_DEV( 0x0727, 0x0306, 0x0100, 0x0100, | 945 | UNUSUAL_DEV( 0x0727, 0x0306, 0x0100, 0x0100, |
888 | "ATMEL", | 946 | "ATMEL", |
@@ -1350,6 +1408,20 @@ UNUSUAL_DEV( 0x0f19, 0x0105, 0x0100, 0x0100, | |||
1350 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1408 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1351 | US_FL_IGNORE_RESIDUE ), | 1409 | US_FL_IGNORE_RESIDUE ), |
1352 | 1410 | ||
1411 | /* Jeremy Katz <katzj@redhat.com>: | ||
1412 | * The Blackberry Pearl can run in two modes; a usb-storage only mode | ||
1413 | * and a mode that allows access via mass storage and to its database. | ||
1414 | * The berry_charge module will set the device to dual mode and thus we | ||
1415 | * should ignore its native mode if that module is built | ||
1416 | */ | ||
1417 | #ifdef CONFIG_USB_BERRY_CHARGE | ||
1418 | UNUSUAL_DEV( 0x0fca, 0x0006, 0x0001, 0x0001, | ||
1419 | "RIM", | ||
1420 | "Blackberry Pearl", | ||
1421 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1422 | US_FL_IGNORE_DEVICE ), | ||
1423 | #endif | ||
1424 | |||
1353 | /* Reported by Michael Stattmann <michael@stattmann.com> */ | 1425 | /* Reported by Michael Stattmann <michael@stattmann.com> */ |
1354 | UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, | 1426 | UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, |
1355 | "Sony Ericsson", | 1427 | "Sony Ericsson", |
@@ -1365,6 +1437,13 @@ UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000, | |||
1365 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1437 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1366 | US_FL_FIX_CAPACITY | US_FL_IGNORE_RESIDUE ), | 1438 | US_FL_FIX_CAPACITY | US_FL_IGNORE_RESIDUE ), |
1367 | 1439 | ||
1440 | /* Reported by Ricardo Barberis <ricardo@dattatec.com> */ | ||
1441 | UNUSUAL_DEV( 0x0fce, 0xe092, 0x0000, 0x0000, | ||
1442 | "Sony Ericsson", | ||
1443 | "P1i", | ||
1444 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1445 | US_FL_IGNORE_RESIDUE ), | ||
1446 | |||
1368 | /* Reported by Emmanuel Vasilakis <evas@forthnet.gr> */ | 1447 | /* Reported by Emmanuel Vasilakis <evas@forthnet.gr> */ |
1369 | UNUSUAL_DEV( 0x0fce, 0xe031, 0x0000, 0x0000, | 1448 | UNUSUAL_DEV( 0x0fce, 0xe031, 0x0000, 0x0000, |
1370 | "Sony Ericsson", | 1449 | "Sony Ericsson", |
@@ -1384,6 +1463,17 @@ UNUSUAL_DEV( 0x1019, 0x0c55, 0x0000, 0x0110, | |||
1384 | US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init, | 1463 | US_SC_DEVICE, US_PR_DEVICE, usb_stor_ucr61s2b_init, |
1385 | 0 ), | 1464 | 0 ), |
1386 | 1465 | ||
1466 | /* Reported by Kevin Lloyd <linux@sierrawireless.com> | ||
1467 | * Entry is needed for the initializer function override, | ||
1468 | * which instructs the device to load as a modem | ||
1469 | * device. | ||
1470 | */ | ||
1471 | UNUSUAL_DEV( 0x1199, 0x0fff, 0x0000, 0x9999, | ||
1472 | "Sierra Wireless", | ||
1473 | "USB MMC Storage", | ||
1474 | US_SC_DEVICE, US_PR_DEVICE, NULL, | ||
1475 | US_FL_IGNORE_DEVICE), | ||
1476 | |||
1387 | /* Reported by Jaco Kroon <jaco@kroon.co.za> | 1477 | /* Reported by Jaco Kroon <jaco@kroon.co.za> |
1388 | * The usb-storage module found on the Digitech GNX4 (and supposedly other | 1478 | * The usb-storage module found on the Digitech GNX4 (and supposedly other |
1389 | * devices) misbehaves and causes a bunch of invalid I/O errors. | 1479 | * devices) misbehaves and causes a bunch of invalid I/O errors. |
@@ -1394,6 +1484,17 @@ UNUSUAL_DEV( 0x1210, 0x0003, 0x0100, 0x0100, | |||
1394 | US_SC_DEVICE, US_PR_DEVICE, NULL, | 1484 | US_SC_DEVICE, US_PR_DEVICE, NULL, |
1395 | US_FL_IGNORE_RESIDUE ), | 1485 | US_FL_IGNORE_RESIDUE ), |
1396 | 1486 | ||
1487 | /* Reported by fangxiaozhi <fangxiaozhi60675@huawei.com> | ||
1488 | * and by linlei <linlei83@huawei.com> | ||
1489 | * Patch reworked by Johann Wilhelm <johann.wilhelm@student.tugraz.at> | ||
1490 | * This brings the HUAWEI E220 devices into multi-port mode | ||
1491 | */ | ||
1492 | UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0x0000, | ||
1493 | "HUAWEI MOBILE", | ||
1494 | "Mass Storage", | ||
1495 | US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init, | ||
1496 | 0), | ||
1497 | |||
1397 | /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */ | 1498 | /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */ |
1398 | UNUSUAL_DEV( 0x132b, 0x000b, 0x0001, 0x0001, | 1499 | UNUSUAL_DEV( 0x132b, 0x000b, 0x0001, 0x0001, |
1399 | "Minolta", | 1500 | "Minolta", |
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 28842d208bb..3451e8d03ab 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c | |||
@@ -112,13 +112,6 @@ module_param(delay_use, uint, S_IRUGO | S_IWUSR); | |||
112 | MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device"); | 112 | MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device"); |
113 | 113 | ||
114 | 114 | ||
115 | /* These are used to make sure the module doesn't unload before all the | ||
116 | * threads have exited. | ||
117 | */ | ||
118 | static atomic_t total_threads = ATOMIC_INIT(0); | ||
119 | static DECLARE_COMPLETION(threads_gone); | ||
120 | |||
121 | |||
122 | /* | 115 | /* |
123 | * The entries in this table correspond, line for line, | 116 | * The entries in this table correspond, line for line, |
124 | * with the entries of us_unusual_dev_list[]. | 117 | * with the entries of us_unusual_dev_list[]. |
@@ -191,14 +184,16 @@ static int storage_suspend(struct usb_interface *iface, pm_message_t message) | |||
191 | { | 184 | { |
192 | struct us_data *us = usb_get_intfdata(iface); | 185 | struct us_data *us = usb_get_intfdata(iface); |
193 | 186 | ||
194 | US_DEBUGP("%s\n", __FUNCTION__); | ||
195 | |||
196 | /* Wait until no command is running */ | 187 | /* Wait until no command is running */ |
197 | mutex_lock(&us->dev_mutex); | 188 | mutex_lock(&us->dev_mutex); |
198 | 189 | ||
190 | US_DEBUGP("%s\n", __FUNCTION__); | ||
199 | if (us->suspend_resume_hook) | 191 | if (us->suspend_resume_hook) |
200 | (us->suspend_resume_hook)(us, US_SUSPEND); | 192 | (us->suspend_resume_hook)(us, US_SUSPEND); |
201 | 193 | ||
194 | /* When runtime PM is working, we'll set a flag to indicate | ||
195 | * whether we should autoresume when a SCSI request arrives. */ | ||
196 | |||
202 | mutex_unlock(&us->dev_mutex); | 197 | mutex_unlock(&us->dev_mutex); |
203 | return 0; | 198 | return 0; |
204 | } | 199 | } |
@@ -207,11 +202,13 @@ static int storage_resume(struct usb_interface *iface) | |||
207 | { | 202 | { |
208 | struct us_data *us = usb_get_intfdata(iface); | 203 | struct us_data *us = usb_get_intfdata(iface); |
209 | 204 | ||
210 | US_DEBUGP("%s\n", __FUNCTION__); | 205 | mutex_lock(&us->dev_mutex); |
211 | 206 | ||
207 | US_DEBUGP("%s\n", __FUNCTION__); | ||
212 | if (us->suspend_resume_hook) | 208 | if (us->suspend_resume_hook) |
213 | (us->suspend_resume_hook)(us, US_RESUME); | 209 | (us->suspend_resume_hook)(us, US_RESUME); |
214 | 210 | ||
211 | mutex_unlock(&us->dev_mutex); | ||
215 | return 0; | 212 | return 0; |
216 | } | 213 | } |
217 | 214 | ||
@@ -309,7 +306,6 @@ static int usb_stor_control_thread(void * __us) | |||
309 | { | 306 | { |
310 | struct us_data *us = (struct us_data *)__us; | 307 | struct us_data *us = (struct us_data *)__us; |
311 | struct Scsi_Host *host = us_to_host(us); | 308 | struct Scsi_Host *host = us_to_host(us); |
312 | int autopm_rc; | ||
313 | 309 | ||
314 | for(;;) { | 310 | for(;;) { |
315 | US_DEBUGP("*** thread sleeping.\n"); | 311 | US_DEBUGP("*** thread sleeping.\n"); |
@@ -318,9 +314,6 @@ static int usb_stor_control_thread(void * __us) | |||
318 | 314 | ||
319 | US_DEBUGP("*** thread awakened.\n"); | 315 | US_DEBUGP("*** thread awakened.\n"); |
320 | 316 | ||
321 | /* Autoresume the device */ | ||
322 | autopm_rc = usb_autopm_get_interface(us->pusb_intf); | ||
323 | |||
324 | /* lock the device pointers */ | 317 | /* lock the device pointers */ |
325 | mutex_lock(&(us->dev_mutex)); | 318 | mutex_lock(&(us->dev_mutex)); |
326 | 319 | ||
@@ -379,12 +372,6 @@ static int usb_stor_control_thread(void * __us) | |||
379 | us->srb->result = SAM_STAT_GOOD; | 372 | us->srb->result = SAM_STAT_GOOD; |
380 | } | 373 | } |
381 | 374 | ||
382 | /* Did the autoresume fail? */ | ||
383 | else if (autopm_rc < 0) { | ||
384 | US_DEBUGP("Could not wake device\n"); | ||
385 | us->srb->result = DID_ERROR << 16; | ||
386 | } | ||
387 | |||
388 | /* we've got a command, let's do it! */ | 375 | /* we've got a command, let's do it! */ |
389 | else { | 376 | else { |
390 | US_DEBUG(usb_stor_show_command(us->srb)); | 377 | US_DEBUG(usb_stor_show_command(us->srb)); |
@@ -427,10 +414,6 @@ SkipForAbort: | |||
427 | 414 | ||
428 | /* unlock the device pointers */ | 415 | /* unlock the device pointers */ |
429 | mutex_unlock(&us->dev_mutex); | 416 | mutex_unlock(&us->dev_mutex); |
430 | |||
431 | /* Start an autosuspend */ | ||
432 | if (autopm_rc == 0) | ||
433 | usb_autopm_put_interface(us->pusb_intf); | ||
434 | } /* for (;;) */ | 417 | } /* for (;;) */ |
435 | 418 | ||
436 | /* Wait until we are told to stop */ | 419 | /* Wait until we are told to stop */ |
@@ -879,9 +862,6 @@ static void quiesce_and_remove_host(struct us_data *us) | |||
879 | usb_stor_stop_transport(us); | 862 | usb_stor_stop_transport(us); |
880 | wake_up(&us->delay_wait); | 863 | wake_up(&us->delay_wait); |
881 | 864 | ||
882 | /* It doesn't matter if the SCSI-scanning thread is still running. | ||
883 | * The thread will exit when it sees the DISCONNECTING flag. */ | ||
884 | |||
885 | /* queuecommand won't accept any new commands and the control | 865 | /* queuecommand won't accept any new commands and the control |
886 | * thread won't execute a previously-queued command. If there | 866 | * thread won't execute a previously-queued command. If there |
887 | * is such a command pending, complete it with an error. */ | 867 | * is such a command pending, complete it with an error. */ |
@@ -891,12 +871,16 @@ static void quiesce_and_remove_host(struct us_data *us) | |||
891 | scsi_lock(host); | 871 | scsi_lock(host); |
892 | us->srb->scsi_done(us->srb); | 872 | us->srb->scsi_done(us->srb); |
893 | us->srb = NULL; | 873 | us->srb = NULL; |
874 | complete(&us->notify); /* in case of an abort */ | ||
894 | scsi_unlock(host); | 875 | scsi_unlock(host); |
895 | } | 876 | } |
896 | mutex_unlock(&us->dev_mutex); | 877 | mutex_unlock(&us->dev_mutex); |
897 | 878 | ||
898 | /* Now we own no commands so it's safe to remove the SCSI host */ | 879 | /* Now we own no commands so it's safe to remove the SCSI host */ |
899 | scsi_remove_host(host); | 880 | scsi_remove_host(host); |
881 | |||
882 | /* Wait for the SCSI-scanning thread to stop */ | ||
883 | wait_for_completion(&us->scanning_done); | ||
900 | } | 884 | } |
901 | 885 | ||
902 | /* Second stage of disconnect processing: deallocate all resources */ | 886 | /* Second stage of disconnect processing: deallocate all resources */ |
@@ -947,9 +931,7 @@ retry: | |||
947 | /* Should we unbind if no devices were detected? */ | 931 | /* Should we unbind if no devices were detected? */ |
948 | } | 932 | } |
949 | 933 | ||
950 | scsi_host_put(us_to_host(us)); | 934 | complete_and_exit(&us->scanning_done, 0); |
951 | usb_autopm_put_interface(us->pusb_intf); | ||
952 | complete_and_exit(&threads_gone, 0); | ||
953 | } | 935 | } |
954 | 936 | ||
955 | 937 | ||
@@ -978,12 +960,17 @@ static int storage_probe(struct usb_interface *intf, | |||
978 | return -ENOMEM; | 960 | return -ENOMEM; |
979 | } | 961 | } |
980 | 962 | ||
963 | /* | ||
964 | * Allow 16-byte CDBs and thus > 2TB | ||
965 | */ | ||
966 | host->max_cmd_len = 16; | ||
981 | us = host_to_us(host); | 967 | us = host_to_us(host); |
982 | memset(us, 0, sizeof(struct us_data)); | 968 | memset(us, 0, sizeof(struct us_data)); |
983 | mutex_init(&(us->dev_mutex)); | 969 | mutex_init(&(us->dev_mutex)); |
984 | init_MUTEX_LOCKED(&(us->sema)); | 970 | init_MUTEX_LOCKED(&(us->sema)); |
985 | init_completion(&(us->notify)); | 971 | init_completion(&(us->notify)); |
986 | init_waitqueue_head(&us->delay_wait); | 972 | init_waitqueue_head(&us->delay_wait); |
973 | init_completion(&us->scanning_done); | ||
987 | 974 | ||
988 | /* Associate the us_data structure with the USB device */ | 975 | /* Associate the us_data structure with the USB device */ |
989 | result = associate_dev(us, intf); | 976 | result = associate_dev(us, intf); |
@@ -1033,12 +1020,6 @@ static int storage_probe(struct usb_interface *intf, | |||
1033 | goto BadDevice; | 1020 | goto BadDevice; |
1034 | } | 1021 | } |
1035 | 1022 | ||
1036 | /* Take a reference to the host for the scanning thread and | ||
1037 | * count it among all the threads we have launched. Then | ||
1038 | * start it up. */ | ||
1039 | scsi_host_get(us_to_host(us)); | ||
1040 | atomic_inc(&total_threads); | ||
1041 | usb_autopm_get_interface(intf); /* dropped in the scanning thread */ | ||
1042 | wake_up_process(th); | 1023 | wake_up_process(th); |
1043 | 1024 | ||
1044 | return 0; | 1025 | return 0; |
@@ -1076,7 +1057,6 @@ static struct usb_driver usb_storage_driver = { | |||
1076 | .pre_reset = storage_pre_reset, | 1057 | .pre_reset = storage_pre_reset, |
1077 | .post_reset = storage_post_reset, | 1058 | .post_reset = storage_post_reset, |
1078 | .id_table = storage_usb_ids, | 1059 | .id_table = storage_usb_ids, |
1079 | .supports_autosuspend = 1, | ||
1080 | }; | 1060 | }; |
1081 | 1061 | ||
1082 | static int __init usb_stor_init(void) | 1062 | static int __init usb_stor_init(void) |
@@ -1104,16 +1084,6 @@ static void __exit usb_stor_exit(void) | |||
1104 | US_DEBUGP("-- calling usb_deregister()\n"); | 1084 | US_DEBUGP("-- calling usb_deregister()\n"); |
1105 | usb_deregister(&usb_storage_driver) ; | 1085 | usb_deregister(&usb_storage_driver) ; |
1106 | 1086 | ||
1107 | /* Don't return until all of our control and scanning threads | ||
1108 | * have exited. Since each thread signals threads_gone as its | ||
1109 | * last act, we have to call wait_for_completion the right number | ||
1110 | * of times. | ||
1111 | */ | ||
1112 | while (atomic_read(&total_threads) > 0) { | ||
1113 | wait_for_completion(&threads_gone); | ||
1114 | atomic_dec(&total_threads); | ||
1115 | } | ||
1116 | |||
1117 | usb_usual_clear_present(USB_US_TYPE_STOR); | 1087 | usb_usual_clear_present(USB_US_TYPE_STOR); |
1118 | } | 1088 | } |
1119 | 1089 | ||
diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 6445665b157..8d87503e256 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h | |||
@@ -150,6 +150,7 @@ struct us_data { | |||
150 | struct semaphore sema; /* to sleep thread on */ | 150 | struct semaphore sema; /* to sleep thread on */ |
151 | struct completion notify; /* thread begin/end */ | 151 | struct completion notify; /* thread begin/end */ |
152 | wait_queue_head_t delay_wait; /* wait during scan, reset */ | 152 | wait_queue_head_t delay_wait; /* wait during scan, reset */ |
153 | struct completion scanning_done; /* wait for scan thread */ | ||
153 | 154 | ||
154 | /* subdriver information */ | 155 | /* subdriver information */ |
155 | void *extra; /* Any extra data */ | 156 | void *extra; /* Any extra data */ |
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index 8de11deb5d1..c815a40e167 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c | |||
@@ -125,6 +125,7 @@ static int skel_open(struct inode *inode, struct file *file) | |||
125 | 125 | ||
126 | /* save our object in the file's private structure */ | 126 | /* save our object in the file's private structure */ |
127 | file->private_data = dev; | 127 | file->private_data = dev; |
128 | mutex_unlock(&dev->io_mutex); | ||
128 | 129 | ||
129 | exit: | 130 | exit: |
130 | return retval; | 131 | return retval; |