diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2011-12-13 12:37:40 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-12-13 12:37:40 -0500 |
commit | 121a8cdd79e2c68ae78c7633f2a46ee65a177ff6 (patch) | |
tree | 03793bef35f590718ebc6ae6110eb0c507ae60bf /drivers/usb/renesas_usbhs | |
parent | a1016ce33ce23296ad030e5276fcfdf9cb27cb6a (diff) | |
parent | 15a3838b101b292c2e40824d843a4d8871ac4010 (diff) |
Merge branch 'for-next/gadget' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb into usb-next
* 'for-next/gadget' of git://git.kernel.org/pub/scm/linux/kernel/git/balbi/usb: (50 commits)
usb: renesas_usbhs: show error reason on usbhsh_urb_enqueu()
usb: renesas_usbhs: add force packet remove method
usb: renesas_usbhs: care usb_hcd_giveback_urb() status
usb: renesas_usbhs: add usbhsh_is_running()
usb: renesas_usbhs: disable attch irq after device attached
usb: renesas_usbhs: care pipe sequence
usb: renesas_usbhs: add usbhs_pipe_attach() method
usb: renesas_usbhs: add usbhsh_endpoint_detach_all() for error case
usb: renesas_usbhs: modify device attach method
usb: renesas_usbhs: pop packet when urb dequeued
usb: renesas_usbhs: add lost error value when enqueue
usb: gadget: mv_udc: replace some debug info
usb: gadget: mv_udc: refine suspend/resume function
usb: gadget: mv_udc: refine the clock relative code
usb: gadget: mv_udc: disable ISR when stopped
usb: gadget: mv_udc: add otg relative code
usb: gadget: Use kcalloc instead of kzalloc to allocate array
usb: renesas_usbhs: remove the_controller_link
usb: renesas_usbhs: add test-mode support
usb: renesas_usbhs: call usbhsg_queue_pop() when pipe disable.
...
Diffstat (limited to 'drivers/usb/renesas_usbhs')
-rw-r--r-- | drivers/usb/renesas_usbhs/common.c | 39 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/common.h | 9 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/fifo.c | 9 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/fifo.h | 3 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/mod.c | 4 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/mod_gadget.c | 193 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/mod_host.c | 953 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/pipe.c | 28 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/pipe.h | 1 |
9 files changed, 814 insertions, 425 deletions
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index aa94e33e6885..e9a5b1d2615e 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c | |||
@@ -95,25 +95,15 @@ struct usbhs_priv *usbhs_pdev_to_priv(struct platform_device *pdev) | |||
95 | /* | 95 | /* |
96 | * syscfg functions | 96 | * syscfg functions |
97 | */ | 97 | */ |
98 | void usbhs_sys_clock_ctrl(struct usbhs_priv *priv, int enable) | 98 | static void usbhs_sys_clock_ctrl(struct usbhs_priv *priv, int enable) |
99 | { | 99 | { |
100 | usbhs_bset(priv, SYSCFG, SCKE, enable ? SCKE : 0); | 100 | usbhs_bset(priv, SYSCFG, SCKE, enable ? SCKE : 0); |
101 | } | 101 | } |
102 | 102 | ||
103 | void usbhs_sys_hispeed_ctrl(struct usbhs_priv *priv, int enable) | ||
104 | { | ||
105 | usbhs_bset(priv, SYSCFG, HSE, enable ? HSE : 0); | ||
106 | } | ||
107 | |||
108 | void usbhs_sys_usb_ctrl(struct usbhs_priv *priv, int enable) | ||
109 | { | ||
110 | usbhs_bset(priv, SYSCFG, USBE, enable ? USBE : 0); | ||
111 | } | ||
112 | |||
113 | void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable) | 103 | void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable) |
114 | { | 104 | { |
115 | u16 mask = DCFM | DRPD | DPRPU; | 105 | u16 mask = DCFM | DRPD | DPRPU | HSE | USBE; |
116 | u16 val = DCFM | DRPD; | 106 | u16 val = DCFM | DRPD | HSE | USBE; |
117 | int has_otg = usbhs_get_dparam(priv, has_otg); | 107 | int has_otg = usbhs_get_dparam(priv, has_otg); |
118 | 108 | ||
119 | if (has_otg) | 109 | if (has_otg) |
@@ -130,8 +120,8 @@ void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable) | |||
130 | 120 | ||
131 | void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable) | 121 | void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable) |
132 | { | 122 | { |
133 | u16 mask = DCFM | DRPD | DPRPU; | 123 | u16 mask = DCFM | DRPD | DPRPU | HSE | USBE; |
134 | u16 val = DPRPU; | 124 | u16 val = DPRPU | HSE | USBE; |
135 | 125 | ||
136 | /* | 126 | /* |
137 | * if enable | 127 | * if enable |
@@ -142,6 +132,11 @@ void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable) | |||
142 | usbhs_bset(priv, SYSCFG, mask, enable ? val : 0); | 132 | usbhs_bset(priv, SYSCFG, mask, enable ? val : 0); |
143 | } | 133 | } |
144 | 134 | ||
135 | void usbhs_sys_set_test_mode(struct usbhs_priv *priv, u16 mode) | ||
136 | { | ||
137 | usbhs_write(priv, TESTMODE, mode); | ||
138 | } | ||
139 | |||
145 | /* | 140 | /* |
146 | * frame functions | 141 | * frame functions |
147 | */ | 142 | */ |
@@ -229,7 +224,7 @@ static void usbhsc_bus_init(struct usbhs_priv *priv) | |||
229 | /* | 224 | /* |
230 | * device configuration | 225 | * device configuration |
231 | */ | 226 | */ |
232 | int usbhs_set_device_speed(struct usbhs_priv *priv, int devnum, | 227 | int usbhs_set_device_config(struct usbhs_priv *priv, int devnum, |
233 | u16 upphub, u16 hubport, u16 speed) | 228 | u16 upphub, u16 hubport, u16 speed) |
234 | { | 229 | { |
235 | struct device *dev = usbhs_priv_to_dev(priv); | 230 | struct device *dev = usbhs_priv_to_dev(priv); |
@@ -301,18 +296,25 @@ static u32 usbhsc_default_pipe_type[] = { | |||
301 | */ | 296 | */ |
302 | static void usbhsc_power_ctrl(struct usbhs_priv *priv, int enable) | 297 | static void usbhsc_power_ctrl(struct usbhs_priv *priv, int enable) |
303 | { | 298 | { |
299 | struct platform_device *pdev = usbhs_priv_to_pdev(priv); | ||
304 | struct device *dev = usbhs_priv_to_dev(priv); | 300 | struct device *dev = usbhs_priv_to_dev(priv); |
305 | 301 | ||
306 | if (enable) { | 302 | if (enable) { |
307 | /* enable PM */ | 303 | /* enable PM */ |
308 | pm_runtime_get_sync(dev); | 304 | pm_runtime_get_sync(dev); |
309 | 305 | ||
306 | /* enable platform power */ | ||
307 | usbhs_platform_call(priv, power_ctrl, pdev, priv->base, enable); | ||
308 | |||
310 | /* USB on */ | 309 | /* USB on */ |
311 | usbhs_sys_clock_ctrl(priv, enable); | 310 | usbhs_sys_clock_ctrl(priv, enable); |
312 | } else { | 311 | } else { |
313 | /* USB off */ | 312 | /* USB off */ |
314 | usbhs_sys_clock_ctrl(priv, enable); | 313 | usbhs_sys_clock_ctrl(priv, enable); |
315 | 314 | ||
315 | /* disable platform power */ | ||
316 | usbhs_platform_call(priv, power_ctrl, pdev, priv->base, enable); | ||
317 | |||
316 | /* disable PM */ | 318 | /* disable PM */ |
317 | pm_runtime_put_sync(dev); | 319 | pm_runtime_put_sync(dev); |
318 | } | 320 | } |
@@ -388,7 +390,7 @@ static void usbhsc_notify_hotplug(struct work_struct *work) | |||
388 | usbhsc_hotplug(priv); | 390 | usbhsc_hotplug(priv); |
389 | } | 391 | } |
390 | 392 | ||
391 | int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev) | 393 | static int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev) |
392 | { | 394 | { |
393 | struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); | 395 | struct usbhs_priv *priv = usbhs_pdev_to_priv(pdev); |
394 | int delay = usbhs_get_dparam(priv, detection_delay); | 396 | int delay = usbhs_get_dparam(priv, detection_delay); |
@@ -398,7 +400,8 @@ int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev) | |||
398 | * To make sure safety context, | 400 | * To make sure safety context, |
399 | * use workqueue for usbhs_notify_hotplug | 401 | * use workqueue for usbhs_notify_hotplug |
400 | */ | 402 | */ |
401 | schedule_delayed_work(&priv->notify_hotplug_work, delay); | 403 | schedule_delayed_work(&priv->notify_hotplug_work, |
404 | msecs_to_jiffies(delay)); | ||
402 | return 0; | 405 | return 0; |
403 | } | 406 | } |
404 | 407 | ||
diff --git a/drivers/usb/renesas_usbhs/common.h b/drivers/usb/renesas_usbhs/common.h index 8729da5c3be6..d79b3e27db95 100644 --- a/drivers/usb/renesas_usbhs/common.h +++ b/drivers/usb/renesas_usbhs/common.h | |||
@@ -33,6 +33,7 @@ struct usbhs_priv; | |||
33 | #define SYSCFG 0x0000 | 33 | #define SYSCFG 0x0000 |
34 | #define BUSWAIT 0x0002 | 34 | #define BUSWAIT 0x0002 |
35 | #define DVSTCTR 0x0008 | 35 | #define DVSTCTR 0x0008 |
36 | #define TESTMODE 0x000C | ||
36 | #define CFIFO 0x0014 | 37 | #define CFIFO 0x0014 |
37 | #define CFIFOSEL 0x0020 | 38 | #define CFIFOSEL 0x0020 |
38 | #define CFIFOCTR 0x0022 | 39 | #define CFIFOCTR 0x0022 |
@@ -275,19 +276,15 @@ u16 usbhs_read(struct usbhs_priv *priv, u32 reg); | |||
275 | void usbhs_write(struct usbhs_priv *priv, u32 reg, u16 data); | 276 | void usbhs_write(struct usbhs_priv *priv, u32 reg, u16 data); |
276 | void usbhs_bset(struct usbhs_priv *priv, u32 reg, u16 mask, u16 data); | 277 | void usbhs_bset(struct usbhs_priv *priv, u32 reg, u16 mask, u16 data); |
277 | 278 | ||
278 | int usbhsc_drvcllbck_notify_hotplug(struct platform_device *pdev); | ||
279 | |||
280 | #define usbhs_lock(p, f) spin_lock_irqsave(usbhs_priv_to_lock(p), f) | 279 | #define usbhs_lock(p, f) spin_lock_irqsave(usbhs_priv_to_lock(p), f) |
281 | #define usbhs_unlock(p, f) spin_unlock_irqrestore(usbhs_priv_to_lock(p), f) | 280 | #define usbhs_unlock(p, f) spin_unlock_irqrestore(usbhs_priv_to_lock(p), f) |
282 | 281 | ||
283 | /* | 282 | /* |
284 | * sysconfig | 283 | * sysconfig |
285 | */ | 284 | */ |
286 | void usbhs_sys_clock_ctrl(struct usbhs_priv *priv, int enable); | ||
287 | void usbhs_sys_hispeed_ctrl(struct usbhs_priv *priv, int enable); | ||
288 | void usbhs_sys_usb_ctrl(struct usbhs_priv *priv, int enable); | ||
289 | void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable); | 285 | void usbhs_sys_host_ctrl(struct usbhs_priv *priv, int enable); |
290 | void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable); | 286 | void usbhs_sys_function_ctrl(struct usbhs_priv *priv, int enable); |
287 | void usbhs_sys_set_test_mode(struct usbhs_priv *priv, u16 mode); | ||
291 | 288 | ||
292 | /* | 289 | /* |
293 | * usb request | 290 | * usb request |
@@ -311,7 +308,7 @@ int usbhs_frame_get_num(struct usbhs_priv *priv); | |||
311 | /* | 308 | /* |
312 | * device config | 309 | * device config |
313 | */ | 310 | */ |
314 | int usbhs_set_device_speed(struct usbhs_priv *priv, int devnum, u16 upphub, | 311 | int usbhs_set_device_config(struct usbhs_priv *priv, int devnum, u16 upphub, |
315 | u16 hubport, u16 speed); | 312 | u16 hubport, u16 speed); |
316 | 313 | ||
317 | /* | 314 | /* |
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index ffdf5d15085e..b51fcd80d244 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c | |||
@@ -56,7 +56,7 @@ static struct usbhs_pkt_handle usbhsf_null_handler = { | |||
56 | void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt, | 56 | void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt, |
57 | void (*done)(struct usbhs_priv *priv, | 57 | void (*done)(struct usbhs_priv *priv, |
58 | struct usbhs_pkt *pkt), | 58 | struct usbhs_pkt *pkt), |
59 | void *buf, int len, int zero) | 59 | void *buf, int len, int zero, int sequence) |
60 | { | 60 | { |
61 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); | 61 | struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); |
62 | struct device *dev = usbhs_priv_to_dev(priv); | 62 | struct device *dev = usbhs_priv_to_dev(priv); |
@@ -90,6 +90,7 @@ void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt, | |||
90 | pkt->zero = zero; | 90 | pkt->zero = zero; |
91 | pkt->actual = 0; | 91 | pkt->actual = 0; |
92 | pkt->done = done; | 92 | pkt->done = done; |
93 | pkt->sequence = sequence; | ||
93 | 94 | ||
94 | usbhs_unlock(priv, flags); | 95 | usbhs_unlock(priv, flags); |
95 | /******************** spin unlock ******************/ | 96 | /******************** spin unlock ******************/ |
@@ -481,6 +482,9 @@ static int usbhsf_pio_try_push(struct usbhs_pkt *pkt, int *is_done) | |||
481 | int i, ret, len; | 482 | int i, ret, len; |
482 | int is_short; | 483 | int is_short; |
483 | 484 | ||
485 | usbhs_pipe_data_sequence(pipe, pkt->sequence); | ||
486 | pkt->sequence = -1; /* -1 sequence will be ignored */ | ||
487 | |||
484 | ret = usbhsf_fifo_select(pipe, fifo, 1); | 488 | ret = usbhsf_fifo_select(pipe, fifo, 1); |
485 | if (ret < 0) | 489 | if (ret < 0) |
486 | return 0; | 490 | return 0; |
@@ -584,6 +588,8 @@ static int usbhsf_prepare_pop(struct usbhs_pkt *pkt, int *is_done) | |||
584 | /* | 588 | /* |
585 | * pipe enable to prepare packet receive | 589 | * pipe enable to prepare packet receive |
586 | */ | 590 | */ |
591 | usbhs_pipe_data_sequence(pipe, pkt->sequence); | ||
592 | pkt->sequence = -1; /* -1 sequence will be ignored */ | ||
587 | 593 | ||
588 | usbhs_pipe_enable(pipe); | 594 | usbhs_pipe_enable(pipe); |
589 | usbhsf_rx_irq_ctrl(pipe, 1); | 595 | usbhsf_rx_irq_ctrl(pipe, 1); |
@@ -641,6 +647,7 @@ static int usbhsf_pio_try_pop(struct usbhs_pkt *pkt, int *is_done) | |||
641 | * "Operation" - "FIFO Buffer Memory" - "FIFO Port Function" | 647 | * "Operation" - "FIFO Buffer Memory" - "FIFO Port Function" |
642 | */ | 648 | */ |
643 | if (0 == rcv_len) { | 649 | if (0 == rcv_len) { |
650 | pkt->zero = 1; | ||
644 | usbhsf_fifo_clear(pipe, fifo); | 651 | usbhsf_fifo_clear(pipe, fifo); |
645 | goto usbhs_fifo_read_end; | 652 | goto usbhs_fifo_read_end; |
646 | } | 653 | } |
diff --git a/drivers/usb/renesas_usbhs/fifo.h b/drivers/usb/renesas_usbhs/fifo.h index 32a7b246b28d..f68609c0f489 100644 --- a/drivers/usb/renesas_usbhs/fifo.h +++ b/drivers/usb/renesas_usbhs/fifo.h | |||
@@ -59,6 +59,7 @@ struct usbhs_pkt { | |||
59 | int trans; | 59 | int trans; |
60 | int actual; | 60 | int actual; |
61 | int zero; | 61 | int zero; |
62 | int sequence; | ||
62 | }; | 63 | }; |
63 | 64 | ||
64 | struct usbhs_pkt_handle { | 65 | struct usbhs_pkt_handle { |
@@ -95,7 +96,7 @@ void usbhs_pkt_init(struct usbhs_pkt *pkt); | |||
95 | void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt, | 96 | void usbhs_pkt_push(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt, |
96 | void (*done)(struct usbhs_priv *priv, | 97 | void (*done)(struct usbhs_priv *priv, |
97 | struct usbhs_pkt *pkt), | 98 | struct usbhs_pkt *pkt), |
98 | void *buf, int len, int zero); | 99 | void *buf, int len, int zero, int sequence); |
99 | struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt); | 100 | struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt); |
100 | void usbhs_pkt_start(struct usbhs_pipe *pipe); | 101 | void usbhs_pkt_start(struct usbhs_pipe *pipe); |
101 | 102 | ||
diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c index 053f86d70009..f382e4314362 100644 --- a/drivers/usb/renesas_usbhs/mod.c +++ b/drivers/usb/renesas_usbhs/mod.c | |||
@@ -50,7 +50,9 @@ static int usbhsm_autonomy_irq_vbus(struct usbhs_priv *priv, | |||
50 | { | 50 | { |
51 | struct platform_device *pdev = usbhs_priv_to_pdev(priv); | 51 | struct platform_device *pdev = usbhs_priv_to_pdev(priv); |
52 | 52 | ||
53 | return usbhsc_drvcllbck_notify_hotplug(pdev); | 53 | renesas_usbhs_call_notify_hotplug(pdev); |
54 | |||
55 | return 0; | ||
54 | } | 56 | } |
55 | 57 | ||
56 | void usbhs_mod_autonomy_mode(struct usbhs_priv *priv) | 58 | void usbhs_mod_autonomy_mode(struct usbhs_priv *priv) |
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c index 7f4e80338570..db2a1c6a0866 100644 --- a/drivers/usb/renesas_usbhs/mod_gadget.c +++ b/drivers/usb/renesas_usbhs/mod_gadget.c | |||
@@ -14,6 +14,7 @@ | |||
14 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 14 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
15 | * | 15 | * |
16 | */ | 16 | */ |
17 | #include <linux/delay.h> | ||
17 | #include <linux/dma-mapping.h> | 18 | #include <linux/dma-mapping.h> |
18 | #include <linux/io.h> | 19 | #include <linux/io.h> |
19 | #include <linux/module.h> | 20 | #include <linux/module.h> |
@@ -44,7 +45,6 @@ struct usbhsg_uep { | |||
44 | struct usbhsg_gpriv { | 45 | struct usbhsg_gpriv { |
45 | struct usb_gadget gadget; | 46 | struct usb_gadget gadget; |
46 | struct usbhs_mod mod; | 47 | struct usbhs_mod mod; |
47 | struct list_head link; | ||
48 | 48 | ||
49 | struct usbhsg_uep *uep; | 49 | struct usbhsg_uep *uep; |
50 | int uep_size; | 50 | int uep_size; |
@@ -114,16 +114,6 @@ struct usbhsg_recip_handle { | |||
114 | #define usbhsg_status_clr(gp, b) (gp->status &= ~b) | 114 | #define usbhsg_status_clr(gp, b) (gp->status &= ~b) |
115 | #define usbhsg_status_has(gp, b) (gp->status & b) | 115 | #define usbhsg_status_has(gp, b) (gp->status & b) |
116 | 116 | ||
117 | /* controller */ | ||
118 | LIST_HEAD(the_controller_link); | ||
119 | |||
120 | #define usbhsg_for_each_controller(gpriv)\ | ||
121 | list_for_each_entry(gpriv, &the_controller_link, link) | ||
122 | #define usbhsg_controller_register(gpriv)\ | ||
123 | list_add_tail(&(gpriv)->link, &the_controller_link) | ||
124 | #define usbhsg_controller_unregister(gpriv)\ | ||
125 | list_del_init(&(gpriv)->link) | ||
126 | |||
127 | /* | 117 | /* |
128 | * queue push/pop | 118 | * queue push/pop |
129 | */ | 119 | */ |
@@ -164,7 +154,7 @@ static void usbhsg_queue_push(struct usbhsg_uep *uep, | |||
164 | req->actual = 0; | 154 | req->actual = 0; |
165 | req->status = -EINPROGRESS; | 155 | req->status = -EINPROGRESS; |
166 | usbhs_pkt_push(pipe, pkt, usbhsg_queue_done, | 156 | usbhs_pkt_push(pipe, pkt, usbhsg_queue_done, |
167 | req->buf, req->length, req->zero); | 157 | req->buf, req->length, req->zero, -1); |
168 | usbhs_pkt_start(pipe); | 158 | usbhs_pkt_start(pipe); |
169 | 159 | ||
170 | dev_dbg(dev, "pipe %d : queue push (%d)\n", | 160 | dev_dbg(dev, "pipe %d : queue push (%d)\n", |
@@ -271,6 +261,8 @@ static int usbhsg_recip_handler_std_clear_endpoint(struct usbhs_priv *priv, | |||
271 | 261 | ||
272 | usbhsg_recip_handler_std_control_done(priv, uep, ctrl); | 262 | usbhsg_recip_handler_std_control_done(priv, uep, ctrl); |
273 | 263 | ||
264 | usbhs_pkt_start(pipe); | ||
265 | |||
274 | return 0; | 266 | return 0; |
275 | } | 267 | } |
276 | 268 | ||
@@ -282,6 +274,145 @@ struct usbhsg_recip_handle req_clear_feature = { | |||
282 | }; | 274 | }; |
283 | 275 | ||
284 | /* | 276 | /* |
277 | * USB_TYPE_STANDARD / set feature functions | ||
278 | */ | ||
279 | static int usbhsg_recip_handler_std_set_device(struct usbhs_priv *priv, | ||
280 | struct usbhsg_uep *uep, | ||
281 | struct usb_ctrlrequest *ctrl) | ||
282 | { | ||
283 | switch (le16_to_cpu(ctrl->wValue)) { | ||
284 | case USB_DEVICE_TEST_MODE: | ||
285 | usbhsg_recip_handler_std_control_done(priv, uep, ctrl); | ||
286 | udelay(100); | ||
287 | usbhs_sys_set_test_mode(priv, le16_to_cpu(ctrl->wIndex >> 8)); | ||
288 | break; | ||
289 | default: | ||
290 | usbhsg_recip_handler_std_control_done(priv, uep, ctrl); | ||
291 | break; | ||
292 | } | ||
293 | |||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | static int usbhsg_recip_handler_std_set_endpoint(struct usbhs_priv *priv, | ||
298 | struct usbhsg_uep *uep, | ||
299 | struct usb_ctrlrequest *ctrl) | ||
300 | { | ||
301 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | ||
302 | |||
303 | usbhs_pipe_stall(pipe); | ||
304 | |||
305 | usbhsg_recip_handler_std_control_done(priv, uep, ctrl); | ||
306 | |||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | struct usbhsg_recip_handle req_set_feature = { | ||
311 | .name = "set feature", | ||
312 | .device = usbhsg_recip_handler_std_set_device, | ||
313 | .interface = usbhsg_recip_handler_std_control_done, | ||
314 | .endpoint = usbhsg_recip_handler_std_set_endpoint, | ||
315 | }; | ||
316 | |||
317 | /* | ||
318 | * USB_TYPE_STANDARD / get status functions | ||
319 | */ | ||
320 | static void __usbhsg_recip_send_complete(struct usb_ep *ep, | ||
321 | struct usb_request *req) | ||
322 | { | ||
323 | struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); | ||
324 | |||
325 | /* free allocated recip-buffer/usb_request */ | ||
326 | kfree(ureq->pkt.buf); | ||
327 | usb_ep_free_request(ep, req); | ||
328 | } | ||
329 | |||
330 | static void __usbhsg_recip_send_status(struct usbhsg_gpriv *gpriv, | ||
331 | unsigned short status) | ||
332 | { | ||
333 | struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); | ||
334 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp); | ||
335 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | ||
336 | struct usb_request *req; | ||
337 | unsigned short *buf; | ||
338 | |||
339 | /* alloc new usb_request for recip */ | ||
340 | req = usb_ep_alloc_request(&dcp->ep, GFP_ATOMIC); | ||
341 | if (!req) { | ||
342 | dev_err(dev, "recip request allocation fail\n"); | ||
343 | return; | ||
344 | } | ||
345 | |||
346 | /* alloc recip data buffer */ | ||
347 | buf = kmalloc(sizeof(*buf), GFP_ATOMIC); | ||
348 | if (!buf) { | ||
349 | usb_ep_free_request(&dcp->ep, req); | ||
350 | dev_err(dev, "recip data allocation fail\n"); | ||
351 | return; | ||
352 | } | ||
353 | |||
354 | /* recip data is status */ | ||
355 | *buf = cpu_to_le16(status); | ||
356 | |||
357 | /* allocated usb_request/buffer will be freed */ | ||
358 | req->complete = __usbhsg_recip_send_complete; | ||
359 | req->buf = buf; | ||
360 | req->length = sizeof(*buf); | ||
361 | req->zero = 0; | ||
362 | |||
363 | /* push packet */ | ||
364 | pipe->handler = &usbhs_fifo_pio_push_handler; | ||
365 | usbhsg_queue_push(dcp, usbhsg_req_to_ureq(req)); | ||
366 | } | ||
367 | |||
368 | static int usbhsg_recip_handler_std_get_device(struct usbhs_priv *priv, | ||
369 | struct usbhsg_uep *uep, | ||
370 | struct usb_ctrlrequest *ctrl) | ||
371 | { | ||
372 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | ||
373 | unsigned short status = 1 << USB_DEVICE_SELF_POWERED; | ||
374 | |||
375 | __usbhsg_recip_send_status(gpriv, status); | ||
376 | |||
377 | return 0; | ||
378 | } | ||
379 | |||
380 | static int usbhsg_recip_handler_std_get_interface(struct usbhs_priv *priv, | ||
381 | struct usbhsg_uep *uep, | ||
382 | struct usb_ctrlrequest *ctrl) | ||
383 | { | ||
384 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | ||
385 | unsigned short status = 0; | ||
386 | |||
387 | __usbhsg_recip_send_status(gpriv, status); | ||
388 | |||
389 | return 0; | ||
390 | } | ||
391 | |||
392 | static int usbhsg_recip_handler_std_get_endpoint(struct usbhs_priv *priv, | ||
393 | struct usbhsg_uep *uep, | ||
394 | struct usb_ctrlrequest *ctrl) | ||
395 | { | ||
396 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | ||
397 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | ||
398 | unsigned short status = 0; | ||
399 | |||
400 | if (usbhs_pipe_is_stall(pipe)) | ||
401 | status = 1 << USB_ENDPOINT_HALT; | ||
402 | |||
403 | __usbhsg_recip_send_status(gpriv, status); | ||
404 | |||
405 | return 0; | ||
406 | } | ||
407 | |||
408 | struct usbhsg_recip_handle req_get_status = { | ||
409 | .name = "get status", | ||
410 | .device = usbhsg_recip_handler_std_get_device, | ||
411 | .interface = usbhsg_recip_handler_std_get_interface, | ||
412 | .endpoint = usbhsg_recip_handler_std_get_endpoint, | ||
413 | }; | ||
414 | |||
415 | /* | ||
285 | * USB_TYPE handler | 416 | * USB_TYPE handler |
286 | */ | 417 | */ |
287 | static int usbhsg_recip_run_handle(struct usbhs_priv *priv, | 418 | static int usbhsg_recip_run_handle(struct usbhs_priv *priv, |
@@ -303,8 +434,7 @@ static int usbhsg_recip_run_handle(struct usbhs_priv *priv, | |||
303 | pipe = usbhsg_uep_to_pipe(uep); | 434 | pipe = usbhsg_uep_to_pipe(uep); |
304 | if (!pipe) { | 435 | if (!pipe) { |
305 | dev_err(dev, "wrong recip request\n"); | 436 | dev_err(dev, "wrong recip request\n"); |
306 | ret = -EINVAL; | 437 | return -EINVAL; |
307 | goto usbhsg_recip_run_handle_end; | ||
308 | } | 438 | } |
309 | 439 | ||
310 | switch (recip) { | 440 | switch (recip) { |
@@ -327,20 +457,10 @@ static int usbhsg_recip_run_handle(struct usbhs_priv *priv, | |||
327 | } | 457 | } |
328 | 458 | ||
329 | if (func) { | 459 | if (func) { |
330 | unsigned long flags; | ||
331 | |||
332 | dev_dbg(dev, "%s (pipe %d :%s)\n", handler->name, nth, msg); | 460 | dev_dbg(dev, "%s (pipe %d :%s)\n", handler->name, nth, msg); |
333 | |||
334 | /******************** spin lock ********************/ | ||
335 | usbhs_lock(priv, flags); | ||
336 | ret = func(priv, uep, ctrl); | 461 | ret = func(priv, uep, ctrl); |
337 | usbhs_unlock(priv, flags); | ||
338 | /******************** spin unlock ******************/ | ||
339 | } | 462 | } |
340 | 463 | ||
341 | usbhsg_recip_run_handle_end: | ||
342 | usbhs_pkt_start(pipe); | ||
343 | |||
344 | return ret; | 464 | return ret; |
345 | } | 465 | } |
346 | 466 | ||
@@ -412,6 +532,12 @@ static int usbhsg_irq_ctrl_stage(struct usbhs_priv *priv, | |||
412 | case USB_REQ_CLEAR_FEATURE: | 532 | case USB_REQ_CLEAR_FEATURE: |
413 | recip_handler = &req_clear_feature; | 533 | recip_handler = &req_clear_feature; |
414 | break; | 534 | break; |
535 | case USB_REQ_SET_FEATURE: | ||
536 | recip_handler = &req_set_feature; | ||
537 | break; | ||
538 | case USB_REQ_GET_STATUS: | ||
539 | recip_handler = &req_get_status; | ||
540 | break; | ||
415 | } | 541 | } |
416 | } | 542 | } |
417 | 543 | ||
@@ -439,14 +565,16 @@ static int usbhsg_pipe_disable(struct usbhsg_uep *uep) | |||
439 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | 565 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); |
440 | struct usbhs_pkt *pkt; | 566 | struct usbhs_pkt *pkt; |
441 | 567 | ||
442 | usbhs_pipe_disable(pipe); | ||
443 | |||
444 | while (1) { | 568 | while (1) { |
445 | pkt = usbhs_pkt_pop(pipe, NULL); | 569 | pkt = usbhs_pkt_pop(pipe, NULL); |
446 | if (!pkt) | 570 | if (!pkt) |
447 | break; | 571 | break; |
572 | |||
573 | usbhsg_queue_pop(uep, usbhsg_pkt_to_ureq(pkt), -ECONNRESET); | ||
448 | } | 574 | } |
449 | 575 | ||
576 | usbhs_pipe_disable(pipe); | ||
577 | |||
450 | return 0; | 578 | return 0; |
451 | } | 579 | } |
452 | 580 | ||
@@ -681,9 +809,7 @@ static int usbhsg_try_start(struct usbhs_priv *priv, u32 status) | |||
681 | * - function | 809 | * - function |
682 | * - usb module | 810 | * - usb module |
683 | */ | 811 | */ |
684 | usbhs_sys_hispeed_ctrl(priv, 1); | ||
685 | usbhs_sys_function_ctrl(priv, 1); | 812 | usbhs_sys_function_ctrl(priv, 1); |
686 | usbhs_sys_usb_ctrl(priv, 1); | ||
687 | 813 | ||
688 | /* | 814 | /* |
689 | * enable irq callback | 815 | * enable irq callback |
@@ -731,9 +857,8 @@ static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status) | |||
731 | gpriv->gadget.speed = USB_SPEED_UNKNOWN; | 857 | gpriv->gadget.speed = USB_SPEED_UNKNOWN; |
732 | 858 | ||
733 | /* disable sys */ | 859 | /* disable sys */ |
734 | usbhs_sys_hispeed_ctrl(priv, 0); | 860 | usbhs_sys_set_test_mode(priv, 0); |
735 | usbhs_sys_function_ctrl(priv, 0); | 861 | usbhs_sys_function_ctrl(priv, 0); |
736 | usbhs_sys_usb_ctrl(priv, 0); | ||
737 | 862 | ||
738 | usbhsg_pipe_disable(dcp); | 863 | usbhsg_pipe_disable(dcp); |
739 | 864 | ||
@@ -755,7 +880,7 @@ static int usbhsg_gadget_start(struct usb_gadget *gadget, | |||
755 | 880 | ||
756 | if (!driver || | 881 | if (!driver || |
757 | !driver->setup || | 882 | !driver->setup || |
758 | driver->speed < USB_SPEED_FULL) | 883 | driver->max_speed < USB_SPEED_FULL) |
759 | return -EINVAL; | 884 | return -EINVAL; |
760 | 885 | ||
761 | /* first hook up the driver ... */ | 886 | /* first hook up the driver ... */ |
@@ -866,7 +991,7 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) | |||
866 | gpriv->gadget.dev.parent = dev; | 991 | gpriv->gadget.dev.parent = dev; |
867 | gpriv->gadget.name = "renesas_usbhs_udc"; | 992 | gpriv->gadget.name = "renesas_usbhs_udc"; |
868 | gpriv->gadget.ops = &usbhsg_gadget_ops; | 993 | gpriv->gadget.ops = &usbhsg_gadget_ops; |
869 | gpriv->gadget.is_dualspeed = 1; | 994 | gpriv->gadget.max_speed = USB_SPEED_HIGH; |
870 | ret = device_register(&gpriv->gadget.dev); | 995 | ret = device_register(&gpriv->gadget.dev); |
871 | if (ret < 0) | 996 | if (ret < 0) |
872 | goto err_add_udc; | 997 | goto err_add_udc; |
@@ -896,8 +1021,6 @@ int usbhs_mod_gadget_probe(struct usbhs_priv *priv) | |||
896 | } | 1021 | } |
897 | } | 1022 | } |
898 | 1023 | ||
899 | usbhsg_controller_register(gpriv); | ||
900 | |||
901 | ret = usb_add_gadget_udc(dev, &gpriv->gadget); | 1024 | ret = usb_add_gadget_udc(dev, &gpriv->gadget); |
902 | if (ret) | 1025 | if (ret) |
903 | goto err_register; | 1026 | goto err_register; |
@@ -926,8 +1049,6 @@ void usbhs_mod_gadget_remove(struct usbhs_priv *priv) | |||
926 | 1049 | ||
927 | device_unregister(&gpriv->gadget.dev); | 1050 | device_unregister(&gpriv->gadget.dev); |
928 | 1051 | ||
929 | usbhsg_controller_unregister(gpriv); | ||
930 | |||
931 | kfree(gpriv->uep); | 1052 | kfree(gpriv->uep); |
932 | kfree(gpriv); | 1053 | kfree(gpriv); |
933 | } | 1054 | } |
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index 75659e0c735d..aa50eaaffcb6 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c | |||
@@ -45,36 +45,34 @@ | |||
45 | * | 45 | * |
46 | * +--------+ pipes are reused for each uep. | 46 | * +--------+ pipes are reused for each uep. |
47 | * | udev 1 |-+- [uep 0 (dcp) ] --+ pipe will be switched when | 47 | * | udev 1 |-+- [uep 0 (dcp) ] --+ pipe will be switched when |
48 | * +--------+ | | target device was changed | 48 | * +--------+ | | other device requested |
49 | * +- [uep 1 (bulk)] --|---+ +--------------+ | 49 | * +- [uep 1 (bulk)] --|---+ +--------------+ |
50 | * | +--------------> | pipe0 (dcp) | | 50 | * | +--------------> | pipe0 (dcp) | |
51 | * +- [uep 2 (bulk)] --|---|---+ +--------------+ | 51 | * +- [uep 2 (bulk)] -@ | +--------------+ |
52 | * | | | | pipe1 (isoc) | | 52 | * | | pipe1 (isoc) | |
53 | * +--------+ | | | +--------------+ | 53 | * +--------+ | +--------------+ |
54 | * | udev 2 |-+- [uep 0 (dcp) ] --+ +-- |------> | pipe2 (bulk) | | 54 | * | udev 2 |-+- [uep 0 (dcp) ] -@ +----------> | pipe2 (bulk) | |
55 | * +--------+ | | | | +--------------+ | 55 | * +--------+ | +--------------+ |
56 | * +- [uep 1 (int) ] --|-+ | +------> | pipe3 (bulk) | | 56 | * +- [uep 1 (int) ] ----+ +------> | pipe3 (bulk) | |
57 | * | | | | +--------------+ | 57 | * | | +--------------+ |
58 | * +--------+ | +-|---|------> | pipe4 (int) | | 58 | * +--------+ +-----|------> | pipe4 (int) | |
59 | * | udev 3 |-+- [uep 0 (dcp) ] --+ | | +--------------+ | 59 | * | udev 3 |-+- [uep 0 (dcp) ] -@ | +--------------+ |
60 | * +--------+ | | | | .... | | 60 | * +--------+ | | | .... | |
61 | * +- [uep 1 (bulk)] ------+ | | .... | | 61 | * +- [uep 1 (bulk)] -@ | | .... | |
62 | * | | | 62 | * | | |
63 | * +- [uep 2 (bulk)]-----------+ | 63 | * +- [uep 2 (bulk)]-----------+ |
64 | * | ||
65 | * @ : uep requested free pipe, but all have been used. | ||
66 | * now it is waiting for free pipe | ||
64 | */ | 67 | */ |
65 | 68 | ||
66 | 69 | ||
67 | /* | 70 | /* |
68 | * struct | 71 | * struct |
69 | */ | 72 | */ |
70 | struct usbhsh_pipe_info { | ||
71 | unsigned int usr_cnt; /* see usbhsh_endpoint_alloc() */ | ||
72 | }; | ||
73 | |||
74 | struct usbhsh_request { | 73 | struct usbhsh_request { |
75 | struct urb *urb; | 74 | struct urb *urb; |
76 | struct usbhs_pkt pkt; | 75 | struct usbhs_pkt pkt; |
77 | struct list_head ureq_link; /* see hpriv :: ureq_link_xxx */ | ||
78 | }; | 76 | }; |
79 | 77 | ||
80 | struct usbhsh_device { | 78 | struct usbhsh_device { |
@@ -83,11 +81,10 @@ struct usbhsh_device { | |||
83 | }; | 81 | }; |
84 | 82 | ||
85 | struct usbhsh_ep { | 83 | struct usbhsh_ep { |
86 | struct usbhs_pipe *pipe; | 84 | struct usbhs_pipe *pipe; /* attached pipe */ |
87 | struct usbhsh_device *udev; /* attached udev */ | 85 | struct usbhsh_device *udev; /* attached udev */ |
86 | struct usb_host_endpoint *ep; | ||
88 | struct list_head ep_list; /* list to usbhsh_device */ | 87 | struct list_head ep_list; /* list to usbhsh_device */ |
89 | |||
90 | int maxp; | ||
91 | }; | 88 | }; |
92 | 89 | ||
93 | #define USBHSH_DEVICE_MAX 10 /* see DEVADDn / DCPMAXP / PIPEMAXP */ | 90 | #define USBHSH_DEVICE_MAX 10 /* see DEVADDn / DCPMAXP / PIPEMAXP */ |
@@ -98,16 +95,9 @@ struct usbhsh_hpriv { | |||
98 | 95 | ||
99 | struct usbhsh_device udev[USBHSH_DEVICE_MAX]; | 96 | struct usbhsh_device udev[USBHSH_DEVICE_MAX]; |
100 | 97 | ||
101 | struct usbhsh_pipe_info *pipe_info; | ||
102 | int pipe_size; | ||
103 | |||
104 | u32 port_stat; /* USB_PORT_STAT_xxx */ | 98 | u32 port_stat; /* USB_PORT_STAT_xxx */ |
105 | 99 | ||
106 | struct completion setup_ack_done; | 100 | struct completion setup_ack_done; |
107 | |||
108 | /* see usbhsh_req_alloc/free */ | ||
109 | struct list_head ureq_link_active; | ||
110 | struct list_head ureq_link_free; | ||
111 | }; | 101 | }; |
112 | 102 | ||
113 | 103 | ||
@@ -119,17 +109,6 @@ static const char usbhsh_hcd_name[] = "renesas_usbhs host"; | |||
119 | #define usbhsh_priv_to_hpriv(priv) \ | 109 | #define usbhsh_priv_to_hpriv(priv) \ |
120 | container_of(usbhs_mod_get(priv, USBHS_HOST), struct usbhsh_hpriv, mod) | 110 | container_of(usbhs_mod_get(priv, USBHS_HOST), struct usbhsh_hpriv, mod) |
121 | 111 | ||
122 | #define __usbhsh_for_each_hpipe(start, pos, h, i) \ | ||
123 | for (i = start, pos = (h)->hpipe + i; \ | ||
124 | i < (h)->hpipe_size; \ | ||
125 | i++, pos = (h)->hpipe + i) | ||
126 | |||
127 | #define usbhsh_for_each_hpipe(pos, hpriv, i) \ | ||
128 | __usbhsh_for_each_hpipe(1, pos, hpriv, i) | ||
129 | |||
130 | #define usbhsh_for_each_hpipe_with_dcp(pos, hpriv, i) \ | ||
131 | __usbhsh_for_each_hpipe(0, pos, hpriv, i) | ||
132 | |||
133 | #define __usbhsh_for_each_udev(start, pos, h, i) \ | 112 | #define __usbhsh_for_each_udev(start, pos, h, i) \ |
134 | for (i = start, pos = (h)->udev + i; \ | 113 | for (i = start, pos = (h)->udev + i; \ |
135 | i < USBHSH_DEVICE_MAX; \ | 114 | i < USBHSH_DEVICE_MAX; \ |
@@ -152,15 +131,20 @@ static const char usbhsh_hcd_name[] = "renesas_usbhs host"; | |||
152 | #define usbhsh_ep_to_uep(u) ((u)->hcpriv) | 131 | #define usbhsh_ep_to_uep(u) ((u)->hcpriv) |
153 | #define usbhsh_uep_to_pipe(u) ((u)->pipe) | 132 | #define usbhsh_uep_to_pipe(u) ((u)->pipe) |
154 | #define usbhsh_uep_to_udev(u) ((u)->udev) | 133 | #define usbhsh_uep_to_udev(u) ((u)->udev) |
134 | #define usbhsh_uep_to_ep(u) ((u)->ep) | ||
135 | |||
155 | #define usbhsh_urb_to_ureq(u) ((u)->hcpriv) | 136 | #define usbhsh_urb_to_ureq(u) ((u)->hcpriv) |
156 | #define usbhsh_urb_to_usbv(u) ((u)->dev) | 137 | #define usbhsh_urb_to_usbv(u) ((u)->dev) |
157 | 138 | ||
158 | #define usbhsh_usbv_to_udev(d) dev_get_drvdata(&(d)->dev) | 139 | #define usbhsh_usbv_to_udev(d) dev_get_drvdata(&(d)->dev) |
159 | 140 | ||
160 | #define usbhsh_udev_to_usbv(h) ((h)->usbv) | 141 | #define usbhsh_udev_to_usbv(h) ((h)->usbv) |
142 | #define usbhsh_udev_is_used(h) usbhsh_udev_to_usbv(h) | ||
161 | 143 | ||
162 | #define usbhsh_pipe_info(p) ((p)->mod_private) | 144 | #define usbhsh_pipe_to_uep(p) ((p)->mod_private) |
163 | 145 | ||
146 | #define usbhsh_device_parent(d) (usbhsh_usbv_to_udev((d)->usbv->parent)) | ||
147 | #define usbhsh_device_hubport(d) ((d)->usbv->portnum) | ||
164 | #define usbhsh_device_number(h, d) ((int)((d) - (h)->udev)) | 148 | #define usbhsh_device_number(h, d) ((int)((d) - (h)->udev)) |
165 | #define usbhsh_device_nth(h, d) ((h)->udev + d) | 149 | #define usbhsh_device_nth(h, d) ((h)->udev + d) |
166 | #define usbhsh_device0(h) usbhsh_device_nth(h, 0) | 150 | #define usbhsh_device0(h) usbhsh_device_nth(h, 0) |
@@ -170,38 +154,13 @@ static const char usbhsh_hcd_name[] = "renesas_usbhs host"; | |||
170 | #define usbhsh_port_stat_clear(h, s) ((h)->port_stat &= ~(s)) | 154 | #define usbhsh_port_stat_clear(h, s) ((h)->port_stat &= ~(s)) |
171 | #define usbhsh_port_stat_get(h) ((h)->port_stat) | 155 | #define usbhsh_port_stat_get(h) ((h)->port_stat) |
172 | 156 | ||
173 | #define usbhsh_pkt_to_req(p) \ | 157 | #define usbhsh_pkt_to_ureq(p) \ |
174 | container_of((void *)p, struct usbhsh_request, pkt) | 158 | container_of((void *)p, struct usbhsh_request, pkt) |
175 | 159 | ||
176 | /* | 160 | /* |
177 | * req alloc/free | 161 | * req alloc/free |
178 | */ | 162 | */ |
179 | static void usbhsh_req_list_init(struct usbhsh_hpriv *hpriv) | 163 | static struct usbhsh_request *usbhsh_ureq_alloc(struct usbhsh_hpriv *hpriv, |
180 | { | ||
181 | INIT_LIST_HEAD(&hpriv->ureq_link_active); | ||
182 | INIT_LIST_HEAD(&hpriv->ureq_link_free); | ||
183 | } | ||
184 | |||
185 | static void usbhsh_req_list_quit(struct usbhsh_hpriv *hpriv) | ||
186 | { | ||
187 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); | ||
188 | struct device *dev = usbhsh_hcd_to_dev(hcd); | ||
189 | struct usbhsh_request *ureq, *next; | ||
190 | |||
191 | /* kfree all active ureq */ | ||
192 | list_for_each_entry_safe(ureq, next, | ||
193 | &hpriv->ureq_link_active, | ||
194 | ureq_link) { | ||
195 | dev_err(dev, "active ureq (%p) is force freed\n", ureq); | ||
196 | kfree(ureq); | ||
197 | } | ||
198 | |||
199 | /* kfree all free ureq */ | ||
200 | list_for_each_entry_safe(ureq, next, &hpriv->ureq_link_free, ureq_link) | ||
201 | kfree(ureq); | ||
202 | } | ||
203 | |||
204 | static struct usbhsh_request *usbhsh_req_alloc(struct usbhsh_hpriv *hpriv, | ||
205 | struct urb *urb, | 164 | struct urb *urb, |
206 | gfp_t mem_flags) | 165 | gfp_t mem_flags) |
207 | { | 166 | { |
@@ -209,270 +168,460 @@ static struct usbhsh_request *usbhsh_req_alloc(struct usbhsh_hpriv *hpriv, | |||
209 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | 168 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); |
210 | struct device *dev = usbhs_priv_to_dev(priv); | 169 | struct device *dev = usbhs_priv_to_dev(priv); |
211 | 170 | ||
212 | if (list_empty(&hpriv->ureq_link_free)) { | 171 | ureq = kzalloc(sizeof(struct usbhsh_request), mem_flags); |
213 | /* | ||
214 | * create new one if there is no free ureq | ||
215 | */ | ||
216 | ureq = kzalloc(sizeof(struct usbhsh_request), mem_flags); | ||
217 | if (ureq) | ||
218 | INIT_LIST_HEAD(&ureq->ureq_link); | ||
219 | } else { | ||
220 | /* | ||
221 | * reuse "free" ureq if exist | ||
222 | */ | ||
223 | ureq = list_entry(hpriv->ureq_link_free.next, | ||
224 | struct usbhsh_request, | ||
225 | ureq_link); | ||
226 | if (ureq) | ||
227 | list_del_init(&ureq->ureq_link); | ||
228 | } | ||
229 | |||
230 | if (!ureq) { | 172 | if (!ureq) { |
231 | dev_err(dev, "ureq alloc fail\n"); | 173 | dev_err(dev, "ureq alloc fail\n"); |
232 | return NULL; | 174 | return NULL; |
233 | } | 175 | } |
234 | 176 | ||
235 | usbhs_pkt_init(&ureq->pkt); | 177 | usbhs_pkt_init(&ureq->pkt); |
236 | |||
237 | /* | ||
238 | * push it to "active" list | ||
239 | */ | ||
240 | list_add_tail(&ureq->ureq_link, &hpriv->ureq_link_active); | ||
241 | ureq->urb = urb; | 178 | ureq->urb = urb; |
179 | usbhsh_urb_to_ureq(urb) = ureq; | ||
242 | 180 | ||
243 | return ureq; | 181 | return ureq; |
244 | } | 182 | } |
245 | 183 | ||
246 | static void usbhsh_req_free(struct usbhsh_hpriv *hpriv, | 184 | static void usbhsh_ureq_free(struct usbhsh_hpriv *hpriv, |
247 | struct usbhsh_request *ureq) | 185 | struct usbhsh_request *ureq) |
248 | { | 186 | { |
249 | struct usbhs_pkt *pkt = &ureq->pkt; | 187 | usbhsh_urb_to_ureq(ureq->urb) = NULL; |
188 | ureq->urb = NULL; | ||
250 | 189 | ||
251 | usbhs_pkt_init(pkt); | 190 | kfree(ureq); |
191 | } | ||
252 | 192 | ||
193 | /* | ||
194 | * status | ||
195 | */ | ||
196 | static int usbhsh_is_running(struct usbhsh_hpriv *hpriv) | ||
197 | { | ||
253 | /* | 198 | /* |
254 | * removed from "active" list, | 199 | * we can decide some device is attached or not |
255 | * and push it to "free" list | 200 | * by checking mod.irq_attch |
201 | * see | ||
202 | * usbhsh_irq_attch() | ||
203 | * usbhsh_irq_dtch() | ||
256 | */ | 204 | */ |
257 | ureq->urb = NULL; | 205 | return (hpriv->mod.irq_attch == NULL); |
258 | list_del_init(&ureq->ureq_link); | ||
259 | list_add_tail(&ureq->ureq_link, &hpriv->ureq_link_free); | ||
260 | } | 206 | } |
261 | 207 | ||
262 | /* | 208 | /* |
263 | * device control | 209 | * pipe control |
264 | */ | 210 | */ |
265 | 211 | static void usbhsh_endpoint_sequence_save(struct usbhsh_hpriv *hpriv, | |
266 | static int usbhsh_device_has_endpoint(struct usbhsh_device *udev) | 212 | struct urb *urb, |
213 | struct usbhs_pkt *pkt) | ||
267 | { | 214 | { |
268 | return !list_empty(&udev->ep_list_head); | 215 | int len = urb->actual_length; |
269 | } | 216 | int maxp = usb_endpoint_maxp(&urb->ep->desc); |
217 | int t = 0; | ||
270 | 218 | ||
271 | static struct usbhsh_device *usbhsh_device_alloc(struct usbhsh_hpriv *hpriv, | 219 | /* DCP is out of sequence control */ |
272 | struct urb *urb) | 220 | if (usb_pipecontrol(urb->pipe)) |
273 | { | 221 | return; |
274 | struct usbhsh_device *udev = NULL; | ||
275 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); | ||
276 | struct device *dev = usbhsh_hcd_to_dev(hcd); | ||
277 | struct usb_device *usbv = usbhsh_urb_to_usbv(urb); | ||
278 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | ||
279 | int i; | ||
280 | 222 | ||
281 | /* | 223 | /* |
282 | * device 0 | 224 | * renesas_usbhs pipe has a limitation in a number. |
225 | * So, driver should re-use the limited pipe for each device/endpoint. | ||
226 | * DATA0/1 sequence should be saved for it. | ||
227 | * see [image of mod_host] | ||
228 | * [HARDWARE LIMITATION] | ||
283 | */ | 229 | */ |
284 | if (0 == usb_pipedevice(urb->pipe)) { | ||
285 | udev = usbhsh_device0(hpriv); | ||
286 | goto usbhsh_device_find; | ||
287 | } | ||
288 | 230 | ||
289 | /* | 231 | /* |
290 | * find unused device | 232 | * next sequence depends on actual_length |
233 | * | ||
234 | * ex) actual_length = 1147, maxp = 512 | ||
235 | * data0 : 512 | ||
236 | * data1 : 512 | ||
237 | * data0 : 123 | ||
238 | * data1 is the next sequence | ||
291 | */ | 239 | */ |
292 | usbhsh_for_each_udev(udev, hpriv, i) { | 240 | t = len / maxp; |
293 | if (usbhsh_udev_to_usbv(udev)) | 241 | if (len % maxp) |
294 | continue; | 242 | t++; |
295 | goto usbhsh_device_find; | 243 | if (pkt->zero) |
244 | t++; | ||
245 | t %= 2; | ||
246 | |||
247 | if (t) | ||
248 | usb_dotoggle(urb->dev, | ||
249 | usb_pipeendpoint(urb->pipe), | ||
250 | usb_pipeout(urb->pipe)); | ||
251 | } | ||
252 | |||
253 | static struct usbhsh_device *usbhsh_device_get(struct usbhsh_hpriv *hpriv, | ||
254 | struct urb *urb); | ||
255 | |||
256 | static int usbhsh_pipe_attach(struct usbhsh_hpriv *hpriv, | ||
257 | struct urb *urb) | ||
258 | { | ||
259 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | ||
260 | struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); | ||
261 | struct usbhsh_device *udev = usbhsh_device_get(hpriv, urb); | ||
262 | struct usbhs_pipe *pipe; | ||
263 | struct usb_endpoint_descriptor *desc = &urb->ep->desc; | ||
264 | struct device *dev = usbhs_priv_to_dev(priv); | ||
265 | unsigned long flags; | ||
266 | int dir_in_req = !!usb_pipein(urb->pipe); | ||
267 | int is_dcp = usb_endpoint_xfer_control(desc); | ||
268 | int i, dir_in; | ||
269 | int ret = -EBUSY; | ||
270 | |||
271 | /******************** spin lock ********************/ | ||
272 | usbhs_lock(priv, flags); | ||
273 | |||
274 | if (unlikely(usbhsh_uep_to_pipe(uep))) { | ||
275 | dev_err(dev, "uep already has pipe\n"); | ||
276 | goto usbhsh_pipe_attach_done; | ||
296 | } | 277 | } |
297 | 278 | ||
298 | dev_err(dev, "no free usbhsh_device\n"); | 279 | usbhs_for_each_pipe_with_dcp(pipe, priv, i) { |
299 | 280 | ||
300 | return NULL; | 281 | /* check pipe type */ |
282 | if (!usbhs_pipe_type_is(pipe, usb_endpoint_type(desc))) | ||
283 | continue; | ||
301 | 284 | ||
302 | usbhsh_device_find: | 285 | /* check pipe direction if normal pipe */ |
303 | if (usbhsh_device_has_endpoint(udev)) | 286 | if (!is_dcp) { |
304 | dev_warn(dev, "udev have old endpoint\n"); | 287 | dir_in = !!usbhs_pipe_is_dir_in(pipe); |
288 | if (0 != (dir_in - dir_in_req)) | ||
289 | continue; | ||
290 | } | ||
305 | 291 | ||
306 | /* uep will be attached */ | 292 | /* check pipe is free */ |
307 | INIT_LIST_HEAD(&udev->ep_list_head); | 293 | if (usbhsh_pipe_to_uep(pipe)) |
294 | continue; | ||
308 | 295 | ||
309 | /* | 296 | /* |
310 | * usbhsh_usbv_to_udev() | 297 | * attach pipe to uep |
311 | * usbhsh_udev_to_usbv() | 298 | * |
312 | * will be enable | 299 | * usbhs_pipe_config_update() should be called after |
313 | */ | 300 | * usbhs_set_device_config() |
314 | dev_set_drvdata(&usbv->dev, udev); | 301 | * see |
315 | udev->usbv = usbv; | 302 | * DCPMAXP/PIPEMAXP |
303 | */ | ||
304 | usbhsh_uep_to_pipe(uep) = pipe; | ||
305 | usbhsh_pipe_to_uep(pipe) = uep; | ||
316 | 306 | ||
317 | /* set device config */ | 307 | usbhs_pipe_config_update(pipe, |
318 | usbhs_set_device_speed(priv, | 308 | usbhsh_device_number(hpriv, udev), |
319 | usbhsh_device_number(hpriv, udev), | 309 | usb_endpoint_num(desc), |
320 | usbhsh_device_number(hpriv, udev), | 310 | usb_endpoint_maxp(desc)); |
321 | 0, /* FIXME no parent */ | ||
322 | usbv->speed); | ||
323 | 311 | ||
324 | dev_dbg(dev, "%s [%d](%p)\n", __func__, | 312 | dev_dbg(dev, "%s [%d-%d(%s:%s)]\n", __func__, |
325 | usbhsh_device_number(hpriv, udev), udev); | 313 | usbhsh_device_number(hpriv, udev), |
314 | usb_endpoint_num(desc), | ||
315 | usbhs_pipe_name(pipe), | ||
316 | dir_in_req ? "in" : "out"); | ||
326 | 317 | ||
327 | return udev; | 318 | ret = 0; |
319 | break; | ||
320 | } | ||
321 | |||
322 | usbhsh_pipe_attach_done: | ||
323 | usbhs_unlock(priv, flags); | ||
324 | /******************** spin unlock ******************/ | ||
325 | |||
326 | return ret; | ||
328 | } | 327 | } |
329 | 328 | ||
330 | static void usbhsh_device_free(struct usbhsh_hpriv *hpriv, | 329 | static void usbhsh_pipe_detach(struct usbhsh_hpriv *hpriv, |
331 | struct usbhsh_device *udev) | 330 | struct usbhsh_ep *uep) |
332 | { | 331 | { |
333 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); | 332 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); |
334 | struct device *dev = usbhsh_hcd_to_dev(hcd); | 333 | struct usbhs_pipe *pipe; |
335 | struct usb_device *usbv = usbhsh_udev_to_usbv(udev); | 334 | struct device *dev = usbhs_priv_to_dev(priv); |
335 | unsigned long flags; | ||
336 | 336 | ||
337 | dev_dbg(dev, "%s [%d](%p)\n", __func__, | 337 | /******************** spin lock ********************/ |
338 | usbhsh_device_number(hpriv, udev), udev); | 338 | usbhs_lock(priv, flags); |
339 | 339 | ||
340 | if (usbhsh_device_has_endpoint(udev)) | 340 | pipe = usbhsh_uep_to_pipe(uep); |
341 | dev_warn(dev, "udev still have endpoint\n"); | ||
342 | 341 | ||
343 | /* | 342 | if (unlikely(!pipe)) { |
344 | * usbhsh_usbv_to_udev() | 343 | dev_err(dev, "uep doens't have pipe\n"); |
345 | * usbhsh_udev_to_usbv() | 344 | } else { |
346 | * will be disable | 345 | struct usb_host_endpoint *ep = usbhsh_uep_to_ep(uep); |
347 | */ | 346 | struct usbhsh_device *udev = usbhsh_uep_to_udev(uep); |
348 | dev_set_drvdata(&usbv->dev, NULL); | 347 | |
349 | udev->usbv = NULL; | 348 | /* detach pipe from uep */ |
349 | usbhsh_uep_to_pipe(uep) = NULL; | ||
350 | usbhsh_pipe_to_uep(pipe) = NULL; | ||
351 | |||
352 | dev_dbg(dev, "%s [%d-%d(%s)]\n", __func__, | ||
353 | usbhsh_device_number(hpriv, udev), | ||
354 | usb_endpoint_num(&ep->desc), | ||
355 | usbhs_pipe_name(pipe)); | ||
356 | } | ||
357 | |||
358 | usbhs_unlock(priv, flags); | ||
359 | /******************** spin unlock ******************/ | ||
350 | } | 360 | } |
351 | 361 | ||
352 | /* | 362 | /* |
353 | * end-point control | 363 | * endpoint control |
354 | */ | 364 | */ |
355 | struct usbhsh_ep *usbhsh_endpoint_alloc(struct usbhsh_hpriv *hpriv, | 365 | static int usbhsh_endpoint_attach(struct usbhsh_hpriv *hpriv, |
356 | struct usbhsh_device *udev, | 366 | struct urb *urb, |
357 | struct usb_host_endpoint *ep, | 367 | gfp_t mem_flags) |
358 | int dir_in_req, | ||
359 | gfp_t mem_flags) | ||
360 | { | 368 | { |
361 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | 369 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); |
362 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); | 370 | struct usbhsh_device *udev = usbhsh_device_get(hpriv, urb); |
371 | struct usb_host_endpoint *ep = urb->ep; | ||
363 | struct usbhsh_ep *uep; | 372 | struct usbhsh_ep *uep; |
364 | struct usbhsh_pipe_info *info; | 373 | struct device *dev = usbhs_priv_to_dev(priv); |
365 | struct usbhs_pipe *pipe, *best_pipe; | ||
366 | struct device *dev = usbhsh_hcd_to_dev(hcd); | ||
367 | struct usb_endpoint_descriptor *desc = &ep->desc; | 374 | struct usb_endpoint_descriptor *desc = &ep->desc; |
368 | int type, i, dir_in; | 375 | unsigned long flags; |
369 | unsigned int min_usr; | ||
370 | |||
371 | dir_in_req = !!dir_in_req; | ||
372 | 376 | ||
373 | uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags); | 377 | uep = kzalloc(sizeof(struct usbhsh_ep), mem_flags); |
374 | if (!uep) { | 378 | if (!uep) { |
375 | dev_err(dev, "usbhsh_ep alloc fail\n"); | 379 | dev_err(dev, "usbhsh_ep alloc fail\n"); |
376 | return NULL; | 380 | return -ENOMEM; |
377 | } | 381 | } |
378 | 382 | ||
379 | if (usb_endpoint_xfer_control(desc)) { | 383 | /******************** spin lock ********************/ |
380 | best_pipe = usbhsh_hpriv_to_dcp(hpriv); | 384 | usbhs_lock(priv, flags); |
381 | goto usbhsh_endpoint_alloc_find_pipe; | 385 | |
386 | /* | ||
387 | * init endpoint | ||
388 | */ | ||
389 | INIT_LIST_HEAD(&uep->ep_list); | ||
390 | list_add_tail(&uep->ep_list, &udev->ep_list_head); | ||
391 | |||
392 | usbhsh_uep_to_udev(uep) = udev; | ||
393 | usbhsh_uep_to_ep(uep) = ep; | ||
394 | usbhsh_ep_to_uep(ep) = uep; | ||
395 | |||
396 | usbhs_unlock(priv, flags); | ||
397 | /******************** spin unlock ******************/ | ||
398 | |||
399 | dev_dbg(dev, "%s [%d-%d]\n", __func__, | ||
400 | usbhsh_device_number(hpriv, udev), | ||
401 | usb_endpoint_num(desc)); | ||
402 | |||
403 | return 0; | ||
404 | } | ||
405 | |||
406 | static void usbhsh_endpoint_detach(struct usbhsh_hpriv *hpriv, | ||
407 | struct usb_host_endpoint *ep) | ||
408 | { | ||
409 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | ||
410 | struct device *dev = usbhs_priv_to_dev(priv); | ||
411 | struct usbhsh_ep *uep = usbhsh_ep_to_uep(ep); | ||
412 | unsigned long flags; | ||
413 | |||
414 | if (!uep) | ||
415 | return; | ||
416 | |||
417 | dev_dbg(dev, "%s [%d-%d]\n", __func__, | ||
418 | usbhsh_device_number(hpriv, usbhsh_uep_to_udev(uep)), | ||
419 | usb_endpoint_num(&ep->desc)); | ||
420 | |||
421 | if (usbhsh_uep_to_pipe(uep)) | ||
422 | usbhsh_pipe_detach(hpriv, uep); | ||
423 | |||
424 | /******************** spin lock ********************/ | ||
425 | usbhs_lock(priv, flags); | ||
426 | |||
427 | /* remove this endpoint from udev */ | ||
428 | list_del_init(&uep->ep_list); | ||
429 | |||
430 | usbhsh_uep_to_udev(uep) = NULL; | ||
431 | usbhsh_uep_to_ep(uep) = NULL; | ||
432 | usbhsh_ep_to_uep(ep) = NULL; | ||
433 | |||
434 | usbhs_unlock(priv, flags); | ||
435 | /******************** spin unlock ******************/ | ||
436 | |||
437 | kfree(uep); | ||
438 | } | ||
439 | |||
440 | static void usbhsh_endpoint_detach_all(struct usbhsh_hpriv *hpriv, | ||
441 | struct usbhsh_device *udev) | ||
442 | { | ||
443 | struct usbhsh_ep *uep, *next; | ||
444 | |||
445 | list_for_each_entry_safe(uep, next, &udev->ep_list_head, ep_list) | ||
446 | usbhsh_endpoint_detach(hpriv, usbhsh_uep_to_ep(uep)); | ||
447 | } | ||
448 | |||
449 | /* | ||
450 | * device control | ||
451 | */ | ||
452 | static int usbhsh_connected_to_rhdev(struct usb_hcd *hcd, | ||
453 | struct usbhsh_device *udev) | ||
454 | { | ||
455 | struct usb_device *usbv = usbhsh_udev_to_usbv(udev); | ||
456 | |||
457 | return hcd->self.root_hub == usbv->parent; | ||
458 | } | ||
459 | |||
460 | static int usbhsh_device_has_endpoint(struct usbhsh_device *udev) | ||
461 | { | ||
462 | return !list_empty(&udev->ep_list_head); | ||
463 | } | ||
464 | |||
465 | static struct usbhsh_device *usbhsh_device_get(struct usbhsh_hpriv *hpriv, | ||
466 | struct urb *urb) | ||
467 | { | ||
468 | struct usb_device *usbv = usbhsh_urb_to_usbv(urb); | ||
469 | struct usbhsh_device *udev = usbhsh_usbv_to_udev(usbv); | ||
470 | |||
471 | /* usbhsh_device_attach() is still not called */ | ||
472 | if (!udev) | ||
473 | return NULL; | ||
474 | |||
475 | /* if it is device0, return it */ | ||
476 | if (0 == usb_pipedevice(urb->pipe)) | ||
477 | return usbhsh_device0(hpriv); | ||
478 | |||
479 | /* return attached device */ | ||
480 | return udev; | ||
481 | } | ||
482 | |||
483 | static struct usbhsh_device *usbhsh_device_attach(struct usbhsh_hpriv *hpriv, | ||
484 | struct urb *urb) | ||
485 | { | ||
486 | struct usbhsh_device *udev = NULL; | ||
487 | struct usbhsh_device *udev0 = usbhsh_device0(hpriv); | ||
488 | struct usbhsh_device *pos; | ||
489 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); | ||
490 | struct device *dev = usbhsh_hcd_to_dev(hcd); | ||
491 | struct usb_device *usbv = usbhsh_urb_to_usbv(urb); | ||
492 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | ||
493 | unsigned long flags; | ||
494 | u16 upphub, hubport; | ||
495 | int i; | ||
496 | |||
497 | /* | ||
498 | * This function should be called only while urb is pointing to device0. | ||
499 | * It will attach unused usbhsh_device to urb (usbv), | ||
500 | * and initialize device0. | ||
501 | * You can use usbhsh_device_get() to get "current" udev, | ||
502 | * and usbhsh_usbv_to_udev() is for "attached" udev. | ||
503 | */ | ||
504 | if (0 != usb_pipedevice(urb->pipe)) { | ||
505 | dev_err(dev, "%s fail: urb isn't pointing device0\n", __func__); | ||
506 | return NULL; | ||
382 | } | 507 | } |
383 | 508 | ||
509 | /******************** spin lock ********************/ | ||
510 | usbhs_lock(priv, flags); | ||
511 | |||
384 | /* | 512 | /* |
385 | * find best pipe for endpoint | 513 | * find unused device |
386 | * see | ||
387 | * HARDWARE LIMITATION | ||
388 | */ | 514 | */ |
389 | type = usb_endpoint_type(desc); | 515 | usbhsh_for_each_udev(pos, hpriv, i) { |
390 | min_usr = ~0; | 516 | if (usbhsh_udev_is_used(pos)) |
391 | best_pipe = NULL; | ||
392 | usbhs_for_each_pipe(pipe, priv, i) { | ||
393 | if (!usbhs_pipe_type_is(pipe, type)) | ||
394 | continue; | 517 | continue; |
518 | udev = pos; | ||
519 | break; | ||
520 | } | ||
395 | 521 | ||
396 | dir_in = !!usbhs_pipe_is_dir_in(pipe); | 522 | if (udev) { |
397 | if (0 != (dir_in - dir_in_req)) | 523 | /* |
398 | continue; | 524 | * usbhsh_usbv_to_udev() |
525 | * usbhsh_udev_to_usbv() | ||
526 | * will be enable | ||
527 | */ | ||
528 | dev_set_drvdata(&usbv->dev, udev); | ||
529 | udev->usbv = usbv; | ||
530 | } | ||
399 | 531 | ||
400 | info = usbhsh_pipe_info(pipe); | 532 | usbhs_unlock(priv, flags); |
533 | /******************** spin unlock ******************/ | ||
401 | 534 | ||
402 | if (min_usr > info->usr_cnt) { | 535 | if (!udev) { |
403 | min_usr = info->usr_cnt; | 536 | dev_err(dev, "no free usbhsh_device\n"); |
404 | best_pipe = pipe; | 537 | return NULL; |
405 | } | ||
406 | } | 538 | } |
407 | 539 | ||
408 | if (unlikely(!best_pipe)) { | 540 | if (usbhsh_device_has_endpoint(udev)) { |
409 | dev_err(dev, "couldn't find best pipe\n"); | 541 | dev_warn(dev, "udev have old endpoint\n"); |
410 | kfree(uep); | 542 | usbhsh_endpoint_detach_all(hpriv, udev); |
411 | return NULL; | 543 | } |
544 | |||
545 | if (usbhsh_device_has_endpoint(udev0)) { | ||
546 | dev_warn(dev, "udev0 have old endpoint\n"); | ||
547 | usbhsh_endpoint_detach_all(hpriv, udev0); | ||
412 | } | 548 | } |
413 | usbhsh_endpoint_alloc_find_pipe: | 549 | |
550 | /* uep will be attached */ | ||
551 | INIT_LIST_HEAD(&udev0->ep_list_head); | ||
552 | INIT_LIST_HEAD(&udev->ep_list_head); | ||
553 | |||
414 | /* | 554 | /* |
415 | * init uep | 555 | * set device0 config |
416 | */ | 556 | */ |
417 | uep->pipe = best_pipe; | 557 | usbhs_set_device_config(priv, |
418 | uep->maxp = usb_endpoint_maxp(desc); | 558 | 0, 0, 0, usbv->speed); |
419 | usbhsh_uep_to_udev(uep) = udev; | ||
420 | usbhsh_ep_to_uep(ep) = uep; | ||
421 | 559 | ||
422 | /* | 560 | /* |
423 | * update pipe user count | 561 | * set new device config |
424 | */ | 562 | */ |
425 | info = usbhsh_pipe_info(best_pipe); | 563 | upphub = 0; |
426 | info->usr_cnt++; | 564 | hubport = 0; |
565 | if (!usbhsh_connected_to_rhdev(hcd, udev)) { | ||
566 | /* if udev is not connected to rhdev, it means parent is Hub */ | ||
567 | struct usbhsh_device *parent = usbhsh_device_parent(udev); | ||
427 | 568 | ||
428 | /* init this endpoint, and attach it to udev */ | 569 | upphub = usbhsh_device_number(hpriv, parent); |
429 | INIT_LIST_HEAD(&uep->ep_list); | 570 | hubport = usbhsh_device_hubport(udev); |
430 | list_add_tail(&uep->ep_list, &udev->ep_list_head); | ||
431 | 571 | ||
432 | /* | 572 | dev_dbg(dev, "%s connecte to Hub [%d:%d](%p)\n", __func__, |
433 | * usbhs_pipe_config_update() should be called after | 573 | upphub, hubport, parent); |
434 | * usbhs_device_config() | 574 | } |
435 | * see | ||
436 | * DCPMAXP/PIPEMAXP | ||
437 | */ | ||
438 | usbhs_pipe_sequence_data0(uep->pipe); | ||
439 | usbhs_pipe_config_update(uep->pipe, | ||
440 | usbhsh_device_number(hpriv, udev), | ||
441 | usb_endpoint_num(desc), | ||
442 | uep->maxp); | ||
443 | 575 | ||
444 | dev_dbg(dev, "%s [%d-%s](%p)\n", __func__, | 576 | usbhs_set_device_config(priv, |
445 | usbhsh_device_number(hpriv, udev), | 577 | usbhsh_device_number(hpriv, udev), |
446 | usbhs_pipe_name(uep->pipe), uep); | 578 | upphub, hubport, usbv->speed); |
447 | 579 | ||
448 | return uep; | 580 | dev_dbg(dev, "%s [%d](%p)\n", __func__, |
581 | usbhsh_device_number(hpriv, udev), udev); | ||
582 | |||
583 | return udev; | ||
449 | } | 584 | } |
450 | 585 | ||
451 | void usbhsh_endpoint_free(struct usbhsh_hpriv *hpriv, | 586 | static void usbhsh_device_detach(struct usbhsh_hpriv *hpriv, |
452 | struct usb_host_endpoint *ep) | 587 | struct usbhsh_device *udev) |
453 | { | 588 | { |
589 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); | ||
454 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | 590 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); |
455 | struct device *dev = usbhs_priv_to_dev(priv); | 591 | struct device *dev = usbhsh_hcd_to_dev(hcd); |
456 | struct usbhsh_ep *uep = usbhsh_ep_to_uep(ep); | 592 | struct usb_device *usbv = usbhsh_udev_to_usbv(udev); |
457 | struct usbhsh_pipe_info *info; | 593 | unsigned long flags; |
458 | 594 | ||
459 | if (!uep) | 595 | dev_dbg(dev, "%s [%d](%p)\n", __func__, |
460 | return; | 596 | usbhsh_device_number(hpriv, udev), udev); |
461 | 597 | ||
462 | dev_dbg(dev, "%s [%d-%s](%p)\n", __func__, | 598 | if (usbhsh_device_has_endpoint(udev)) { |
463 | usbhsh_device_number(hpriv, usbhsh_uep_to_udev(uep)), | 599 | dev_warn(dev, "udev still have endpoint\n"); |
464 | usbhs_pipe_name(uep->pipe), uep); | 600 | usbhsh_endpoint_detach_all(hpriv, udev); |
601 | } | ||
465 | 602 | ||
466 | info = usbhsh_pipe_info(uep->pipe); | 603 | /* |
467 | info->usr_cnt--; | 604 | * There is nothing to do if it is device0. |
605 | * see | ||
606 | * usbhsh_device_attach() | ||
607 | * usbhsh_device_get() | ||
608 | */ | ||
609 | if (0 == usbhsh_device_number(hpriv, udev)) | ||
610 | return; | ||
468 | 611 | ||
469 | /* remove this endpoint from udev */ | 612 | /******************** spin lock ********************/ |
470 | list_del_init(&uep->ep_list); | 613 | usbhs_lock(priv, flags); |
471 | 614 | ||
472 | usbhsh_uep_to_udev(uep) = NULL; | 615 | /* |
473 | usbhsh_ep_to_uep(ep) = NULL; | 616 | * usbhsh_usbv_to_udev() |
617 | * usbhsh_udev_to_usbv() | ||
618 | * will be disable | ||
619 | */ | ||
620 | dev_set_drvdata(&usbv->dev, NULL); | ||
621 | udev->usbv = NULL; | ||
474 | 622 | ||
475 | kfree(uep); | 623 | usbhs_unlock(priv, flags); |
624 | /******************** spin unlock ******************/ | ||
476 | } | 625 | } |
477 | 626 | ||
478 | /* | 627 | /* |
@@ -480,11 +629,13 @@ void usbhsh_endpoint_free(struct usbhsh_hpriv *hpriv, | |||
480 | */ | 629 | */ |
481 | static void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) | 630 | static void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) |
482 | { | 631 | { |
483 | struct usbhsh_request *ureq = usbhsh_pkt_to_req(pkt); | 632 | struct usbhsh_request *ureq = usbhsh_pkt_to_ureq(pkt); |
484 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); | 633 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); |
485 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); | 634 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); |
486 | struct urb *urb = ureq->urb; | 635 | struct urb *urb = ureq->urb; |
636 | struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); | ||
487 | struct device *dev = usbhs_priv_to_dev(priv); | 637 | struct device *dev = usbhs_priv_to_dev(priv); |
638 | int status = 0; | ||
488 | 639 | ||
489 | dev_dbg(dev, "%s\n", __func__); | 640 | dev_dbg(dev, "%s\n", __func__); |
490 | 641 | ||
@@ -493,29 +644,43 @@ static void usbhsh_queue_done(struct usbhs_priv *priv, struct usbhs_pkt *pkt) | |||
493 | return; | 644 | return; |
494 | } | 645 | } |
495 | 646 | ||
647 | if (!usbhsh_is_running(hpriv)) | ||
648 | status = -ESHUTDOWN; | ||
649 | |||
496 | urb->actual_length = pkt->actual; | 650 | urb->actual_length = pkt->actual; |
497 | usbhsh_req_free(hpriv, ureq); | 651 | usbhsh_ureq_free(hpriv, ureq); |
498 | usbhsh_urb_to_ureq(urb) = NULL; | 652 | |
653 | usbhsh_endpoint_sequence_save(hpriv, urb, pkt); | ||
654 | usbhsh_pipe_detach(hpriv, uep); | ||
499 | 655 | ||
500 | usb_hcd_unlink_urb_from_ep(hcd, urb); | 656 | usb_hcd_unlink_urb_from_ep(hcd, urb); |
501 | usb_hcd_giveback_urb(hcd, urb, 0); | 657 | usb_hcd_giveback_urb(hcd, urb, status); |
502 | } | 658 | } |
503 | 659 | ||
504 | static int usbhsh_queue_push(struct usb_hcd *hcd, | 660 | static int usbhsh_queue_push(struct usb_hcd *hcd, |
505 | struct usbhs_pipe *pipe, | 661 | struct urb *urb, |
506 | struct urb *urb) | 662 | gfp_t mem_flags) |
507 | { | 663 | { |
508 | struct usbhsh_request *ureq = usbhsh_urb_to_ureq(urb); | 664 | struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); |
509 | struct usbhs_pkt *pkt = &ureq->pkt; | 665 | struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); |
666 | struct usbhs_pipe *pipe = usbhsh_uep_to_pipe(uep); | ||
510 | struct device *dev = usbhsh_hcd_to_dev(hcd); | 667 | struct device *dev = usbhsh_hcd_to_dev(hcd); |
668 | struct usbhsh_request *ureq; | ||
511 | void *buf; | 669 | void *buf; |
512 | int len; | 670 | int len, sequence; |
513 | 671 | ||
514 | if (usb_pipeisoc(urb->pipe)) { | 672 | if (usb_pipeisoc(urb->pipe)) { |
515 | dev_err(dev, "pipe iso is not supported now\n"); | 673 | dev_err(dev, "pipe iso is not supported now\n"); |
516 | return -EIO; | 674 | return -EIO; |
517 | } | 675 | } |
518 | 676 | ||
677 | /* this ureq will be freed on usbhsh_queue_done() */ | ||
678 | ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags); | ||
679 | if (unlikely(!ureq)) { | ||
680 | dev_err(dev, "ureq alloc fail\n"); | ||
681 | return -ENOMEM; | ||
682 | } | ||
683 | |||
519 | if (usb_pipein(urb->pipe)) | 684 | if (usb_pipein(urb->pipe)) |
520 | pipe->handler = &usbhs_fifo_pio_pop_handler; | 685 | pipe->handler = &usbhs_fifo_pio_pop_handler; |
521 | else | 686 | else |
@@ -524,25 +689,59 @@ static int usbhsh_queue_push(struct usb_hcd *hcd, | |||
524 | buf = (void *)(urb->transfer_buffer + urb->actual_length); | 689 | buf = (void *)(urb->transfer_buffer + urb->actual_length); |
525 | len = urb->transfer_buffer_length - urb->actual_length; | 690 | len = urb->transfer_buffer_length - urb->actual_length; |
526 | 691 | ||
692 | sequence = usb_gettoggle(urb->dev, | ||
693 | usb_pipeendpoint(urb->pipe), | ||
694 | usb_pipeout(urb->pipe)); | ||
695 | |||
527 | dev_dbg(dev, "%s\n", __func__); | 696 | dev_dbg(dev, "%s\n", __func__); |
528 | usbhs_pkt_push(pipe, pkt, usbhsh_queue_done, | 697 | usbhs_pkt_push(pipe, &ureq->pkt, usbhsh_queue_done, |
529 | buf, len, (urb->transfer_flags & URB_ZERO_PACKET)); | 698 | buf, len, (urb->transfer_flags & URB_ZERO_PACKET), |
699 | sequence); | ||
700 | |||
530 | usbhs_pkt_start(pipe); | 701 | usbhs_pkt_start(pipe); |
531 | 702 | ||
532 | return 0; | 703 | return 0; |
533 | } | 704 | } |
534 | 705 | ||
706 | static void usbhsh_queue_force_pop(struct usbhs_priv *priv, | ||
707 | struct usbhs_pipe *pipe) | ||
708 | { | ||
709 | struct usbhs_pkt *pkt; | ||
710 | |||
711 | while (1) { | ||
712 | pkt = usbhs_pkt_pop(pipe, NULL); | ||
713 | if (!pkt) | ||
714 | break; | ||
715 | |||
716 | /* | ||
717 | * if all packet are gone, usbhsh_endpoint_disable() | ||
718 | * will be called. | ||
719 | * then, attached device/endpoint/pipe will be detached | ||
720 | */ | ||
721 | usbhsh_queue_done(priv, pkt); | ||
722 | } | ||
723 | } | ||
724 | |||
725 | static void usbhsh_queue_force_pop_all(struct usbhs_priv *priv) | ||
726 | { | ||
727 | struct usbhs_pipe *pos; | ||
728 | int i; | ||
729 | |||
730 | usbhs_for_each_pipe_with_dcp(pos, priv, i) | ||
731 | usbhsh_queue_force_pop(priv, pos); | ||
732 | } | ||
733 | |||
535 | /* | 734 | /* |
536 | * DCP setup stage | 735 | * DCP setup stage |
537 | */ | 736 | */ |
538 | static int usbhsh_is_request_address(struct urb *urb) | 737 | static int usbhsh_is_request_address(struct urb *urb) |
539 | { | 738 | { |
540 | struct usb_ctrlrequest *cmd; | 739 | struct usb_ctrlrequest *req; |
541 | 740 | ||
542 | cmd = (struct usb_ctrlrequest *)urb->setup_packet; | 741 | req = (struct usb_ctrlrequest *)urb->setup_packet; |
543 | 742 | ||
544 | if ((DeviceOutRequest == cmd->bRequestType << 8) && | 743 | if ((DeviceOutRequest == req->bRequestType << 8) && |
545 | (USB_REQ_SET_ADDRESS == cmd->bRequest)) | 744 | (USB_REQ_SET_ADDRESS == req->bRequest)) |
546 | return 1; | 745 | return 1; |
547 | else | 746 | else |
548 | return 0; | 747 | return 0; |
@@ -570,11 +769,15 @@ static void usbhsh_setup_stage_packet_push(struct usbhsh_hpriv *hpriv, | |||
570 | /* | 769 | /* |
571 | * renesas_usbhs can not use original usb address. | 770 | * renesas_usbhs can not use original usb address. |
572 | * see HARDWARE LIMITATION. | 771 | * see HARDWARE LIMITATION. |
573 | * modify usb address here. | 772 | * modify usb address here to use attached device. |
773 | * see usbhsh_device_attach() | ||
574 | */ | 774 | */ |
575 | if (usbhsh_is_request_address(urb)) { | 775 | if (usbhsh_is_request_address(urb)) { |
576 | /* FIXME */ | 776 | struct usb_device *usbv = usbhsh_urb_to_usbv(urb); |
577 | req.wValue = 1; | 777 | struct usbhsh_device *udev = usbhsh_usbv_to_udev(usbv); |
778 | |||
779 | /* udev is a attached device */ | ||
780 | req.wValue = usbhsh_device_number(hpriv, udev); | ||
578 | dev_dbg(dev, "create new address - %d\n", req.wValue); | 781 | dev_dbg(dev, "create new address - %d\n", req.wValue); |
579 | } | 782 | } |
580 | 783 | ||
@@ -595,82 +798,80 @@ static void usbhsh_setup_stage_packet_push(struct usbhsh_hpriv *hpriv, | |||
595 | static void usbhsh_data_stage_packet_done(struct usbhs_priv *priv, | 798 | static void usbhsh_data_stage_packet_done(struct usbhs_priv *priv, |
596 | struct usbhs_pkt *pkt) | 799 | struct usbhs_pkt *pkt) |
597 | { | 800 | { |
598 | struct usbhsh_request *ureq = usbhsh_pkt_to_req(pkt); | 801 | struct usbhsh_request *ureq = usbhsh_pkt_to_ureq(pkt); |
599 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); | 802 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); |
600 | struct urb *urb = ureq->urb; | ||
601 | 803 | ||
602 | /* this ureq was connected to urb when usbhsh_urb_enqueue() */ | 804 | /* this ureq was connected to urb when usbhsh_urb_enqueue() */ |
603 | 805 | ||
604 | usbhsh_req_free(hpriv, ureq); | 806 | usbhsh_ureq_free(hpriv, ureq); |
605 | usbhsh_urb_to_ureq(urb) = NULL; | ||
606 | } | 807 | } |
607 | 808 | ||
608 | static void usbhsh_data_stage_packet_push(struct usbhsh_hpriv *hpriv, | 809 | static int usbhsh_data_stage_packet_push(struct usbhsh_hpriv *hpriv, |
609 | struct urb *urb, | 810 | struct urb *urb, |
610 | struct usbhs_pipe *pipe) | 811 | struct usbhs_pipe *pipe, |
812 | gfp_t mem_flags) | ||
813 | |||
611 | { | 814 | { |
612 | struct usbhsh_request *ureq; | 815 | struct usbhsh_request *ureq; |
613 | struct usbhs_pkt *pkt; | ||
614 | 816 | ||
615 | /* | 817 | /* this ureq will be freed on usbhsh_data_stage_packet_done() */ |
616 | * FIXME | 818 | ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags); |
617 | * | 819 | if (unlikely(!ureq)) |
618 | * data stage uses ureq which is connected to urb | 820 | return -ENOMEM; |
619 | * see usbhsh_urb_enqueue() :: alloc new request. | ||
620 | * it will be freed in usbhsh_data_stage_packet_done() | ||
621 | */ | ||
622 | ureq = usbhsh_urb_to_ureq(urb); | ||
623 | pkt = &ureq->pkt; | ||
624 | 821 | ||
625 | if (usb_pipein(urb->pipe)) | 822 | if (usb_pipein(urb->pipe)) |
626 | pipe->handler = &usbhs_dcp_data_stage_in_handler; | 823 | pipe->handler = &usbhs_dcp_data_stage_in_handler; |
627 | else | 824 | else |
628 | pipe->handler = &usbhs_dcp_data_stage_out_handler; | 825 | pipe->handler = &usbhs_dcp_data_stage_out_handler; |
629 | 826 | ||
630 | usbhs_pkt_push(pipe, pkt, | 827 | usbhs_pkt_push(pipe, &ureq->pkt, |
631 | usbhsh_data_stage_packet_done, | 828 | usbhsh_data_stage_packet_done, |
632 | urb->transfer_buffer, | 829 | urb->transfer_buffer, |
633 | urb->transfer_buffer_length, | 830 | urb->transfer_buffer_length, |
634 | (urb->transfer_flags & URB_ZERO_PACKET)); | 831 | (urb->transfer_flags & URB_ZERO_PACKET), |
832 | -1); | ||
833 | |||
834 | return 0; | ||
635 | } | 835 | } |
636 | 836 | ||
637 | /* | 837 | /* |
638 | * DCP status stage | 838 | * DCP status stage |
639 | */ | 839 | */ |
640 | static void usbhsh_status_stage_packet_push(struct usbhsh_hpriv *hpriv, | 840 | static int usbhsh_status_stage_packet_push(struct usbhsh_hpriv *hpriv, |
641 | struct urb *urb, | 841 | struct urb *urb, |
642 | struct usbhs_pipe *pipe) | 842 | struct usbhs_pipe *pipe, |
843 | gfp_t mem_flags) | ||
643 | { | 844 | { |
644 | struct usbhsh_request *ureq; | 845 | struct usbhsh_request *ureq; |
645 | struct usbhs_pkt *pkt; | ||
646 | 846 | ||
647 | /* | 847 | /* This ureq will be freed on usbhsh_queue_done() */ |
648 | * FIXME | 848 | ureq = usbhsh_ureq_alloc(hpriv, urb, mem_flags); |
649 | * | 849 | if (unlikely(!ureq)) |
650 | * status stage uses allocated ureq. | 850 | return -ENOMEM; |
651 | * it will be freed on usbhsh_queue_done() | ||
652 | */ | ||
653 | ureq = usbhsh_req_alloc(hpriv, urb, GFP_KERNEL); | ||
654 | pkt = &ureq->pkt; | ||
655 | 851 | ||
656 | if (usb_pipein(urb->pipe)) | 852 | if (usb_pipein(urb->pipe)) |
657 | pipe->handler = &usbhs_dcp_status_stage_in_handler; | 853 | pipe->handler = &usbhs_dcp_status_stage_in_handler; |
658 | else | 854 | else |
659 | pipe->handler = &usbhs_dcp_status_stage_out_handler; | 855 | pipe->handler = &usbhs_dcp_status_stage_out_handler; |
660 | 856 | ||
661 | usbhs_pkt_push(pipe, pkt, | 857 | usbhs_pkt_push(pipe, &ureq->pkt, |
662 | usbhsh_queue_done, | 858 | usbhsh_queue_done, |
663 | NULL, | 859 | NULL, |
664 | urb->transfer_buffer_length, | 860 | urb->transfer_buffer_length, |
665 | 0); | 861 | 0, -1); |
862 | |||
863 | return 0; | ||
666 | } | 864 | } |
667 | 865 | ||
668 | static int usbhsh_dcp_queue_push(struct usb_hcd *hcd, | 866 | static int usbhsh_dcp_queue_push(struct usb_hcd *hcd, |
669 | struct usbhsh_hpriv *hpriv, | 867 | struct urb *urb, |
670 | struct usbhs_pipe *pipe, | 868 | gfp_t mflags) |
671 | struct urb *urb) | ||
672 | { | 869 | { |
870 | struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); | ||
871 | struct usbhsh_ep *uep = usbhsh_ep_to_uep(urb->ep); | ||
872 | struct usbhs_pipe *pipe = usbhsh_uep_to_pipe(uep); | ||
673 | struct device *dev = usbhsh_hcd_to_dev(hcd); | 873 | struct device *dev = usbhsh_hcd_to_dev(hcd); |
874 | int ret; | ||
674 | 875 | ||
675 | dev_dbg(dev, "%s\n", __func__); | 876 | dev_dbg(dev, "%s\n", __func__); |
676 | 877 | ||
@@ -686,13 +887,22 @@ static int usbhsh_dcp_queue_push(struct usb_hcd *hcd, | |||
686 | * | 887 | * |
687 | * It is pushed only when urb has buffer. | 888 | * It is pushed only when urb has buffer. |
688 | */ | 889 | */ |
689 | if (urb->transfer_buffer_length) | 890 | if (urb->transfer_buffer_length) { |
690 | usbhsh_data_stage_packet_push(hpriv, urb, pipe); | 891 | ret = usbhsh_data_stage_packet_push(hpriv, urb, pipe, mflags); |
892 | if (ret < 0) { | ||
893 | dev_err(dev, "data stage failed\n"); | ||
894 | return ret; | ||
895 | } | ||
896 | } | ||
691 | 897 | ||
692 | /* | 898 | /* |
693 | * status stage | 899 | * status stage |
694 | */ | 900 | */ |
695 | usbhsh_status_stage_packet_push(hpriv, urb, pipe); | 901 | ret = usbhsh_status_stage_packet_push(hpriv, urb, pipe, mflags); |
902 | if (ret < 0) { | ||
903 | dev_err(dev, "status stage failed\n"); | ||
904 | return ret; | ||
905 | } | ||
696 | 906 | ||
697 | /* | 907 | /* |
698 | * start pushed packets | 908 | * start pushed packets |
@@ -729,71 +939,82 @@ static int usbhsh_urb_enqueue(struct usb_hcd *hcd, | |||
729 | struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); | 939 | struct usbhsh_hpriv *hpriv = usbhsh_hcd_to_hpriv(hcd); |
730 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); | 940 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); |
731 | struct device *dev = usbhs_priv_to_dev(priv); | 941 | struct device *dev = usbhs_priv_to_dev(priv); |
732 | struct usb_device *usbv = usbhsh_urb_to_usbv(urb); | ||
733 | struct usb_host_endpoint *ep = urb->ep; | 942 | struct usb_host_endpoint *ep = urb->ep; |
734 | struct usbhsh_request *ureq; | 943 | struct usbhsh_device *new_udev = NULL; |
735 | struct usbhsh_device *udev, *new_udev = NULL; | ||
736 | struct usbhs_pipe *pipe; | ||
737 | struct usbhsh_ep *uep; | ||
738 | int is_dir_in = usb_pipein(urb->pipe); | 944 | int is_dir_in = usb_pipein(urb->pipe); |
739 | 945 | int i; | |
740 | int ret; | 946 | int ret; |
741 | 947 | ||
742 | dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out"); | 948 | dev_dbg(dev, "%s (%s)\n", __func__, is_dir_in ? "in" : "out"); |
743 | 949 | ||
950 | if (!usbhsh_is_running(hpriv)) { | ||
951 | ret = -EIO; | ||
952 | dev_err(dev, "host is not running\n"); | ||
953 | goto usbhsh_urb_enqueue_error_not_linked; | ||
954 | } | ||
955 | |||
744 | ret = usb_hcd_link_urb_to_ep(hcd, urb); | 956 | ret = usb_hcd_link_urb_to_ep(hcd, urb); |
745 | if (ret) | 957 | if (ret) { |
958 | dev_err(dev, "urb link failed\n"); | ||
746 | goto usbhsh_urb_enqueue_error_not_linked; | 959 | goto usbhsh_urb_enqueue_error_not_linked; |
960 | } | ||
747 | 961 | ||
748 | /* | 962 | /* |
749 | * get udev | 963 | * attach udev if needed |
964 | * see [image of mod_host] | ||
750 | */ | 965 | */ |
751 | udev = usbhsh_usbv_to_udev(usbv); | 966 | if (!usbhsh_device_get(hpriv, urb)) { |
752 | if (!udev) { | 967 | new_udev = usbhsh_device_attach(hpriv, urb); |
753 | new_udev = usbhsh_device_alloc(hpriv, urb); | 968 | if (!new_udev) { |
754 | if (!new_udev) | 969 | ret = -EIO; |
970 | dev_err(dev, "device attach failed\n"); | ||
755 | goto usbhsh_urb_enqueue_error_not_linked; | 971 | goto usbhsh_urb_enqueue_error_not_linked; |
756 | 972 | } | |
757 | udev = new_udev; | ||
758 | } | 973 | } |
759 | 974 | ||
760 | /* | 975 | /* |
761 | * get uep | 976 | * attach endpoint if needed |
977 | * see [image of mod_host] | ||
762 | */ | 978 | */ |
763 | uep = usbhsh_ep_to_uep(ep); | 979 | if (!usbhsh_ep_to_uep(ep)) { |
764 | if (!uep) { | 980 | ret = usbhsh_endpoint_attach(hpriv, urb, mem_flags); |
765 | uep = usbhsh_endpoint_alloc(hpriv, udev, ep, | 981 | if (ret < 0) { |
766 | is_dir_in, mem_flags); | 982 | dev_err(dev, "endpoint attach failed\n"); |
767 | if (!uep) | ||
768 | goto usbhsh_urb_enqueue_error_free_device; | 983 | goto usbhsh_urb_enqueue_error_free_device; |
984 | } | ||
769 | } | 985 | } |
770 | pipe = usbhsh_uep_to_pipe(uep); | ||
771 | 986 | ||
772 | /* | 987 | /* |
773 | * alloc new request | 988 | * attach pipe to endpoint |
989 | * see [image of mod_host] | ||
774 | */ | 990 | */ |
775 | ureq = usbhsh_req_alloc(hpriv, urb, mem_flags); | 991 | for (i = 0; i < 1024; i++) { |
776 | if (unlikely(!ureq)) { | 992 | ret = usbhsh_pipe_attach(hpriv, urb); |
777 | ret = -ENOMEM; | 993 | if (ret < 0) |
994 | msleep(100); | ||
995 | else | ||
996 | break; | ||
997 | } | ||
998 | if (ret < 0) { | ||
999 | dev_err(dev, "pipe attach failed\n"); | ||
778 | goto usbhsh_urb_enqueue_error_free_endpoint; | 1000 | goto usbhsh_urb_enqueue_error_free_endpoint; |
779 | } | 1001 | } |
780 | usbhsh_urb_to_ureq(urb) = ureq; | ||
781 | 1002 | ||
782 | /* | 1003 | /* |
783 | * push packet | 1004 | * push packet |
784 | */ | 1005 | */ |
785 | if (usb_pipecontrol(urb->pipe)) | 1006 | if (usb_pipecontrol(urb->pipe)) |
786 | usbhsh_dcp_queue_push(hcd, hpriv, pipe, urb); | 1007 | ret = usbhsh_dcp_queue_push(hcd, urb, mem_flags); |
787 | else | 1008 | else |
788 | usbhsh_queue_push(hcd, pipe, urb); | 1009 | ret = usbhsh_queue_push(hcd, urb, mem_flags); |
789 | 1010 | ||
790 | return 0; | 1011 | return ret; |
791 | 1012 | ||
792 | usbhsh_urb_enqueue_error_free_endpoint: | 1013 | usbhsh_urb_enqueue_error_free_endpoint: |
793 | usbhsh_endpoint_free(hpriv, ep); | 1014 | usbhsh_endpoint_detach(hpriv, ep); |
794 | usbhsh_urb_enqueue_error_free_device: | 1015 | usbhsh_urb_enqueue_error_free_device: |
795 | if (new_udev) | 1016 | if (new_udev) |
796 | usbhsh_device_free(hpriv, new_udev); | 1017 | usbhsh_device_detach(hpriv, new_udev); |
797 | usbhsh_urb_enqueue_error_not_linked: | 1018 | usbhsh_urb_enqueue_error_not_linked: |
798 | 1019 | ||
799 | dev_dbg(dev, "%s error\n", __func__); | 1020 | dev_dbg(dev, "%s error\n", __func__); |
@@ -807,8 +1028,11 @@ static int usbhsh_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) | |||
807 | struct usbhsh_request *ureq = usbhsh_urb_to_ureq(urb); | 1028 | struct usbhsh_request *ureq = usbhsh_urb_to_ureq(urb); |
808 | 1029 | ||
809 | if (ureq) { | 1030 | if (ureq) { |
810 | usbhsh_req_free(hpriv, ureq); | 1031 | struct usbhs_priv *priv = usbhsh_hpriv_to_priv(hpriv); |
811 | usbhsh_urb_to_ureq(urb) = NULL; | 1032 | struct usbhs_pkt *pkt = &ureq->pkt; |
1033 | |||
1034 | usbhs_pkt_pop(pkt->pipe, pkt); | ||
1035 | usbhsh_queue_done(priv, pkt); | ||
812 | } | 1036 | } |
813 | 1037 | ||
814 | return 0; | 1038 | return 0; |
@@ -823,7 +1047,7 @@ static void usbhsh_endpoint_disable(struct usb_hcd *hcd, | |||
823 | 1047 | ||
824 | /* | 1048 | /* |
825 | * this function might be called manytimes by same hcd/ep | 1049 | * this function might be called manytimes by same hcd/ep |
826 | * in-endpoitn == out-endpoint if ep == dcp. | 1050 | * in-endpoint == out-endpoint if ep == dcp. |
827 | */ | 1051 | */ |
828 | if (!uep) | 1052 | if (!uep) |
829 | return; | 1053 | return; |
@@ -831,15 +1055,14 @@ static void usbhsh_endpoint_disable(struct usb_hcd *hcd, | |||
831 | udev = usbhsh_uep_to_udev(uep); | 1055 | udev = usbhsh_uep_to_udev(uep); |
832 | hpriv = usbhsh_hcd_to_hpriv(hcd); | 1056 | hpriv = usbhsh_hcd_to_hpriv(hcd); |
833 | 1057 | ||
834 | usbhsh_endpoint_free(hpriv, ep); | 1058 | usbhsh_endpoint_detach(hpriv, ep); |
835 | ep->hcpriv = NULL; | ||
836 | 1059 | ||
837 | /* | 1060 | /* |
838 | * if there is no endpoint, | 1061 | * if there is no endpoint, |
839 | * free device | 1062 | * free device |
840 | */ | 1063 | */ |
841 | if (!usbhsh_device_has_endpoint(udev)) | 1064 | if (!usbhsh_device_has_endpoint(udev)) |
842 | usbhsh_device_free(hpriv, udev); | 1065 | usbhsh_device_detach(hpriv, udev); |
843 | } | 1066 | } |
844 | 1067 | ||
845 | static int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf) | 1068 | static int usbhsh_hub_status_data(struct usb_hcd *hcd, char *buf) |
@@ -919,6 +1142,8 @@ static int __usbhsh_hub_port_feature(struct usbhsh_hpriv *hpriv, | |||
919 | USB_PORT_STAT_HIGH_SPEED | | 1142 | USB_PORT_STAT_HIGH_SPEED | |
920 | USB_PORT_STAT_LOW_SPEED); | 1143 | USB_PORT_STAT_LOW_SPEED); |
921 | 1144 | ||
1145 | usbhsh_queue_force_pop_all(priv); | ||
1146 | |||
922 | usbhs_bus_send_reset(priv); | 1147 | usbhs_bus_send_reset(priv); |
923 | msleep(20); | 1148 | msleep(20); |
924 | usbhs_bus_send_sof_enable(priv); | 1149 | usbhs_bus_send_sof_enable(priv); |
@@ -1082,6 +1307,20 @@ static int usbhsh_irq_attch(struct usbhs_priv *priv, | |||
1082 | usbhsh_port_stat_set(hpriv, USB_PORT_STAT_CONNECTION); | 1307 | usbhsh_port_stat_set(hpriv, USB_PORT_STAT_CONNECTION); |
1083 | usbhsh_port_stat_set(hpriv, USB_PORT_STAT_C_CONNECTION << 16); | 1308 | usbhsh_port_stat_set(hpriv, USB_PORT_STAT_C_CONNECTION << 16); |
1084 | 1309 | ||
1310 | /* | ||
1311 | * attch interrupt might happen infinitely on some device | ||
1312 | * (on self power USB hub ?) | ||
1313 | * disable it here. | ||
1314 | * | ||
1315 | * usbhsh_is_running() becomes effective | ||
1316 | * according to this process. | ||
1317 | * see | ||
1318 | * usbhsh_is_running() | ||
1319 | * usbhsh_urb_enqueue() | ||
1320 | */ | ||
1321 | hpriv->mod.irq_attch = NULL; | ||
1322 | usbhs_irq_callback_update(priv, &hpriv->mod); | ||
1323 | |||
1085 | return 0; | 1324 | return 0; |
1086 | } | 1325 | } |
1087 | 1326 | ||
@@ -1096,6 +1335,24 @@ static int usbhsh_irq_dtch(struct usbhs_priv *priv, | |||
1096 | usbhsh_port_stat_clear(hpriv, USB_PORT_STAT_CONNECTION); | 1335 | usbhsh_port_stat_clear(hpriv, USB_PORT_STAT_CONNECTION); |
1097 | usbhsh_port_stat_set(hpriv, USB_PORT_STAT_C_CONNECTION << 16); | 1336 | usbhsh_port_stat_set(hpriv, USB_PORT_STAT_C_CONNECTION << 16); |
1098 | 1337 | ||
1338 | /* | ||
1339 | * enable attch interrupt again | ||
1340 | * | ||
1341 | * usbhsh_is_running() becomes invalid | ||
1342 | * according to this process. | ||
1343 | * see | ||
1344 | * usbhsh_is_running() | ||
1345 | * usbhsh_urb_enqueue() | ||
1346 | */ | ||
1347 | hpriv->mod.irq_attch = usbhsh_irq_attch; | ||
1348 | usbhs_irq_callback_update(priv, &hpriv->mod); | ||
1349 | |||
1350 | /* | ||
1351 | * usbhsh_queue_force_pop_all() should be called | ||
1352 | * after usbhsh_is_running() becomes invalid. | ||
1353 | */ | ||
1354 | usbhsh_queue_force_pop_all(priv); | ||
1355 | |||
1099 | return 0; | 1356 | return 0; |
1100 | } | 1357 | } |
1101 | 1358 | ||
@@ -1131,7 +1388,6 @@ static int usbhsh_irq_setup_err(struct usbhs_priv *priv, | |||
1131 | static void usbhsh_pipe_init_for_host(struct usbhs_priv *priv) | 1388 | static void usbhsh_pipe_init_for_host(struct usbhs_priv *priv) |
1132 | { | 1389 | { |
1133 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); | 1390 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); |
1134 | struct usbhsh_pipe_info *pipe_info = hpriv->pipe_info; | ||
1135 | struct usbhs_pipe *pipe; | 1391 | struct usbhs_pipe *pipe; |
1136 | u32 *pipe_type = usbhs_get_dparam(priv, pipe_type); | 1392 | u32 *pipe_type = usbhs_get_dparam(priv, pipe_type); |
1137 | int pipe_size = usbhs_get_dparam(priv, pipe_size); | 1393 | int pipe_size = usbhs_get_dparam(priv, pipe_size); |
@@ -1140,7 +1396,6 @@ static void usbhsh_pipe_init_for_host(struct usbhs_priv *priv) | |||
1140 | /* init all pipe */ | 1396 | /* init all pipe */ |
1141 | old_type = USB_ENDPOINT_XFER_CONTROL; | 1397 | old_type = USB_ENDPOINT_XFER_CONTROL; |
1142 | for (i = 0; i < pipe_size; i++) { | 1398 | for (i = 0; i < pipe_size; i++) { |
1143 | pipe_info[i].usr_cnt = 0; | ||
1144 | 1399 | ||
1145 | /* | 1400 | /* |
1146 | * data "output" will be finished as soon as possible, | 1401 | * data "output" will be finished as soon as possible, |
@@ -1174,7 +1429,7 @@ static void usbhsh_pipe_init_for_host(struct usbhs_priv *priv) | |||
1174 | dir_in); | 1429 | dir_in); |
1175 | } | 1430 | } |
1176 | 1431 | ||
1177 | pipe->mod_private = pipe_info + i; | 1432 | pipe->mod_private = NULL; |
1178 | } | 1433 | } |
1179 | } | 1434 | } |
1180 | 1435 | ||
@@ -1205,9 +1460,7 @@ static int usbhsh_start(struct usbhs_priv *priv) | |||
1205 | * - host | 1460 | * - host |
1206 | * - usb module | 1461 | * - usb module |
1207 | */ | 1462 | */ |
1208 | usbhs_sys_hispeed_ctrl(priv, 1); | ||
1209 | usbhs_sys_host_ctrl(priv, 1); | 1463 | usbhs_sys_host_ctrl(priv, 1); |
1210 | usbhs_sys_usb_ctrl(priv, 1); | ||
1211 | 1464 | ||
1212 | /* | 1465 | /* |
1213 | * enable irq callback | 1466 | * enable irq callback |
@@ -1242,9 +1495,7 @@ static int usbhsh_stop(struct usbhs_priv *priv) | |||
1242 | usb_remove_hcd(hcd); | 1495 | usb_remove_hcd(hcd); |
1243 | 1496 | ||
1244 | /* disable sys */ | 1497 | /* disable sys */ |
1245 | usbhs_sys_hispeed_ctrl(priv, 0); | ||
1246 | usbhs_sys_host_ctrl(priv, 0); | 1498 | usbhs_sys_host_ctrl(priv, 0); |
1247 | usbhs_sys_usb_ctrl(priv, 0); | ||
1248 | 1499 | ||
1249 | dev_dbg(dev, "quit host\n"); | 1500 | dev_dbg(dev, "quit host\n"); |
1250 | 1501 | ||
@@ -1255,10 +1506,8 @@ int usbhs_mod_host_probe(struct usbhs_priv *priv) | |||
1255 | { | 1506 | { |
1256 | struct usbhsh_hpriv *hpriv; | 1507 | struct usbhsh_hpriv *hpriv; |
1257 | struct usb_hcd *hcd; | 1508 | struct usb_hcd *hcd; |
1258 | struct usbhsh_pipe_info *pipe_info; | ||
1259 | struct usbhsh_device *udev; | 1509 | struct usbhsh_device *udev; |
1260 | struct device *dev = usbhs_priv_to_dev(priv); | 1510 | struct device *dev = usbhs_priv_to_dev(priv); |
1261 | int pipe_size = usbhs_get_dparam(priv, pipe_size); | ||
1262 | int i; | 1511 | int i; |
1263 | 1512 | ||
1264 | /* initialize hcd */ | 1513 | /* initialize hcd */ |
@@ -1268,12 +1517,6 @@ int usbhs_mod_host_probe(struct usbhs_priv *priv) | |||
1268 | return -ENOMEM; | 1517 | return -ENOMEM; |
1269 | } | 1518 | } |
1270 | 1519 | ||
1271 | pipe_info = kcalloc(pipe_size, sizeof(*pipe_info), GFP_KERNEL); | ||
1272 | if (!pipe_info) { | ||
1273 | dev_err(dev, "Could not allocate pipe_info\n"); | ||
1274 | goto usbhs_mod_host_probe_err; | ||
1275 | } | ||
1276 | |||
1277 | /* | 1520 | /* |
1278 | * CAUTION | 1521 | * CAUTION |
1279 | * | 1522 | * |
@@ -1293,9 +1536,6 @@ int usbhs_mod_host_probe(struct usbhs_priv *priv) | |||
1293 | hpriv->mod.name = "host"; | 1536 | hpriv->mod.name = "host"; |
1294 | hpriv->mod.start = usbhsh_start; | 1537 | hpriv->mod.start = usbhsh_start; |
1295 | hpriv->mod.stop = usbhsh_stop; | 1538 | hpriv->mod.stop = usbhsh_stop; |
1296 | hpriv->pipe_info = pipe_info; | ||
1297 | hpriv->pipe_size = pipe_size; | ||
1298 | usbhsh_req_list_init(hpriv); | ||
1299 | usbhsh_port_stat_init(hpriv); | 1539 | usbhsh_port_stat_init(hpriv); |
1300 | 1540 | ||
1301 | /* init all device */ | 1541 | /* init all device */ |
@@ -1307,11 +1547,6 @@ int usbhs_mod_host_probe(struct usbhs_priv *priv) | |||
1307 | dev_info(dev, "host probed\n"); | 1547 | dev_info(dev, "host probed\n"); |
1308 | 1548 | ||
1309 | return 0; | 1549 | return 0; |
1310 | |||
1311 | usbhs_mod_host_probe_err: | ||
1312 | usb_put_hcd(hcd); | ||
1313 | |||
1314 | return -ENOMEM; | ||
1315 | } | 1550 | } |
1316 | 1551 | ||
1317 | int usbhs_mod_host_remove(struct usbhs_priv *priv) | 1552 | int usbhs_mod_host_remove(struct usbhs_priv *priv) |
@@ -1319,8 +1554,6 @@ int usbhs_mod_host_remove(struct usbhs_priv *priv) | |||
1319 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); | 1554 | struct usbhsh_hpriv *hpriv = usbhsh_priv_to_hpriv(priv); |
1320 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); | 1555 | struct usb_hcd *hcd = usbhsh_hpriv_to_hcd(hpriv); |
1321 | 1556 | ||
1322 | usbhsh_req_list_quit(hpriv); | ||
1323 | |||
1324 | usb_put_hcd(hcd); | 1557 | usb_put_hcd(hcd); |
1325 | 1558 | ||
1326 | return 0; | 1559 | return 0; |
diff --git a/drivers/usb/renesas_usbhs/pipe.c b/drivers/usb/renesas_usbhs/pipe.c index c74389ce2177..c2559e80d41f 100644 --- a/drivers/usb/renesas_usbhs/pipe.c +++ b/drivers/usb/renesas_usbhs/pipe.c | |||
@@ -257,6 +257,13 @@ void usbhs_pipe_stall(struct usbhs_pipe *pipe) | |||
257 | } | 257 | } |
258 | } | 258 | } |
259 | 259 | ||
260 | int usbhs_pipe_is_stall(struct usbhs_pipe *pipe) | ||
261 | { | ||
262 | u16 pid = usbhsp_pipectrl_get(pipe) & PID_MASK; | ||
263 | |||
264 | return (int)(pid == PID_STALL10 || pid == PID_STALL11); | ||
265 | } | ||
266 | |||
260 | /* | 267 | /* |
261 | * pipe setup | 268 | * pipe setup |
262 | */ | 269 | */ |
@@ -471,10 +478,27 @@ int usbhs_pipe_is_dir_host(struct usbhs_pipe *pipe) | |||
471 | return usbhsp_flags_has(pipe, IS_DIR_HOST); | 478 | return usbhsp_flags_has(pipe, IS_DIR_HOST); |
472 | } | 479 | } |
473 | 480 | ||
474 | void usbhs_pipe_data_sequence(struct usbhs_pipe *pipe, int data) | 481 | void usbhs_pipe_data_sequence(struct usbhs_pipe *pipe, int sequence) |
475 | { | 482 | { |
476 | u16 mask = (SQCLR | SQSET); | 483 | u16 mask = (SQCLR | SQSET); |
477 | u16 val = (data) ? SQSET : SQCLR; | 484 | u16 val; |
485 | |||
486 | /* | ||
487 | * sequence | ||
488 | * 0 : data0 | ||
489 | * 1 : data1 | ||
490 | * -1 : no change | ||
491 | */ | ||
492 | switch (sequence) { | ||
493 | case 0: | ||
494 | val = SQCLR; | ||
495 | break; | ||
496 | case 1: | ||
497 | val = SQSET; | ||
498 | break; | ||
499 | default: | ||
500 | return; | ||
501 | } | ||
478 | 502 | ||
479 | usbhsp_pipectrl_set(pipe, mask, val); | 503 | usbhsp_pipectrl_set(pipe, mask, val); |
480 | } | 504 | } |
diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h index 6334fc644cc0..fa18b7dc2b2a 100644 --- a/drivers/usb/renesas_usbhs/pipe.h +++ b/drivers/usb/renesas_usbhs/pipe.h | |||
@@ -87,6 +87,7 @@ int usbhs_pipe_is_accessible(struct usbhs_pipe *pipe); | |||
87 | void usbhs_pipe_enable(struct usbhs_pipe *pipe); | 87 | void usbhs_pipe_enable(struct usbhs_pipe *pipe); |
88 | void usbhs_pipe_disable(struct usbhs_pipe *pipe); | 88 | void usbhs_pipe_disable(struct usbhs_pipe *pipe); |
89 | void usbhs_pipe_stall(struct usbhs_pipe *pipe); | 89 | void usbhs_pipe_stall(struct usbhs_pipe *pipe); |
90 | int usbhs_pipe_is_stall(struct usbhs_pipe *pipe); | ||
90 | void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo); | 91 | void usbhs_pipe_select_fifo(struct usbhs_pipe *pipe, struct usbhs_fifo *fifo); |
91 | void usbhs_pipe_config_update(struct usbhs_pipe *pipe, u16 devsel, | 92 | void usbhs_pipe_config_update(struct usbhs_pipe *pipe, u16 devsel, |
92 | u16 epnum, u16 maxp); | 93 | u16 epnum, u16 maxp); |