diff options
author | Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | 2011-04-04 22:40:54 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2011-04-13 19:07:07 -0400 |
commit | 2f98382dcdfe1f0048b447da35f34507ffb514dc (patch) | |
tree | 2b488080471eceb387de0f7ccb22d8a8c12be403 /drivers | |
parent | f1407d5c66240b33d11a7f1a41d55ccf6a9d7647 (diff) |
usb: renesas_usbhs: Add Renesas USBHS Gadget
This patch add usb gadget code to SuperH USBHS.
Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/usb/gadget/Kconfig | 18 | ||||
-rw-r--r-- | drivers/usb/gadget/gadget_chips.h | 9 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/Makefile | 2 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/mod.c | 17 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/mod.h | 16 | ||||
-rw-r--r-- | drivers/usb/renesas_usbhs/mod_gadget.c | 1341 |
6 files changed, 1402 insertions, 1 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index bc5123cf41c2..4c02b9f1597e 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig | |||
@@ -260,6 +260,24 @@ config USB_R8A66597 | |||
260 | default USB_GADGET | 260 | default USB_GADGET |
261 | select USB_GADGET_SELECTED | 261 | select USB_GADGET_SELECTED |
262 | 262 | ||
263 | config USB_GADGET_RENESAS_USBHS | ||
264 | boolean "Renesas USBHS" | ||
265 | depends on USB_RENESAS_USBHS | ||
266 | select USB_GADGET_DUALSPEED | ||
267 | help | ||
268 | Renesas USBHS is a discrete USB host and peripheral controller | ||
269 | chip that supports both full and high speed USB 2.0 data transfers. | ||
270 | platform is able to configure endpoint (pipe) style | ||
271 | |||
272 | Say "y" to enable the gadget specific portion of the USBHS driver. | ||
273 | |||
274 | |||
275 | config USB_RENESAS_USBHS_UDC | ||
276 | tristate | ||
277 | depends on USB_GADGET_RENESAS_USBHS | ||
278 | default USB_GADGET | ||
279 | select USB_GADGET_SELECTED | ||
280 | |||
263 | config USB_GADGET_PXA27X | 281 | config USB_GADGET_PXA27X |
264 | boolean "PXA 27x" | 282 | boolean "PXA 27x" |
265 | depends on ARCH_PXA && (PXA27x || PXA3xx) | 283 | depends on ARCH_PXA && (PXA27x || PXA3xx) |
diff --git a/drivers/usb/gadget/gadget_chips.h b/drivers/usb/gadget/gadget_chips.h index e896f6359dfe..ec3fd979c71d 100644 --- a/drivers/usb/gadget/gadget_chips.h +++ b/drivers/usb/gadget/gadget_chips.h | |||
@@ -148,6 +148,12 @@ | |||
148 | #define gadget_is_ci13xxx_msm(g) 0 | 148 | #define gadget_is_ci13xxx_msm(g) 0 |
149 | #endif | 149 | #endif |
150 | 150 | ||
151 | #ifdef CONFIG_USB_GADGET_RENESAS_USBHS | ||
152 | #define gadget_is_renesas_usbhs(g) (!strcmp("renesas_usbhs_udc", (g)->name)) | ||
153 | #else | ||
154 | #define gadget_is_renesas_usbhs(g) 0 | ||
155 | #endif | ||
156 | |||
151 | /** | 157 | /** |
152 | * usb_gadget_controller_number - support bcdDevice id convention | 158 | * usb_gadget_controller_number - support bcdDevice id convention |
153 | * @gadget: the controller being driven | 159 | * @gadget: the controller being driven |
@@ -207,6 +213,9 @@ static inline int usb_gadget_controller_number(struct usb_gadget *gadget) | |||
207 | return 0x27; | 213 | return 0x27; |
208 | else if (gadget_is_ci13xxx_msm(gadget)) | 214 | else if (gadget_is_ci13xxx_msm(gadget)) |
209 | return 0x28; | 215 | return 0x28; |
216 | else if (gadget_is_renesas_usbhs(gadget)) | ||
217 | return 0x29; | ||
218 | |||
210 | return -ENOENT; | 219 | return -ENOENT; |
211 | } | 220 | } |
212 | 221 | ||
diff --git a/drivers/usb/renesas_usbhs/Makefile b/drivers/usb/renesas_usbhs/Makefile index d76f3dd3b9d1..b8798ad16278 100644 --- a/drivers/usb/renesas_usbhs/Makefile +++ b/drivers/usb/renesas_usbhs/Makefile | |||
@@ -5,3 +5,5 @@ | |||
5 | obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs.o | 5 | obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs.o |
6 | 6 | ||
7 | renesas_usbhs-y := common.o mod.o pipe.o | 7 | renesas_usbhs-y := common.o mod.o pipe.o |
8 | |||
9 | renesas_usbhs-$(CONFIG_USB_RENESAS_USBHS_UDC) += mod_gadget.o | ||
diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c index 4a3398484cd7..73604a1d6843 100644 --- a/drivers/usb/renesas_usbhs/mod.c +++ b/drivers/usb/renesas_usbhs/mod.c | |||
@@ -94,17 +94,32 @@ int usbhs_mod_probe(struct usbhs_priv *priv) | |||
94 | struct device *dev = usbhs_priv_to_dev(priv); | 94 | struct device *dev = usbhs_priv_to_dev(priv); |
95 | int ret; | 95 | int ret; |
96 | 96 | ||
97 | /* | ||
98 | * install host/gadget driver | ||
99 | */ | ||
100 | ret = usbhs_mod_gadget_probe(priv); | ||
101 | if (ret < 0) | ||
102 | return ret; | ||
103 | |||
97 | /* irq settings */ | 104 | /* irq settings */ |
98 | ret = request_irq(priv->irq, usbhs_interrupt, | 105 | ret = request_irq(priv->irq, usbhs_interrupt, |
99 | IRQF_DISABLED, dev_name(dev), priv); | 106 | IRQF_DISABLED, dev_name(dev), priv); |
100 | if (ret) | 107 | if (ret) { |
101 | dev_err(dev, "irq request err\n"); | 108 | dev_err(dev, "irq request err\n"); |
109 | goto mod_init_gadget_err; | ||
110 | } | ||
111 | |||
112 | return ret; | ||
113 | |||
114 | mod_init_gadget_err: | ||
115 | usbhs_mod_gadget_remove(priv); | ||
102 | 116 | ||
103 | return ret; | 117 | return ret; |
104 | } | 118 | } |
105 | 119 | ||
106 | void usbhs_mod_remove(struct usbhs_priv *priv) | 120 | void usbhs_mod_remove(struct usbhs_priv *priv) |
107 | { | 121 | { |
122 | usbhs_mod_gadget_remove(priv); | ||
108 | free_irq(priv->irq, priv); | 123 | free_irq(priv->irq, priv); |
109 | } | 124 | } |
110 | 125 | ||
diff --git a/drivers/usb/renesas_usbhs/mod.h b/drivers/usb/renesas_usbhs/mod.h index bd873d5b432a..8644191e164f 100644 --- a/drivers/usb/renesas_usbhs/mod.h +++ b/drivers/usb/renesas_usbhs/mod.h | |||
@@ -103,4 +103,20 @@ void usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod); | |||
103 | mod->func(param); \ | 103 | mod->func(param); \ |
104 | }) | 104 | }) |
105 | 105 | ||
106 | /* | ||
107 | * gadget control | ||
108 | */ | ||
109 | #ifdef CONFIG_USB_RENESAS_USBHS_UDC | ||
110 | extern int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv); | ||
111 | extern void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv); | ||
112 | #else | ||
113 | static inline int usbhs_mod_gadget_probe(struct usbhs_priv *priv) | ||
114 | { | ||
115 | return 0; | ||
116 | } | ||
117 | static inline void usbhs_mod_gadget_remove(struct usbhs_priv *priv) | ||
118 | { | ||
119 | } | ||
120 | #endif | ||
121 | |||
106 | #endif /* RENESAS_USB_MOD_H */ | 122 | #endif /* RENESAS_USB_MOD_H */ |
diff --git a/drivers/usb/renesas_usbhs/mod_gadget.c b/drivers/usb/renesas_usbhs/mod_gadget.c new file mode 100644 index 000000000000..9a5ac02077b9 --- /dev/null +++ b/drivers/usb/renesas_usbhs/mod_gadget.c | |||
@@ -0,0 +1,1341 @@ | |||
1 | /* | ||
2 | * Renesas USB driver | ||
3 | * | ||
4 | * Copyright (C) 2011 Renesas Solutions Corp. | ||
5 | * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> | ||
6 | * | ||
7 | * This program is distributed in the hope that it will be useful, | ||
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
10 | * GNU General Public License for more details. | ||
11 | * | ||
12 | * You should have received a copy of the GNU General Public License | ||
13 | * along with this program; if not, write to the Free Software | ||
14 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
15 | * | ||
16 | */ | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/module.h> | ||
19 | #include <linux/platform_device.h> | ||
20 | #include <linux/usb/ch9.h> | ||
21 | #include <linux/usb/gadget.h> | ||
22 | #include "common.h" | ||
23 | |||
24 | /* | ||
25 | * struct | ||
26 | */ | ||
27 | struct usbhsg_request { | ||
28 | struct usb_request req; | ||
29 | struct list_head node; | ||
30 | }; | ||
31 | |||
32 | #define EP_NAME_SIZE 8 | ||
33 | struct usbhsg_gpriv; | ||
34 | struct usbhsg_pipe_handle; | ||
35 | struct usbhsg_uep { | ||
36 | struct usb_ep ep; | ||
37 | struct usbhs_pipe *pipe; | ||
38 | struct list_head list; | ||
39 | |||
40 | char ep_name[EP_NAME_SIZE]; | ||
41 | |||
42 | struct usbhsg_gpriv *gpriv; | ||
43 | struct usbhsg_pipe_handle *handler; | ||
44 | }; | ||
45 | |||
46 | struct usbhsg_gpriv { | ||
47 | struct usb_gadget gadget; | ||
48 | struct usbhs_mod mod; | ||
49 | |||
50 | struct usbhsg_uep *uep; | ||
51 | int uep_size; | ||
52 | |||
53 | struct usb_gadget_driver *driver; | ||
54 | |||
55 | u32 status; | ||
56 | #define USBHSG_STATUS_STARTED (1 << 0) | ||
57 | #define USBHSG_STATUS_REGISTERD (1 << 1) | ||
58 | #define USBHSG_STATUS_WEDGE (1 << 2) | ||
59 | }; | ||
60 | |||
61 | struct usbhsg_pipe_handle { | ||
62 | int (*prepare)(struct usbhsg_uep *uep, struct usbhsg_request *ureq); | ||
63 | int (*try_run)(struct usbhsg_uep *uep, struct usbhsg_request *ureq); | ||
64 | void (*irq_mask)(struct usbhsg_uep *uep, int enable); | ||
65 | }; | ||
66 | |||
67 | struct usbhsg_recip_handle { | ||
68 | char *name; | ||
69 | int (*device)(struct usbhs_priv *priv, struct usbhsg_uep *uep, | ||
70 | struct usb_ctrlrequest *ctrl); | ||
71 | int (*interface)(struct usbhs_priv *priv, struct usbhsg_uep *uep, | ||
72 | struct usb_ctrlrequest *ctrl); | ||
73 | int (*endpoint)(struct usbhs_priv *priv, struct usbhsg_uep *uep, | ||
74 | struct usb_ctrlrequest *ctrl); | ||
75 | }; | ||
76 | |||
77 | /* | ||
78 | * macro | ||
79 | */ | ||
80 | #define usbhsg_priv_to_gpriv(priv) \ | ||
81 | container_of( \ | ||
82 | usbhs_mod_get(priv, USBHS_GADGET), \ | ||
83 | struct usbhsg_gpriv, mod) | ||
84 | |||
85 | #define __usbhsg_for_each_uep(start, pos, g, i) \ | ||
86 | for (i = start, pos = (g)->uep; \ | ||
87 | i < (g)->uep_size; \ | ||
88 | i++, pos = (g)->uep + i) | ||
89 | |||
90 | #define usbhsg_for_each_uep(pos, gpriv, i) \ | ||
91 | __usbhsg_for_each_uep(1, pos, gpriv, i) | ||
92 | |||
93 | #define usbhsg_for_each_uep_with_dcp(pos, gpriv, i) \ | ||
94 | __usbhsg_for_each_uep(0, pos, gpriv, i) | ||
95 | |||
96 | #define usbhsg_gadget_to_gpriv(g)\ | ||
97 | container_of(g, struct usbhsg_gpriv, gadget) | ||
98 | |||
99 | #define usbhsg_req_to_ureq(r)\ | ||
100 | container_of(r, struct usbhsg_request, req) | ||
101 | |||
102 | #define usbhsg_ep_to_uep(e) container_of(e, struct usbhsg_uep, ep) | ||
103 | #define usbhsg_gpriv_to_lock(gp) usbhs_priv_to_lock((gp)->mod.priv) | ||
104 | #define usbhsg_gpriv_to_dev(gp) usbhs_priv_to_dev((gp)->mod.priv) | ||
105 | #define usbhsg_gpriv_to_priv(gp) ((gp)->mod.priv) | ||
106 | #define usbhsg_gpriv_to_dcp(gp) ((gp)->uep) | ||
107 | #define usbhsg_gpriv_to_nth_uep(gp, i) ((gp)->uep + i) | ||
108 | #define usbhsg_uep_to_gpriv(u) ((u)->gpriv) | ||
109 | #define usbhsg_uep_to_pipe(u) ((u)->pipe) | ||
110 | #define usbhsg_pipe_to_uep(p) ((p)->mod_private) | ||
111 | #define usbhsg_is_dcp(u) ((u) == usbhsg_gpriv_to_dcp((u)->gpriv)) | ||
112 | |||
113 | #define usbhsg_is_not_connected(gp) ((gp)->gadget.speed == USB_SPEED_UNKNOWN) | ||
114 | |||
115 | /* status */ | ||
116 | #define usbhsg_status_init(gp) do {(gp)->status = 0; } while (0) | ||
117 | #define usbhsg_status_set(gp, b) (gp->status |= b) | ||
118 | #define usbhsg_status_clr(gp, b) (gp->status &= ~b) | ||
119 | #define usbhsg_status_has(gp, b) (gp->status & b) | ||
120 | |||
121 | /* | ||
122 | * list push/pop | ||
123 | */ | ||
124 | static void usbhsg_queue_push(struct usbhsg_uep *uep, | ||
125 | struct usbhsg_request *ureq) | ||
126 | { | ||
127 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | ||
128 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | ||
129 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | ||
130 | |||
131 | /* | ||
132 | ********* assume under spin lock ********* | ||
133 | */ | ||
134 | list_del_init(&ureq->node); | ||
135 | list_add_tail(&ureq->node, &uep->list); | ||
136 | ureq->req.actual = 0; | ||
137 | ureq->req.status = -EINPROGRESS; | ||
138 | |||
139 | dev_dbg(dev, "pipe %d : queue push (%d)\n", | ||
140 | usbhs_pipe_number(pipe), | ||
141 | ureq->req.length); | ||
142 | } | ||
143 | |||
144 | static struct usbhsg_request *usbhsg_queue_get(struct usbhsg_uep *uep) | ||
145 | { | ||
146 | /* | ||
147 | ********* assume under spin lock ********* | ||
148 | */ | ||
149 | if (list_empty(&uep->list)) | ||
150 | return NULL; | ||
151 | |||
152 | return list_entry(uep->list.next, struct usbhsg_request, node); | ||
153 | } | ||
154 | |||
155 | #define usbhsg_queue_prepare(uep) __usbhsg_queue_handler(uep, 1); | ||
156 | #define usbhsg_queue_handle(uep) __usbhsg_queue_handler(uep, 0); | ||
157 | static int __usbhsg_queue_handler(struct usbhsg_uep *uep, int prepare) | ||
158 | { | ||
159 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | ||
160 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | ||
161 | struct usbhsg_request *ureq; | ||
162 | spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); | ||
163 | unsigned long flags; | ||
164 | int is_locked; | ||
165 | int ret = 0; | ||
166 | |||
167 | if (!uep->handler) { | ||
168 | dev_err(dev, "no handler function\n"); | ||
169 | return -EIO; | ||
170 | } | ||
171 | |||
172 | /* | ||
173 | * CAUTION [*queue handler*] | ||
174 | * | ||
175 | * This function will be called for start/restart queue operation. | ||
176 | * OTOH the most much worry for USB driver is spinlock nest. | ||
177 | * Specially it are | ||
178 | * - usb_ep_ops :: queue | ||
179 | * - usb_request :: complete | ||
180 | * | ||
181 | * But the caller of this function need not care about spinlock. | ||
182 | * This function is using spin_trylock_irqsave for it. | ||
183 | * if "is_locked" is 1, this mean this function lock it. | ||
184 | * but if it is 0, this mean it is already under spin lock. | ||
185 | * see also | ||
186 | * CAUTION [*endpoint queue*] | ||
187 | * CAUTION [*request complete*] | ||
188 | */ | ||
189 | |||
190 | /****************** spin try lock *******************/ | ||
191 | is_locked = spin_trylock_irqsave(lock, flags); | ||
192 | ureq = usbhsg_queue_get(uep); | ||
193 | if (ureq) { | ||
194 | if (prepare) | ||
195 | ret = uep->handler->prepare(uep, ureq); | ||
196 | else | ||
197 | ret = uep->handler->try_run(uep, ureq); | ||
198 | } | ||
199 | if (is_locked) | ||
200 | spin_unlock_irqrestore(lock, flags); | ||
201 | /******************** spin unlock ******************/ | ||
202 | |||
203 | return ret; | ||
204 | } | ||
205 | |||
206 | static void usbhsg_queue_pop(struct usbhsg_uep *uep, | ||
207 | struct usbhsg_request *ureq, | ||
208 | int status) | ||
209 | { | ||
210 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | ||
211 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | ||
212 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | ||
213 | |||
214 | /* | ||
215 | ********* assume under spin lock ********* | ||
216 | */ | ||
217 | |||
218 | /* | ||
219 | * CAUTION [*request complete*] | ||
220 | * | ||
221 | * There is a possibility not to be called in correct order | ||
222 | * if "complete" is called without spinlock. | ||
223 | * | ||
224 | * So, this function assume it is under spinlock, | ||
225 | * and call usb_request :: complete. | ||
226 | * | ||
227 | * But this "complete" will push next usb_request. | ||
228 | * It mean "usb_ep_ops :: queue" which is using spinlock is called | ||
229 | * under spinlock. | ||
230 | * | ||
231 | * To avoid dead-lock, this driver is using spin_trylock. | ||
232 | * CAUTION [*endpoint queue*] | ||
233 | * CAUTION [*queue handler*] | ||
234 | */ | ||
235 | |||
236 | dev_dbg(dev, "pipe %d : queue pop\n", usbhs_pipe_number(pipe)); | ||
237 | |||
238 | list_del_init(&ureq->node); | ||
239 | |||
240 | ureq->req.status = status; | ||
241 | ureq->req.complete(&uep->ep, &ureq->req); | ||
242 | |||
243 | /* more request ? */ | ||
244 | if (0 == status) | ||
245 | usbhsg_queue_prepare(uep); | ||
246 | } | ||
247 | |||
248 | /* | ||
249 | * irq enable/disable function | ||
250 | */ | ||
251 | #define usbhsg_irq_callback_ctrl(uep, status, enable) \ | ||
252 | ({ \ | ||
253 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); \ | ||
254 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); \ | ||
255 | struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); \ | ||
256 | struct usbhs_mod *mod = usbhs_mod_get_current(priv); \ | ||
257 | if (!mod) \ | ||
258 | return; \ | ||
259 | if (enable) \ | ||
260 | mod->irq_##status |= (1 << usbhs_pipe_number(pipe)); \ | ||
261 | else \ | ||
262 | mod->irq_##status &= ~(1 << usbhs_pipe_number(pipe)); \ | ||
263 | usbhs_irq_callback_update(priv, mod); \ | ||
264 | }) | ||
265 | |||
266 | static void usbhsg_irq_empty_ctrl(struct usbhsg_uep *uep, int enable) | ||
267 | { | ||
268 | usbhsg_irq_callback_ctrl(uep, bempsts, enable); | ||
269 | } | ||
270 | |||
271 | static void usbhsg_irq_ready_ctrl(struct usbhsg_uep *uep, int enable) | ||
272 | { | ||
273 | usbhsg_irq_callback_ctrl(uep, brdysts, enable); | ||
274 | } | ||
275 | |||
276 | /* | ||
277 | * handler function | ||
278 | */ | ||
279 | static int usbhsg_try_run_ctrl_stage_end(struct usbhsg_uep *uep, | ||
280 | struct usbhsg_request *ureq) | ||
281 | { | ||
282 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | ||
283 | |||
284 | /* | ||
285 | ********* assume under spin lock ********* | ||
286 | */ | ||
287 | |||
288 | usbhs_dcp_control_transfer_done(pipe); | ||
289 | usbhsg_queue_pop(uep, ureq, 0); | ||
290 | |||
291 | return 0; | ||
292 | } | ||
293 | |||
294 | static int usbhsg_try_run_send_packet(struct usbhsg_uep *uep, | ||
295 | struct usbhsg_request *ureq) | ||
296 | { | ||
297 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | ||
298 | struct usb_request *req = &ureq->req; | ||
299 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | ||
300 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | ||
301 | void *buf; | ||
302 | int remainder, send; | ||
303 | int is_done = 0; | ||
304 | int enable; | ||
305 | int maxp; | ||
306 | |||
307 | /* | ||
308 | ********* assume under spin lock ********* | ||
309 | */ | ||
310 | |||
311 | maxp = usbhs_pipe_get_maxpacket(pipe); | ||
312 | buf = req->buf + req->actual; | ||
313 | remainder = req->length - req->actual; | ||
314 | |||
315 | send = usbhs_fifo_write(pipe, buf, remainder); | ||
316 | |||
317 | /* | ||
318 | * send < 0 : pipe busy | ||
319 | * send = 0 : send zero packet | ||
320 | * send > 0 : send data | ||
321 | * | ||
322 | * send <= max_packet | ||
323 | */ | ||
324 | if (send > 0) | ||
325 | req->actual += send; | ||
326 | |||
327 | /* send all packet ? */ | ||
328 | if (send < remainder) | ||
329 | is_done = 0; /* there are remainder data */ | ||
330 | else if (send < maxp) | ||
331 | is_done = 1; /* short packet */ | ||
332 | else | ||
333 | is_done = !req->zero; /* send zero packet ? */ | ||
334 | |||
335 | dev_dbg(dev, " send %d (%d/ %d/ %d/ %d)\n", | ||
336 | usbhs_pipe_number(pipe), | ||
337 | remainder, send, is_done, req->zero); | ||
338 | |||
339 | /* | ||
340 | * enable interrupt and send again in irq handler | ||
341 | * if it still have remainder data which should be sent. | ||
342 | */ | ||
343 | enable = !is_done; | ||
344 | uep->handler->irq_mask(uep, enable); | ||
345 | |||
346 | /* | ||
347 | * usbhs_fifo_enable execute | ||
348 | * - after callback_update, | ||
349 | * - before queue_pop / stage_end | ||
350 | */ | ||
351 | usbhs_fifo_enable(pipe); | ||
352 | |||
353 | /* | ||
354 | * all data were sent ? | ||
355 | */ | ||
356 | if (is_done) { | ||
357 | /* it care below call in | ||
358 | "function mode" */ | ||
359 | if (usbhsg_is_dcp(uep)) | ||
360 | usbhs_dcp_control_transfer_done(pipe); | ||
361 | |||
362 | usbhsg_queue_pop(uep, ureq, 0); | ||
363 | } | ||
364 | |||
365 | return 0; | ||
366 | } | ||
367 | |||
368 | static int usbhsg_prepare_send_packet(struct usbhsg_uep *uep, | ||
369 | struct usbhsg_request *ureq) | ||
370 | { | ||
371 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | ||
372 | |||
373 | /* | ||
374 | ********* assume under spin lock ********* | ||
375 | */ | ||
376 | |||
377 | usbhs_fifo_prepare_write(pipe); | ||
378 | usbhsg_try_run_send_packet(uep, ureq); | ||
379 | |||
380 | return 0; | ||
381 | } | ||
382 | |||
383 | static int usbhsg_try_run_receive_packet(struct usbhsg_uep *uep, | ||
384 | struct usbhsg_request *ureq) | ||
385 | { | ||
386 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | ||
387 | struct usb_request *req = &ureq->req; | ||
388 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | ||
389 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | ||
390 | void *buf; | ||
391 | int maxp; | ||
392 | int remainder, recv; | ||
393 | int is_done = 0; | ||
394 | |||
395 | /* | ||
396 | ********* assume under spin lock ********* | ||
397 | */ | ||
398 | |||
399 | maxp = usbhs_pipe_get_maxpacket(pipe); | ||
400 | buf = req->buf + req->actual; | ||
401 | remainder = req->length - req->actual; | ||
402 | |||
403 | recv = usbhs_fifo_read(pipe, buf, remainder); | ||
404 | /* | ||
405 | * recv < 0 : pipe busy | ||
406 | * recv >= 0 : receive data | ||
407 | * | ||
408 | * recv <= max_packet | ||
409 | */ | ||
410 | if (recv < 0) | ||
411 | return -EBUSY; | ||
412 | |||
413 | /* update parameters */ | ||
414 | req->actual += recv; | ||
415 | |||
416 | if ((recv == remainder) || /* receive all data */ | ||
417 | (recv < maxp)) /* short packet */ | ||
418 | is_done = 1; | ||
419 | |||
420 | dev_dbg(dev, " recv %d (%d/ %d/ %d/ %d)\n", | ||
421 | usbhs_pipe_number(pipe), | ||
422 | remainder, recv, is_done, req->zero); | ||
423 | |||
424 | /* read all data ? */ | ||
425 | if (is_done) { | ||
426 | int disable = 0; | ||
427 | |||
428 | uep->handler->irq_mask(uep, disable); | ||
429 | usbhs_fifo_disable(pipe); | ||
430 | usbhsg_queue_pop(uep, ureq, 0); | ||
431 | } | ||
432 | |||
433 | return 0; | ||
434 | } | ||
435 | |||
436 | static int usbhsg_prepare_receive_packet(struct usbhsg_uep *uep, | ||
437 | struct usbhsg_request *ureq) | ||
438 | { | ||
439 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | ||
440 | int enable = 1; | ||
441 | int ret; | ||
442 | |||
443 | /* | ||
444 | ********* assume under spin lock ********* | ||
445 | */ | ||
446 | |||
447 | ret = usbhs_fifo_prepare_read(pipe); | ||
448 | if (ret < 0) | ||
449 | return ret; | ||
450 | |||
451 | /* | ||
452 | * data will be read in interrupt handler | ||
453 | */ | ||
454 | uep->handler->irq_mask(uep, enable); | ||
455 | |||
456 | return ret; | ||
457 | } | ||
458 | |||
459 | static struct usbhsg_pipe_handle usbhsg_handler_send_by_empty = { | ||
460 | .prepare = usbhsg_prepare_send_packet, | ||
461 | .try_run = usbhsg_try_run_send_packet, | ||
462 | .irq_mask = usbhsg_irq_empty_ctrl, | ||
463 | }; | ||
464 | |||
465 | static struct usbhsg_pipe_handle usbhsg_handler_send_by_ready = { | ||
466 | .prepare = usbhsg_prepare_send_packet, | ||
467 | .try_run = usbhsg_try_run_send_packet, | ||
468 | .irq_mask = usbhsg_irq_ready_ctrl, | ||
469 | }; | ||
470 | |||
471 | static struct usbhsg_pipe_handle usbhsg_handler_recv_by_ready = { | ||
472 | .prepare = usbhsg_prepare_receive_packet, | ||
473 | .try_run = usbhsg_try_run_receive_packet, | ||
474 | .irq_mask = usbhsg_irq_ready_ctrl, | ||
475 | }; | ||
476 | |||
477 | static struct usbhsg_pipe_handle usbhsg_handler_ctrl_stage_end = { | ||
478 | .prepare = usbhsg_try_run_ctrl_stage_end, | ||
479 | .try_run = usbhsg_try_run_ctrl_stage_end, | ||
480 | }; | ||
481 | |||
482 | /* | ||
483 | * DCP pipe can NOT use "ready interrupt" for "send" | ||
484 | * it should use "empty" interrupt. | ||
485 | * see | ||
486 | * "Operation" - "Interrupt Function" - "BRDY Interrupt" | ||
487 | * | ||
488 | * on the other hand, normal pipe can use "ready interrupt" for "send" | ||
489 | * even though it is single/double buffer | ||
490 | */ | ||
491 | #define usbhsg_handler_send_ctrl usbhsg_handler_send_by_empty | ||
492 | #define usbhsg_handler_recv_ctrl usbhsg_handler_recv_by_ready | ||
493 | |||
494 | #define usbhsg_handler_send_packet usbhsg_handler_send_by_ready | ||
495 | #define usbhsg_handler_recv_packet usbhsg_handler_recv_by_ready | ||
496 | |||
497 | /* | ||
498 | * USB_TYPE_STANDARD / clear feature functions | ||
499 | */ | ||
500 | static int usbhsg_recip_handler_std_control_done(struct usbhs_priv *priv, | ||
501 | struct usbhsg_uep *uep, | ||
502 | struct usb_ctrlrequest *ctrl) | ||
503 | { | ||
504 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); | ||
505 | struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); | ||
506 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp); | ||
507 | |||
508 | usbhs_dcp_control_transfer_done(pipe); | ||
509 | |||
510 | return 0; | ||
511 | } | ||
512 | |||
513 | static int usbhsg_recip_handler_std_clear_endpoint(struct usbhs_priv *priv, | ||
514 | struct usbhsg_uep *uep, | ||
515 | struct usb_ctrlrequest *ctrl) | ||
516 | { | ||
517 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | ||
518 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | ||
519 | |||
520 | if (!usbhsg_status_has(gpriv, USBHSG_STATUS_WEDGE)) { | ||
521 | usbhs_fifo_disable(pipe); | ||
522 | usbhs_pipe_clear_sequence(pipe); | ||
523 | usbhs_fifo_enable(pipe); | ||
524 | } | ||
525 | |||
526 | usbhsg_recip_handler_std_control_done(priv, uep, ctrl); | ||
527 | |||
528 | usbhsg_queue_prepare(uep); | ||
529 | |||
530 | return 0; | ||
531 | } | ||
532 | |||
533 | struct usbhsg_recip_handle req_clear_feature = { | ||
534 | .name = "clear feature", | ||
535 | .device = usbhsg_recip_handler_std_control_done, | ||
536 | .interface = usbhsg_recip_handler_std_control_done, | ||
537 | .endpoint = usbhsg_recip_handler_std_clear_endpoint, | ||
538 | }; | ||
539 | |||
540 | /* | ||
541 | * USB_TYPE handler | ||
542 | */ | ||
543 | static int usbhsg_recip_run_handle(struct usbhs_priv *priv, | ||
544 | struct usbhsg_recip_handle *handler, | ||
545 | struct usb_ctrlrequest *ctrl) | ||
546 | { | ||
547 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); | ||
548 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | ||
549 | struct usbhsg_uep *uep; | ||
550 | int recip = ctrl->bRequestType & USB_RECIP_MASK; | ||
551 | int nth = le16_to_cpu(ctrl->wIndex) & USB_ENDPOINT_NUMBER_MASK; | ||
552 | int ret; | ||
553 | int (*func)(struct usbhs_priv *priv, struct usbhsg_uep *uep, | ||
554 | struct usb_ctrlrequest *ctrl); | ||
555 | char *msg; | ||
556 | |||
557 | uep = usbhsg_gpriv_to_nth_uep(gpriv, nth); | ||
558 | |||
559 | switch (recip) { | ||
560 | case USB_RECIP_DEVICE: | ||
561 | msg = "DEVICE"; | ||
562 | func = handler->device; | ||
563 | break; | ||
564 | case USB_RECIP_INTERFACE: | ||
565 | msg = "INTERFACE"; | ||
566 | func = handler->interface; | ||
567 | break; | ||
568 | case USB_RECIP_ENDPOINT: | ||
569 | msg = "ENDPOINT"; | ||
570 | func = handler->endpoint; | ||
571 | break; | ||
572 | default: | ||
573 | dev_warn(dev, "unsupported RECIP(%d)\n", recip); | ||
574 | func = NULL; | ||
575 | ret = -EINVAL; | ||
576 | } | ||
577 | |||
578 | if (func) { | ||
579 | dev_dbg(dev, "%s (pipe %d :%s)\n", handler->name, nth, msg); | ||
580 | ret = func(priv, uep, ctrl); | ||
581 | } | ||
582 | |||
583 | return ret; | ||
584 | } | ||
585 | |||
586 | /* | ||
587 | * irq functions | ||
588 | * | ||
589 | * it will be called from usbhs_interrupt | ||
590 | */ | ||
591 | static int usbhsg_irq_dev_state(struct usbhs_priv *priv, | ||
592 | struct usbhs_irq_state *irq_state) | ||
593 | { | ||
594 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); | ||
595 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | ||
596 | |||
597 | gpriv->gadget.speed = usbhs_status_get_usb_speed(irq_state); | ||
598 | |||
599 | dev_dbg(dev, "state = %x : speed : %d\n", | ||
600 | usbhs_status_get_device_state(irq_state), | ||
601 | gpriv->gadget.speed); | ||
602 | |||
603 | return 0; | ||
604 | } | ||
605 | |||
606 | static int usbhsg_irq_ctrl_stage(struct usbhs_priv *priv, | ||
607 | struct usbhs_irq_state *irq_state) | ||
608 | { | ||
609 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); | ||
610 | struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); | ||
611 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(dcp); | ||
612 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | ||
613 | struct usb_ctrlrequest ctrl; | ||
614 | struct usbhsg_recip_handle *recip_handler = NULL; | ||
615 | int stage = usbhs_status_get_ctrl_stage(irq_state); | ||
616 | int ret = 0; | ||
617 | |||
618 | dev_dbg(dev, "stage = %d\n", stage); | ||
619 | |||
620 | /* | ||
621 | * see Manual | ||
622 | * | ||
623 | * "Operation" | ||
624 | * - "Interrupt Function" | ||
625 | * - "Control Transfer Stage Transition Interrupt" | ||
626 | * - Fig. "Control Transfer Stage Transitions" | ||
627 | */ | ||
628 | |||
629 | switch (stage) { | ||
630 | case READ_DATA_STAGE: | ||
631 | dcp->handler = &usbhsg_handler_send_ctrl; | ||
632 | break; | ||
633 | case WRITE_DATA_STAGE: | ||
634 | dcp->handler = &usbhsg_handler_recv_ctrl; | ||
635 | break; | ||
636 | case NODATA_STATUS_STAGE: | ||
637 | dcp->handler = &usbhsg_handler_ctrl_stage_end; | ||
638 | break; | ||
639 | default: | ||
640 | return ret; | ||
641 | } | ||
642 | |||
643 | /* | ||
644 | * get usb request | ||
645 | */ | ||
646 | usbhs_usbreq_get_val(priv, &ctrl); | ||
647 | |||
648 | switch (ctrl.bRequestType & USB_TYPE_MASK) { | ||
649 | case USB_TYPE_STANDARD: | ||
650 | switch (ctrl.bRequest) { | ||
651 | case USB_REQ_CLEAR_FEATURE: | ||
652 | recip_handler = &req_clear_feature; | ||
653 | break; | ||
654 | } | ||
655 | } | ||
656 | |||
657 | /* | ||
658 | * setup stage / run recip | ||
659 | */ | ||
660 | if (recip_handler) | ||
661 | ret = usbhsg_recip_run_handle(priv, recip_handler, &ctrl); | ||
662 | else | ||
663 | ret = gpriv->driver->setup(&gpriv->gadget, &ctrl); | ||
664 | |||
665 | if (ret < 0) | ||
666 | usbhs_fifo_stall(pipe); | ||
667 | |||
668 | return ret; | ||
669 | } | ||
670 | |||
671 | static int usbhsg_irq_empty(struct usbhs_priv *priv, | ||
672 | struct usbhs_irq_state *irq_state) | ||
673 | { | ||
674 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); | ||
675 | struct usbhsg_uep *uep; | ||
676 | struct usbhs_pipe *pipe; | ||
677 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | ||
678 | int i, ret; | ||
679 | |||
680 | if (!irq_state->bempsts) { | ||
681 | dev_err(dev, "debug %s !!\n", __func__); | ||
682 | return -EIO; | ||
683 | } | ||
684 | |||
685 | dev_dbg(dev, "irq empty [0x%04x]\n", irq_state->bempsts); | ||
686 | |||
687 | /* | ||
688 | * search interrupted "pipe" | ||
689 | * not "uep". | ||
690 | */ | ||
691 | usbhs_for_each_pipe_with_dcp(pipe, priv, i) { | ||
692 | if (!(irq_state->bempsts & (1 << i))) | ||
693 | continue; | ||
694 | |||
695 | uep = usbhsg_pipe_to_uep(pipe); | ||
696 | ret = usbhsg_queue_handle(uep); | ||
697 | if (ret < 0) | ||
698 | dev_err(dev, "send error %d : %d\n", i, ret); | ||
699 | } | ||
700 | |||
701 | return 0; | ||
702 | } | ||
703 | |||
704 | static int usbhsg_irq_ready(struct usbhs_priv *priv, | ||
705 | struct usbhs_irq_state *irq_state) | ||
706 | { | ||
707 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); | ||
708 | struct usbhsg_uep *uep; | ||
709 | struct usbhs_pipe *pipe; | ||
710 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | ||
711 | int i, ret; | ||
712 | |||
713 | if (!irq_state->brdysts) { | ||
714 | dev_err(dev, "debug %s !!\n", __func__); | ||
715 | return -EIO; | ||
716 | } | ||
717 | |||
718 | dev_dbg(dev, "irq ready [0x%04x]\n", irq_state->brdysts); | ||
719 | |||
720 | /* | ||
721 | * search interrupted "pipe" | ||
722 | * not "uep". | ||
723 | */ | ||
724 | usbhs_for_each_pipe_with_dcp(pipe, priv, i) { | ||
725 | if (!(irq_state->brdysts & (1 << i))) | ||
726 | continue; | ||
727 | |||
728 | uep = usbhsg_pipe_to_uep(pipe); | ||
729 | ret = usbhsg_queue_handle(uep); | ||
730 | if (ret < 0) | ||
731 | dev_err(dev, "receive error %d : %d\n", i, ret); | ||
732 | } | ||
733 | |||
734 | return 0; | ||
735 | } | ||
736 | |||
737 | /* | ||
738 | * | ||
739 | * usb_dcp_ops | ||
740 | * | ||
741 | */ | ||
742 | static int usbhsg_dcp_enable(struct usbhsg_uep *uep) | ||
743 | { | ||
744 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | ||
745 | struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); | ||
746 | struct usbhs_pipe *pipe; | ||
747 | |||
748 | /* | ||
749 | ********* assume under spin lock ********* | ||
750 | */ | ||
751 | |||
752 | pipe = usbhs_dcp_malloc(priv); | ||
753 | if (!pipe) | ||
754 | return -EIO; | ||
755 | |||
756 | uep->pipe = pipe; | ||
757 | uep->pipe->mod_private = uep; | ||
758 | INIT_LIST_HEAD(&uep->list); | ||
759 | |||
760 | return 0; | ||
761 | } | ||
762 | |||
763 | #define usbhsg_dcp_disable usbhsg_pipe_disable | ||
764 | static int usbhsg_pipe_disable(struct usbhsg_uep *uep) | ||
765 | { | ||
766 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | ||
767 | struct usbhsg_request *ureq; | ||
768 | int disable = 0; | ||
769 | |||
770 | /* | ||
771 | ********* assume under spin lock ********* | ||
772 | */ | ||
773 | |||
774 | usbhs_fifo_disable(pipe); | ||
775 | |||
776 | /* | ||
777 | * disable pipe irq | ||
778 | */ | ||
779 | usbhsg_irq_empty_ctrl(uep, disable); | ||
780 | usbhsg_irq_ready_ctrl(uep, disable); | ||
781 | |||
782 | while (1) { | ||
783 | ureq = usbhsg_queue_get(uep); | ||
784 | if (!ureq) | ||
785 | break; | ||
786 | |||
787 | usbhsg_queue_pop(uep, ureq, -ECONNRESET); | ||
788 | } | ||
789 | |||
790 | uep->pipe->mod_private = NULL; | ||
791 | uep->pipe = NULL; | ||
792 | |||
793 | return 0; | ||
794 | } | ||
795 | |||
796 | /* | ||
797 | * | ||
798 | * usb_ep_ops | ||
799 | * | ||
800 | */ | ||
801 | static int usbhsg_ep_enable(struct usb_ep *ep, | ||
802 | const struct usb_endpoint_descriptor *desc) | ||
803 | { | ||
804 | struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); | ||
805 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | ||
806 | struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); | ||
807 | struct usbhs_pipe *pipe; | ||
808 | spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); | ||
809 | unsigned long flags; | ||
810 | int ret = -EIO; | ||
811 | |||
812 | /******************** spin lock ********************/ | ||
813 | spin_lock_irqsave(lock, flags); | ||
814 | |||
815 | pipe = usbhs_pipe_malloc(priv, desc); | ||
816 | if (pipe) { | ||
817 | uep->pipe = pipe; | ||
818 | pipe->mod_private = uep; | ||
819 | INIT_LIST_HEAD(&uep->list); | ||
820 | |||
821 | if (usb_endpoint_dir_in(desc)) | ||
822 | uep->handler = &usbhsg_handler_send_packet; | ||
823 | else | ||
824 | uep->handler = &usbhsg_handler_recv_packet; | ||
825 | |||
826 | ret = 0; | ||
827 | } | ||
828 | spin_unlock_irqrestore(lock, flags); | ||
829 | /******************** spin unlock ******************/ | ||
830 | |||
831 | return ret; | ||
832 | } | ||
833 | |||
834 | static int usbhsg_ep_disable(struct usb_ep *ep) | ||
835 | { | ||
836 | struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); | ||
837 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | ||
838 | spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); | ||
839 | unsigned long flags; | ||
840 | int ret; | ||
841 | |||
842 | /******************** spin lock ********************/ | ||
843 | spin_lock_irqsave(lock, flags); | ||
844 | ret = usbhsg_pipe_disable(uep); | ||
845 | spin_unlock_irqrestore(lock, flags); | ||
846 | /******************** spin unlock ******************/ | ||
847 | |||
848 | return ret; | ||
849 | } | ||
850 | |||
851 | static struct usb_request *usbhsg_ep_alloc_request(struct usb_ep *ep, | ||
852 | gfp_t gfp_flags) | ||
853 | { | ||
854 | struct usbhsg_request *ureq; | ||
855 | |||
856 | ureq = kzalloc(sizeof *ureq, gfp_flags); | ||
857 | if (!ureq) | ||
858 | return NULL; | ||
859 | |||
860 | INIT_LIST_HEAD(&ureq->node); | ||
861 | return &ureq->req; | ||
862 | } | ||
863 | |||
864 | static void usbhsg_ep_free_request(struct usb_ep *ep, | ||
865 | struct usb_request *req) | ||
866 | { | ||
867 | struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); | ||
868 | |||
869 | WARN_ON(!list_empty(&ureq->node)); | ||
870 | kfree(ureq); | ||
871 | } | ||
872 | |||
873 | static int usbhsg_ep_queue(struct usb_ep *ep, struct usb_request *req, | ||
874 | gfp_t gfp_flags) | ||
875 | { | ||
876 | struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); | ||
877 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | ||
878 | struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); | ||
879 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | ||
880 | spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); | ||
881 | unsigned long flags; | ||
882 | int ret = 0; | ||
883 | int is_locked; | ||
884 | |||
885 | /* | ||
886 | * CAUTION [*endpoint queue*] | ||
887 | * | ||
888 | * This function will be called from usb_request :: complete | ||
889 | * or usb driver timing. | ||
890 | * If this function is called from usb_request :: complete, | ||
891 | * it is already under spinlock on this driver. | ||
892 | * but it is called frm usb driver, this function should call spinlock. | ||
893 | * | ||
894 | * This function is using spin_trylock_irqsave to solve this issue. | ||
895 | * if "is_locked" is 1, this mean this function lock it. | ||
896 | * but if it is 0, this mean it is already under spin lock. | ||
897 | * see also | ||
898 | * CAUTION [*queue handler*] | ||
899 | * CAUTION [*request complete*] | ||
900 | */ | ||
901 | |||
902 | /******************** spin lock ********************/ | ||
903 | is_locked = spin_trylock_irqsave(lock, flags); | ||
904 | |||
905 | /* param check */ | ||
906 | if (usbhsg_is_not_connected(gpriv) || | ||
907 | unlikely(!gpriv->driver) || | ||
908 | unlikely(!pipe)) | ||
909 | ret = -ESHUTDOWN; | ||
910 | else | ||
911 | usbhsg_queue_push(uep, ureq); | ||
912 | |||
913 | if (is_locked) | ||
914 | spin_unlock_irqrestore(lock, flags); | ||
915 | /******************** spin unlock ******************/ | ||
916 | |||
917 | usbhsg_queue_prepare(uep); | ||
918 | |||
919 | return ret; | ||
920 | } | ||
921 | |||
922 | static int usbhsg_ep_dequeue(struct usb_ep *ep, struct usb_request *req) | ||
923 | { | ||
924 | struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); | ||
925 | struct usbhsg_request *ureq = usbhsg_req_to_ureq(req); | ||
926 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | ||
927 | spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); | ||
928 | unsigned long flags; | ||
929 | int is_locked; | ||
930 | |||
931 | /* | ||
932 | * see | ||
933 | * CAUTION [*queue handler*] | ||
934 | * CAUTION [*endpoint queue*] | ||
935 | * CAUTION [*request complete*] | ||
936 | */ | ||
937 | |||
938 | /******************** spin lock ********************/ | ||
939 | is_locked = spin_trylock_irqsave(lock, flags); | ||
940 | |||
941 | usbhsg_queue_pop(uep, ureq, -ECONNRESET); | ||
942 | |||
943 | if (is_locked) | ||
944 | spin_unlock_irqrestore(lock, flags); | ||
945 | /******************** spin unlock ******************/ | ||
946 | |||
947 | return 0; | ||
948 | } | ||
949 | |||
950 | static int __usbhsg_ep_set_halt_wedge(struct usb_ep *ep, int halt, int wedge) | ||
951 | { | ||
952 | struct usbhsg_uep *uep = usbhsg_ep_to_uep(ep); | ||
953 | struct usbhs_pipe *pipe = usbhsg_uep_to_pipe(uep); | ||
954 | struct usbhsg_gpriv *gpriv = usbhsg_uep_to_gpriv(uep); | ||
955 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | ||
956 | spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); | ||
957 | unsigned long flags; | ||
958 | int ret = -EAGAIN; | ||
959 | int is_locked; | ||
960 | |||
961 | /* | ||
962 | * see | ||
963 | * CAUTION [*queue handler*] | ||
964 | * CAUTION [*endpoint queue*] | ||
965 | * CAUTION [*request complete*] | ||
966 | */ | ||
967 | |||
968 | /******************** spin lock ********************/ | ||
969 | is_locked = spin_trylock_irqsave(lock, flags); | ||
970 | if (!usbhsg_queue_get(uep)) { | ||
971 | |||
972 | dev_dbg(dev, "set halt %d (pipe %d)\n", | ||
973 | halt, usbhs_pipe_number(pipe)); | ||
974 | |||
975 | if (halt) | ||
976 | usbhs_fifo_stall(pipe); | ||
977 | else | ||
978 | usbhs_fifo_disable(pipe); | ||
979 | |||
980 | if (halt && wedge) | ||
981 | usbhsg_status_set(gpriv, USBHSG_STATUS_WEDGE); | ||
982 | else | ||
983 | usbhsg_status_clr(gpriv, USBHSG_STATUS_WEDGE); | ||
984 | |||
985 | ret = 0; | ||
986 | } | ||
987 | |||
988 | if (is_locked) | ||
989 | spin_unlock_irqrestore(lock, flags); | ||
990 | /******************** spin unlock ******************/ | ||
991 | |||
992 | return ret; | ||
993 | } | ||
994 | |||
995 | static int usbhsg_ep_set_halt(struct usb_ep *ep, int value) | ||
996 | { | ||
997 | return __usbhsg_ep_set_halt_wedge(ep, value, 0); | ||
998 | } | ||
999 | |||
1000 | static int usbhsg_ep_set_wedge(struct usb_ep *ep) | ||
1001 | { | ||
1002 | return __usbhsg_ep_set_halt_wedge(ep, 1, 1); | ||
1003 | } | ||
1004 | |||
1005 | static struct usb_ep_ops usbhsg_ep_ops = { | ||
1006 | .enable = usbhsg_ep_enable, | ||
1007 | .disable = usbhsg_ep_disable, | ||
1008 | |||
1009 | .alloc_request = usbhsg_ep_alloc_request, | ||
1010 | .free_request = usbhsg_ep_free_request, | ||
1011 | |||
1012 | .queue = usbhsg_ep_queue, | ||
1013 | .dequeue = usbhsg_ep_dequeue, | ||
1014 | |||
1015 | .set_halt = usbhsg_ep_set_halt, | ||
1016 | .set_wedge = usbhsg_ep_set_wedge, | ||
1017 | }; | ||
1018 | |||
1019 | /* | ||
1020 | * usb module start/end | ||
1021 | */ | ||
1022 | static int usbhsg_try_start(struct usbhs_priv *priv, u32 status) | ||
1023 | { | ||
1024 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); | ||
1025 | struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); | ||
1026 | struct usbhs_mod *mod = usbhs_mod_get_current(priv); | ||
1027 | struct device *dev = usbhs_priv_to_dev(priv); | ||
1028 | spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); | ||
1029 | unsigned long flags; | ||
1030 | |||
1031 | /******************** spin lock ********************/ | ||
1032 | spin_lock_irqsave(lock, flags); | ||
1033 | |||
1034 | /* | ||
1035 | * enable interrupt and systems if ready | ||
1036 | */ | ||
1037 | usbhsg_status_set(gpriv, status); | ||
1038 | if (!(usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) && | ||
1039 | usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD))) | ||
1040 | goto usbhsg_try_start_unlock; | ||
1041 | |||
1042 | dev_dbg(dev, "start gadget\n"); | ||
1043 | |||
1044 | /* | ||
1045 | * pipe initialize and enable DCP | ||
1046 | */ | ||
1047 | usbhs_pipe_init(priv); | ||
1048 | usbhsg_dcp_enable(dcp); | ||
1049 | |||
1050 | /* | ||
1051 | * system config enble | ||
1052 | * - HI speed | ||
1053 | * - function | ||
1054 | * - usb module | ||
1055 | */ | ||
1056 | usbhs_sys_hispeed_ctrl(priv, 1); | ||
1057 | usbhs_sys_function_ctrl(priv, 1); | ||
1058 | usbhs_sys_usb_ctrl(priv, 1); | ||
1059 | |||
1060 | /* | ||
1061 | * enable irq callback | ||
1062 | */ | ||
1063 | mod->irq_dev_state = usbhsg_irq_dev_state; | ||
1064 | mod->irq_ctrl_stage = usbhsg_irq_ctrl_stage; | ||
1065 | mod->irq_empty = usbhsg_irq_empty; | ||
1066 | mod->irq_ready = usbhsg_irq_ready; | ||
1067 | mod->irq_bempsts = 0; | ||
1068 | mod->irq_brdysts = 0; | ||
1069 | usbhs_irq_callback_update(priv, mod); | ||
1070 | |||
1071 | usbhsg_try_start_unlock: | ||
1072 | spin_unlock_irqrestore(lock, flags); | ||
1073 | /******************** spin unlock ********************/ | ||
1074 | |||
1075 | return 0; | ||
1076 | } | ||
1077 | |||
1078 | static int usbhsg_try_stop(struct usbhs_priv *priv, u32 status) | ||
1079 | { | ||
1080 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); | ||
1081 | struct usbhs_mod *mod = usbhs_mod_get_current(priv); | ||
1082 | struct usbhsg_uep *dcp = usbhsg_gpriv_to_dcp(gpriv); | ||
1083 | struct device *dev = usbhs_priv_to_dev(priv); | ||
1084 | spinlock_t *lock = usbhsg_gpriv_to_lock(gpriv); | ||
1085 | unsigned long flags; | ||
1086 | |||
1087 | /******************** spin lock ********************/ | ||
1088 | spin_lock_irqsave(lock, flags); | ||
1089 | |||
1090 | /* | ||
1091 | * disable interrupt and systems if 1st try | ||
1092 | */ | ||
1093 | usbhsg_status_clr(gpriv, status); | ||
1094 | if (!usbhsg_status_has(gpriv, USBHSG_STATUS_STARTED) && | ||
1095 | !usbhsg_status_has(gpriv, USBHSG_STATUS_REGISTERD)) | ||
1096 | goto usbhsg_try_stop_unlock; | ||
1097 | |||
1098 | /* disable all irq */ | ||
1099 | mod->irq_dev_state = NULL; | ||
1100 | mod->irq_ctrl_stage = NULL; | ||
1101 | mod->irq_empty = NULL; | ||
1102 | mod->irq_ready = NULL; | ||
1103 | mod->irq_bempsts = 0; | ||
1104 | mod->irq_brdysts = 0; | ||
1105 | usbhs_irq_callback_update(priv, mod); | ||
1106 | |||
1107 | usbhsg_dcp_disable(dcp); | ||
1108 | |||
1109 | gpriv->gadget.speed = USB_SPEED_UNKNOWN; | ||
1110 | |||
1111 | /* disable sys */ | ||
1112 | usbhs_sys_hispeed_ctrl(priv, 0); | ||
1113 | usbhs_sys_function_ctrl(priv, 0); | ||
1114 | usbhs_sys_usb_ctrl(priv, 0); | ||
1115 | |||
1116 | spin_unlock_irqrestore(lock, flags); | ||
1117 | /******************** spin unlock ********************/ | ||
1118 | |||
1119 | if (gpriv->driver && | ||
1120 | gpriv->driver->disconnect) | ||
1121 | gpriv->driver->disconnect(&gpriv->gadget); | ||
1122 | |||
1123 | dev_dbg(dev, "stop gadget\n"); | ||
1124 | |||
1125 | return 0; | ||
1126 | |||
1127 | usbhsg_try_stop_unlock: | ||
1128 | spin_unlock_irqrestore(lock, flags); | ||
1129 | |||
1130 | return 0; | ||
1131 | } | ||
1132 | |||
1133 | /* | ||
1134 | * | ||
1135 | * linux usb function | ||
1136 | * | ||
1137 | */ | ||
1138 | struct usbhsg_gpriv *the_controller; | ||
1139 | int usb_gadget_probe_driver(struct usb_gadget_driver *driver, | ||
1140 | int (*bind)(struct usb_gadget *)) | ||
1141 | { | ||
1142 | struct usbhsg_gpriv *gpriv = the_controller; | ||
1143 | struct usbhs_priv *priv; | ||
1144 | struct device *dev; | ||
1145 | int ret; | ||
1146 | |||
1147 | if (!bind || | ||
1148 | !driver || | ||
1149 | !driver->setup || | ||
1150 | driver->speed != USB_SPEED_HIGH) | ||
1151 | return -EINVAL; | ||
1152 | if (!gpriv) | ||
1153 | return -ENODEV; | ||
1154 | if (gpriv->driver) | ||
1155 | return -EBUSY; | ||
1156 | |||
1157 | dev = usbhsg_gpriv_to_dev(gpriv); | ||
1158 | priv = usbhsg_gpriv_to_priv(gpriv); | ||
1159 | |||
1160 | /* first hook up the driver ... */ | ||
1161 | gpriv->driver = driver; | ||
1162 | gpriv->gadget.dev.driver = &driver->driver; | ||
1163 | |||
1164 | ret = device_add(&gpriv->gadget.dev); | ||
1165 | if (ret) { | ||
1166 | dev_err(dev, "device_add error %d\n", ret); | ||
1167 | goto add_fail; | ||
1168 | } | ||
1169 | |||
1170 | ret = bind(&gpriv->gadget); | ||
1171 | if (ret) { | ||
1172 | dev_err(dev, "bind to driver %s error %d\n", | ||
1173 | driver->driver.name, ret); | ||
1174 | goto bind_fail; | ||
1175 | } | ||
1176 | |||
1177 | dev_dbg(dev, "bind %s\n", driver->driver.name); | ||
1178 | |||
1179 | return usbhsg_try_start(priv, USBHSG_STATUS_REGISTERD); | ||
1180 | |||
1181 | bind_fail: | ||
1182 | device_del(&gpriv->gadget.dev); | ||
1183 | add_fail: | ||
1184 | gpriv->driver = NULL; | ||
1185 | gpriv->gadget.dev.driver = NULL; | ||
1186 | |||
1187 | return ret; | ||
1188 | } | ||
1189 | EXPORT_SYMBOL(usb_gadget_probe_driver); | ||
1190 | |||
1191 | int usb_gadget_unregister_driver(struct usb_gadget_driver *driver) | ||
1192 | { | ||
1193 | struct usbhsg_gpriv *gpriv = the_controller; | ||
1194 | struct usbhs_priv *priv; | ||
1195 | struct device *dev = usbhsg_gpriv_to_dev(gpriv); | ||
1196 | |||
1197 | if (!gpriv) | ||
1198 | return -ENODEV; | ||
1199 | |||
1200 | if (!driver || | ||
1201 | !driver->unbind || | ||
1202 | driver != gpriv->driver) | ||
1203 | return -EINVAL; | ||
1204 | |||
1205 | dev = usbhsg_gpriv_to_dev(gpriv); | ||
1206 | priv = usbhsg_gpriv_to_priv(gpriv); | ||
1207 | |||
1208 | usbhsg_try_stop(priv, USBHSG_STATUS_REGISTERD); | ||
1209 | device_del(&gpriv->gadget.dev); | ||
1210 | gpriv->driver = NULL; | ||
1211 | |||
1212 | if (driver->disconnect) | ||
1213 | driver->disconnect(&gpriv->gadget); | ||
1214 | |||
1215 | driver->unbind(&gpriv->gadget); | ||
1216 | dev_dbg(dev, "unbind %s\n", driver->driver.name); | ||
1217 | |||
1218 | return 0; | ||
1219 | } | ||
1220 | EXPORT_SYMBOL(usb_gadget_unregister_driver); | ||
1221 | |||
1222 | /* | ||
1223 | * usb gadget ops | ||
1224 | */ | ||
1225 | static int usbhsg_get_frame(struct usb_gadget *gadget) | ||
1226 | { | ||
1227 | struct usbhsg_gpriv *gpriv = usbhsg_gadget_to_gpriv(gadget); | ||
1228 | struct usbhs_priv *priv = usbhsg_gpriv_to_priv(gpriv); | ||
1229 | |||
1230 | return usbhs_frame_get_num(priv); | ||
1231 | } | ||
1232 | |||
1233 | static struct usb_gadget_ops usbhsg_gadget_ops = { | ||
1234 | .get_frame = usbhsg_get_frame, | ||
1235 | }; | ||
1236 | |||
1237 | static int usbhsg_start(struct usbhs_priv *priv) | ||
1238 | { | ||
1239 | return usbhsg_try_start(priv, USBHSG_STATUS_STARTED); | ||
1240 | } | ||
1241 | |||
1242 | static int usbhsg_stop(struct usbhs_priv *priv) | ||
1243 | { | ||
1244 | return usbhsg_try_stop(priv, USBHSG_STATUS_STARTED); | ||
1245 | } | ||
1246 | |||
1247 | int __devinit usbhs_mod_gadget_probe(struct usbhs_priv *priv) | ||
1248 | { | ||
1249 | struct usbhsg_gpriv *gpriv; | ||
1250 | struct usbhsg_uep *uep; | ||
1251 | struct device *dev = usbhs_priv_to_dev(priv); | ||
1252 | int pipe_size = usbhs_get_dparam(priv, pipe_size); | ||
1253 | int i; | ||
1254 | |||
1255 | gpriv = kzalloc(sizeof(struct usbhsg_gpriv), GFP_KERNEL); | ||
1256 | if (!gpriv) { | ||
1257 | dev_err(dev, "Could not allocate gadget priv\n"); | ||
1258 | return -ENOMEM; | ||
1259 | } | ||
1260 | |||
1261 | uep = kzalloc(sizeof(struct usbhsg_uep) * pipe_size, GFP_KERNEL); | ||
1262 | if (!uep) { | ||
1263 | dev_err(dev, "Could not allocate ep\n"); | ||
1264 | goto usbhs_mod_gadget_probe_err_gpriv; | ||
1265 | } | ||
1266 | |||
1267 | /* | ||
1268 | * CAUTION | ||
1269 | * | ||
1270 | * There is no guarantee that it is possible to access usb module here. | ||
1271 | * Don't accesses to it. | ||
1272 | * The accesse will be enable after "usbhsg_start" | ||
1273 | */ | ||
1274 | |||
1275 | /* | ||
1276 | * register itself | ||
1277 | */ | ||
1278 | usbhs_mod_register(priv, &gpriv->mod, USBHS_GADGET); | ||
1279 | |||
1280 | /* init gpriv */ | ||
1281 | gpriv->mod.name = "gadget"; | ||
1282 | gpriv->mod.start = usbhsg_start; | ||
1283 | gpriv->mod.stop = usbhsg_stop; | ||
1284 | gpriv->uep = uep; | ||
1285 | gpriv->uep_size = pipe_size; | ||
1286 | usbhsg_status_init(gpriv); | ||
1287 | |||
1288 | /* | ||
1289 | * init gadget | ||
1290 | */ | ||
1291 | device_initialize(&gpriv->gadget.dev); | ||
1292 | dev_set_name(&gpriv->gadget.dev, "gadget"); | ||
1293 | gpriv->gadget.dev.parent = dev; | ||
1294 | gpriv->gadget.name = "renesas_usbhs_udc"; | ||
1295 | gpriv->gadget.ops = &usbhsg_gadget_ops; | ||
1296 | gpriv->gadget.is_dualspeed = 1; | ||
1297 | |||
1298 | INIT_LIST_HEAD(&gpriv->gadget.ep_list); | ||
1299 | |||
1300 | /* | ||
1301 | * init usb_ep | ||
1302 | */ | ||
1303 | usbhsg_for_each_uep_with_dcp(uep, gpriv, i) { | ||
1304 | uep->gpriv = gpriv; | ||
1305 | snprintf(uep->ep_name, EP_NAME_SIZE, "ep%d", i); | ||
1306 | |||
1307 | uep->ep.name = uep->ep_name; | ||
1308 | uep->ep.ops = &usbhsg_ep_ops; | ||
1309 | INIT_LIST_HEAD(&uep->ep.ep_list); | ||
1310 | INIT_LIST_HEAD(&uep->list); | ||
1311 | |||
1312 | /* init DCP */ | ||
1313 | if (usbhsg_is_dcp(uep)) { | ||
1314 | gpriv->gadget.ep0 = &uep->ep; | ||
1315 | uep->ep.maxpacket = 64; | ||
1316 | } | ||
1317 | /* init normal pipe */ | ||
1318 | else { | ||
1319 | uep->ep.maxpacket = 512; | ||
1320 | list_add_tail(&uep->ep.ep_list, &gpriv->gadget.ep_list); | ||
1321 | } | ||
1322 | } | ||
1323 | |||
1324 | the_controller = gpriv; | ||
1325 | |||
1326 | dev_info(dev, "gadget probed\n"); | ||
1327 | |||
1328 | return 0; | ||
1329 | |||
1330 | usbhs_mod_gadget_probe_err_gpriv: | ||
1331 | kfree(gpriv); | ||
1332 | |||
1333 | return -ENOMEM; | ||
1334 | } | ||
1335 | |||
1336 | void __devexit usbhs_mod_gadget_remove(struct usbhs_priv *priv) | ||
1337 | { | ||
1338 | struct usbhsg_gpriv *gpriv = usbhsg_priv_to_gpriv(priv); | ||
1339 | |||
1340 | kfree(gpriv); | ||
1341 | } | ||