Deleted Added
full compact
musb_otg.c (187172) musb_otg.c (187173)
1/* $FreeBSD: head/sys/dev/usb2/controller/musb2_otg.c 187172 2009-01-13 19:03:01Z thompsa $ */
1/* $FreeBSD: head/sys/dev/usb2/controller/musb2_otg.c 187173 2009-01-13 19:03:12Z thompsa $ */
2/*-
3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27/*
28 * Thanks to Mentor Graphics for providing a reference driver for this
29 * USB chip at their homepage.
30 */
31
32/*
33 * This file contains the driver for the Mentor Graphics Inventra USB
34 * 2.0 High Speed Dual-Role controller.
35 *
36 * NOTE: The current implementation only supports Device Side Mode!
37 */
38
39#include <dev/usb2/include/usb2_standard.h>
40#include <dev/usb2/include/usb2_mfunc.h>
41#include <dev/usb2/include/usb2_error.h>
42#include <dev/usb2/include/usb2_defs.h>
43
44#define USB_DEBUG_VAR musbotgdebug
45
46#include <dev/usb2/core/usb2_core.h>
47#include <dev/usb2/core/usb2_debug.h>
48#include <dev/usb2/core/usb2_busdma.h>
49#include <dev/usb2/core/usb2_process.h>
50#include <dev/usb2/core/usb2_sw_transfer.h>
51#include <dev/usb2/core/usb2_transfer.h>
52#include <dev/usb2/core/usb2_device.h>
53#include <dev/usb2/core/usb2_hub.h>
54#include <dev/usb2/core/usb2_util.h>
55
56#include <dev/usb2/controller/usb2_controller.h>
57#include <dev/usb2/controller/usb2_bus.h>
58#include <dev/usb2/controller/musb2_otg.h>
59
60#define MUSBOTG_INTR_ENDPT 1
61
62#define MUSBOTG_BUS2SC(bus) \
63 ((struct musbotg_softc *)(((uint8_t *)(bus)) - \
64 USB_P2U(&(((struct musbotg_softc *)0)->sc_bus))))
65
66#define MUSBOTG_PC2SC(pc) \
67 MUSBOTG_BUS2SC((pc)->tag_parent->info->bus)
68
69#if USB_DEBUG
70static int musbotgdebug = 0;
71
72SYSCTL_NODE(_hw_usb2, OID_AUTO, musbotg, CTLFLAG_RW, 0, "USB musbotg");
73SYSCTL_INT(_hw_usb2_musbotg, OID_AUTO, debug, CTLFLAG_RW,
74 &musbotgdebug, 0, "Debug level");
75#endif
76
77/* prototypes */
78
79struct usb2_bus_methods musbotg_bus_methods;
80struct usb2_pipe_methods musbotg_device_bulk_methods;
81struct usb2_pipe_methods musbotg_device_ctrl_methods;
82struct usb2_pipe_methods musbotg_device_intr_methods;
83struct usb2_pipe_methods musbotg_device_isoc_methods;
84struct usb2_pipe_methods musbotg_root_ctrl_methods;
85struct usb2_pipe_methods musbotg_root_intr_methods;
86
87static musbotg_cmd_t musbotg_setup_rx;
88static musbotg_cmd_t musbotg_setup_data_rx;
89static musbotg_cmd_t musbotg_setup_data_tx;
90static musbotg_cmd_t musbotg_setup_status;
91static musbotg_cmd_t musbotg_data_rx;
92static musbotg_cmd_t musbotg_data_tx;
93static void musbotg_device_done(struct usb2_xfer *, usb2_error_t);
94static void musbotg_do_poll(struct usb2_bus *);
95static void musbotg_root_ctrl_poll(struct musbotg_softc *);
96static void musbotg_standard_done(struct usb2_xfer *);
97static void musbotg_interrupt_poll(struct musbotg_softc *);
98
99static usb2_sw_transfer_func_t musbotg_root_intr_done;
100static usb2_sw_transfer_func_t musbotg_root_ctrl_done;
101
102/*
103 * Here is a configuration that the chip supports.
104 */
105static const struct usb2_hw_ep_profile musbotg_ep_profile[1] = {
106
107 [0] = {
108 .max_in_frame_size = 64,/* fixed */
109 .max_out_frame_size = 64, /* fixed */
110 .is_simplex = 1,
111 .support_control = 1,
112 }
113};
114
115static void
116musbotg_get_hw_ep_profile(struct usb2_device *udev,
117 const struct usb2_hw_ep_profile **ppf, uint8_t ep_addr)
118{
119 struct musbotg_softc *sc;
120
121 sc = MUSBOTG_BUS2SC(udev->bus);
122
123 if (ep_addr == 0) {
124 /* control endpoint */
125 *ppf = musbotg_ep_profile;
126 } else if (ep_addr <= sc->sc_ep_max) {
127 /* other endpoints */
128 *ppf = sc->sc_hw_ep_profile + ep_addr;
129 } else {
130 *ppf = NULL;
131 }
132}
133
134static void
135musbotg_clocks_on(struct musbotg_softc *sc)
136{
137 if (sc->sc_flags.clocks_off &&
138 sc->sc_flags.port_powered) {
139
140 DPRINTFN(4, "\n");
141
142 if (sc->sc_clocks_on) {
143 (sc->sc_clocks_on) (sc->sc_clocks_arg);
144 }
145 sc->sc_flags.clocks_off = 0;
146
147 /* XXX enable Transceiver */
148 }
149}
150
151static void
152musbotg_clocks_off(struct musbotg_softc *sc)
153{
154 if (!sc->sc_flags.clocks_off) {
155
156 DPRINTFN(4, "\n");
157
158 /* XXX disable Transceiver */
159
160 if (sc->sc_clocks_off) {
161 (sc->sc_clocks_off) (sc->sc_clocks_arg);
162 }
163 sc->sc_flags.clocks_off = 1;
164 }
165}
166
167static void
168musbotg_pull_common(struct musbotg_softc *sc, uint8_t on)
169{
170 uint8_t temp;
171
172 temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
173 if (on)
174 temp |= MUSB2_MASK_SOFTC;
175 else
176 temp &= ~MUSB2_MASK_SOFTC;
177
178 MUSB2_WRITE_1(sc, MUSB2_REG_POWER, temp);
179}
180
181static void
182musbotg_pull_up(struct musbotg_softc *sc)
183{
184 /* pullup D+, if possible */
185
186 if (!sc->sc_flags.d_pulled_up &&
187 sc->sc_flags.port_powered) {
188 sc->sc_flags.d_pulled_up = 1;
189 musbotg_pull_common(sc, 1);
190 }
191}
192
193static void
194musbotg_pull_down(struct musbotg_softc *sc)
195{
196 /* pulldown D+, if possible */
197
198 if (sc->sc_flags.d_pulled_up) {
199 sc->sc_flags.d_pulled_up = 0;
200 musbotg_pull_common(sc, 0);
201 }
202}
203
204static void
205musbotg_wakeup_peer(struct usb2_xfer *xfer)
206{
2/*-
3 * Copyright (c) 2008 Hans Petter Selasky. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 */
26
27/*
28 * Thanks to Mentor Graphics for providing a reference driver for this
29 * USB chip at their homepage.
30 */
31
32/*
33 * This file contains the driver for the Mentor Graphics Inventra USB
34 * 2.0 High Speed Dual-Role controller.
35 *
36 * NOTE: The current implementation only supports Device Side Mode!
37 */
38
39#include <dev/usb2/include/usb2_standard.h>
40#include <dev/usb2/include/usb2_mfunc.h>
41#include <dev/usb2/include/usb2_error.h>
42#include <dev/usb2/include/usb2_defs.h>
43
44#define USB_DEBUG_VAR musbotgdebug
45
46#include <dev/usb2/core/usb2_core.h>
47#include <dev/usb2/core/usb2_debug.h>
48#include <dev/usb2/core/usb2_busdma.h>
49#include <dev/usb2/core/usb2_process.h>
50#include <dev/usb2/core/usb2_sw_transfer.h>
51#include <dev/usb2/core/usb2_transfer.h>
52#include <dev/usb2/core/usb2_device.h>
53#include <dev/usb2/core/usb2_hub.h>
54#include <dev/usb2/core/usb2_util.h>
55
56#include <dev/usb2/controller/usb2_controller.h>
57#include <dev/usb2/controller/usb2_bus.h>
58#include <dev/usb2/controller/musb2_otg.h>
59
60#define MUSBOTG_INTR_ENDPT 1
61
62#define MUSBOTG_BUS2SC(bus) \
63 ((struct musbotg_softc *)(((uint8_t *)(bus)) - \
64 USB_P2U(&(((struct musbotg_softc *)0)->sc_bus))))
65
66#define MUSBOTG_PC2SC(pc) \
67 MUSBOTG_BUS2SC((pc)->tag_parent->info->bus)
68
69#if USB_DEBUG
70static int musbotgdebug = 0;
71
72SYSCTL_NODE(_hw_usb2, OID_AUTO, musbotg, CTLFLAG_RW, 0, "USB musbotg");
73SYSCTL_INT(_hw_usb2_musbotg, OID_AUTO, debug, CTLFLAG_RW,
74 &musbotgdebug, 0, "Debug level");
75#endif
76
77/* prototypes */
78
79struct usb2_bus_methods musbotg_bus_methods;
80struct usb2_pipe_methods musbotg_device_bulk_methods;
81struct usb2_pipe_methods musbotg_device_ctrl_methods;
82struct usb2_pipe_methods musbotg_device_intr_methods;
83struct usb2_pipe_methods musbotg_device_isoc_methods;
84struct usb2_pipe_methods musbotg_root_ctrl_methods;
85struct usb2_pipe_methods musbotg_root_intr_methods;
86
87static musbotg_cmd_t musbotg_setup_rx;
88static musbotg_cmd_t musbotg_setup_data_rx;
89static musbotg_cmd_t musbotg_setup_data_tx;
90static musbotg_cmd_t musbotg_setup_status;
91static musbotg_cmd_t musbotg_data_rx;
92static musbotg_cmd_t musbotg_data_tx;
93static void musbotg_device_done(struct usb2_xfer *, usb2_error_t);
94static void musbotg_do_poll(struct usb2_bus *);
95static void musbotg_root_ctrl_poll(struct musbotg_softc *);
96static void musbotg_standard_done(struct usb2_xfer *);
97static void musbotg_interrupt_poll(struct musbotg_softc *);
98
99static usb2_sw_transfer_func_t musbotg_root_intr_done;
100static usb2_sw_transfer_func_t musbotg_root_ctrl_done;
101
102/*
103 * Here is a configuration that the chip supports.
104 */
105static const struct usb2_hw_ep_profile musbotg_ep_profile[1] = {
106
107 [0] = {
108 .max_in_frame_size = 64,/* fixed */
109 .max_out_frame_size = 64, /* fixed */
110 .is_simplex = 1,
111 .support_control = 1,
112 }
113};
114
115static void
116musbotg_get_hw_ep_profile(struct usb2_device *udev,
117 const struct usb2_hw_ep_profile **ppf, uint8_t ep_addr)
118{
119 struct musbotg_softc *sc;
120
121 sc = MUSBOTG_BUS2SC(udev->bus);
122
123 if (ep_addr == 0) {
124 /* control endpoint */
125 *ppf = musbotg_ep_profile;
126 } else if (ep_addr <= sc->sc_ep_max) {
127 /* other endpoints */
128 *ppf = sc->sc_hw_ep_profile + ep_addr;
129 } else {
130 *ppf = NULL;
131 }
132}
133
134static void
135musbotg_clocks_on(struct musbotg_softc *sc)
136{
137 if (sc->sc_flags.clocks_off &&
138 sc->sc_flags.port_powered) {
139
140 DPRINTFN(4, "\n");
141
142 if (sc->sc_clocks_on) {
143 (sc->sc_clocks_on) (sc->sc_clocks_arg);
144 }
145 sc->sc_flags.clocks_off = 0;
146
147 /* XXX enable Transceiver */
148 }
149}
150
151static void
152musbotg_clocks_off(struct musbotg_softc *sc)
153{
154 if (!sc->sc_flags.clocks_off) {
155
156 DPRINTFN(4, "\n");
157
158 /* XXX disable Transceiver */
159
160 if (sc->sc_clocks_off) {
161 (sc->sc_clocks_off) (sc->sc_clocks_arg);
162 }
163 sc->sc_flags.clocks_off = 1;
164 }
165}
166
167static void
168musbotg_pull_common(struct musbotg_softc *sc, uint8_t on)
169{
170 uint8_t temp;
171
172 temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
173 if (on)
174 temp |= MUSB2_MASK_SOFTC;
175 else
176 temp &= ~MUSB2_MASK_SOFTC;
177
178 MUSB2_WRITE_1(sc, MUSB2_REG_POWER, temp);
179}
180
181static void
182musbotg_pull_up(struct musbotg_softc *sc)
183{
184 /* pullup D+, if possible */
185
186 if (!sc->sc_flags.d_pulled_up &&
187 sc->sc_flags.port_powered) {
188 sc->sc_flags.d_pulled_up = 1;
189 musbotg_pull_common(sc, 1);
190 }
191}
192
193static void
194musbotg_pull_down(struct musbotg_softc *sc)
195{
196 /* pulldown D+, if possible */
197
198 if (sc->sc_flags.d_pulled_up) {
199 sc->sc_flags.d_pulled_up = 0;
200 musbotg_pull_common(sc, 0);
201 }
202}
203
204static void
205musbotg_wakeup_peer(struct usb2_xfer *xfer)
206{
207 struct musbotg_softc *sc = xfer->usb2_sc;
207 struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
208 uint8_t temp;
209 uint8_t use_polling;
210
211 if (!(sc->sc_flags.status_suspend)) {
212 return;
213 }
208 uint8_t temp;
209 uint8_t use_polling;
210
211 if (!(sc->sc_flags.status_suspend)) {
212 return;
213 }
214 use_polling = mtx_owned(xfer->xfer_mtx) ? 1 : 0;
214 use_polling = mtx_owned(xfer->xroot->xfer_mtx) ? 1 : 0;
215
216 temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
217 temp |= MUSB2_MASK_RESUME;
218 MUSB2_WRITE_1(sc, MUSB2_REG_POWER, temp);
219
220 /* wait 8 milliseconds */
221 if (use_polling) {
222 /* polling */
223 DELAY(8000);
224 } else {
225 /* Wait for reset to complete. */
226 usb2_pause_mtx(&sc->sc_bus.bus_mtx, 8);
227 }
228
229 temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
230 temp &= ~MUSB2_MASK_RESUME;
231 MUSB2_WRITE_1(sc, MUSB2_REG_POWER, temp);
232}
233
234static void
235musbotg_set_address(struct musbotg_softc *sc, uint8_t addr)
236{
237 DPRINTFN(4, "addr=%d\n", addr);
238 addr &= 0x7F;
239 MUSB2_WRITE_1(sc, MUSB2_REG_FADDR, addr);
240}
241
242static uint8_t
243musbotg_setup_rx(struct musbotg_td *td)
244{
245 struct musbotg_softc *sc;
246 struct usb2_device_request req;
247 uint16_t count;
248 uint8_t csr;
249
250 /* get pointer to softc */
251 sc = MUSBOTG_PC2SC(td->pc);
252
253 /* select endpoint 0 */
254 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
255
256 /* read out FIFO status */
257 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
258
259 DPRINTFN(4, "csr=0x%02x\n", csr);
260
261 /*
262 * NOTE: If DATAEND is set we should not call the
263 * callback, hence the status stage is not complete.
264 */
265 if (csr & MUSB2_MASK_CSR0L_DATAEND) {
266 /* wait for interrupt */
267 goto not_complete;
268 }
269 if (csr & MUSB2_MASK_CSR0L_SENTSTALL) {
270 /* clear SENTSTALL */
271 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
272 /* get latest status */
273 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
274 /* update EP0 state */
275 sc->sc_ep0_busy = 0;
276 }
277 if (csr & MUSB2_MASK_CSR0L_SETUPEND) {
278 /* clear SETUPEND */
279 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
280 MUSB2_MASK_CSR0L_SETUPEND_CLR);
281 /* get latest status */
282 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
283 /* update EP0 state */
284 sc->sc_ep0_busy = 0;
285 }
286 if (sc->sc_ep0_busy) {
287 /* abort any ongoing transfer */
288 if (!td->did_stall) {
289 DPRINTFN(4, "stalling\n");
290 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
291 MUSB2_MASK_CSR0L_SENDSTALL);
292 td->did_stall = 1;
293 }
294 goto not_complete;
295 }
296 if (!(csr & MUSB2_MASK_CSR0L_RXPKTRDY)) {
297 goto not_complete;
298 }
299 /* get the packet byte count */
300 count = MUSB2_READ_2(sc, MUSB2_REG_RXCOUNT);
301
302 /* verify data length */
303 if (count != td->remainder) {
304 DPRINTFN(0, "Invalid SETUP packet "
305 "length, %d bytes\n", count);
306 goto not_complete;
307 }
308 if (count != sizeof(req)) {
309 DPRINTFN(0, "Unsupported SETUP packet "
310 "length, %d bytes\n", count);
311 goto not_complete;
312 }
313 /* receive data */
314 bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
315 MUSB2_REG_EPFIFO(0), (void *)&req, sizeof(req));
316
317 /* copy data into real buffer */
318 usb2_copy_in(td->pc, 0, &req, sizeof(req));
319
320 td->offset = sizeof(req);
321 td->remainder = 0;
322
323 /* set pending command */
324 sc->sc_ep0_cmd = MUSB2_MASK_CSR0L_RXPKTRDY_CLR;
325
326 /* we need set stall or dataend after this */
327 sc->sc_ep0_busy = 1;
328
329 /* sneak peek the set address */
330 if ((req.bmRequestType == UT_WRITE_DEVICE) &&
331 (req.bRequest == UR_SET_ADDRESS)) {
332 sc->sc_dv_addr = req.wValue[0] & 0x7F;
333 } else {
334 sc->sc_dv_addr = 0xFF;
335 }
336 return (0); /* complete */
337
338not_complete:
339 return (1); /* not complete */
340}
341
342/* Control endpoint only data handling functions (RX/TX/SYNC) */
343
344static uint8_t
345musbotg_setup_data_rx(struct musbotg_td *td)
346{
347 struct usb2_page_search buf_res;
348 struct musbotg_softc *sc;
349 uint16_t count;
350 uint8_t csr;
351 uint8_t got_short;
352
353 /* get pointer to softc */
354 sc = MUSBOTG_PC2SC(td->pc);
355
356 /* select endpoint 0 */
357 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
358
359 /* check if a command is pending */
360 if (sc->sc_ep0_cmd) {
361 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, sc->sc_ep0_cmd);
362 sc->sc_ep0_cmd = 0;
363 }
364 /* read out FIFO status */
365 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
366
367 DPRINTFN(4, "csr=0x%02x\n", csr);
368
369 got_short = 0;
370
371 if (csr & (MUSB2_MASK_CSR0L_SETUPEND |
372 MUSB2_MASK_CSR0L_SENTSTALL)) {
373 if (td->remainder == 0) {
374 /*
375 * We are actually complete and have
376 * received the next SETUP
377 */
378 DPRINTFN(4, "faking complete\n");
379 return (0); /* complete */
380 }
381 /*
382 * USB Host Aborted the transfer.
383 */
384 td->error = 1;
385 return (0); /* complete */
386 }
387 if (!(csr & MUSB2_MASK_CSR0L_RXPKTRDY)) {
388 return (1); /* not complete */
389 }
390 /* get the packet byte count */
391 count = MUSB2_READ_2(sc, MUSB2_REG_RXCOUNT);
392
393 /* verify the packet byte count */
394 if (count != td->max_frame_size) {
395 if (count < td->max_frame_size) {
396 /* we have a short packet */
397 td->short_pkt = 1;
398 got_short = 1;
399 } else {
400 /* invalid USB packet */
401 td->error = 1;
402 return (0); /* we are complete */
403 }
404 }
405 /* verify the packet byte count */
406 if (count > td->remainder) {
407 /* invalid USB packet */
408 td->error = 1;
409 return (0); /* we are complete */
410 }
411 while (count > 0) {
412 uint32_t temp;
413
414 usb2_get_page(td->pc, td->offset, &buf_res);
415
416 /* get correct length */
417 if (buf_res.length > count) {
418 buf_res.length = count;
419 }
420 /* check for unaligned memory address */
421 if (USB_P2U(buf_res.buffer) & 3) {
422
423 temp = count & ~3;
424
425 if (temp) {
426 /* receive data 4 bytes at a time */
427 bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
428 MUSB2_REG_EPFIFO(0), sc->sc_bounce_buf,
429 temp / 4);
430 }
431 temp = count & 3;
432 if (temp) {
433 /* receive data 1 byte at a time */
434 bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
435 MUSB2_REG_EPFIFO(0),
436 (void *)(&sc->sc_bounce_buf[count / 4]), temp);
437 }
438 usb2_copy_in(td->pc, td->offset,
439 sc->sc_bounce_buf, count);
440
441 /* update offset and remainder */
442 td->offset += count;
443 td->remainder -= count;
444 break;
445 }
446 /* check if we can optimise */
447 if (buf_res.length >= 4) {
448
449 /* receive data 4 bytes at a time */
450 bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
451 MUSB2_REG_EPFIFO(0), buf_res.buffer,
452 buf_res.length / 4);
453
454 temp = buf_res.length & ~3;
455
456 /* update counters */
457 count -= temp;
458 td->offset += temp;
459 td->remainder -= temp;
460 continue;
461 }
462 /* receive data */
463 bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
464 MUSB2_REG_EPFIFO(0), buf_res.buffer, buf_res.length);
465
466 /* update counters */
467 count -= buf_res.length;
468 td->offset += buf_res.length;
469 td->remainder -= buf_res.length;
470 }
471
472 /* check if we are complete */
473 if ((td->remainder == 0) || got_short) {
474 if (td->short_pkt) {
475 /* we are complete */
476 sc->sc_ep0_cmd = MUSB2_MASK_CSR0L_RXPKTRDY_CLR;
477 return (0);
478 }
479 /* else need to receive a zero length packet */
480 }
481 /* write command - need more data */
482 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
483 MUSB2_MASK_CSR0L_RXPKTRDY_CLR);
484 return (1); /* not complete */
485}
486
487static uint8_t
488musbotg_setup_data_tx(struct musbotg_td *td)
489{
490 struct usb2_page_search buf_res;
491 struct musbotg_softc *sc;
492 uint16_t count;
493 uint8_t csr;
494
495 /* get pointer to softc */
496 sc = MUSBOTG_PC2SC(td->pc);
497
498 /* select endpoint 0 */
499 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
500
501 /* check if a command is pending */
502 if (sc->sc_ep0_cmd) {
503 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, sc->sc_ep0_cmd);
504 sc->sc_ep0_cmd = 0;
505 }
506 /* read out FIFO status */
507 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
508
509 DPRINTFN(4, "csr=0x%02x\n", csr);
510
511 if (csr & (MUSB2_MASK_CSR0L_SETUPEND |
512 MUSB2_MASK_CSR0L_SENTSTALL)) {
513 /*
514 * The current transfer was aborted
515 * by the USB Host
516 */
517 td->error = 1;
518 return (0); /* complete */
519 }
520 if (csr & MUSB2_MASK_CSR0L_TXPKTRDY) {
521 return (1); /* not complete */
522 }
523 count = td->max_frame_size;
524 if (td->remainder < count) {
525 /* we have a short packet */
526 td->short_pkt = 1;
527 count = td->remainder;
528 }
529 while (count > 0) {
530 uint32_t temp;
531
532 usb2_get_page(td->pc, td->offset, &buf_res);
533
534 /* get correct length */
535 if (buf_res.length > count) {
536 buf_res.length = count;
537 }
538 /* check for unaligned memory address */
539 if (USB_P2U(buf_res.buffer) & 3) {
540
541 usb2_copy_out(td->pc, td->offset,
542 sc->sc_bounce_buf, count);
543
544 temp = count & ~3;
545
546 if (temp) {
547 /* transmit data 4 bytes at a time */
548 bus_space_write_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
549 MUSB2_REG_EPFIFO(0), sc->sc_bounce_buf,
550 temp / 4);
551 }
552 temp = count & 3;
553 if (temp) {
554 /* receive data 1 byte at a time */
555 bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
556 MUSB2_REG_EPFIFO(0),
557 ((void *)&sc->sc_bounce_buf[count / 4]), temp);
558 }
559 /* update offset and remainder */
560 td->offset += count;
561 td->remainder -= count;
562 break;
563 }
564 /* check if we can optimise */
565 if (buf_res.length >= 4) {
566
567 /* transmit data 4 bytes at a time */
568 bus_space_write_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
569 MUSB2_REG_EPFIFO(0), buf_res.buffer,
570 buf_res.length / 4);
571
572 temp = buf_res.length & ~3;
573
574 /* update counters */
575 count -= temp;
576 td->offset += temp;
577 td->remainder -= temp;
578 continue;
579 }
580 /* transmit data */
581 bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
582 MUSB2_REG_EPFIFO(0), buf_res.buffer, buf_res.length);
583
584 /* update counters */
585 count -= buf_res.length;
586 td->offset += buf_res.length;
587 td->remainder -= buf_res.length;
588 }
589
590 /* check remainder */
591 if (td->remainder == 0) {
592 if (td->short_pkt) {
593 sc->sc_ep0_cmd = MUSB2_MASK_CSR0L_TXPKTRDY;
594 return (0); /* complete */
595 }
596 /* else we need to transmit a short packet */
597 }
598 /* write command */
599 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
600 MUSB2_MASK_CSR0L_TXPKTRDY);
601
602 return (1); /* not complete */
603}
604
605static uint8_t
606musbotg_setup_status(struct musbotg_td *td)
607{
608 struct musbotg_softc *sc;
609 uint8_t csr;
610
611 /* get pointer to softc */
612 sc = MUSBOTG_PC2SC(td->pc);
613
614 /* select endpoint 0 */
615 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
616
617 if (sc->sc_ep0_busy) {
618 sc->sc_ep0_busy = 0;
619 sc->sc_ep0_cmd |= MUSB2_MASK_CSR0L_DATAEND;
620 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, sc->sc_ep0_cmd);
621 sc->sc_ep0_cmd = 0;
622 }
623 /* read out FIFO status */
624 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
625
626 DPRINTFN(4, "csr=0x%02x\n", csr);
627
628 if (csr & MUSB2_MASK_CSR0L_DATAEND) {
629 /* wait for interrupt */
630 return (1); /* not complete */
631 }
632 if (sc->sc_dv_addr != 0xFF) {
633 /* write function address */
634 musbotg_set_address(sc, sc->sc_dv_addr);
635 }
636 return (0); /* complete */
637}
638
639static uint8_t
640musbotg_data_rx(struct musbotg_td *td)
641{
642 struct usb2_page_search buf_res;
643 struct musbotg_softc *sc;
644 uint16_t count;
645 uint8_t csr;
646 uint8_t to;
647 uint8_t got_short;
648
649 to = 8; /* don't loop forever! */
650 got_short = 0;
651
652 /* get pointer to softc */
653 sc = MUSBOTG_PC2SC(td->pc);
654
655 /* select endpoint */
656 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, td->ep_no);
657
658repeat:
659 /* read out FIFO status */
660 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
661
662 DPRINTFN(4, "csr=0x%02x\n", csr);
663
664 /* clear overrun */
665 if (csr & MUSB2_MASK_CSRL_RXOVERRUN) {
666 /* make sure we don't clear "RXPKTRDY" */
667 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
668 MUSB2_MASK_CSRL_RXPKTRDY);
669 }
670 /* check status */
671 if (!(csr & MUSB2_MASK_CSRL_RXPKTRDY)) {
672 return (1); /* not complete */
673 }
674 /* get the packet byte count */
675 count = MUSB2_READ_2(sc, MUSB2_REG_RXCOUNT);
676
677 DPRINTFN(4, "count=0x%04x\n", count);
678
679 /*
680 * Check for short or invalid packet:
681 */
682 if (count != td->max_frame_size) {
683 if (count < td->max_frame_size) {
684 /* we have a short packet */
685 td->short_pkt = 1;
686 got_short = 1;
687 } else {
688 /* invalid USB packet */
689 td->error = 1;
690 return (0); /* we are complete */
691 }
692 }
693 /* verify the packet byte count */
694 if (count > td->remainder) {
695 /* invalid USB packet */
696 td->error = 1;
697 return (0); /* we are complete */
698 }
699 while (count > 0) {
700 uint32_t temp;
701
702 usb2_get_page(td->pc, td->offset, &buf_res);
703
704 /* get correct length */
705 if (buf_res.length > count) {
706 buf_res.length = count;
707 }
708 /* check for unaligned memory address */
709 if (USB_P2U(buf_res.buffer) & 3) {
710
711 temp = count & ~3;
712
713 if (temp) {
714 /* receive data 4 bytes at a time */
715 bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
716 MUSB2_REG_EPFIFO(td->ep_no), sc->sc_bounce_buf,
717 temp / 4);
718 }
719 temp = count & 3;
720 if (temp) {
721 /* receive data 1 byte at a time */
722 bus_space_read_multi_1(sc->sc_io_tag,
723 sc->sc_io_hdl, MUSB2_REG_EPFIFO(td->ep_no),
724 ((void *)&sc->sc_bounce_buf[count / 4]), temp);
725 }
726 usb2_copy_in(td->pc, td->offset,
727 sc->sc_bounce_buf, count);
728
729 /* update offset and remainder */
730 td->offset += count;
731 td->remainder -= count;
732 break;
733 }
734 /* check if we can optimise */
735 if (buf_res.length >= 4) {
736
737 /* receive data 4 bytes at a time */
738 bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
739 MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
740 buf_res.length / 4);
741
742 temp = buf_res.length & ~3;
743
744 /* update counters */
745 count -= temp;
746 td->offset += temp;
747 td->remainder -= temp;
748 continue;
749 }
750 /* receive data */
751 bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
752 MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
753 buf_res.length);
754
755 /* update counters */
756 count -= buf_res.length;
757 td->offset += buf_res.length;
758 td->remainder -= buf_res.length;
759 }
760
761 /* clear status bits */
762 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL, 0);
763
764 /* check if we are complete */
765 if ((td->remainder == 0) || got_short) {
766 if (td->short_pkt) {
767 /* we are complete */
768 return (0);
769 }
770 /* else need to receive a zero length packet */
771 }
772 if (--to) {
773 goto repeat;
774 }
775 return (1); /* not complete */
776}
777
778static uint8_t
779musbotg_data_tx(struct musbotg_td *td)
780{
781 struct usb2_page_search buf_res;
782 struct musbotg_softc *sc;
783 uint16_t count;
784 uint8_t csr;
785 uint8_t to;
786
787 to = 8; /* don't loop forever! */
788
789 /* get pointer to softc */
790 sc = MUSBOTG_PC2SC(td->pc);
791
792 /* select endpoint */
793 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, td->ep_no);
794
795repeat:
796
797 /* read out FIFO status */
798 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
799
800 DPRINTFN(4, "csr=0x%02x\n", csr);
801
802 if (csr & (MUSB2_MASK_CSRL_TXINCOMP |
803 MUSB2_MASK_CSRL_TXUNDERRUN)) {
804 /* clear status bits */
805 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
806 }
807 if (csr & MUSB2_MASK_CSRL_TXPKTRDY) {
808 return (1); /* not complete */
809 }
810 /* check for short packet */
811 count = td->max_frame_size;
812 if (td->remainder < count) {
813 /* we have a short packet */
814 td->short_pkt = 1;
815 count = td->remainder;
816 }
817 while (count > 0) {
818 uint32_t temp;
819
820 usb2_get_page(td->pc, td->offset, &buf_res);
821
822 /* get correct length */
823 if (buf_res.length > count) {
824 buf_res.length = count;
825 }
826 /* check for unaligned memory address */
827 if (USB_P2U(buf_res.buffer) & 3) {
828
829 usb2_copy_out(td->pc, td->offset,
830 sc->sc_bounce_buf, count);
831
832 temp = count & ~3;
833
834 if (temp) {
835 /* transmit data 4 bytes at a time */
836 bus_space_write_multi_4(sc->sc_io_tag,
837 sc->sc_io_hdl, MUSB2_REG_EPFIFO(td->ep_no),
838 sc->sc_bounce_buf, temp / 4);
839 }
840 temp = count & 3;
841 if (temp) {
842 /* receive data 1 byte at a time */
843 bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
844 MUSB2_REG_EPFIFO(td->ep_no),
845 ((void *)&sc->sc_bounce_buf[count / 4]), temp);
846 }
847 /* update offset and remainder */
848 td->offset += count;
849 td->remainder -= count;
850 break;
851 }
852 /* check if we can optimise */
853 if (buf_res.length >= 4) {
854
855 /* transmit data 4 bytes at a time */
856 bus_space_write_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
857 MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
858 buf_res.length / 4);
859
860 temp = buf_res.length & ~3;
861
862 /* update counters */
863 count -= temp;
864 td->offset += temp;
865 td->remainder -= temp;
866 continue;
867 }
868 /* transmit data */
869 bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
870 MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
871 buf_res.length);
872
873 /* update counters */
874 count -= buf_res.length;
875 td->offset += buf_res.length;
876 td->remainder -= buf_res.length;
877 }
878
879 /* write command */
880 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
881 MUSB2_MASK_CSRL_TXPKTRDY);
882
883 /* check remainder */
884 if (td->remainder == 0) {
885 if (td->short_pkt) {
886 return (0); /* complete */
887 }
888 /* else we need to transmit a short packet */
889 }
890 if (--to) {
891 goto repeat;
892 }
893 return (1); /* not complete */
894}
895
896static uint8_t
897musbotg_xfer_do_fifo(struct usb2_xfer *xfer)
898{
899 struct musbotg_softc *sc;
900 struct musbotg_td *td;
901
902 DPRINTFN(8, "\n");
903
904 td = xfer->td_transfer_cache;
905 while (1) {
906 if ((td->func) (td)) {
907 /* operation in progress */
908 break;
909 }
910 if (((void *)td) == xfer->td_transfer_last) {
911 goto done;
912 }
913 if (td->error) {
914 goto done;
915 } else if (td->remainder > 0) {
916 /*
917 * We had a short transfer. If there is no alternate
918 * next, stop processing !
919 */
920 if (!td->alt_next) {
921 goto done;
922 }
923 }
924 /*
925 * Fetch the next transfer descriptor and transfer
926 * some flags to the next transfer descriptor
927 */
928 td = td->obj_next;
929 xfer->td_transfer_cache = td;
930 }
931 return (1); /* not complete */
932
933done:
215
216 temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
217 temp |= MUSB2_MASK_RESUME;
218 MUSB2_WRITE_1(sc, MUSB2_REG_POWER, temp);
219
220 /* wait 8 milliseconds */
221 if (use_polling) {
222 /* polling */
223 DELAY(8000);
224 } else {
225 /* Wait for reset to complete. */
226 usb2_pause_mtx(&sc->sc_bus.bus_mtx, 8);
227 }
228
229 temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
230 temp &= ~MUSB2_MASK_RESUME;
231 MUSB2_WRITE_1(sc, MUSB2_REG_POWER, temp);
232}
233
234static void
235musbotg_set_address(struct musbotg_softc *sc, uint8_t addr)
236{
237 DPRINTFN(4, "addr=%d\n", addr);
238 addr &= 0x7F;
239 MUSB2_WRITE_1(sc, MUSB2_REG_FADDR, addr);
240}
241
242static uint8_t
243musbotg_setup_rx(struct musbotg_td *td)
244{
245 struct musbotg_softc *sc;
246 struct usb2_device_request req;
247 uint16_t count;
248 uint8_t csr;
249
250 /* get pointer to softc */
251 sc = MUSBOTG_PC2SC(td->pc);
252
253 /* select endpoint 0 */
254 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
255
256 /* read out FIFO status */
257 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
258
259 DPRINTFN(4, "csr=0x%02x\n", csr);
260
261 /*
262 * NOTE: If DATAEND is set we should not call the
263 * callback, hence the status stage is not complete.
264 */
265 if (csr & MUSB2_MASK_CSR0L_DATAEND) {
266 /* wait for interrupt */
267 goto not_complete;
268 }
269 if (csr & MUSB2_MASK_CSR0L_SENTSTALL) {
270 /* clear SENTSTALL */
271 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
272 /* get latest status */
273 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
274 /* update EP0 state */
275 sc->sc_ep0_busy = 0;
276 }
277 if (csr & MUSB2_MASK_CSR0L_SETUPEND) {
278 /* clear SETUPEND */
279 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
280 MUSB2_MASK_CSR0L_SETUPEND_CLR);
281 /* get latest status */
282 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
283 /* update EP0 state */
284 sc->sc_ep0_busy = 0;
285 }
286 if (sc->sc_ep0_busy) {
287 /* abort any ongoing transfer */
288 if (!td->did_stall) {
289 DPRINTFN(4, "stalling\n");
290 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
291 MUSB2_MASK_CSR0L_SENDSTALL);
292 td->did_stall = 1;
293 }
294 goto not_complete;
295 }
296 if (!(csr & MUSB2_MASK_CSR0L_RXPKTRDY)) {
297 goto not_complete;
298 }
299 /* get the packet byte count */
300 count = MUSB2_READ_2(sc, MUSB2_REG_RXCOUNT);
301
302 /* verify data length */
303 if (count != td->remainder) {
304 DPRINTFN(0, "Invalid SETUP packet "
305 "length, %d bytes\n", count);
306 goto not_complete;
307 }
308 if (count != sizeof(req)) {
309 DPRINTFN(0, "Unsupported SETUP packet "
310 "length, %d bytes\n", count);
311 goto not_complete;
312 }
313 /* receive data */
314 bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
315 MUSB2_REG_EPFIFO(0), (void *)&req, sizeof(req));
316
317 /* copy data into real buffer */
318 usb2_copy_in(td->pc, 0, &req, sizeof(req));
319
320 td->offset = sizeof(req);
321 td->remainder = 0;
322
323 /* set pending command */
324 sc->sc_ep0_cmd = MUSB2_MASK_CSR0L_RXPKTRDY_CLR;
325
326 /* we need set stall or dataend after this */
327 sc->sc_ep0_busy = 1;
328
329 /* sneak peek the set address */
330 if ((req.bmRequestType == UT_WRITE_DEVICE) &&
331 (req.bRequest == UR_SET_ADDRESS)) {
332 sc->sc_dv_addr = req.wValue[0] & 0x7F;
333 } else {
334 sc->sc_dv_addr = 0xFF;
335 }
336 return (0); /* complete */
337
338not_complete:
339 return (1); /* not complete */
340}
341
342/* Control endpoint only data handling functions (RX/TX/SYNC) */
343
344static uint8_t
345musbotg_setup_data_rx(struct musbotg_td *td)
346{
347 struct usb2_page_search buf_res;
348 struct musbotg_softc *sc;
349 uint16_t count;
350 uint8_t csr;
351 uint8_t got_short;
352
353 /* get pointer to softc */
354 sc = MUSBOTG_PC2SC(td->pc);
355
356 /* select endpoint 0 */
357 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
358
359 /* check if a command is pending */
360 if (sc->sc_ep0_cmd) {
361 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, sc->sc_ep0_cmd);
362 sc->sc_ep0_cmd = 0;
363 }
364 /* read out FIFO status */
365 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
366
367 DPRINTFN(4, "csr=0x%02x\n", csr);
368
369 got_short = 0;
370
371 if (csr & (MUSB2_MASK_CSR0L_SETUPEND |
372 MUSB2_MASK_CSR0L_SENTSTALL)) {
373 if (td->remainder == 0) {
374 /*
375 * We are actually complete and have
376 * received the next SETUP
377 */
378 DPRINTFN(4, "faking complete\n");
379 return (0); /* complete */
380 }
381 /*
382 * USB Host Aborted the transfer.
383 */
384 td->error = 1;
385 return (0); /* complete */
386 }
387 if (!(csr & MUSB2_MASK_CSR0L_RXPKTRDY)) {
388 return (1); /* not complete */
389 }
390 /* get the packet byte count */
391 count = MUSB2_READ_2(sc, MUSB2_REG_RXCOUNT);
392
393 /* verify the packet byte count */
394 if (count != td->max_frame_size) {
395 if (count < td->max_frame_size) {
396 /* we have a short packet */
397 td->short_pkt = 1;
398 got_short = 1;
399 } else {
400 /* invalid USB packet */
401 td->error = 1;
402 return (0); /* we are complete */
403 }
404 }
405 /* verify the packet byte count */
406 if (count > td->remainder) {
407 /* invalid USB packet */
408 td->error = 1;
409 return (0); /* we are complete */
410 }
411 while (count > 0) {
412 uint32_t temp;
413
414 usb2_get_page(td->pc, td->offset, &buf_res);
415
416 /* get correct length */
417 if (buf_res.length > count) {
418 buf_res.length = count;
419 }
420 /* check for unaligned memory address */
421 if (USB_P2U(buf_res.buffer) & 3) {
422
423 temp = count & ~3;
424
425 if (temp) {
426 /* receive data 4 bytes at a time */
427 bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
428 MUSB2_REG_EPFIFO(0), sc->sc_bounce_buf,
429 temp / 4);
430 }
431 temp = count & 3;
432 if (temp) {
433 /* receive data 1 byte at a time */
434 bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
435 MUSB2_REG_EPFIFO(0),
436 (void *)(&sc->sc_bounce_buf[count / 4]), temp);
437 }
438 usb2_copy_in(td->pc, td->offset,
439 sc->sc_bounce_buf, count);
440
441 /* update offset and remainder */
442 td->offset += count;
443 td->remainder -= count;
444 break;
445 }
446 /* check if we can optimise */
447 if (buf_res.length >= 4) {
448
449 /* receive data 4 bytes at a time */
450 bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
451 MUSB2_REG_EPFIFO(0), buf_res.buffer,
452 buf_res.length / 4);
453
454 temp = buf_res.length & ~3;
455
456 /* update counters */
457 count -= temp;
458 td->offset += temp;
459 td->remainder -= temp;
460 continue;
461 }
462 /* receive data */
463 bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
464 MUSB2_REG_EPFIFO(0), buf_res.buffer, buf_res.length);
465
466 /* update counters */
467 count -= buf_res.length;
468 td->offset += buf_res.length;
469 td->remainder -= buf_res.length;
470 }
471
472 /* check if we are complete */
473 if ((td->remainder == 0) || got_short) {
474 if (td->short_pkt) {
475 /* we are complete */
476 sc->sc_ep0_cmd = MUSB2_MASK_CSR0L_RXPKTRDY_CLR;
477 return (0);
478 }
479 /* else need to receive a zero length packet */
480 }
481 /* write command - need more data */
482 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
483 MUSB2_MASK_CSR0L_RXPKTRDY_CLR);
484 return (1); /* not complete */
485}
486
487static uint8_t
488musbotg_setup_data_tx(struct musbotg_td *td)
489{
490 struct usb2_page_search buf_res;
491 struct musbotg_softc *sc;
492 uint16_t count;
493 uint8_t csr;
494
495 /* get pointer to softc */
496 sc = MUSBOTG_PC2SC(td->pc);
497
498 /* select endpoint 0 */
499 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
500
501 /* check if a command is pending */
502 if (sc->sc_ep0_cmd) {
503 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, sc->sc_ep0_cmd);
504 sc->sc_ep0_cmd = 0;
505 }
506 /* read out FIFO status */
507 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
508
509 DPRINTFN(4, "csr=0x%02x\n", csr);
510
511 if (csr & (MUSB2_MASK_CSR0L_SETUPEND |
512 MUSB2_MASK_CSR0L_SENTSTALL)) {
513 /*
514 * The current transfer was aborted
515 * by the USB Host
516 */
517 td->error = 1;
518 return (0); /* complete */
519 }
520 if (csr & MUSB2_MASK_CSR0L_TXPKTRDY) {
521 return (1); /* not complete */
522 }
523 count = td->max_frame_size;
524 if (td->remainder < count) {
525 /* we have a short packet */
526 td->short_pkt = 1;
527 count = td->remainder;
528 }
529 while (count > 0) {
530 uint32_t temp;
531
532 usb2_get_page(td->pc, td->offset, &buf_res);
533
534 /* get correct length */
535 if (buf_res.length > count) {
536 buf_res.length = count;
537 }
538 /* check for unaligned memory address */
539 if (USB_P2U(buf_res.buffer) & 3) {
540
541 usb2_copy_out(td->pc, td->offset,
542 sc->sc_bounce_buf, count);
543
544 temp = count & ~3;
545
546 if (temp) {
547 /* transmit data 4 bytes at a time */
548 bus_space_write_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
549 MUSB2_REG_EPFIFO(0), sc->sc_bounce_buf,
550 temp / 4);
551 }
552 temp = count & 3;
553 if (temp) {
554 /* receive data 1 byte at a time */
555 bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
556 MUSB2_REG_EPFIFO(0),
557 ((void *)&sc->sc_bounce_buf[count / 4]), temp);
558 }
559 /* update offset and remainder */
560 td->offset += count;
561 td->remainder -= count;
562 break;
563 }
564 /* check if we can optimise */
565 if (buf_res.length >= 4) {
566
567 /* transmit data 4 bytes at a time */
568 bus_space_write_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
569 MUSB2_REG_EPFIFO(0), buf_res.buffer,
570 buf_res.length / 4);
571
572 temp = buf_res.length & ~3;
573
574 /* update counters */
575 count -= temp;
576 td->offset += temp;
577 td->remainder -= temp;
578 continue;
579 }
580 /* transmit data */
581 bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
582 MUSB2_REG_EPFIFO(0), buf_res.buffer, buf_res.length);
583
584 /* update counters */
585 count -= buf_res.length;
586 td->offset += buf_res.length;
587 td->remainder -= buf_res.length;
588 }
589
590 /* check remainder */
591 if (td->remainder == 0) {
592 if (td->short_pkt) {
593 sc->sc_ep0_cmd = MUSB2_MASK_CSR0L_TXPKTRDY;
594 return (0); /* complete */
595 }
596 /* else we need to transmit a short packet */
597 }
598 /* write command */
599 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
600 MUSB2_MASK_CSR0L_TXPKTRDY);
601
602 return (1); /* not complete */
603}
604
605static uint8_t
606musbotg_setup_status(struct musbotg_td *td)
607{
608 struct musbotg_softc *sc;
609 uint8_t csr;
610
611 /* get pointer to softc */
612 sc = MUSBOTG_PC2SC(td->pc);
613
614 /* select endpoint 0 */
615 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
616
617 if (sc->sc_ep0_busy) {
618 sc->sc_ep0_busy = 0;
619 sc->sc_ep0_cmd |= MUSB2_MASK_CSR0L_DATAEND;
620 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, sc->sc_ep0_cmd);
621 sc->sc_ep0_cmd = 0;
622 }
623 /* read out FIFO status */
624 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
625
626 DPRINTFN(4, "csr=0x%02x\n", csr);
627
628 if (csr & MUSB2_MASK_CSR0L_DATAEND) {
629 /* wait for interrupt */
630 return (1); /* not complete */
631 }
632 if (sc->sc_dv_addr != 0xFF) {
633 /* write function address */
634 musbotg_set_address(sc, sc->sc_dv_addr);
635 }
636 return (0); /* complete */
637}
638
639static uint8_t
640musbotg_data_rx(struct musbotg_td *td)
641{
642 struct usb2_page_search buf_res;
643 struct musbotg_softc *sc;
644 uint16_t count;
645 uint8_t csr;
646 uint8_t to;
647 uint8_t got_short;
648
649 to = 8; /* don't loop forever! */
650 got_short = 0;
651
652 /* get pointer to softc */
653 sc = MUSBOTG_PC2SC(td->pc);
654
655 /* select endpoint */
656 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, td->ep_no);
657
658repeat:
659 /* read out FIFO status */
660 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
661
662 DPRINTFN(4, "csr=0x%02x\n", csr);
663
664 /* clear overrun */
665 if (csr & MUSB2_MASK_CSRL_RXOVERRUN) {
666 /* make sure we don't clear "RXPKTRDY" */
667 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
668 MUSB2_MASK_CSRL_RXPKTRDY);
669 }
670 /* check status */
671 if (!(csr & MUSB2_MASK_CSRL_RXPKTRDY)) {
672 return (1); /* not complete */
673 }
674 /* get the packet byte count */
675 count = MUSB2_READ_2(sc, MUSB2_REG_RXCOUNT);
676
677 DPRINTFN(4, "count=0x%04x\n", count);
678
679 /*
680 * Check for short or invalid packet:
681 */
682 if (count != td->max_frame_size) {
683 if (count < td->max_frame_size) {
684 /* we have a short packet */
685 td->short_pkt = 1;
686 got_short = 1;
687 } else {
688 /* invalid USB packet */
689 td->error = 1;
690 return (0); /* we are complete */
691 }
692 }
693 /* verify the packet byte count */
694 if (count > td->remainder) {
695 /* invalid USB packet */
696 td->error = 1;
697 return (0); /* we are complete */
698 }
699 while (count > 0) {
700 uint32_t temp;
701
702 usb2_get_page(td->pc, td->offset, &buf_res);
703
704 /* get correct length */
705 if (buf_res.length > count) {
706 buf_res.length = count;
707 }
708 /* check for unaligned memory address */
709 if (USB_P2U(buf_res.buffer) & 3) {
710
711 temp = count & ~3;
712
713 if (temp) {
714 /* receive data 4 bytes at a time */
715 bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
716 MUSB2_REG_EPFIFO(td->ep_no), sc->sc_bounce_buf,
717 temp / 4);
718 }
719 temp = count & 3;
720 if (temp) {
721 /* receive data 1 byte at a time */
722 bus_space_read_multi_1(sc->sc_io_tag,
723 sc->sc_io_hdl, MUSB2_REG_EPFIFO(td->ep_no),
724 ((void *)&sc->sc_bounce_buf[count / 4]), temp);
725 }
726 usb2_copy_in(td->pc, td->offset,
727 sc->sc_bounce_buf, count);
728
729 /* update offset and remainder */
730 td->offset += count;
731 td->remainder -= count;
732 break;
733 }
734 /* check if we can optimise */
735 if (buf_res.length >= 4) {
736
737 /* receive data 4 bytes at a time */
738 bus_space_read_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
739 MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
740 buf_res.length / 4);
741
742 temp = buf_res.length & ~3;
743
744 /* update counters */
745 count -= temp;
746 td->offset += temp;
747 td->remainder -= temp;
748 continue;
749 }
750 /* receive data */
751 bus_space_read_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
752 MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
753 buf_res.length);
754
755 /* update counters */
756 count -= buf_res.length;
757 td->offset += buf_res.length;
758 td->remainder -= buf_res.length;
759 }
760
761 /* clear status bits */
762 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL, 0);
763
764 /* check if we are complete */
765 if ((td->remainder == 0) || got_short) {
766 if (td->short_pkt) {
767 /* we are complete */
768 return (0);
769 }
770 /* else need to receive a zero length packet */
771 }
772 if (--to) {
773 goto repeat;
774 }
775 return (1); /* not complete */
776}
777
778static uint8_t
779musbotg_data_tx(struct musbotg_td *td)
780{
781 struct usb2_page_search buf_res;
782 struct musbotg_softc *sc;
783 uint16_t count;
784 uint8_t csr;
785 uint8_t to;
786
787 to = 8; /* don't loop forever! */
788
789 /* get pointer to softc */
790 sc = MUSBOTG_PC2SC(td->pc);
791
792 /* select endpoint */
793 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, td->ep_no);
794
795repeat:
796
797 /* read out FIFO status */
798 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
799
800 DPRINTFN(4, "csr=0x%02x\n", csr);
801
802 if (csr & (MUSB2_MASK_CSRL_TXINCOMP |
803 MUSB2_MASK_CSRL_TXUNDERRUN)) {
804 /* clear status bits */
805 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
806 }
807 if (csr & MUSB2_MASK_CSRL_TXPKTRDY) {
808 return (1); /* not complete */
809 }
810 /* check for short packet */
811 count = td->max_frame_size;
812 if (td->remainder < count) {
813 /* we have a short packet */
814 td->short_pkt = 1;
815 count = td->remainder;
816 }
817 while (count > 0) {
818 uint32_t temp;
819
820 usb2_get_page(td->pc, td->offset, &buf_res);
821
822 /* get correct length */
823 if (buf_res.length > count) {
824 buf_res.length = count;
825 }
826 /* check for unaligned memory address */
827 if (USB_P2U(buf_res.buffer) & 3) {
828
829 usb2_copy_out(td->pc, td->offset,
830 sc->sc_bounce_buf, count);
831
832 temp = count & ~3;
833
834 if (temp) {
835 /* transmit data 4 bytes at a time */
836 bus_space_write_multi_4(sc->sc_io_tag,
837 sc->sc_io_hdl, MUSB2_REG_EPFIFO(td->ep_no),
838 sc->sc_bounce_buf, temp / 4);
839 }
840 temp = count & 3;
841 if (temp) {
842 /* receive data 1 byte at a time */
843 bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
844 MUSB2_REG_EPFIFO(td->ep_no),
845 ((void *)&sc->sc_bounce_buf[count / 4]), temp);
846 }
847 /* update offset and remainder */
848 td->offset += count;
849 td->remainder -= count;
850 break;
851 }
852 /* check if we can optimise */
853 if (buf_res.length >= 4) {
854
855 /* transmit data 4 bytes at a time */
856 bus_space_write_multi_4(sc->sc_io_tag, sc->sc_io_hdl,
857 MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
858 buf_res.length / 4);
859
860 temp = buf_res.length & ~3;
861
862 /* update counters */
863 count -= temp;
864 td->offset += temp;
865 td->remainder -= temp;
866 continue;
867 }
868 /* transmit data */
869 bus_space_write_multi_1(sc->sc_io_tag, sc->sc_io_hdl,
870 MUSB2_REG_EPFIFO(td->ep_no), buf_res.buffer,
871 buf_res.length);
872
873 /* update counters */
874 count -= buf_res.length;
875 td->offset += buf_res.length;
876 td->remainder -= buf_res.length;
877 }
878
879 /* write command */
880 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
881 MUSB2_MASK_CSRL_TXPKTRDY);
882
883 /* check remainder */
884 if (td->remainder == 0) {
885 if (td->short_pkt) {
886 return (0); /* complete */
887 }
888 /* else we need to transmit a short packet */
889 }
890 if (--to) {
891 goto repeat;
892 }
893 return (1); /* not complete */
894}
895
896static uint8_t
897musbotg_xfer_do_fifo(struct usb2_xfer *xfer)
898{
899 struct musbotg_softc *sc;
900 struct musbotg_td *td;
901
902 DPRINTFN(8, "\n");
903
904 td = xfer->td_transfer_cache;
905 while (1) {
906 if ((td->func) (td)) {
907 /* operation in progress */
908 break;
909 }
910 if (((void *)td) == xfer->td_transfer_last) {
911 goto done;
912 }
913 if (td->error) {
914 goto done;
915 } else if (td->remainder > 0) {
916 /*
917 * We had a short transfer. If there is no alternate
918 * next, stop processing !
919 */
920 if (!td->alt_next) {
921 goto done;
922 }
923 }
924 /*
925 * Fetch the next transfer descriptor and transfer
926 * some flags to the next transfer descriptor
927 */
928 td = td->obj_next;
929 xfer->td_transfer_cache = td;
930 }
931 return (1); /* not complete */
932
933done:
934 sc = xfer->usb2_sc;
934 sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
935
936 /* compute all actual lengths */
937
938 musbotg_standard_done(xfer);
939
940 return (0); /* complete */
941}
942
943static void
944musbotg_interrupt_poll(struct musbotg_softc *sc)
945{
946 struct usb2_xfer *xfer;
947
948repeat:
949 TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
950 if (!musbotg_xfer_do_fifo(xfer)) {
951 /* queue has been modified */
952 goto repeat;
953 }
954 }
955}
956
957static void
958musbotg_vbus_interrupt(struct usb2_bus *bus, uint8_t is_on)
959{
960 struct musbotg_softc *sc = MUSBOTG_BUS2SC(bus);
961
962 DPRINTFN(4, "vbus = %u\n", is_on);
963
964 USB_BUS_LOCK(&sc->sc_bus);
965 if (is_on) {
966 if (!sc->sc_flags.status_vbus) {
967 sc->sc_flags.status_vbus = 1;
968
969 /* complete root HUB interrupt endpoint */
970
971 usb2_sw_transfer(&sc->sc_root_intr,
972 &musbotg_root_intr_done);
973 }
974 } else {
975 if (sc->sc_flags.status_vbus) {
976 sc->sc_flags.status_vbus = 0;
977 sc->sc_flags.status_bus_reset = 0;
978 sc->sc_flags.status_suspend = 0;
979 sc->sc_flags.change_suspend = 0;
980 sc->sc_flags.change_connect = 1;
981
982 /* complete root HUB interrupt endpoint */
983
984 usb2_sw_transfer(&sc->sc_root_intr,
985 &musbotg_root_intr_done);
986 }
987 }
988
989 USB_BUS_UNLOCK(&sc->sc_bus);
990}
991
992void
993musbotg_interrupt(struct musbotg_softc *sc)
994{
995 uint16_t rx_status;
996 uint16_t tx_status;
997 uint8_t usb_status;
998 uint8_t temp;
999 uint8_t to = 2;
1000
1001 USB_BUS_LOCK(&sc->sc_bus);
1002
1003repeat:
1004
1005 /* read all interrupt registers */
1006 usb_status = MUSB2_READ_1(sc, MUSB2_REG_INTUSB);
1007
1008 /* read all FIFO interrupts */
1009 rx_status = MUSB2_READ_2(sc, MUSB2_REG_INTRX);
1010 tx_status = MUSB2_READ_2(sc, MUSB2_REG_INTTX);
1011
1012 /* check for any bus state change interrupts */
1013
1014 if (usb_status & (MUSB2_MASK_IRESET |
1015 MUSB2_MASK_IRESUME | MUSB2_MASK_ISUSP)) {
1016
1017 DPRINTFN(4, "real bus interrupt 0x%08x\n", usb_status);
1018
1019 if (usb_status & MUSB2_MASK_IRESET) {
1020
1021 /* set correct state */
1022 sc->sc_flags.status_bus_reset = 1;
1023 sc->sc_flags.status_suspend = 0;
1024 sc->sc_flags.change_suspend = 0;
1025 sc->sc_flags.change_connect = 1;
1026
1027 /* determine line speed */
1028 temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
1029 if (temp & MUSB2_MASK_HSMODE)
1030 sc->sc_flags.status_high_speed = 1;
1031 else
1032 sc->sc_flags.status_high_speed = 0;
1033
1034 /*
1035 * After reset all interrupts are on and we need to
1036 * turn them off!
1037 */
1038 temp = MUSB2_MASK_IRESET;
1039 /* disable resume interrupt */
1040 temp &= ~MUSB2_MASK_IRESUME;
1041 /* enable suspend interrupt */
1042 temp |= MUSB2_MASK_ISUSP;
1043 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, temp);
1044 /* disable TX and RX interrupts */
1045 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, 0);
1046 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, 0);
1047 }
1048 /*
1049 * If RXRSM and RXSUSP is set at the same time we interpret
1050 * that like RESUME. Resume is set when there is at least 3
1051 * milliseconds of inactivity on the USB BUS.
1052 */
1053 if (usb_status & MUSB2_MASK_IRESUME) {
1054 if (sc->sc_flags.status_suspend) {
1055 sc->sc_flags.status_suspend = 0;
1056 sc->sc_flags.change_suspend = 1;
1057
1058 temp = MUSB2_READ_1(sc, MUSB2_REG_INTUSBE);
1059 /* disable resume interrupt */
1060 temp &= ~MUSB2_MASK_IRESUME;
1061 /* enable suspend interrupt */
1062 temp |= MUSB2_MASK_ISUSP;
1063 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, temp);
1064 }
1065 } else if (usb_status & MUSB2_MASK_ISUSP) {
1066 if (!sc->sc_flags.status_suspend) {
1067 sc->sc_flags.status_suspend = 1;
1068 sc->sc_flags.change_suspend = 1;
1069
1070 temp = MUSB2_READ_1(sc, MUSB2_REG_INTUSBE);
1071 /* disable suspend interrupt */
1072 temp &= ~MUSB2_MASK_ISUSP;
1073 /* enable resume interrupt */
1074 temp |= MUSB2_MASK_IRESUME;
1075 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, temp);
1076 }
1077 }
1078 /* complete root HUB interrupt endpoint */
1079
1080 usb2_sw_transfer(&sc->sc_root_intr,
1081 &musbotg_root_intr_done);
1082 }
1083 /* check for any endpoint interrupts */
1084
1085 if (rx_status || tx_status) {
1086 DPRINTFN(4, "real endpoint interrupt "
1087 "rx=0x%04x, tx=0x%04x\n", rx_status, tx_status);
1088 }
1089 /* poll one time regardless of FIFO status */
1090
1091 musbotg_interrupt_poll(sc);
1092
1093 if (--to)
1094 goto repeat;
1095
1096 USB_BUS_UNLOCK(&sc->sc_bus);
1097}
1098
1099static void
1100musbotg_setup_standard_chain_sub(struct musbotg_std_temp *temp)
1101{
1102 struct musbotg_td *td;
1103
1104 /* get current Transfer Descriptor */
1105 td = temp->td_next;
1106 temp->td = td;
1107
1108 /* prepare for next TD */
1109 temp->td_next = td->obj_next;
1110
1111 /* fill out the Transfer Descriptor */
1112 td->func = temp->func;
1113 td->pc = temp->pc;
1114 td->offset = temp->offset;
1115 td->remainder = temp->len;
1116 td->error = 0;
1117 td->did_stall = 0;
1118 td->short_pkt = temp->short_pkt;
1119 td->alt_next = temp->setup_alt_next;
1120}
1121
1122static void
1123musbotg_setup_standard_chain(struct usb2_xfer *xfer)
1124{
1125 struct musbotg_std_temp temp;
1126 struct musbotg_softc *sc;
1127 struct musbotg_td *td;
1128 uint32_t x;
1129 uint8_t ep_no;
1130
1131 DPRINTFN(8, "addr=%d endpt=%d sumlen=%d speed=%d\n",
1132 xfer->address, UE_GET_ADDR(xfer->endpoint),
935
936 /* compute all actual lengths */
937
938 musbotg_standard_done(xfer);
939
940 return (0); /* complete */
941}
942
943static void
944musbotg_interrupt_poll(struct musbotg_softc *sc)
945{
946 struct usb2_xfer *xfer;
947
948repeat:
949 TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) {
950 if (!musbotg_xfer_do_fifo(xfer)) {
951 /* queue has been modified */
952 goto repeat;
953 }
954 }
955}
956
957static void
958musbotg_vbus_interrupt(struct usb2_bus *bus, uint8_t is_on)
959{
960 struct musbotg_softc *sc = MUSBOTG_BUS2SC(bus);
961
962 DPRINTFN(4, "vbus = %u\n", is_on);
963
964 USB_BUS_LOCK(&sc->sc_bus);
965 if (is_on) {
966 if (!sc->sc_flags.status_vbus) {
967 sc->sc_flags.status_vbus = 1;
968
969 /* complete root HUB interrupt endpoint */
970
971 usb2_sw_transfer(&sc->sc_root_intr,
972 &musbotg_root_intr_done);
973 }
974 } else {
975 if (sc->sc_flags.status_vbus) {
976 sc->sc_flags.status_vbus = 0;
977 sc->sc_flags.status_bus_reset = 0;
978 sc->sc_flags.status_suspend = 0;
979 sc->sc_flags.change_suspend = 0;
980 sc->sc_flags.change_connect = 1;
981
982 /* complete root HUB interrupt endpoint */
983
984 usb2_sw_transfer(&sc->sc_root_intr,
985 &musbotg_root_intr_done);
986 }
987 }
988
989 USB_BUS_UNLOCK(&sc->sc_bus);
990}
991
992void
993musbotg_interrupt(struct musbotg_softc *sc)
994{
995 uint16_t rx_status;
996 uint16_t tx_status;
997 uint8_t usb_status;
998 uint8_t temp;
999 uint8_t to = 2;
1000
1001 USB_BUS_LOCK(&sc->sc_bus);
1002
1003repeat:
1004
1005 /* read all interrupt registers */
1006 usb_status = MUSB2_READ_1(sc, MUSB2_REG_INTUSB);
1007
1008 /* read all FIFO interrupts */
1009 rx_status = MUSB2_READ_2(sc, MUSB2_REG_INTRX);
1010 tx_status = MUSB2_READ_2(sc, MUSB2_REG_INTTX);
1011
1012 /* check for any bus state change interrupts */
1013
1014 if (usb_status & (MUSB2_MASK_IRESET |
1015 MUSB2_MASK_IRESUME | MUSB2_MASK_ISUSP)) {
1016
1017 DPRINTFN(4, "real bus interrupt 0x%08x\n", usb_status);
1018
1019 if (usb_status & MUSB2_MASK_IRESET) {
1020
1021 /* set correct state */
1022 sc->sc_flags.status_bus_reset = 1;
1023 sc->sc_flags.status_suspend = 0;
1024 sc->sc_flags.change_suspend = 0;
1025 sc->sc_flags.change_connect = 1;
1026
1027 /* determine line speed */
1028 temp = MUSB2_READ_1(sc, MUSB2_REG_POWER);
1029 if (temp & MUSB2_MASK_HSMODE)
1030 sc->sc_flags.status_high_speed = 1;
1031 else
1032 sc->sc_flags.status_high_speed = 0;
1033
1034 /*
1035 * After reset all interrupts are on and we need to
1036 * turn them off!
1037 */
1038 temp = MUSB2_MASK_IRESET;
1039 /* disable resume interrupt */
1040 temp &= ~MUSB2_MASK_IRESUME;
1041 /* enable suspend interrupt */
1042 temp |= MUSB2_MASK_ISUSP;
1043 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, temp);
1044 /* disable TX and RX interrupts */
1045 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, 0);
1046 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, 0);
1047 }
1048 /*
1049 * If RXRSM and RXSUSP is set at the same time we interpret
1050 * that like RESUME. Resume is set when there is at least 3
1051 * milliseconds of inactivity on the USB BUS.
1052 */
1053 if (usb_status & MUSB2_MASK_IRESUME) {
1054 if (sc->sc_flags.status_suspend) {
1055 sc->sc_flags.status_suspend = 0;
1056 sc->sc_flags.change_suspend = 1;
1057
1058 temp = MUSB2_READ_1(sc, MUSB2_REG_INTUSBE);
1059 /* disable resume interrupt */
1060 temp &= ~MUSB2_MASK_IRESUME;
1061 /* enable suspend interrupt */
1062 temp |= MUSB2_MASK_ISUSP;
1063 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, temp);
1064 }
1065 } else if (usb_status & MUSB2_MASK_ISUSP) {
1066 if (!sc->sc_flags.status_suspend) {
1067 sc->sc_flags.status_suspend = 1;
1068 sc->sc_flags.change_suspend = 1;
1069
1070 temp = MUSB2_READ_1(sc, MUSB2_REG_INTUSBE);
1071 /* disable suspend interrupt */
1072 temp &= ~MUSB2_MASK_ISUSP;
1073 /* enable resume interrupt */
1074 temp |= MUSB2_MASK_IRESUME;
1075 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, temp);
1076 }
1077 }
1078 /* complete root HUB interrupt endpoint */
1079
1080 usb2_sw_transfer(&sc->sc_root_intr,
1081 &musbotg_root_intr_done);
1082 }
1083 /* check for any endpoint interrupts */
1084
1085 if (rx_status || tx_status) {
1086 DPRINTFN(4, "real endpoint interrupt "
1087 "rx=0x%04x, tx=0x%04x\n", rx_status, tx_status);
1088 }
1089 /* poll one time regardless of FIFO status */
1090
1091 musbotg_interrupt_poll(sc);
1092
1093 if (--to)
1094 goto repeat;
1095
1096 USB_BUS_UNLOCK(&sc->sc_bus);
1097}
1098
1099static void
1100musbotg_setup_standard_chain_sub(struct musbotg_std_temp *temp)
1101{
1102 struct musbotg_td *td;
1103
1104 /* get current Transfer Descriptor */
1105 td = temp->td_next;
1106 temp->td = td;
1107
1108 /* prepare for next TD */
1109 temp->td_next = td->obj_next;
1110
1111 /* fill out the Transfer Descriptor */
1112 td->func = temp->func;
1113 td->pc = temp->pc;
1114 td->offset = temp->offset;
1115 td->remainder = temp->len;
1116 td->error = 0;
1117 td->did_stall = 0;
1118 td->short_pkt = temp->short_pkt;
1119 td->alt_next = temp->setup_alt_next;
1120}
1121
1122static void
1123musbotg_setup_standard_chain(struct usb2_xfer *xfer)
1124{
1125 struct musbotg_std_temp temp;
1126 struct musbotg_softc *sc;
1127 struct musbotg_td *td;
1128 uint32_t x;
1129 uint8_t ep_no;
1130
1131 DPRINTFN(8, "addr=%d endpt=%d sumlen=%d speed=%d\n",
1132 xfer->address, UE_GET_ADDR(xfer->endpoint),
1133 xfer->sumlen, usb2_get_speed(xfer->udev));
1133 xfer->sumlen, usb2_get_speed(xfer->xroot->udev));
1134
1135 temp.max_frame_size = xfer->max_frame_size;
1136
1137 td = xfer->td_start[0];
1138 xfer->td_transfer_first = td;
1139 xfer->td_transfer_cache = td;
1140
1141 /* setup temp */
1142
1143 temp.td = NULL;
1144 temp.td_next = xfer->td_start[0];
1145 temp.setup_alt_next = xfer->flags_int.short_frames_ok;
1146 temp.offset = 0;
1147
1134
1135 temp.max_frame_size = xfer->max_frame_size;
1136
1137 td = xfer->td_start[0];
1138 xfer->td_transfer_first = td;
1139 xfer->td_transfer_cache = td;
1140
1141 /* setup temp */
1142
1143 temp.td = NULL;
1144 temp.td_next = xfer->td_start[0];
1145 temp.setup_alt_next = xfer->flags_int.short_frames_ok;
1146 temp.offset = 0;
1147
1148 sc = xfer->usb2_sc;
1148 sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
1149 ep_no = (xfer->endpoint & UE_ADDR);
1150
1151 /* check if we should prepend a setup message */
1152
1153 if (xfer->flags_int.control_xfr) {
1154 if (xfer->flags_int.control_hdr) {
1155
1156 temp.func = &musbotg_setup_rx;
1157 temp.len = xfer->frlengths[0];
1158 temp.pc = xfer->frbuffers + 0;
1159 temp.short_pkt = temp.len ? 1 : 0;
1160
1161 musbotg_setup_standard_chain_sub(&temp);
1162 }
1163 x = 1;
1164 } else {
1165 x = 0;
1166 }
1167
1168 if (x != xfer->nframes) {
1169 if (xfer->endpoint & UE_DIR_IN) {
1170 if (xfer->flags_int.control_xfr)
1171 temp.func = &musbotg_setup_data_tx;
1172 else
1173 temp.func = &musbotg_data_tx;
1174 } else {
1175 if (xfer->flags_int.control_xfr)
1176 temp.func = &musbotg_setup_data_rx;
1177 else
1178 temp.func = &musbotg_data_rx;
1179 }
1180
1181 /* setup "pc" pointer */
1182 temp.pc = xfer->frbuffers + x;
1183 }
1184 while (x != xfer->nframes) {
1185
1186 /* DATA0 / DATA1 message */
1187
1188 temp.len = xfer->frlengths[x];
1189
1190 x++;
1191
1192 if (x == xfer->nframes) {
1193 temp.setup_alt_next = 0;
1194 }
1195 if (temp.len == 0) {
1196
1197 /* make sure that we send an USB packet */
1198
1199 temp.short_pkt = 0;
1200
1201 } else {
1202
1203 /* regular data transfer */
1204
1205 temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1;
1206 }
1207
1208 musbotg_setup_standard_chain_sub(&temp);
1209
1210 if (xfer->flags_int.isochronous_xfr) {
1211 temp.offset += temp.len;
1212 } else {
1213 /* get next Page Cache pointer */
1214 temp.pc = xfer->frbuffers + x;
1215 }
1216 }
1217
1218 /* always setup a valid "pc" pointer for status and sync */
1219 temp.pc = xfer->frbuffers + 0;
1220
1221 /* check if we should append a status stage */
1222
1223 if (xfer->flags_int.control_xfr &&
1224 !xfer->flags_int.control_act) {
1225
1226 /*
1227 * Send a DATA1 message and invert the current
1228 * endpoint direction.
1229 */
1230 temp.func = &musbotg_setup_status;
1231 temp.len = 0;
1232 temp.short_pkt = 0;
1233
1234 musbotg_setup_standard_chain_sub(&temp);
1235 }
1236 /* must have at least one frame! */
1237 td = temp.td;
1238 xfer->td_transfer_last = td;
1239}
1240
1241static void
1242musbotg_timeout(void *arg)
1243{
1244 struct usb2_xfer *xfer = arg;
1245
1246 DPRINTFN(1, "xfer=%p\n", xfer);
1247
1149 ep_no = (xfer->endpoint & UE_ADDR);
1150
1151 /* check if we should prepend a setup message */
1152
1153 if (xfer->flags_int.control_xfr) {
1154 if (xfer->flags_int.control_hdr) {
1155
1156 temp.func = &musbotg_setup_rx;
1157 temp.len = xfer->frlengths[0];
1158 temp.pc = xfer->frbuffers + 0;
1159 temp.short_pkt = temp.len ? 1 : 0;
1160
1161 musbotg_setup_standard_chain_sub(&temp);
1162 }
1163 x = 1;
1164 } else {
1165 x = 0;
1166 }
1167
1168 if (x != xfer->nframes) {
1169 if (xfer->endpoint & UE_DIR_IN) {
1170 if (xfer->flags_int.control_xfr)
1171 temp.func = &musbotg_setup_data_tx;
1172 else
1173 temp.func = &musbotg_data_tx;
1174 } else {
1175 if (xfer->flags_int.control_xfr)
1176 temp.func = &musbotg_setup_data_rx;
1177 else
1178 temp.func = &musbotg_data_rx;
1179 }
1180
1181 /* setup "pc" pointer */
1182 temp.pc = xfer->frbuffers + x;
1183 }
1184 while (x != xfer->nframes) {
1185
1186 /* DATA0 / DATA1 message */
1187
1188 temp.len = xfer->frlengths[x];
1189
1190 x++;
1191
1192 if (x == xfer->nframes) {
1193 temp.setup_alt_next = 0;
1194 }
1195 if (temp.len == 0) {
1196
1197 /* make sure that we send an USB packet */
1198
1199 temp.short_pkt = 0;
1200
1201 } else {
1202
1203 /* regular data transfer */
1204
1205 temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1;
1206 }
1207
1208 musbotg_setup_standard_chain_sub(&temp);
1209
1210 if (xfer->flags_int.isochronous_xfr) {
1211 temp.offset += temp.len;
1212 } else {
1213 /* get next Page Cache pointer */
1214 temp.pc = xfer->frbuffers + x;
1215 }
1216 }
1217
1218 /* always setup a valid "pc" pointer for status and sync */
1219 temp.pc = xfer->frbuffers + 0;
1220
1221 /* check if we should append a status stage */
1222
1223 if (xfer->flags_int.control_xfr &&
1224 !xfer->flags_int.control_act) {
1225
1226 /*
1227 * Send a DATA1 message and invert the current
1228 * endpoint direction.
1229 */
1230 temp.func = &musbotg_setup_status;
1231 temp.len = 0;
1232 temp.short_pkt = 0;
1233
1234 musbotg_setup_standard_chain_sub(&temp);
1235 }
1236 /* must have at least one frame! */
1237 td = temp.td;
1238 xfer->td_transfer_last = td;
1239}
1240
1241static void
1242musbotg_timeout(void *arg)
1243{
1244 struct usb2_xfer *xfer = arg;
1245
1246 DPRINTFN(1, "xfer=%p\n", xfer);
1247
1248 USB_BUS_LOCK_ASSERT(xfer->udev->bus, MA_OWNED);
1248 USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
1249
1250 /* transfer is transferred */
1251 musbotg_device_done(xfer, USB_ERR_TIMEOUT);
1252}
1253
1254static void
1255musbotg_ep_int_set(struct usb2_xfer *xfer, uint8_t on)
1256{
1249
1250 /* transfer is transferred */
1251 musbotg_device_done(xfer, USB_ERR_TIMEOUT);
1252}
1253
1254static void
1255musbotg_ep_int_set(struct usb2_xfer *xfer, uint8_t on)
1256{
1257 struct musbotg_softc *sc = xfer->usb2_sc;
1257 struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
1258 uint16_t temp;
1259 uint8_t ep_no = xfer->endpoint & UE_ADDR;
1260
1261 /*
1262 * Only enable the endpoint interrupt when we are
1263 * actually waiting for data, hence we are dealing
1264 * with level triggered interrupts !
1265 */
1266 if (ep_no == 0) {
1267 temp = MUSB2_READ_2(sc, MUSB2_REG_INTTXE);
1268 if (on)
1269 temp |= MUSB2_MASK_EPINT(0);
1270 else
1271 temp &= ~MUSB2_MASK_EPINT(0);
1272
1273 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, temp);
1274 } else {
1275 if (USB_GET_DATA_ISREAD(xfer)) {
1276 temp = MUSB2_READ_2(sc, MUSB2_REG_INTRXE);
1277 if (on)
1278 temp |= MUSB2_MASK_EPINT(ep_no);
1279 else
1280 temp &= ~MUSB2_MASK_EPINT(ep_no);
1281 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, temp);
1282
1283 } else {
1284 temp = MUSB2_READ_2(sc, MUSB2_REG_INTTXE);
1285 if (on)
1286 temp |= MUSB2_MASK_EPINT(ep_no);
1287 else
1288 temp &= ~MUSB2_MASK_EPINT(ep_no);
1289 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, temp);
1290 }
1291 }
1292}
1293
1294static void
1295musbotg_start_standard_chain(struct usb2_xfer *xfer)
1296{
1297 DPRINTFN(8, "\n");
1298
1299 /* poll one time */
1300 if (musbotg_xfer_do_fifo(xfer)) {
1301
1302 musbotg_ep_int_set(xfer, 1);
1303
1304 DPRINTFN(14, "enabled interrupts on endpoint\n");
1305
1306 /* put transfer on interrupt queue */
1258 uint16_t temp;
1259 uint8_t ep_no = xfer->endpoint & UE_ADDR;
1260
1261 /*
1262 * Only enable the endpoint interrupt when we are
1263 * actually waiting for data, hence we are dealing
1264 * with level triggered interrupts !
1265 */
1266 if (ep_no == 0) {
1267 temp = MUSB2_READ_2(sc, MUSB2_REG_INTTXE);
1268 if (on)
1269 temp |= MUSB2_MASK_EPINT(0);
1270 else
1271 temp &= ~MUSB2_MASK_EPINT(0);
1272
1273 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, temp);
1274 } else {
1275 if (USB_GET_DATA_ISREAD(xfer)) {
1276 temp = MUSB2_READ_2(sc, MUSB2_REG_INTRXE);
1277 if (on)
1278 temp |= MUSB2_MASK_EPINT(ep_no);
1279 else
1280 temp &= ~MUSB2_MASK_EPINT(ep_no);
1281 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, temp);
1282
1283 } else {
1284 temp = MUSB2_READ_2(sc, MUSB2_REG_INTTXE);
1285 if (on)
1286 temp |= MUSB2_MASK_EPINT(ep_no);
1287 else
1288 temp &= ~MUSB2_MASK_EPINT(ep_no);
1289 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, temp);
1290 }
1291 }
1292}
1293
1294static void
1295musbotg_start_standard_chain(struct usb2_xfer *xfer)
1296{
1297 DPRINTFN(8, "\n");
1298
1299 /* poll one time */
1300 if (musbotg_xfer_do_fifo(xfer)) {
1301
1302 musbotg_ep_int_set(xfer, 1);
1303
1304 DPRINTFN(14, "enabled interrupts on endpoint\n");
1305
1306 /* put transfer on interrupt queue */
1307 usb2_transfer_enqueue(&xfer->udev->bus->intr_q, xfer);
1307 usb2_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer);
1308
1309 /* start timeout, if any */
1310 if (xfer->timeout != 0) {
1311 usb2_transfer_timeout_ms(xfer,
1312 &musbotg_timeout, xfer->timeout);
1313 }
1314 }
1315}
1316
1317static void
1318musbotg_root_intr_done(struct usb2_xfer *xfer,
1319 struct usb2_sw_transfer *std)
1320{
1308
1309 /* start timeout, if any */
1310 if (xfer->timeout != 0) {
1311 usb2_transfer_timeout_ms(xfer,
1312 &musbotg_timeout, xfer->timeout);
1313 }
1314 }
1315}
1316
1317static void
1318musbotg_root_intr_done(struct usb2_xfer *xfer,
1319 struct usb2_sw_transfer *std)
1320{
1321 struct musbotg_softc *sc = xfer->usb2_sc;
1321 struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
1322
1323 DPRINTFN(8, "\n");
1324
1325 USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
1326
1327 if (std->state != USB_SW_TR_PRE_DATA) {
1328 if (std->state == USB_SW_TR_PRE_CALLBACK) {
1329 /* transfer transferred */
1330 musbotg_device_done(xfer, std->err);
1331 }
1332 goto done;
1333 }
1334 /* setup buffer */
1335 std->ptr = sc->sc_hub_idata;
1336 std->len = sizeof(sc->sc_hub_idata);
1337
1338 /* set port bit */
1339 sc->sc_hub_idata[0] = 0x02; /* we only have one port */
1340
1341done:
1342 return;
1343}
1344
1345static usb2_error_t
1346musbotg_standard_done_sub(struct usb2_xfer *xfer)
1347{
1348 struct musbotg_td *td;
1349 uint32_t len;
1350 uint8_t error;
1351
1352 DPRINTFN(8, "\n");
1353
1354 td = xfer->td_transfer_cache;
1355
1356 do {
1357 len = td->remainder;
1358
1359 if (xfer->aframes != xfer->nframes) {
1360 /*
1361 * Verify the length and subtract
1362 * the remainder from "frlengths[]":
1363 */
1364 if (len > xfer->frlengths[xfer->aframes]) {
1365 td->error = 1;
1366 } else {
1367 xfer->frlengths[xfer->aframes] -= len;
1368 }
1369 }
1370 /* Check for transfer error */
1371 if (td->error) {
1372 /* the transfer is finished */
1373 error = 1;
1374 td = NULL;
1375 break;
1376 }
1377 /* Check for short transfer */
1378 if (len > 0) {
1379 if (xfer->flags_int.short_frames_ok) {
1380 /* follow alt next */
1381 if (td->alt_next) {
1382 td = td->obj_next;
1383 } else {
1384 td = NULL;
1385 }
1386 } else {
1387 /* the transfer is finished */
1388 td = NULL;
1389 }
1390 error = 0;
1391 break;
1392 }
1393 td = td->obj_next;
1394
1395 /* this USB frame is complete */
1396 error = 0;
1397 break;
1398
1399 } while (0);
1400
1401 /* update transfer cache */
1402
1403 xfer->td_transfer_cache = td;
1404
1405 return (error ?
1406 USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION);
1407}
1408
1409static void
1410musbotg_standard_done(struct usb2_xfer *xfer)
1411{
1412 usb2_error_t err = 0;
1413
1414 DPRINTFN(12, "xfer=%p pipe=%p transfer done\n",
1415 xfer, xfer->pipe);
1416
1417 /* reset scanner */
1418
1419 xfer->td_transfer_cache = xfer->td_transfer_first;
1420
1421 if (xfer->flags_int.control_xfr) {
1422
1423 if (xfer->flags_int.control_hdr) {
1424
1425 err = musbotg_standard_done_sub(xfer);
1426 }
1427 xfer->aframes = 1;
1428
1429 if (xfer->td_transfer_cache == NULL) {
1430 goto done;
1431 }
1432 }
1433 while (xfer->aframes != xfer->nframes) {
1434
1435 err = musbotg_standard_done_sub(xfer);
1436 xfer->aframes++;
1437
1438 if (xfer->td_transfer_cache == NULL) {
1439 goto done;
1440 }
1441 }
1442
1443 if (xfer->flags_int.control_xfr &&
1444 !xfer->flags_int.control_act) {
1445
1446 err = musbotg_standard_done_sub(xfer);
1447 }
1448done:
1449 musbotg_device_done(xfer, err);
1450}
1451
1452/*------------------------------------------------------------------------*
1453 * musbotg_device_done
1454 *
1455 * NOTE: this function can be called more than one time on the
1456 * same USB transfer!
1457 *------------------------------------------------------------------------*/
1458static void
1459musbotg_device_done(struct usb2_xfer *xfer, usb2_error_t error)
1460{
1322
1323 DPRINTFN(8, "\n");
1324
1325 USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
1326
1327 if (std->state != USB_SW_TR_PRE_DATA) {
1328 if (std->state == USB_SW_TR_PRE_CALLBACK) {
1329 /* transfer transferred */
1330 musbotg_device_done(xfer, std->err);
1331 }
1332 goto done;
1333 }
1334 /* setup buffer */
1335 std->ptr = sc->sc_hub_idata;
1336 std->len = sizeof(sc->sc_hub_idata);
1337
1338 /* set port bit */
1339 sc->sc_hub_idata[0] = 0x02; /* we only have one port */
1340
1341done:
1342 return;
1343}
1344
1345static usb2_error_t
1346musbotg_standard_done_sub(struct usb2_xfer *xfer)
1347{
1348 struct musbotg_td *td;
1349 uint32_t len;
1350 uint8_t error;
1351
1352 DPRINTFN(8, "\n");
1353
1354 td = xfer->td_transfer_cache;
1355
1356 do {
1357 len = td->remainder;
1358
1359 if (xfer->aframes != xfer->nframes) {
1360 /*
1361 * Verify the length and subtract
1362 * the remainder from "frlengths[]":
1363 */
1364 if (len > xfer->frlengths[xfer->aframes]) {
1365 td->error = 1;
1366 } else {
1367 xfer->frlengths[xfer->aframes] -= len;
1368 }
1369 }
1370 /* Check for transfer error */
1371 if (td->error) {
1372 /* the transfer is finished */
1373 error = 1;
1374 td = NULL;
1375 break;
1376 }
1377 /* Check for short transfer */
1378 if (len > 0) {
1379 if (xfer->flags_int.short_frames_ok) {
1380 /* follow alt next */
1381 if (td->alt_next) {
1382 td = td->obj_next;
1383 } else {
1384 td = NULL;
1385 }
1386 } else {
1387 /* the transfer is finished */
1388 td = NULL;
1389 }
1390 error = 0;
1391 break;
1392 }
1393 td = td->obj_next;
1394
1395 /* this USB frame is complete */
1396 error = 0;
1397 break;
1398
1399 } while (0);
1400
1401 /* update transfer cache */
1402
1403 xfer->td_transfer_cache = td;
1404
1405 return (error ?
1406 USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION);
1407}
1408
1409static void
1410musbotg_standard_done(struct usb2_xfer *xfer)
1411{
1412 usb2_error_t err = 0;
1413
1414 DPRINTFN(12, "xfer=%p pipe=%p transfer done\n",
1415 xfer, xfer->pipe);
1416
1417 /* reset scanner */
1418
1419 xfer->td_transfer_cache = xfer->td_transfer_first;
1420
1421 if (xfer->flags_int.control_xfr) {
1422
1423 if (xfer->flags_int.control_hdr) {
1424
1425 err = musbotg_standard_done_sub(xfer);
1426 }
1427 xfer->aframes = 1;
1428
1429 if (xfer->td_transfer_cache == NULL) {
1430 goto done;
1431 }
1432 }
1433 while (xfer->aframes != xfer->nframes) {
1434
1435 err = musbotg_standard_done_sub(xfer);
1436 xfer->aframes++;
1437
1438 if (xfer->td_transfer_cache == NULL) {
1439 goto done;
1440 }
1441 }
1442
1443 if (xfer->flags_int.control_xfr &&
1444 !xfer->flags_int.control_act) {
1445
1446 err = musbotg_standard_done_sub(xfer);
1447 }
1448done:
1449 musbotg_device_done(xfer, err);
1450}
1451
1452/*------------------------------------------------------------------------*
1453 * musbotg_device_done
1454 *
1455 * NOTE: this function can be called more than one time on the
1456 * same USB transfer!
1457 *------------------------------------------------------------------------*/
1458static void
1459musbotg_device_done(struct usb2_xfer *xfer, usb2_error_t error)
1460{
1461 USB_BUS_LOCK_ASSERT(xfer->udev->bus, MA_OWNED);
1461 USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED);
1462
1463 DPRINTFN(2, "xfer=%p, pipe=%p, error=%d\n",
1464 xfer, xfer->pipe, error);
1465
1466 if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE) {
1467
1468 musbotg_ep_int_set(xfer, 0);
1469
1470 DPRINTFN(14, "disabled interrupts on endpoint\n");
1471 }
1472 /* dequeue transfer and start next transfer */
1473 usb2_transfer_done(xfer, error);
1474}
1475
1476static void
1477musbotg_set_stall(struct usb2_device *udev, struct usb2_xfer *xfer,
1478 struct usb2_pipe *pipe)
1479{
1480 struct musbotg_softc *sc;
1481 uint8_t ep_no;
1482
1483 USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
1484
1485 DPRINTFN(4, "pipe=%p\n", pipe);
1486
1487 if (xfer) {
1488 /* cancel any ongoing transfers */
1489 musbotg_device_done(xfer, USB_ERR_STALLED);
1490 }
1491 /* set FORCESTALL */
1492 sc = MUSBOTG_BUS2SC(udev->bus);
1493
1494 ep_no = (pipe->edesc->bEndpointAddress & UE_ADDR);
1495
1496 /* select endpoint */
1497 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, ep_no);
1498
1499 if (pipe->edesc->bEndpointAddress & UE_DIR_IN) {
1500 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1501 MUSB2_MASK_CSRL_TXSENDSTALL);
1502 } else {
1503 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1504 MUSB2_MASK_CSRL_RXSENDSTALL);
1505 }
1506}
1507
1508static void
1509musbotg_clear_stall_sub(struct musbotg_softc *sc, uint16_t wMaxPacket,
1510 uint8_t ep_no, uint8_t ep_type, uint8_t ep_dir)
1511{
1512 uint16_t mps;
1513 uint16_t temp;
1514 uint8_t csr;
1515
1516 if (ep_type == UE_CONTROL) {
1517 /* clearing stall is not needed */
1518 return;
1519 }
1520 /* select endpoint */
1521 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, ep_no);
1522
1523 /* compute max frame size */
1524 mps = wMaxPacket & 0x7FF;
1525 switch ((wMaxPacket >> 11) & 3) {
1526 case 1:
1527 mps *= 2;
1528 break;
1529 case 2:
1530 mps *= 3;
1531 break;
1532 default:
1533 break;
1534 }
1535
1536 if (ep_dir == UE_DIR_IN) {
1537
1538 temp = 0;
1539
1540 /* Configure endpoint */
1541 switch (ep_type) {
1542 case UE_INTERRUPT:
1543 MUSB2_WRITE_1(sc, MUSB2_REG_TXMAXP, wMaxPacket);
1544 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH,
1545 MUSB2_MASK_CSRH_TXMODE | temp);
1546 break;
1547 case UE_ISOCHRONOUS:
1548 MUSB2_WRITE_1(sc, MUSB2_REG_TXMAXP, wMaxPacket);
1549 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH,
1550 MUSB2_MASK_CSRH_TXMODE |
1551 MUSB2_MASK_CSRH_TXISO | temp);
1552 break;
1553 case UE_BULK:
1554 MUSB2_WRITE_1(sc, MUSB2_REG_TXMAXP, wMaxPacket);
1555 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH,
1556 MUSB2_MASK_CSRH_TXMODE | temp);
1557 break;
1558 default:
1559 break;
1560 }
1561
1562 /* Need to flush twice in case of double bufring */
1563 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1564 if (csr & MUSB2_MASK_CSRL_TXFIFONEMPTY) {
1565 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1566 MUSB2_MASK_CSRL_TXFFLUSH);
1567 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1568 if (csr & MUSB2_MASK_CSRL_TXFIFONEMPTY) {
1569 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1570 MUSB2_MASK_CSRL_TXFFLUSH);
1571 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1572 }
1573 }
1574 /* reset data toggle */
1575 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1576 MUSB2_MASK_CSRL_TXDT_CLR);
1577 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
1578 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1579
1580 /* set double/single buffering */
1581 temp = MUSB2_READ_2(sc, MUSB2_REG_TXDBDIS);
1582 if (mps <= (sc->sc_hw_ep_profile[ep_no].
1583 max_in_frame_size / 2)) {
1584 /* double buffer */
1585 temp &= ~(1 << ep_no);
1586 } else {
1587 /* single buffer */
1588 temp |= (1 << ep_no);
1589 }
1590 MUSB2_WRITE_2(sc, MUSB2_REG_TXDBDIS, temp);
1591
1592 /* clear sent stall */
1593 if (csr & MUSB2_MASK_CSRL_TXSENTSTALL) {
1594 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
1595 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1596 }
1597 } else {
1598
1599 temp = 0;
1600
1601 /* Configure endpoint */
1602 switch (ep_type) {
1603 case UE_INTERRUPT:
1604 MUSB2_WRITE_1(sc, MUSB2_REG_RXMAXP, wMaxPacket);
1605 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH,
1606 MUSB2_MASK_CSRH_RXNYET | temp);
1607 break;
1608 case UE_ISOCHRONOUS:
1609 MUSB2_WRITE_1(sc, MUSB2_REG_RXMAXP, wMaxPacket);
1610 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH,
1611 MUSB2_MASK_CSRH_RXNYET |
1612 MUSB2_MASK_CSRH_RXISO | temp);
1613 break;
1614 case UE_BULK:
1615 MUSB2_WRITE_1(sc, MUSB2_REG_RXMAXP, wMaxPacket);
1616 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH, temp);
1617 break;
1618 default:
1619 break;
1620 }
1621
1622 /* Need to flush twice in case of double bufring */
1623 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1624 if (csr & MUSB2_MASK_CSRL_RXPKTRDY) {
1625 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1626 MUSB2_MASK_CSRL_RXFFLUSH);
1627 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1628 if (csr & MUSB2_MASK_CSRL_RXPKTRDY) {
1629 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1630 MUSB2_MASK_CSRL_RXFFLUSH);
1631 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1632 }
1633 }
1634 /* reset data toggle */
1635 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1636 MUSB2_MASK_CSRL_RXDT_CLR);
1637 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL, 0);
1638 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1639
1640 /* set double/single buffering */
1641 temp = MUSB2_READ_2(sc, MUSB2_REG_RXDBDIS);
1642 if (mps <= (sc->sc_hw_ep_profile[ep_no].
1643 max_out_frame_size / 2)) {
1644 /* double buffer */
1645 temp &= ~(1 << ep_no);
1646 } else {
1647 /* single buffer */
1648 temp |= (1 << ep_no);
1649 }
1650 MUSB2_WRITE_2(sc, MUSB2_REG_RXDBDIS, temp);
1651
1652 /* clear sent stall */
1653 if (csr & MUSB2_MASK_CSRL_RXSENTSTALL) {
1654 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL, 0);
1655 }
1656 }
1657}
1658
1659static void
1660musbotg_clear_stall(struct usb2_device *udev, struct usb2_pipe *pipe)
1661{
1662 struct musbotg_softc *sc;
1663 struct usb2_endpoint_descriptor *ed;
1664
1665 DPRINTFN(4, "pipe=%p\n", pipe);
1666
1667 USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
1668
1669 /* check mode */
1670 if (udev->flags.usb2_mode != USB_MODE_DEVICE) {
1671 /* not supported */
1672 return;
1673 }
1674 /* get softc */
1675 sc = MUSBOTG_BUS2SC(udev->bus);
1676
1677 /* get endpoint descriptor */
1678 ed = pipe->edesc;
1679
1680 /* reset endpoint */
1681 musbotg_clear_stall_sub(sc,
1682 UGETW(ed->wMaxPacketSize),
1683 (ed->bEndpointAddress & UE_ADDR),
1684 (ed->bmAttributes & UE_XFERTYPE),
1685 (ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT)));
1686}
1687
1688usb2_error_t
1689musbotg_init(struct musbotg_softc *sc)
1690{
1691 struct usb2_hw_ep_profile *pf;
1692 uint8_t nrx;
1693 uint8_t ntx;
1694 uint8_t temp;
1695 uint8_t fsize;
1696 uint8_t frx;
1697 uint8_t ftx;
1698
1699 DPRINTFN(1, "start\n");
1700
1701 /* set up the bus structure */
1702 sc->sc_bus.usbrev = USB_REV_2_0;
1703 sc->sc_bus.methods = &musbotg_bus_methods;
1704
1705 USB_BUS_LOCK(&sc->sc_bus);
1706
1707 /* turn on clocks */
1708
1709 if (sc->sc_clocks_on) {
1710 (sc->sc_clocks_on) (sc->sc_clocks_arg);
1711 }
1712 /* wait a little for things to stabilise */
1713 usb2_pause_mtx(&sc->sc_bus.bus_mtx, 1);
1714
1715 /* disable all interrupts */
1716
1717 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, 0);
1718 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, 0);
1719 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, 0);
1720
1721 /* disable pullup */
1722
1723 musbotg_pull_common(sc, 0);
1724
1725 /* wait a little bit (10ms) */
1726 usb2_pause_mtx(&sc->sc_bus.bus_mtx, 10);
1727
1728 /* disable double packet buffering */
1729 MUSB2_WRITE_2(sc, MUSB2_REG_RXDBDIS, 0xFFFF);
1730 MUSB2_WRITE_2(sc, MUSB2_REG_TXDBDIS, 0xFFFF);
1731
1732 /* enable HighSpeed and ISO Update flags */
1733
1734 MUSB2_WRITE_1(sc, MUSB2_REG_POWER,
1735 MUSB2_MASK_HSENAB | MUSB2_MASK_ISOUPD);
1736
1737 /* clear Session bit, if set */
1738
1739 temp = MUSB2_READ_1(sc, MUSB2_REG_DEVCTL);
1740 temp &= ~MUSB2_MASK_SESS;
1741 MUSB2_WRITE_1(sc, MUSB2_REG_DEVCTL, temp);
1742
1743 DPRINTF("DEVCTL=0x%02x\n", temp);
1744
1745 /* disable testmode */
1746
1747 MUSB2_WRITE_1(sc, MUSB2_REG_TESTMODE, 0);
1748
1749 /* set default value */
1750
1751 MUSB2_WRITE_1(sc, MUSB2_REG_MISC, 0);
1752
1753 /* select endpoint index 0 */
1754
1755 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
1756
1757 /* read out number of endpoints */
1758
1759 nrx =
1760 (MUSB2_READ_1(sc, MUSB2_REG_EPINFO) / 16);
1761
1762 ntx =
1763 (MUSB2_READ_1(sc, MUSB2_REG_EPINFO) % 16);
1764
1765 /* these numbers exclude the control endpoint */
1766
1767 DPRINTFN(2, "RX/TX endpoints: %u/%u\n", nrx, ntx);
1768
1769 sc->sc_ep_max = (nrx > ntx) ? nrx : ntx;
1770 if (sc->sc_ep_max == 0) {
1771 DPRINTFN(2, "ERROR: Looks like the clocks are off!\n");
1772 }
1773 /* read out configuration data */
1774
1775 sc->sc_conf_data = MUSB2_READ_1(sc, MUSB2_REG_CONFDATA);
1776
1777 DPRINTFN(2, "Config Data: 0x%02x\n",
1778 sc->sc_conf_data);
1779
1780 DPRINTFN(2, "HW version: 0x%04x\n",
1781 MUSB2_READ_1(sc, MUSB2_REG_HWVERS));
1782
1783 /* initialise endpoint profiles */
1784
1785 for (temp = 1; temp <= sc->sc_ep_max; temp++) {
1786 pf = sc->sc_hw_ep_profile + temp;
1787
1788 /* select endpoint */
1789 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, temp);
1790
1791 fsize = MUSB2_READ_1(sc, MUSB2_REG_FSIZE);
1792 frx = (fsize & MUSB2_MASK_RX_FSIZE) / 16;;
1793 ftx = (fsize & MUSB2_MASK_TX_FSIZE);
1794
1795 DPRINTF("Endpoint %u FIFO size: IN=%u, OUT=%u\n",
1796 temp, pf->max_in_frame_size,
1797 pf->max_out_frame_size);
1798
1799 if (frx && ftx && (temp <= nrx) && (temp <= ntx)) {
1800 pf->max_in_frame_size = 1 << ftx;
1801 pf->max_out_frame_size = 1 << frx;
1802 pf->is_simplex = 0; /* duplex */
1803 pf->support_multi_buffer = 1;
1804 pf->support_bulk = 1;
1805 pf->support_interrupt = 1;
1806 pf->support_isochronous = 1;
1807 pf->support_in = 1;
1808 pf->support_out = 1;
1809 } else if (frx && (temp <= nrx)) {
1810 pf->max_out_frame_size = 1 << frx;
1811 pf->is_simplex = 1; /* simplex */
1812 pf->support_multi_buffer = 1;
1813 pf->support_bulk = 1;
1814 pf->support_interrupt = 1;
1815 pf->support_isochronous = 1;
1816 pf->support_out = 1;
1817 } else if (ftx && (temp <= ntx)) {
1818 pf->max_in_frame_size = 1 << ftx;
1819 pf->is_simplex = 1; /* simplex */
1820 pf->support_multi_buffer = 1;
1821 pf->support_bulk = 1;
1822 pf->support_interrupt = 1;
1823 pf->support_isochronous = 1;
1824 pf->support_in = 1;
1825 }
1826 }
1827
1828 /* turn on default interrupts */
1829
1830 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE,
1831 MUSB2_MASK_IRESET);
1832
1833 musbotg_clocks_off(sc);
1834
1835 USB_BUS_UNLOCK(&sc->sc_bus);
1836
1837 /* catch any lost interrupts */
1838
1839 musbotg_do_poll(&sc->sc_bus);
1840
1841 return (0); /* success */
1842}
1843
1844void
1845musbotg_uninit(struct musbotg_softc *sc)
1846{
1847 USB_BUS_LOCK(&sc->sc_bus);
1848
1849 /* disable all interrupts */
1850 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, 0);
1851 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, 0);
1852 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, 0);
1853
1854 sc->sc_flags.port_powered = 0;
1855 sc->sc_flags.status_vbus = 0;
1856 sc->sc_flags.status_bus_reset = 0;
1857 sc->sc_flags.status_suspend = 0;
1858 sc->sc_flags.change_suspend = 0;
1859 sc->sc_flags.change_connect = 1;
1860
1861 musbotg_pull_down(sc);
1862 musbotg_clocks_off(sc);
1863 USB_BUS_UNLOCK(&sc->sc_bus);
1864}
1865
1866void
1867musbotg_suspend(struct musbotg_softc *sc)
1868{
1869 return;
1870}
1871
1872void
1873musbotg_resume(struct musbotg_softc *sc)
1874{
1875 return;
1876}
1877
1878static void
1879musbotg_do_poll(struct usb2_bus *bus)
1880{
1881 struct musbotg_softc *sc = MUSBOTG_BUS2SC(bus);
1882
1883 USB_BUS_LOCK(&sc->sc_bus);
1884 musbotg_interrupt_poll(sc);
1885 musbotg_root_ctrl_poll(sc);
1886 USB_BUS_UNLOCK(&sc->sc_bus);
1887}
1888
1889/*------------------------------------------------------------------------*
1890 * musbotg bulk support
1891 *------------------------------------------------------------------------*/
1892static void
1893musbotg_device_bulk_open(struct usb2_xfer *xfer)
1894{
1895 return;
1896}
1897
1898static void
1899musbotg_device_bulk_close(struct usb2_xfer *xfer)
1900{
1901 musbotg_device_done(xfer, USB_ERR_CANCELLED);
1902}
1903
1904static void
1905musbotg_device_bulk_enter(struct usb2_xfer *xfer)
1906{
1907 return;
1908}
1909
1910static void
1911musbotg_device_bulk_start(struct usb2_xfer *xfer)
1912{
1913 /* setup TDs */
1914 musbotg_setup_standard_chain(xfer);
1915 musbotg_start_standard_chain(xfer);
1916}
1917
1918struct usb2_pipe_methods musbotg_device_bulk_methods =
1919{
1920 .open = musbotg_device_bulk_open,
1921 .close = musbotg_device_bulk_close,
1922 .enter = musbotg_device_bulk_enter,
1923 .start = musbotg_device_bulk_start,
1924 .enter_is_cancelable = 1,
1925 .start_is_cancelable = 1,
1926};
1927
1928/*------------------------------------------------------------------------*
1929 * musbotg control support
1930 *------------------------------------------------------------------------*/
1931static void
1932musbotg_device_ctrl_open(struct usb2_xfer *xfer)
1933{
1934 return;
1935}
1936
1937static void
1938musbotg_device_ctrl_close(struct usb2_xfer *xfer)
1939{
1940 musbotg_device_done(xfer, USB_ERR_CANCELLED);
1941}
1942
1943static void
1944musbotg_device_ctrl_enter(struct usb2_xfer *xfer)
1945{
1946 return;
1947}
1948
1949static void
1950musbotg_device_ctrl_start(struct usb2_xfer *xfer)
1951{
1952 /* setup TDs */
1953 musbotg_setup_standard_chain(xfer);
1954 musbotg_start_standard_chain(xfer);
1955}
1956
1957struct usb2_pipe_methods musbotg_device_ctrl_methods =
1958{
1959 .open = musbotg_device_ctrl_open,
1960 .close = musbotg_device_ctrl_close,
1961 .enter = musbotg_device_ctrl_enter,
1962 .start = musbotg_device_ctrl_start,
1963 .enter_is_cancelable = 1,
1964 .start_is_cancelable = 1,
1965};
1966
1967/*------------------------------------------------------------------------*
1968 * musbotg interrupt support
1969 *------------------------------------------------------------------------*/
1970static void
1971musbotg_device_intr_open(struct usb2_xfer *xfer)
1972{
1973 return;
1974}
1975
1976static void
1977musbotg_device_intr_close(struct usb2_xfer *xfer)
1978{
1979 musbotg_device_done(xfer, USB_ERR_CANCELLED);
1980}
1981
1982static void
1983musbotg_device_intr_enter(struct usb2_xfer *xfer)
1984{
1985 return;
1986}
1987
1988static void
1989musbotg_device_intr_start(struct usb2_xfer *xfer)
1990{
1991 /* setup TDs */
1992 musbotg_setup_standard_chain(xfer);
1993 musbotg_start_standard_chain(xfer);
1994}
1995
1996struct usb2_pipe_methods musbotg_device_intr_methods =
1997{
1998 .open = musbotg_device_intr_open,
1999 .close = musbotg_device_intr_close,
2000 .enter = musbotg_device_intr_enter,
2001 .start = musbotg_device_intr_start,
2002 .enter_is_cancelable = 1,
2003 .start_is_cancelable = 1,
2004};
2005
2006/*------------------------------------------------------------------------*
2007 * musbotg full speed isochronous support
2008 *------------------------------------------------------------------------*/
2009static void
2010musbotg_device_isoc_open(struct usb2_xfer *xfer)
2011{
2012 return;
2013}
2014
2015static void
2016musbotg_device_isoc_close(struct usb2_xfer *xfer)
2017{
2018 musbotg_device_done(xfer, USB_ERR_CANCELLED);
2019}
2020
2021static void
2022musbotg_device_isoc_enter(struct usb2_xfer *xfer)
2023{
1462
1463 DPRINTFN(2, "xfer=%p, pipe=%p, error=%d\n",
1464 xfer, xfer->pipe, error);
1465
1466 if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE) {
1467
1468 musbotg_ep_int_set(xfer, 0);
1469
1470 DPRINTFN(14, "disabled interrupts on endpoint\n");
1471 }
1472 /* dequeue transfer and start next transfer */
1473 usb2_transfer_done(xfer, error);
1474}
1475
1476static void
1477musbotg_set_stall(struct usb2_device *udev, struct usb2_xfer *xfer,
1478 struct usb2_pipe *pipe)
1479{
1480 struct musbotg_softc *sc;
1481 uint8_t ep_no;
1482
1483 USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
1484
1485 DPRINTFN(4, "pipe=%p\n", pipe);
1486
1487 if (xfer) {
1488 /* cancel any ongoing transfers */
1489 musbotg_device_done(xfer, USB_ERR_STALLED);
1490 }
1491 /* set FORCESTALL */
1492 sc = MUSBOTG_BUS2SC(udev->bus);
1493
1494 ep_no = (pipe->edesc->bEndpointAddress & UE_ADDR);
1495
1496 /* select endpoint */
1497 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, ep_no);
1498
1499 if (pipe->edesc->bEndpointAddress & UE_DIR_IN) {
1500 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1501 MUSB2_MASK_CSRL_TXSENDSTALL);
1502 } else {
1503 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1504 MUSB2_MASK_CSRL_RXSENDSTALL);
1505 }
1506}
1507
1508static void
1509musbotg_clear_stall_sub(struct musbotg_softc *sc, uint16_t wMaxPacket,
1510 uint8_t ep_no, uint8_t ep_type, uint8_t ep_dir)
1511{
1512 uint16_t mps;
1513 uint16_t temp;
1514 uint8_t csr;
1515
1516 if (ep_type == UE_CONTROL) {
1517 /* clearing stall is not needed */
1518 return;
1519 }
1520 /* select endpoint */
1521 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, ep_no);
1522
1523 /* compute max frame size */
1524 mps = wMaxPacket & 0x7FF;
1525 switch ((wMaxPacket >> 11) & 3) {
1526 case 1:
1527 mps *= 2;
1528 break;
1529 case 2:
1530 mps *= 3;
1531 break;
1532 default:
1533 break;
1534 }
1535
1536 if (ep_dir == UE_DIR_IN) {
1537
1538 temp = 0;
1539
1540 /* Configure endpoint */
1541 switch (ep_type) {
1542 case UE_INTERRUPT:
1543 MUSB2_WRITE_1(sc, MUSB2_REG_TXMAXP, wMaxPacket);
1544 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH,
1545 MUSB2_MASK_CSRH_TXMODE | temp);
1546 break;
1547 case UE_ISOCHRONOUS:
1548 MUSB2_WRITE_1(sc, MUSB2_REG_TXMAXP, wMaxPacket);
1549 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH,
1550 MUSB2_MASK_CSRH_TXMODE |
1551 MUSB2_MASK_CSRH_TXISO | temp);
1552 break;
1553 case UE_BULK:
1554 MUSB2_WRITE_1(sc, MUSB2_REG_TXMAXP, wMaxPacket);
1555 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRH,
1556 MUSB2_MASK_CSRH_TXMODE | temp);
1557 break;
1558 default:
1559 break;
1560 }
1561
1562 /* Need to flush twice in case of double bufring */
1563 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1564 if (csr & MUSB2_MASK_CSRL_TXFIFONEMPTY) {
1565 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1566 MUSB2_MASK_CSRL_TXFFLUSH);
1567 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1568 if (csr & MUSB2_MASK_CSRL_TXFIFONEMPTY) {
1569 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1570 MUSB2_MASK_CSRL_TXFFLUSH);
1571 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1572 }
1573 }
1574 /* reset data toggle */
1575 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL,
1576 MUSB2_MASK_CSRL_TXDT_CLR);
1577 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
1578 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1579
1580 /* set double/single buffering */
1581 temp = MUSB2_READ_2(sc, MUSB2_REG_TXDBDIS);
1582 if (mps <= (sc->sc_hw_ep_profile[ep_no].
1583 max_in_frame_size / 2)) {
1584 /* double buffer */
1585 temp &= ~(1 << ep_no);
1586 } else {
1587 /* single buffer */
1588 temp |= (1 << ep_no);
1589 }
1590 MUSB2_WRITE_2(sc, MUSB2_REG_TXDBDIS, temp);
1591
1592 /* clear sent stall */
1593 if (csr & MUSB2_MASK_CSRL_TXSENTSTALL) {
1594 MUSB2_WRITE_1(sc, MUSB2_REG_TXCSRL, 0);
1595 csr = MUSB2_READ_1(sc, MUSB2_REG_TXCSRL);
1596 }
1597 } else {
1598
1599 temp = 0;
1600
1601 /* Configure endpoint */
1602 switch (ep_type) {
1603 case UE_INTERRUPT:
1604 MUSB2_WRITE_1(sc, MUSB2_REG_RXMAXP, wMaxPacket);
1605 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH,
1606 MUSB2_MASK_CSRH_RXNYET | temp);
1607 break;
1608 case UE_ISOCHRONOUS:
1609 MUSB2_WRITE_1(sc, MUSB2_REG_RXMAXP, wMaxPacket);
1610 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH,
1611 MUSB2_MASK_CSRH_RXNYET |
1612 MUSB2_MASK_CSRH_RXISO | temp);
1613 break;
1614 case UE_BULK:
1615 MUSB2_WRITE_1(sc, MUSB2_REG_RXMAXP, wMaxPacket);
1616 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRH, temp);
1617 break;
1618 default:
1619 break;
1620 }
1621
1622 /* Need to flush twice in case of double bufring */
1623 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1624 if (csr & MUSB2_MASK_CSRL_RXPKTRDY) {
1625 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1626 MUSB2_MASK_CSRL_RXFFLUSH);
1627 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1628 if (csr & MUSB2_MASK_CSRL_RXPKTRDY) {
1629 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1630 MUSB2_MASK_CSRL_RXFFLUSH);
1631 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1632 }
1633 }
1634 /* reset data toggle */
1635 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL,
1636 MUSB2_MASK_CSRL_RXDT_CLR);
1637 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL, 0);
1638 csr = MUSB2_READ_1(sc, MUSB2_REG_RXCSRL);
1639
1640 /* set double/single buffering */
1641 temp = MUSB2_READ_2(sc, MUSB2_REG_RXDBDIS);
1642 if (mps <= (sc->sc_hw_ep_profile[ep_no].
1643 max_out_frame_size / 2)) {
1644 /* double buffer */
1645 temp &= ~(1 << ep_no);
1646 } else {
1647 /* single buffer */
1648 temp |= (1 << ep_no);
1649 }
1650 MUSB2_WRITE_2(sc, MUSB2_REG_RXDBDIS, temp);
1651
1652 /* clear sent stall */
1653 if (csr & MUSB2_MASK_CSRL_RXSENTSTALL) {
1654 MUSB2_WRITE_1(sc, MUSB2_REG_RXCSRL, 0);
1655 }
1656 }
1657}
1658
1659static void
1660musbotg_clear_stall(struct usb2_device *udev, struct usb2_pipe *pipe)
1661{
1662 struct musbotg_softc *sc;
1663 struct usb2_endpoint_descriptor *ed;
1664
1665 DPRINTFN(4, "pipe=%p\n", pipe);
1666
1667 USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED);
1668
1669 /* check mode */
1670 if (udev->flags.usb2_mode != USB_MODE_DEVICE) {
1671 /* not supported */
1672 return;
1673 }
1674 /* get softc */
1675 sc = MUSBOTG_BUS2SC(udev->bus);
1676
1677 /* get endpoint descriptor */
1678 ed = pipe->edesc;
1679
1680 /* reset endpoint */
1681 musbotg_clear_stall_sub(sc,
1682 UGETW(ed->wMaxPacketSize),
1683 (ed->bEndpointAddress & UE_ADDR),
1684 (ed->bmAttributes & UE_XFERTYPE),
1685 (ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT)));
1686}
1687
1688usb2_error_t
1689musbotg_init(struct musbotg_softc *sc)
1690{
1691 struct usb2_hw_ep_profile *pf;
1692 uint8_t nrx;
1693 uint8_t ntx;
1694 uint8_t temp;
1695 uint8_t fsize;
1696 uint8_t frx;
1697 uint8_t ftx;
1698
1699 DPRINTFN(1, "start\n");
1700
1701 /* set up the bus structure */
1702 sc->sc_bus.usbrev = USB_REV_2_0;
1703 sc->sc_bus.methods = &musbotg_bus_methods;
1704
1705 USB_BUS_LOCK(&sc->sc_bus);
1706
1707 /* turn on clocks */
1708
1709 if (sc->sc_clocks_on) {
1710 (sc->sc_clocks_on) (sc->sc_clocks_arg);
1711 }
1712 /* wait a little for things to stabilise */
1713 usb2_pause_mtx(&sc->sc_bus.bus_mtx, 1);
1714
1715 /* disable all interrupts */
1716
1717 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, 0);
1718 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, 0);
1719 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, 0);
1720
1721 /* disable pullup */
1722
1723 musbotg_pull_common(sc, 0);
1724
1725 /* wait a little bit (10ms) */
1726 usb2_pause_mtx(&sc->sc_bus.bus_mtx, 10);
1727
1728 /* disable double packet buffering */
1729 MUSB2_WRITE_2(sc, MUSB2_REG_RXDBDIS, 0xFFFF);
1730 MUSB2_WRITE_2(sc, MUSB2_REG_TXDBDIS, 0xFFFF);
1731
1732 /* enable HighSpeed and ISO Update flags */
1733
1734 MUSB2_WRITE_1(sc, MUSB2_REG_POWER,
1735 MUSB2_MASK_HSENAB | MUSB2_MASK_ISOUPD);
1736
1737 /* clear Session bit, if set */
1738
1739 temp = MUSB2_READ_1(sc, MUSB2_REG_DEVCTL);
1740 temp &= ~MUSB2_MASK_SESS;
1741 MUSB2_WRITE_1(sc, MUSB2_REG_DEVCTL, temp);
1742
1743 DPRINTF("DEVCTL=0x%02x\n", temp);
1744
1745 /* disable testmode */
1746
1747 MUSB2_WRITE_1(sc, MUSB2_REG_TESTMODE, 0);
1748
1749 /* set default value */
1750
1751 MUSB2_WRITE_1(sc, MUSB2_REG_MISC, 0);
1752
1753 /* select endpoint index 0 */
1754
1755 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, 0);
1756
1757 /* read out number of endpoints */
1758
1759 nrx =
1760 (MUSB2_READ_1(sc, MUSB2_REG_EPINFO) / 16);
1761
1762 ntx =
1763 (MUSB2_READ_1(sc, MUSB2_REG_EPINFO) % 16);
1764
1765 /* these numbers exclude the control endpoint */
1766
1767 DPRINTFN(2, "RX/TX endpoints: %u/%u\n", nrx, ntx);
1768
1769 sc->sc_ep_max = (nrx > ntx) ? nrx : ntx;
1770 if (sc->sc_ep_max == 0) {
1771 DPRINTFN(2, "ERROR: Looks like the clocks are off!\n");
1772 }
1773 /* read out configuration data */
1774
1775 sc->sc_conf_data = MUSB2_READ_1(sc, MUSB2_REG_CONFDATA);
1776
1777 DPRINTFN(2, "Config Data: 0x%02x\n",
1778 sc->sc_conf_data);
1779
1780 DPRINTFN(2, "HW version: 0x%04x\n",
1781 MUSB2_READ_1(sc, MUSB2_REG_HWVERS));
1782
1783 /* initialise endpoint profiles */
1784
1785 for (temp = 1; temp <= sc->sc_ep_max; temp++) {
1786 pf = sc->sc_hw_ep_profile + temp;
1787
1788 /* select endpoint */
1789 MUSB2_WRITE_1(sc, MUSB2_REG_EPINDEX, temp);
1790
1791 fsize = MUSB2_READ_1(sc, MUSB2_REG_FSIZE);
1792 frx = (fsize & MUSB2_MASK_RX_FSIZE) / 16;;
1793 ftx = (fsize & MUSB2_MASK_TX_FSIZE);
1794
1795 DPRINTF("Endpoint %u FIFO size: IN=%u, OUT=%u\n",
1796 temp, pf->max_in_frame_size,
1797 pf->max_out_frame_size);
1798
1799 if (frx && ftx && (temp <= nrx) && (temp <= ntx)) {
1800 pf->max_in_frame_size = 1 << ftx;
1801 pf->max_out_frame_size = 1 << frx;
1802 pf->is_simplex = 0; /* duplex */
1803 pf->support_multi_buffer = 1;
1804 pf->support_bulk = 1;
1805 pf->support_interrupt = 1;
1806 pf->support_isochronous = 1;
1807 pf->support_in = 1;
1808 pf->support_out = 1;
1809 } else if (frx && (temp <= nrx)) {
1810 pf->max_out_frame_size = 1 << frx;
1811 pf->is_simplex = 1; /* simplex */
1812 pf->support_multi_buffer = 1;
1813 pf->support_bulk = 1;
1814 pf->support_interrupt = 1;
1815 pf->support_isochronous = 1;
1816 pf->support_out = 1;
1817 } else if (ftx && (temp <= ntx)) {
1818 pf->max_in_frame_size = 1 << ftx;
1819 pf->is_simplex = 1; /* simplex */
1820 pf->support_multi_buffer = 1;
1821 pf->support_bulk = 1;
1822 pf->support_interrupt = 1;
1823 pf->support_isochronous = 1;
1824 pf->support_in = 1;
1825 }
1826 }
1827
1828 /* turn on default interrupts */
1829
1830 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE,
1831 MUSB2_MASK_IRESET);
1832
1833 musbotg_clocks_off(sc);
1834
1835 USB_BUS_UNLOCK(&sc->sc_bus);
1836
1837 /* catch any lost interrupts */
1838
1839 musbotg_do_poll(&sc->sc_bus);
1840
1841 return (0); /* success */
1842}
1843
1844void
1845musbotg_uninit(struct musbotg_softc *sc)
1846{
1847 USB_BUS_LOCK(&sc->sc_bus);
1848
1849 /* disable all interrupts */
1850 MUSB2_WRITE_1(sc, MUSB2_REG_INTUSBE, 0);
1851 MUSB2_WRITE_2(sc, MUSB2_REG_INTTXE, 0);
1852 MUSB2_WRITE_2(sc, MUSB2_REG_INTRXE, 0);
1853
1854 sc->sc_flags.port_powered = 0;
1855 sc->sc_flags.status_vbus = 0;
1856 sc->sc_flags.status_bus_reset = 0;
1857 sc->sc_flags.status_suspend = 0;
1858 sc->sc_flags.change_suspend = 0;
1859 sc->sc_flags.change_connect = 1;
1860
1861 musbotg_pull_down(sc);
1862 musbotg_clocks_off(sc);
1863 USB_BUS_UNLOCK(&sc->sc_bus);
1864}
1865
1866void
1867musbotg_suspend(struct musbotg_softc *sc)
1868{
1869 return;
1870}
1871
1872void
1873musbotg_resume(struct musbotg_softc *sc)
1874{
1875 return;
1876}
1877
1878static void
1879musbotg_do_poll(struct usb2_bus *bus)
1880{
1881 struct musbotg_softc *sc = MUSBOTG_BUS2SC(bus);
1882
1883 USB_BUS_LOCK(&sc->sc_bus);
1884 musbotg_interrupt_poll(sc);
1885 musbotg_root_ctrl_poll(sc);
1886 USB_BUS_UNLOCK(&sc->sc_bus);
1887}
1888
1889/*------------------------------------------------------------------------*
1890 * musbotg bulk support
1891 *------------------------------------------------------------------------*/
1892static void
1893musbotg_device_bulk_open(struct usb2_xfer *xfer)
1894{
1895 return;
1896}
1897
1898static void
1899musbotg_device_bulk_close(struct usb2_xfer *xfer)
1900{
1901 musbotg_device_done(xfer, USB_ERR_CANCELLED);
1902}
1903
1904static void
1905musbotg_device_bulk_enter(struct usb2_xfer *xfer)
1906{
1907 return;
1908}
1909
1910static void
1911musbotg_device_bulk_start(struct usb2_xfer *xfer)
1912{
1913 /* setup TDs */
1914 musbotg_setup_standard_chain(xfer);
1915 musbotg_start_standard_chain(xfer);
1916}
1917
1918struct usb2_pipe_methods musbotg_device_bulk_methods =
1919{
1920 .open = musbotg_device_bulk_open,
1921 .close = musbotg_device_bulk_close,
1922 .enter = musbotg_device_bulk_enter,
1923 .start = musbotg_device_bulk_start,
1924 .enter_is_cancelable = 1,
1925 .start_is_cancelable = 1,
1926};
1927
1928/*------------------------------------------------------------------------*
1929 * musbotg control support
1930 *------------------------------------------------------------------------*/
1931static void
1932musbotg_device_ctrl_open(struct usb2_xfer *xfer)
1933{
1934 return;
1935}
1936
1937static void
1938musbotg_device_ctrl_close(struct usb2_xfer *xfer)
1939{
1940 musbotg_device_done(xfer, USB_ERR_CANCELLED);
1941}
1942
1943static void
1944musbotg_device_ctrl_enter(struct usb2_xfer *xfer)
1945{
1946 return;
1947}
1948
1949static void
1950musbotg_device_ctrl_start(struct usb2_xfer *xfer)
1951{
1952 /* setup TDs */
1953 musbotg_setup_standard_chain(xfer);
1954 musbotg_start_standard_chain(xfer);
1955}
1956
1957struct usb2_pipe_methods musbotg_device_ctrl_methods =
1958{
1959 .open = musbotg_device_ctrl_open,
1960 .close = musbotg_device_ctrl_close,
1961 .enter = musbotg_device_ctrl_enter,
1962 .start = musbotg_device_ctrl_start,
1963 .enter_is_cancelable = 1,
1964 .start_is_cancelable = 1,
1965};
1966
1967/*------------------------------------------------------------------------*
1968 * musbotg interrupt support
1969 *------------------------------------------------------------------------*/
1970static void
1971musbotg_device_intr_open(struct usb2_xfer *xfer)
1972{
1973 return;
1974}
1975
1976static void
1977musbotg_device_intr_close(struct usb2_xfer *xfer)
1978{
1979 musbotg_device_done(xfer, USB_ERR_CANCELLED);
1980}
1981
1982static void
1983musbotg_device_intr_enter(struct usb2_xfer *xfer)
1984{
1985 return;
1986}
1987
1988static void
1989musbotg_device_intr_start(struct usb2_xfer *xfer)
1990{
1991 /* setup TDs */
1992 musbotg_setup_standard_chain(xfer);
1993 musbotg_start_standard_chain(xfer);
1994}
1995
1996struct usb2_pipe_methods musbotg_device_intr_methods =
1997{
1998 .open = musbotg_device_intr_open,
1999 .close = musbotg_device_intr_close,
2000 .enter = musbotg_device_intr_enter,
2001 .start = musbotg_device_intr_start,
2002 .enter_is_cancelable = 1,
2003 .start_is_cancelable = 1,
2004};
2005
2006/*------------------------------------------------------------------------*
2007 * musbotg full speed isochronous support
2008 *------------------------------------------------------------------------*/
2009static void
2010musbotg_device_isoc_open(struct usb2_xfer *xfer)
2011{
2012 return;
2013}
2014
2015static void
2016musbotg_device_isoc_close(struct usb2_xfer *xfer)
2017{
2018 musbotg_device_done(xfer, USB_ERR_CANCELLED);
2019}
2020
2021static void
2022musbotg_device_isoc_enter(struct usb2_xfer *xfer)
2023{
2024 struct musbotg_softc *sc = xfer->usb2_sc;
2024 struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
2025 uint32_t temp;
2026 uint32_t nframes;
2027 uint32_t fs_frames;
2028
2029 DPRINTFN(5, "xfer=%p next=%d nframes=%d\n",
2030 xfer, xfer->pipe->isoc_next, xfer->nframes);
2031
2032 /* get the current frame index */
2033
2034 nframes = MUSB2_READ_2(sc, MUSB2_REG_FRAME);
2035
2036 /*
2037 * check if the frame index is within the window where the frames
2038 * will be inserted
2039 */
2040 temp = (nframes - xfer->pipe->isoc_next) & MUSB2_MASK_FRAME;
2041
2025 uint32_t temp;
2026 uint32_t nframes;
2027 uint32_t fs_frames;
2028
2029 DPRINTFN(5, "xfer=%p next=%d nframes=%d\n",
2030 xfer, xfer->pipe->isoc_next, xfer->nframes);
2031
2032 /* get the current frame index */
2033
2034 nframes = MUSB2_READ_2(sc, MUSB2_REG_FRAME);
2035
2036 /*
2037 * check if the frame index is within the window where the frames
2038 * will be inserted
2039 */
2040 temp = (nframes - xfer->pipe->isoc_next) & MUSB2_MASK_FRAME;
2041
2042 if (usb2_get_speed(xfer->udev) == USB_SPEED_HIGH) {
2042 if (usb2_get_speed(xfer->xroot->udev) == USB_SPEED_HIGH) {
2043 fs_frames = (xfer->nframes + 7) / 8;
2044 } else {
2045 fs_frames = xfer->nframes;
2046 }
2047
2048 if ((xfer->pipe->is_synced == 0) ||
2049 (temp < fs_frames)) {
2050 /*
2051 * If there is data underflow or the pipe queue is
2052 * empty we schedule the transfer a few frames ahead
2053 * of the current frame position. Else two isochronous
2054 * transfers might overlap.
2055 */
2056 xfer->pipe->isoc_next = (nframes + 3) & MUSB2_MASK_FRAME;
2057 xfer->pipe->is_synced = 1;
2058 DPRINTFN(2, "start next=%d\n", xfer->pipe->isoc_next);
2059 }
2060 /*
2061 * compute how many milliseconds the insertion is ahead of the
2062 * current frame position:
2063 */
2064 temp = (xfer->pipe->isoc_next - nframes) & MUSB2_MASK_FRAME;
2065
2066 /*
2067 * pre-compute when the isochronous transfer will be finished:
2068 */
2069 xfer->isoc_time_complete =
2070 usb2_isoc_time_expand(&sc->sc_bus, nframes) + temp +
2071 fs_frames;
2072
2073 /* compute frame number for next insertion */
2074 xfer->pipe->isoc_next += fs_frames;
2075
2076 /* setup TDs */
2077 musbotg_setup_standard_chain(xfer);
2078}
2079
2080static void
2081musbotg_device_isoc_start(struct usb2_xfer *xfer)
2082{
2083 /* start TD chain */
2084 musbotg_start_standard_chain(xfer);
2085}
2086
2087struct usb2_pipe_methods musbotg_device_isoc_methods =
2088{
2089 .open = musbotg_device_isoc_open,
2090 .close = musbotg_device_isoc_close,
2091 .enter = musbotg_device_isoc_enter,
2092 .start = musbotg_device_isoc_start,
2093 .enter_is_cancelable = 1,
2094 .start_is_cancelable = 1,
2095};
2096
2097/*------------------------------------------------------------------------*
2098 * musbotg root control support
2099 *------------------------------------------------------------------------*
2100 * simulate a hardware HUB by handling
2101 * all the necessary requests
2102 *------------------------------------------------------------------------*/
2103static void
2104musbotg_root_ctrl_open(struct usb2_xfer *xfer)
2105{
2106 return;
2107}
2108
2109static void
2110musbotg_root_ctrl_close(struct usb2_xfer *xfer)
2111{
2043 fs_frames = (xfer->nframes + 7) / 8;
2044 } else {
2045 fs_frames = xfer->nframes;
2046 }
2047
2048 if ((xfer->pipe->is_synced == 0) ||
2049 (temp < fs_frames)) {
2050 /*
2051 * If there is data underflow or the pipe queue is
2052 * empty we schedule the transfer a few frames ahead
2053 * of the current frame position. Else two isochronous
2054 * transfers might overlap.
2055 */
2056 xfer->pipe->isoc_next = (nframes + 3) & MUSB2_MASK_FRAME;
2057 xfer->pipe->is_synced = 1;
2058 DPRINTFN(2, "start next=%d\n", xfer->pipe->isoc_next);
2059 }
2060 /*
2061 * compute how many milliseconds the insertion is ahead of the
2062 * current frame position:
2063 */
2064 temp = (xfer->pipe->isoc_next - nframes) & MUSB2_MASK_FRAME;
2065
2066 /*
2067 * pre-compute when the isochronous transfer will be finished:
2068 */
2069 xfer->isoc_time_complete =
2070 usb2_isoc_time_expand(&sc->sc_bus, nframes) + temp +
2071 fs_frames;
2072
2073 /* compute frame number for next insertion */
2074 xfer->pipe->isoc_next += fs_frames;
2075
2076 /* setup TDs */
2077 musbotg_setup_standard_chain(xfer);
2078}
2079
2080static void
2081musbotg_device_isoc_start(struct usb2_xfer *xfer)
2082{
2083 /* start TD chain */
2084 musbotg_start_standard_chain(xfer);
2085}
2086
2087struct usb2_pipe_methods musbotg_device_isoc_methods =
2088{
2089 .open = musbotg_device_isoc_open,
2090 .close = musbotg_device_isoc_close,
2091 .enter = musbotg_device_isoc_enter,
2092 .start = musbotg_device_isoc_start,
2093 .enter_is_cancelable = 1,
2094 .start_is_cancelable = 1,
2095};
2096
2097/*------------------------------------------------------------------------*
2098 * musbotg root control support
2099 *------------------------------------------------------------------------*
2100 * simulate a hardware HUB by handling
2101 * all the necessary requests
2102 *------------------------------------------------------------------------*/
2103static void
2104musbotg_root_ctrl_open(struct usb2_xfer *xfer)
2105{
2106 return;
2107}
2108
2109static void
2110musbotg_root_ctrl_close(struct usb2_xfer *xfer)
2111{
2112 struct musbotg_softc *sc = xfer->usb2_sc;
2112 struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
2113
2114 if (sc->sc_root_ctrl.xfer == xfer) {
2115 sc->sc_root_ctrl.xfer = NULL;
2116 }
2117 musbotg_device_done(xfer, USB_ERR_CANCELLED);
2118}
2119
2120/*
2121 * USB descriptors for the virtual Root HUB:
2122 */
2123
2124static const struct usb2_device_descriptor musbotg_devd = {
2125 .bLength = sizeof(struct usb2_device_descriptor),
2126 .bDescriptorType = UDESC_DEVICE,
2127 .bcdUSB = {0x00, 0x02},
2128 .bDeviceClass = UDCLASS_HUB,
2129 .bDeviceSubClass = UDSUBCLASS_HUB,
2130 .bDeviceProtocol = UDPROTO_HSHUBSTT,
2131 .bMaxPacketSize = 64,
2132 .bcdDevice = {0x00, 0x01},
2133 .iManufacturer = 1,
2134 .iProduct = 2,
2135 .bNumConfigurations = 1,
2136};
2137
2138static const struct usb2_device_qualifier musbotg_odevd = {
2139 .bLength = sizeof(struct usb2_device_qualifier),
2140 .bDescriptorType = UDESC_DEVICE_QUALIFIER,
2141 .bcdUSB = {0x00, 0x02},
2142 .bDeviceClass = UDCLASS_HUB,
2143 .bDeviceSubClass = UDSUBCLASS_HUB,
2144 .bDeviceProtocol = UDPROTO_FSHUB,
2145 .bMaxPacketSize0 = 0,
2146 .bNumConfigurations = 0,
2147};
2148
2149static const struct musbotg_config_desc musbotg_confd = {
2150 .confd = {
2151 .bLength = sizeof(struct usb2_config_descriptor),
2152 .bDescriptorType = UDESC_CONFIG,
2153 .wTotalLength[0] = sizeof(musbotg_confd),
2154 .bNumInterface = 1,
2155 .bConfigurationValue = 1,
2156 .iConfiguration = 0,
2157 .bmAttributes = UC_SELF_POWERED,
2158 .bMaxPower = 0,
2159 },
2160 .ifcd = {
2161 .bLength = sizeof(struct usb2_interface_descriptor),
2162 .bDescriptorType = UDESC_INTERFACE,
2163 .bNumEndpoints = 1,
2164 .bInterfaceClass = UICLASS_HUB,
2165 .bInterfaceSubClass = UISUBCLASS_HUB,
2166 .bInterfaceProtocol = UIPROTO_HSHUBSTT,
2167 },
2168
2169 .endpd = {
2170 .bLength = sizeof(struct usb2_endpoint_descriptor),
2171 .bDescriptorType = UDESC_ENDPOINT,
2172 .bEndpointAddress = (UE_DIR_IN | MUSBOTG_INTR_ENDPT),
2173 .bmAttributes = UE_INTERRUPT,
2174 .wMaxPacketSize[0] = 8,
2175 .bInterval = 255,
2176 },
2177};
2178
2179static const struct usb2_hub_descriptor_min musbotg_hubd = {
2180 .bDescLength = sizeof(musbotg_hubd),
2181 .bDescriptorType = UDESC_HUB,
2182 .bNbrPorts = 1,
2183 .wHubCharacteristics[0] =
2184 (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) & 0xFF,
2185 .wHubCharacteristics[1] =
2186 (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) >> 16,
2187 .bPwrOn2PwrGood = 50,
2188 .bHubContrCurrent = 0,
2189 .DeviceRemovable = {0}, /* port is removable */
2190};
2191
2192#define STRING_LANG \
2193 0x09, 0x04, /* American English */
2194
2195#define STRING_VENDOR \
2196 'M', 0, 'e', 0, 'n', 0, 't', 0, 'o', 0, 'r', 0, ' ', 0, \
2197 'G', 0, 'r', 0, 'a', 0, 'p', 0, 'h', 0, 'i', 0, 'c', 0, 's', 0
2198
2199#define STRING_PRODUCT \
2200 'O', 0, 'T', 0, 'G', 0, ' ', 0, 'R', 0, \
2201 'o', 0, 'o', 0, 't', 0, ' ', 0, 'H', 0, \
2202 'U', 0, 'B', 0,
2203
2204USB_MAKE_STRING_DESC(STRING_LANG, musbotg_langtab);
2205USB_MAKE_STRING_DESC(STRING_VENDOR, musbotg_vendor);
2206USB_MAKE_STRING_DESC(STRING_PRODUCT, musbotg_product);
2207
2208static void
2209musbotg_root_ctrl_enter(struct usb2_xfer *xfer)
2210{
2211 return;
2212}
2213
2214static void
2215musbotg_root_ctrl_start(struct usb2_xfer *xfer)
2216{
2113
2114 if (sc->sc_root_ctrl.xfer == xfer) {
2115 sc->sc_root_ctrl.xfer = NULL;
2116 }
2117 musbotg_device_done(xfer, USB_ERR_CANCELLED);
2118}
2119
2120/*
2121 * USB descriptors for the virtual Root HUB:
2122 */
2123
2124static const struct usb2_device_descriptor musbotg_devd = {
2125 .bLength = sizeof(struct usb2_device_descriptor),
2126 .bDescriptorType = UDESC_DEVICE,
2127 .bcdUSB = {0x00, 0x02},
2128 .bDeviceClass = UDCLASS_HUB,
2129 .bDeviceSubClass = UDSUBCLASS_HUB,
2130 .bDeviceProtocol = UDPROTO_HSHUBSTT,
2131 .bMaxPacketSize = 64,
2132 .bcdDevice = {0x00, 0x01},
2133 .iManufacturer = 1,
2134 .iProduct = 2,
2135 .bNumConfigurations = 1,
2136};
2137
2138static const struct usb2_device_qualifier musbotg_odevd = {
2139 .bLength = sizeof(struct usb2_device_qualifier),
2140 .bDescriptorType = UDESC_DEVICE_QUALIFIER,
2141 .bcdUSB = {0x00, 0x02},
2142 .bDeviceClass = UDCLASS_HUB,
2143 .bDeviceSubClass = UDSUBCLASS_HUB,
2144 .bDeviceProtocol = UDPROTO_FSHUB,
2145 .bMaxPacketSize0 = 0,
2146 .bNumConfigurations = 0,
2147};
2148
2149static const struct musbotg_config_desc musbotg_confd = {
2150 .confd = {
2151 .bLength = sizeof(struct usb2_config_descriptor),
2152 .bDescriptorType = UDESC_CONFIG,
2153 .wTotalLength[0] = sizeof(musbotg_confd),
2154 .bNumInterface = 1,
2155 .bConfigurationValue = 1,
2156 .iConfiguration = 0,
2157 .bmAttributes = UC_SELF_POWERED,
2158 .bMaxPower = 0,
2159 },
2160 .ifcd = {
2161 .bLength = sizeof(struct usb2_interface_descriptor),
2162 .bDescriptorType = UDESC_INTERFACE,
2163 .bNumEndpoints = 1,
2164 .bInterfaceClass = UICLASS_HUB,
2165 .bInterfaceSubClass = UISUBCLASS_HUB,
2166 .bInterfaceProtocol = UIPROTO_HSHUBSTT,
2167 },
2168
2169 .endpd = {
2170 .bLength = sizeof(struct usb2_endpoint_descriptor),
2171 .bDescriptorType = UDESC_ENDPOINT,
2172 .bEndpointAddress = (UE_DIR_IN | MUSBOTG_INTR_ENDPT),
2173 .bmAttributes = UE_INTERRUPT,
2174 .wMaxPacketSize[0] = 8,
2175 .bInterval = 255,
2176 },
2177};
2178
2179static const struct usb2_hub_descriptor_min musbotg_hubd = {
2180 .bDescLength = sizeof(musbotg_hubd),
2181 .bDescriptorType = UDESC_HUB,
2182 .bNbrPorts = 1,
2183 .wHubCharacteristics[0] =
2184 (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) & 0xFF,
2185 .wHubCharacteristics[1] =
2186 (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) >> 16,
2187 .bPwrOn2PwrGood = 50,
2188 .bHubContrCurrent = 0,
2189 .DeviceRemovable = {0}, /* port is removable */
2190};
2191
2192#define STRING_LANG \
2193 0x09, 0x04, /* American English */
2194
2195#define STRING_VENDOR \
2196 'M', 0, 'e', 0, 'n', 0, 't', 0, 'o', 0, 'r', 0, ' ', 0, \
2197 'G', 0, 'r', 0, 'a', 0, 'p', 0, 'h', 0, 'i', 0, 'c', 0, 's', 0
2198
2199#define STRING_PRODUCT \
2200 'O', 0, 'T', 0, 'G', 0, ' ', 0, 'R', 0, \
2201 'o', 0, 'o', 0, 't', 0, ' ', 0, 'H', 0, \
2202 'U', 0, 'B', 0,
2203
2204USB_MAKE_STRING_DESC(STRING_LANG, musbotg_langtab);
2205USB_MAKE_STRING_DESC(STRING_VENDOR, musbotg_vendor);
2206USB_MAKE_STRING_DESC(STRING_PRODUCT, musbotg_product);
2207
2208static void
2209musbotg_root_ctrl_enter(struct usb2_xfer *xfer)
2210{
2211 return;
2212}
2213
2214static void
2215musbotg_root_ctrl_start(struct usb2_xfer *xfer)
2216{
2217 struct musbotg_softc *sc = xfer->usb2_sc;
2217 struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
2218
2219 sc->sc_root_ctrl.xfer = xfer;
2220
2218
2219 sc->sc_root_ctrl.xfer = xfer;
2220
2221 usb2_bus_roothub_exec(xfer->udev->bus);
2221 usb2_bus_roothub_exec(xfer->xroot->bus);
2222}
2223
2224static void
2225musbotg_root_ctrl_task(struct usb2_bus *bus)
2226{
2227 musbotg_root_ctrl_poll(MUSBOTG_BUS2SC(bus));
2228}
2229
2230static void
2231musbotg_root_ctrl_done(struct usb2_xfer *xfer,
2232 struct usb2_sw_transfer *std)
2233{
2222}
2223
2224static void
2225musbotg_root_ctrl_task(struct usb2_bus *bus)
2226{
2227 musbotg_root_ctrl_poll(MUSBOTG_BUS2SC(bus));
2228}
2229
2230static void
2231musbotg_root_ctrl_done(struct usb2_xfer *xfer,
2232 struct usb2_sw_transfer *std)
2233{
2234 struct musbotg_softc *sc = xfer->usb2_sc;
2234 struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
2235 uint16_t value;
2236 uint16_t index;
2237 uint8_t use_polling;
2238
2239 USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
2240
2241 if (std->state != USB_SW_TR_SETUP) {
2242 if (std->state == USB_SW_TR_PRE_CALLBACK) {
2243 /* transfer transferred */
2244 musbotg_device_done(xfer, std->err);
2245 }
2246 goto done;
2247 }
2248 /* buffer reset */
2249 std->ptr = USB_ADD_BYTES(&sc->sc_hub_temp, 0);
2250 std->len = 0;
2251
2252 value = UGETW(std->req.wValue);
2253 index = UGETW(std->req.wIndex);
2254
2235 uint16_t value;
2236 uint16_t index;
2237 uint8_t use_polling;
2238
2239 USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED);
2240
2241 if (std->state != USB_SW_TR_SETUP) {
2242 if (std->state == USB_SW_TR_PRE_CALLBACK) {
2243 /* transfer transferred */
2244 musbotg_device_done(xfer, std->err);
2245 }
2246 goto done;
2247 }
2248 /* buffer reset */
2249 std->ptr = USB_ADD_BYTES(&sc->sc_hub_temp, 0);
2250 std->len = 0;
2251
2252 value = UGETW(std->req.wValue);
2253 index = UGETW(std->req.wIndex);
2254
2255 use_polling = mtx_owned(xfer->xfer_mtx) ? 1 : 0;
2255 use_polling = mtx_owned(xfer->xroot->xfer_mtx) ? 1 : 0;
2256
2257 /* demultiplex the control request */
2258
2259 switch (std->req.bmRequestType) {
2260 case UT_READ_DEVICE:
2261 switch (std->req.bRequest) {
2262 case UR_GET_DESCRIPTOR:
2263 goto tr_handle_get_descriptor;
2264 case UR_GET_CONFIG:
2265 goto tr_handle_get_config;
2266 case UR_GET_STATUS:
2267 goto tr_handle_get_status;
2268 default:
2269 goto tr_stalled;
2270 }
2271 break;
2272
2273 case UT_WRITE_DEVICE:
2274 switch (std->req.bRequest) {
2275 case UR_SET_ADDRESS:
2276 goto tr_handle_set_address;
2277 case UR_SET_CONFIG:
2278 goto tr_handle_set_config;
2279 case UR_CLEAR_FEATURE:
2280 goto tr_valid; /* nop */
2281 case UR_SET_DESCRIPTOR:
2282 goto tr_valid; /* nop */
2283 case UR_SET_FEATURE:
2284 default:
2285 goto tr_stalled;
2286 }
2287 break;
2288
2289 case UT_WRITE_ENDPOINT:
2290 switch (std->req.bRequest) {
2291 case UR_CLEAR_FEATURE:
2292 switch (UGETW(std->req.wValue)) {
2293 case UF_ENDPOINT_HALT:
2294 goto tr_handle_clear_halt;
2295 case UF_DEVICE_REMOTE_WAKEUP:
2296 goto tr_handle_clear_wakeup;
2297 default:
2298 goto tr_stalled;
2299 }
2300 break;
2301 case UR_SET_FEATURE:
2302 switch (UGETW(std->req.wValue)) {
2303 case UF_ENDPOINT_HALT:
2304 goto tr_handle_set_halt;
2305 case UF_DEVICE_REMOTE_WAKEUP:
2306 goto tr_handle_set_wakeup;
2307 default:
2308 goto tr_stalled;
2309 }
2310 break;
2311 case UR_SYNCH_FRAME:
2312 goto tr_valid; /* nop */
2313 default:
2314 goto tr_stalled;
2315 }
2316 break;
2317
2318 case UT_READ_ENDPOINT:
2319 switch (std->req.bRequest) {
2320 case UR_GET_STATUS:
2321 goto tr_handle_get_ep_status;
2322 default:
2323 goto tr_stalled;
2324 }
2325 break;
2326
2327 case UT_WRITE_INTERFACE:
2328 switch (std->req.bRequest) {
2329 case UR_SET_INTERFACE:
2330 goto tr_handle_set_interface;
2331 case UR_CLEAR_FEATURE:
2332 goto tr_valid; /* nop */
2333 case UR_SET_FEATURE:
2334 default:
2335 goto tr_stalled;
2336 }
2337 break;
2338
2339 case UT_READ_INTERFACE:
2340 switch (std->req.bRequest) {
2341 case UR_GET_INTERFACE:
2342 goto tr_handle_get_interface;
2343 case UR_GET_STATUS:
2344 goto tr_handle_get_iface_status;
2345 default:
2346 goto tr_stalled;
2347 }
2348 break;
2349
2350 case UT_WRITE_CLASS_INTERFACE:
2351 case UT_WRITE_VENDOR_INTERFACE:
2352 /* XXX forward */
2353 break;
2354
2355 case UT_READ_CLASS_INTERFACE:
2356 case UT_READ_VENDOR_INTERFACE:
2357 /* XXX forward */
2358 break;
2359
2360 case UT_WRITE_CLASS_DEVICE:
2361 switch (std->req.bRequest) {
2362 case UR_CLEAR_FEATURE:
2363 goto tr_valid;
2364 case UR_SET_DESCRIPTOR:
2365 case UR_SET_FEATURE:
2366 break;
2367 default:
2368 goto tr_stalled;
2369 }
2370 break;
2371
2372 case UT_WRITE_CLASS_OTHER:
2373 switch (std->req.bRequest) {
2374 case UR_CLEAR_FEATURE:
2375 goto tr_handle_clear_port_feature;
2376 case UR_SET_FEATURE:
2377 goto tr_handle_set_port_feature;
2378 case UR_CLEAR_TT_BUFFER:
2379 case UR_RESET_TT:
2380 case UR_STOP_TT:
2381 goto tr_valid;
2382
2383 default:
2384 goto tr_stalled;
2385 }
2386 break;
2387
2388 case UT_READ_CLASS_OTHER:
2389 switch (std->req.bRequest) {
2390 case UR_GET_TT_STATE:
2391 goto tr_handle_get_tt_state;
2392 case UR_GET_STATUS:
2393 goto tr_handle_get_port_status;
2394 default:
2395 goto tr_stalled;
2396 }
2397 break;
2398
2399 case UT_READ_CLASS_DEVICE:
2400 switch (std->req.bRequest) {
2401 case UR_GET_DESCRIPTOR:
2402 goto tr_handle_get_class_descriptor;
2403 case UR_GET_STATUS:
2404 goto tr_handle_get_class_status;
2405
2406 default:
2407 goto tr_stalled;
2408 }
2409 break;
2410 default:
2411 goto tr_stalled;
2412 }
2413 goto tr_valid;
2414
2415tr_handle_get_descriptor:
2416 switch (value >> 8) {
2417 case UDESC_DEVICE:
2418 if (value & 0xff) {
2419 goto tr_stalled;
2420 }
2421 std->len = sizeof(musbotg_devd);
2422 std->ptr = USB_ADD_BYTES(&musbotg_devd, 0);
2423 goto tr_valid;
2424 case UDESC_CONFIG:
2425 if (value & 0xff) {
2426 goto tr_stalled;
2427 }
2428 std->len = sizeof(musbotg_confd);
2429 std->ptr = USB_ADD_BYTES(&musbotg_confd, 0);
2430 goto tr_valid;
2431 case UDESC_STRING:
2432 switch (value & 0xff) {
2433 case 0: /* Language table */
2434 std->len = sizeof(musbotg_langtab);
2435 std->ptr = USB_ADD_BYTES(&musbotg_langtab, 0);
2436 goto tr_valid;
2437
2438 case 1: /* Vendor */
2439 std->len = sizeof(musbotg_vendor);
2440 std->ptr = USB_ADD_BYTES(&musbotg_vendor, 0);
2441 goto tr_valid;
2442
2443 case 2: /* Product */
2444 std->len = sizeof(musbotg_product);
2445 std->ptr = USB_ADD_BYTES(&musbotg_product, 0);
2446 goto tr_valid;
2447 default:
2448 break;
2449 }
2450 break;
2451 default:
2452 goto tr_stalled;
2453 }
2454 goto tr_stalled;
2455
2456tr_handle_get_config:
2457 std->len = 1;
2458 sc->sc_hub_temp.wValue[0] = sc->sc_conf;
2459 goto tr_valid;
2460
2461tr_handle_get_status:
2462 std->len = 2;
2463 USETW(sc->sc_hub_temp.wValue, UDS_SELF_POWERED);
2464 goto tr_valid;
2465
2466tr_handle_set_address:
2467 if (value & 0xFF00) {
2468 goto tr_stalled;
2469 }
2470 sc->sc_rt_addr = value;
2471 goto tr_valid;
2472
2473tr_handle_set_config:
2474 if (value >= 2) {
2475 goto tr_stalled;
2476 }
2477 sc->sc_conf = value;
2478 goto tr_valid;
2479
2480tr_handle_get_interface:
2481 std->len = 1;
2482 sc->sc_hub_temp.wValue[0] = 0;
2483 goto tr_valid;
2484
2485tr_handle_get_tt_state:
2486tr_handle_get_class_status:
2487tr_handle_get_iface_status:
2488tr_handle_get_ep_status:
2489 std->len = 2;
2490 USETW(sc->sc_hub_temp.wValue, 0);
2491 goto tr_valid;
2492
2493tr_handle_set_halt:
2494tr_handle_set_interface:
2495tr_handle_set_wakeup:
2496tr_handle_clear_wakeup:
2497tr_handle_clear_halt:
2498 goto tr_valid;
2499
2500tr_handle_clear_port_feature:
2501 if (index != 1) {
2502 goto tr_stalled;
2503 }
2504 DPRINTFN(8, "UR_CLEAR_PORT_FEATURE on port %d\n", index);
2505
2506 switch (value) {
2507 case UHF_PORT_SUSPEND:
2508 musbotg_wakeup_peer(xfer);
2509 break;
2510
2511 case UHF_PORT_ENABLE:
2512 sc->sc_flags.port_enabled = 0;
2513 break;
2514
2515 case UHF_PORT_TEST:
2516 case UHF_PORT_INDICATOR:
2517 case UHF_C_PORT_ENABLE:
2518 case UHF_C_PORT_OVER_CURRENT:
2519 case UHF_C_PORT_RESET:
2520 /* nops */
2521 break;
2522 case UHF_PORT_POWER:
2523 sc->sc_flags.port_powered = 0;
2524 musbotg_pull_down(sc);
2525 musbotg_clocks_off(sc);
2526 break;
2527 case UHF_C_PORT_CONNECTION:
2528 sc->sc_flags.change_connect = 0;
2529 break;
2530 case UHF_C_PORT_SUSPEND:
2531 sc->sc_flags.change_suspend = 0;
2532 break;
2533 default:
2534 std->err = USB_ERR_IOERROR;
2535 goto done;
2536 }
2537 goto tr_valid;
2538
2539tr_handle_set_port_feature:
2540 if (index != 1) {
2541 goto tr_stalled;
2542 }
2543 DPRINTFN(8, "UR_SET_PORT_FEATURE\n");
2544
2545 switch (value) {
2546 case UHF_PORT_ENABLE:
2547 sc->sc_flags.port_enabled = 1;
2548 break;
2549 case UHF_PORT_SUSPEND:
2550 case UHF_PORT_RESET:
2551 case UHF_PORT_TEST:
2552 case UHF_PORT_INDICATOR:
2553 /* nops */
2554 break;
2555 case UHF_PORT_POWER:
2556 sc->sc_flags.port_powered = 1;
2557 break;
2558 default:
2559 std->err = USB_ERR_IOERROR;
2560 goto done;
2561 }
2562 goto tr_valid;
2563
2564tr_handle_get_port_status:
2565
2566 DPRINTFN(8, "UR_GET_PORT_STATUS\n");
2567
2568 if (index != 1) {
2569 goto tr_stalled;
2570 }
2571 if (sc->sc_flags.status_vbus) {
2572 musbotg_clocks_on(sc);
2573 musbotg_pull_up(sc);
2574 } else {
2575 musbotg_pull_down(sc);
2576 musbotg_clocks_off(sc);
2577 }
2578
2579 /* Select Device Side Mode */
2580 value = UPS_PORT_MODE_DEVICE;
2581
2582 if (sc->sc_flags.status_high_speed) {
2583 value |= UPS_HIGH_SPEED;
2584 }
2585 if (sc->sc_flags.port_powered) {
2586 value |= UPS_PORT_POWER;
2587 }
2588 if (sc->sc_flags.port_enabled) {
2589 value |= UPS_PORT_ENABLED;
2590 }
2591 if (sc->sc_flags.status_vbus &&
2592 sc->sc_flags.status_bus_reset) {
2593 value |= UPS_CURRENT_CONNECT_STATUS;
2594 }
2595 if (sc->sc_flags.status_suspend) {
2596 value |= UPS_SUSPEND;
2597 }
2598 USETW(sc->sc_hub_temp.ps.wPortStatus, value);
2599
2600 value = 0;
2601
2602 if (sc->sc_flags.change_connect) {
2603 value |= UPS_C_CONNECT_STATUS;
2604
2605 if (sc->sc_flags.status_vbus &&
2606 sc->sc_flags.status_bus_reset) {
2607 /* reset EP0 state */
2608 sc->sc_ep0_busy = 0;
2609 sc->sc_ep0_cmd = 0;
2610 }
2611 }
2612 if (sc->sc_flags.change_suspend) {
2613 value |= UPS_C_SUSPEND;
2614 }
2615 USETW(sc->sc_hub_temp.ps.wPortChange, value);
2616 std->len = sizeof(sc->sc_hub_temp.ps);
2617 goto tr_valid;
2618
2619tr_handle_get_class_descriptor:
2620 if (value & 0xFF) {
2621 goto tr_stalled;
2622 }
2623 std->ptr = USB_ADD_BYTES(&musbotg_hubd, 0);
2624 std->len = sizeof(musbotg_hubd);
2625 goto tr_valid;
2626
2627tr_stalled:
2628 std->err = USB_ERR_STALLED;
2629tr_valid:
2630done:
2631 return;
2632}
2633
2634static void
2635musbotg_root_ctrl_poll(struct musbotg_softc *sc)
2636{
2637 usb2_sw_transfer(&sc->sc_root_ctrl,
2638 &musbotg_root_ctrl_done);
2639}
2640
2641struct usb2_pipe_methods musbotg_root_ctrl_methods =
2642{
2643 .open = musbotg_root_ctrl_open,
2644 .close = musbotg_root_ctrl_close,
2645 .enter = musbotg_root_ctrl_enter,
2646 .start = musbotg_root_ctrl_start,
2647 .enter_is_cancelable = 1,
2648 .start_is_cancelable = 0,
2649};
2650
2651/*------------------------------------------------------------------------*
2652 * musbotg root interrupt support
2653 *------------------------------------------------------------------------*/
2654static void
2655musbotg_root_intr_open(struct usb2_xfer *xfer)
2656{
2657 return;
2658}
2659
2660static void
2661musbotg_root_intr_close(struct usb2_xfer *xfer)
2662{
2256
2257 /* demultiplex the control request */
2258
2259 switch (std->req.bmRequestType) {
2260 case UT_READ_DEVICE:
2261 switch (std->req.bRequest) {
2262 case UR_GET_DESCRIPTOR:
2263 goto tr_handle_get_descriptor;
2264 case UR_GET_CONFIG:
2265 goto tr_handle_get_config;
2266 case UR_GET_STATUS:
2267 goto tr_handle_get_status;
2268 default:
2269 goto tr_stalled;
2270 }
2271 break;
2272
2273 case UT_WRITE_DEVICE:
2274 switch (std->req.bRequest) {
2275 case UR_SET_ADDRESS:
2276 goto tr_handle_set_address;
2277 case UR_SET_CONFIG:
2278 goto tr_handle_set_config;
2279 case UR_CLEAR_FEATURE:
2280 goto tr_valid; /* nop */
2281 case UR_SET_DESCRIPTOR:
2282 goto tr_valid; /* nop */
2283 case UR_SET_FEATURE:
2284 default:
2285 goto tr_stalled;
2286 }
2287 break;
2288
2289 case UT_WRITE_ENDPOINT:
2290 switch (std->req.bRequest) {
2291 case UR_CLEAR_FEATURE:
2292 switch (UGETW(std->req.wValue)) {
2293 case UF_ENDPOINT_HALT:
2294 goto tr_handle_clear_halt;
2295 case UF_DEVICE_REMOTE_WAKEUP:
2296 goto tr_handle_clear_wakeup;
2297 default:
2298 goto tr_stalled;
2299 }
2300 break;
2301 case UR_SET_FEATURE:
2302 switch (UGETW(std->req.wValue)) {
2303 case UF_ENDPOINT_HALT:
2304 goto tr_handle_set_halt;
2305 case UF_DEVICE_REMOTE_WAKEUP:
2306 goto tr_handle_set_wakeup;
2307 default:
2308 goto tr_stalled;
2309 }
2310 break;
2311 case UR_SYNCH_FRAME:
2312 goto tr_valid; /* nop */
2313 default:
2314 goto tr_stalled;
2315 }
2316 break;
2317
2318 case UT_READ_ENDPOINT:
2319 switch (std->req.bRequest) {
2320 case UR_GET_STATUS:
2321 goto tr_handle_get_ep_status;
2322 default:
2323 goto tr_stalled;
2324 }
2325 break;
2326
2327 case UT_WRITE_INTERFACE:
2328 switch (std->req.bRequest) {
2329 case UR_SET_INTERFACE:
2330 goto tr_handle_set_interface;
2331 case UR_CLEAR_FEATURE:
2332 goto tr_valid; /* nop */
2333 case UR_SET_FEATURE:
2334 default:
2335 goto tr_stalled;
2336 }
2337 break;
2338
2339 case UT_READ_INTERFACE:
2340 switch (std->req.bRequest) {
2341 case UR_GET_INTERFACE:
2342 goto tr_handle_get_interface;
2343 case UR_GET_STATUS:
2344 goto tr_handle_get_iface_status;
2345 default:
2346 goto tr_stalled;
2347 }
2348 break;
2349
2350 case UT_WRITE_CLASS_INTERFACE:
2351 case UT_WRITE_VENDOR_INTERFACE:
2352 /* XXX forward */
2353 break;
2354
2355 case UT_READ_CLASS_INTERFACE:
2356 case UT_READ_VENDOR_INTERFACE:
2357 /* XXX forward */
2358 break;
2359
2360 case UT_WRITE_CLASS_DEVICE:
2361 switch (std->req.bRequest) {
2362 case UR_CLEAR_FEATURE:
2363 goto tr_valid;
2364 case UR_SET_DESCRIPTOR:
2365 case UR_SET_FEATURE:
2366 break;
2367 default:
2368 goto tr_stalled;
2369 }
2370 break;
2371
2372 case UT_WRITE_CLASS_OTHER:
2373 switch (std->req.bRequest) {
2374 case UR_CLEAR_FEATURE:
2375 goto tr_handle_clear_port_feature;
2376 case UR_SET_FEATURE:
2377 goto tr_handle_set_port_feature;
2378 case UR_CLEAR_TT_BUFFER:
2379 case UR_RESET_TT:
2380 case UR_STOP_TT:
2381 goto tr_valid;
2382
2383 default:
2384 goto tr_stalled;
2385 }
2386 break;
2387
2388 case UT_READ_CLASS_OTHER:
2389 switch (std->req.bRequest) {
2390 case UR_GET_TT_STATE:
2391 goto tr_handle_get_tt_state;
2392 case UR_GET_STATUS:
2393 goto tr_handle_get_port_status;
2394 default:
2395 goto tr_stalled;
2396 }
2397 break;
2398
2399 case UT_READ_CLASS_DEVICE:
2400 switch (std->req.bRequest) {
2401 case UR_GET_DESCRIPTOR:
2402 goto tr_handle_get_class_descriptor;
2403 case UR_GET_STATUS:
2404 goto tr_handle_get_class_status;
2405
2406 default:
2407 goto tr_stalled;
2408 }
2409 break;
2410 default:
2411 goto tr_stalled;
2412 }
2413 goto tr_valid;
2414
2415tr_handle_get_descriptor:
2416 switch (value >> 8) {
2417 case UDESC_DEVICE:
2418 if (value & 0xff) {
2419 goto tr_stalled;
2420 }
2421 std->len = sizeof(musbotg_devd);
2422 std->ptr = USB_ADD_BYTES(&musbotg_devd, 0);
2423 goto tr_valid;
2424 case UDESC_CONFIG:
2425 if (value & 0xff) {
2426 goto tr_stalled;
2427 }
2428 std->len = sizeof(musbotg_confd);
2429 std->ptr = USB_ADD_BYTES(&musbotg_confd, 0);
2430 goto tr_valid;
2431 case UDESC_STRING:
2432 switch (value & 0xff) {
2433 case 0: /* Language table */
2434 std->len = sizeof(musbotg_langtab);
2435 std->ptr = USB_ADD_BYTES(&musbotg_langtab, 0);
2436 goto tr_valid;
2437
2438 case 1: /* Vendor */
2439 std->len = sizeof(musbotg_vendor);
2440 std->ptr = USB_ADD_BYTES(&musbotg_vendor, 0);
2441 goto tr_valid;
2442
2443 case 2: /* Product */
2444 std->len = sizeof(musbotg_product);
2445 std->ptr = USB_ADD_BYTES(&musbotg_product, 0);
2446 goto tr_valid;
2447 default:
2448 break;
2449 }
2450 break;
2451 default:
2452 goto tr_stalled;
2453 }
2454 goto tr_stalled;
2455
2456tr_handle_get_config:
2457 std->len = 1;
2458 sc->sc_hub_temp.wValue[0] = sc->sc_conf;
2459 goto tr_valid;
2460
2461tr_handle_get_status:
2462 std->len = 2;
2463 USETW(sc->sc_hub_temp.wValue, UDS_SELF_POWERED);
2464 goto tr_valid;
2465
2466tr_handle_set_address:
2467 if (value & 0xFF00) {
2468 goto tr_stalled;
2469 }
2470 sc->sc_rt_addr = value;
2471 goto tr_valid;
2472
2473tr_handle_set_config:
2474 if (value >= 2) {
2475 goto tr_stalled;
2476 }
2477 sc->sc_conf = value;
2478 goto tr_valid;
2479
2480tr_handle_get_interface:
2481 std->len = 1;
2482 sc->sc_hub_temp.wValue[0] = 0;
2483 goto tr_valid;
2484
2485tr_handle_get_tt_state:
2486tr_handle_get_class_status:
2487tr_handle_get_iface_status:
2488tr_handle_get_ep_status:
2489 std->len = 2;
2490 USETW(sc->sc_hub_temp.wValue, 0);
2491 goto tr_valid;
2492
2493tr_handle_set_halt:
2494tr_handle_set_interface:
2495tr_handle_set_wakeup:
2496tr_handle_clear_wakeup:
2497tr_handle_clear_halt:
2498 goto tr_valid;
2499
2500tr_handle_clear_port_feature:
2501 if (index != 1) {
2502 goto tr_stalled;
2503 }
2504 DPRINTFN(8, "UR_CLEAR_PORT_FEATURE on port %d\n", index);
2505
2506 switch (value) {
2507 case UHF_PORT_SUSPEND:
2508 musbotg_wakeup_peer(xfer);
2509 break;
2510
2511 case UHF_PORT_ENABLE:
2512 sc->sc_flags.port_enabled = 0;
2513 break;
2514
2515 case UHF_PORT_TEST:
2516 case UHF_PORT_INDICATOR:
2517 case UHF_C_PORT_ENABLE:
2518 case UHF_C_PORT_OVER_CURRENT:
2519 case UHF_C_PORT_RESET:
2520 /* nops */
2521 break;
2522 case UHF_PORT_POWER:
2523 sc->sc_flags.port_powered = 0;
2524 musbotg_pull_down(sc);
2525 musbotg_clocks_off(sc);
2526 break;
2527 case UHF_C_PORT_CONNECTION:
2528 sc->sc_flags.change_connect = 0;
2529 break;
2530 case UHF_C_PORT_SUSPEND:
2531 sc->sc_flags.change_suspend = 0;
2532 break;
2533 default:
2534 std->err = USB_ERR_IOERROR;
2535 goto done;
2536 }
2537 goto tr_valid;
2538
2539tr_handle_set_port_feature:
2540 if (index != 1) {
2541 goto tr_stalled;
2542 }
2543 DPRINTFN(8, "UR_SET_PORT_FEATURE\n");
2544
2545 switch (value) {
2546 case UHF_PORT_ENABLE:
2547 sc->sc_flags.port_enabled = 1;
2548 break;
2549 case UHF_PORT_SUSPEND:
2550 case UHF_PORT_RESET:
2551 case UHF_PORT_TEST:
2552 case UHF_PORT_INDICATOR:
2553 /* nops */
2554 break;
2555 case UHF_PORT_POWER:
2556 sc->sc_flags.port_powered = 1;
2557 break;
2558 default:
2559 std->err = USB_ERR_IOERROR;
2560 goto done;
2561 }
2562 goto tr_valid;
2563
2564tr_handle_get_port_status:
2565
2566 DPRINTFN(8, "UR_GET_PORT_STATUS\n");
2567
2568 if (index != 1) {
2569 goto tr_stalled;
2570 }
2571 if (sc->sc_flags.status_vbus) {
2572 musbotg_clocks_on(sc);
2573 musbotg_pull_up(sc);
2574 } else {
2575 musbotg_pull_down(sc);
2576 musbotg_clocks_off(sc);
2577 }
2578
2579 /* Select Device Side Mode */
2580 value = UPS_PORT_MODE_DEVICE;
2581
2582 if (sc->sc_flags.status_high_speed) {
2583 value |= UPS_HIGH_SPEED;
2584 }
2585 if (sc->sc_flags.port_powered) {
2586 value |= UPS_PORT_POWER;
2587 }
2588 if (sc->sc_flags.port_enabled) {
2589 value |= UPS_PORT_ENABLED;
2590 }
2591 if (sc->sc_flags.status_vbus &&
2592 sc->sc_flags.status_bus_reset) {
2593 value |= UPS_CURRENT_CONNECT_STATUS;
2594 }
2595 if (sc->sc_flags.status_suspend) {
2596 value |= UPS_SUSPEND;
2597 }
2598 USETW(sc->sc_hub_temp.ps.wPortStatus, value);
2599
2600 value = 0;
2601
2602 if (sc->sc_flags.change_connect) {
2603 value |= UPS_C_CONNECT_STATUS;
2604
2605 if (sc->sc_flags.status_vbus &&
2606 sc->sc_flags.status_bus_reset) {
2607 /* reset EP0 state */
2608 sc->sc_ep0_busy = 0;
2609 sc->sc_ep0_cmd = 0;
2610 }
2611 }
2612 if (sc->sc_flags.change_suspend) {
2613 value |= UPS_C_SUSPEND;
2614 }
2615 USETW(sc->sc_hub_temp.ps.wPortChange, value);
2616 std->len = sizeof(sc->sc_hub_temp.ps);
2617 goto tr_valid;
2618
2619tr_handle_get_class_descriptor:
2620 if (value & 0xFF) {
2621 goto tr_stalled;
2622 }
2623 std->ptr = USB_ADD_BYTES(&musbotg_hubd, 0);
2624 std->len = sizeof(musbotg_hubd);
2625 goto tr_valid;
2626
2627tr_stalled:
2628 std->err = USB_ERR_STALLED;
2629tr_valid:
2630done:
2631 return;
2632}
2633
2634static void
2635musbotg_root_ctrl_poll(struct musbotg_softc *sc)
2636{
2637 usb2_sw_transfer(&sc->sc_root_ctrl,
2638 &musbotg_root_ctrl_done);
2639}
2640
2641struct usb2_pipe_methods musbotg_root_ctrl_methods =
2642{
2643 .open = musbotg_root_ctrl_open,
2644 .close = musbotg_root_ctrl_close,
2645 .enter = musbotg_root_ctrl_enter,
2646 .start = musbotg_root_ctrl_start,
2647 .enter_is_cancelable = 1,
2648 .start_is_cancelable = 0,
2649};
2650
2651/*------------------------------------------------------------------------*
2652 * musbotg root interrupt support
2653 *------------------------------------------------------------------------*/
2654static void
2655musbotg_root_intr_open(struct usb2_xfer *xfer)
2656{
2657 return;
2658}
2659
2660static void
2661musbotg_root_intr_close(struct usb2_xfer *xfer)
2662{
2663 struct musbotg_softc *sc = xfer->usb2_sc;
2663 struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
2664
2665 if (sc->sc_root_intr.xfer == xfer) {
2666 sc->sc_root_intr.xfer = NULL;
2667 }
2668 musbotg_device_done(xfer, USB_ERR_CANCELLED);
2669}
2670
2671static void
2672musbotg_root_intr_enter(struct usb2_xfer *xfer)
2673{
2674 return;
2675}
2676
2677static void
2678musbotg_root_intr_start(struct usb2_xfer *xfer)
2679{
2664
2665 if (sc->sc_root_intr.xfer == xfer) {
2666 sc->sc_root_intr.xfer = NULL;
2667 }
2668 musbotg_device_done(xfer, USB_ERR_CANCELLED);
2669}
2670
2671static void
2672musbotg_root_intr_enter(struct usb2_xfer *xfer)
2673{
2674 return;
2675}
2676
2677static void
2678musbotg_root_intr_start(struct usb2_xfer *xfer)
2679{
2680 struct musbotg_softc *sc = xfer->usb2_sc;
2680 struct musbotg_softc *sc = MUSBOTG_BUS2SC(xfer->xroot->bus);
2681
2682 sc->sc_root_intr.xfer = xfer;
2683}
2684
2685struct usb2_pipe_methods musbotg_root_intr_methods =
2686{
2687 .open = musbotg_root_intr_open,
2688 .close = musbotg_root_intr_close,
2689 .enter = musbotg_root_intr_enter,
2690 .start = musbotg_root_intr_start,
2691 .enter_is_cancelable = 1,
2692 .start_is_cancelable = 1,
2693};
2694
2695static void
2696musbotg_xfer_setup(struct usb2_setup_params *parm)
2697{
2698 const struct usb2_hw_ep_profile *pf;
2699 struct musbotg_softc *sc;
2700 struct usb2_xfer *xfer;
2701 void *last_obj;
2702 uint32_t ntd;
2703 uint32_t n;
2704 uint8_t ep_no;
2705
2706 sc = MUSBOTG_BUS2SC(parm->udev->bus);
2707 xfer = parm->curr_xfer;
2708
2709 /*
2681
2682 sc->sc_root_intr.xfer = xfer;
2683}
2684
2685struct usb2_pipe_methods musbotg_root_intr_methods =
2686{
2687 .open = musbotg_root_intr_open,
2688 .close = musbotg_root_intr_close,
2689 .enter = musbotg_root_intr_enter,
2690 .start = musbotg_root_intr_start,
2691 .enter_is_cancelable = 1,
2692 .start_is_cancelable = 1,
2693};
2694
2695static void
2696musbotg_xfer_setup(struct usb2_setup_params *parm)
2697{
2698 const struct usb2_hw_ep_profile *pf;
2699 struct musbotg_softc *sc;
2700 struct usb2_xfer *xfer;
2701 void *last_obj;
2702 uint32_t ntd;
2703 uint32_t n;
2704 uint8_t ep_no;
2705
2706 sc = MUSBOTG_BUS2SC(parm->udev->bus);
2707 xfer = parm->curr_xfer;
2708
2709 /*
2710 * setup xfer
2711 */
2712 xfer->usb2_sc = sc;
2713
2714 /*
2715 * NOTE: This driver does not use any of the parameters that
2716 * are computed from the following values. Just set some
2717 * reasonable dummies:
2718 */
2719 parm->hc_max_packet_size = 0x400;
2720 parm->hc_max_frame_size = 0x400;
2721
2722 if ((parm->methods == &musbotg_device_isoc_methods) ||
2723 (parm->methods == &musbotg_device_intr_methods))
2724 parm->hc_max_packet_count = 3;
2725 else
2726 parm->hc_max_packet_count = 1;
2727
2728 usb2_transfer_setup_sub(parm);
2729
2730 /*
2731 * compute maximum number of TDs
2732 */
2733 if (parm->methods == &musbotg_device_ctrl_methods) {
2734
2735 ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC */ ;
2736
2737 } else if (parm->methods == &musbotg_device_bulk_methods) {
2738
2739 ntd = xfer->nframes + 1 /* SYNC */ ;
2740
2741 } else if (parm->methods == &musbotg_device_intr_methods) {
2742
2743 ntd = xfer->nframes + 1 /* SYNC */ ;
2744
2745 } else if (parm->methods == &musbotg_device_isoc_methods) {
2746
2747 ntd = xfer->nframes + 1 /* SYNC */ ;
2748
2749 } else {
2750
2751 ntd = 0;
2752 }
2753
2754 /*
2755 * check if "usb2_transfer_setup_sub" set an error
2756 */
2757 if (parm->err) {
2758 return;
2759 }
2760 /*
2761 * allocate transfer descriptors
2762 */
2763 last_obj = NULL;
2764
2765 /*
2766 * get profile stuff
2767 */
2768 if (ntd) {
2769
2770 ep_no = xfer->endpoint & UE_ADDR;
2771 musbotg_get_hw_ep_profile(parm->udev, &pf, ep_no);
2772
2773 if (pf == NULL) {
2774 /* should not happen */
2775 parm->err = USB_ERR_INVAL;
2776 return;
2777 }
2778 } else {
2779 ep_no = 0;
2780 pf = NULL;
2781 }
2782
2783 /* align data */
2784 parm->size[0] += ((-parm->size[0]) & (USB_HOST_ALIGN - 1));
2785
2786 for (n = 0; n != ntd; n++) {
2787
2788 struct musbotg_td *td;
2789
2790 if (parm->buf) {
2791
2792 td = USB_ADD_BYTES(parm->buf, parm->size[0]);
2793
2794 /* init TD */
2795 td->max_frame_size = xfer->max_frame_size;
2796 td->ep_no = ep_no;
2797 td->obj_next = last_obj;
2798
2799 last_obj = td;
2800 }
2801 parm->size[0] += sizeof(*td);
2802 }
2803
2804 xfer->td_start[0] = last_obj;
2805}
2806
2807static void
2808musbotg_xfer_unsetup(struct usb2_xfer *xfer)
2809{
2810 return;
2811}
2812
2813static void
2814musbotg_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *edesc,
2815 struct usb2_pipe *pipe)
2816{
2817 struct musbotg_softc *sc = MUSBOTG_BUS2SC(udev->bus);
2818
2819 DPRINTFN(2, "pipe=%p, addr=%d, endpt=%d, mode=%d (%d)\n",
2820 pipe, udev->address,
2821 edesc->bEndpointAddress, udev->flags.usb2_mode,
2822 sc->sc_rt_addr);
2823
2824 if (udev->device_index == sc->sc_rt_addr) {
2825
2826 if (udev->flags.usb2_mode != USB_MODE_HOST) {
2827 /* not supported */
2828 return;
2829 }
2830 switch (edesc->bEndpointAddress) {
2831 case USB_CONTROL_ENDPOINT:
2832 pipe->methods = &musbotg_root_ctrl_methods;
2833 break;
2834 case UE_DIR_IN | MUSBOTG_INTR_ENDPT:
2835 pipe->methods = &musbotg_root_intr_methods;
2836 break;
2837 default:
2838 /* do nothing */
2839 break;
2840 }
2841 } else {
2842
2843 if (udev->flags.usb2_mode != USB_MODE_DEVICE) {
2844 /* not supported */
2845 return;
2846 }
2847 if ((udev->speed != USB_SPEED_FULL) &&
2848 (udev->speed != USB_SPEED_HIGH)) {
2849 /* not supported */
2850 return;
2851 }
2852 switch (edesc->bmAttributes & UE_XFERTYPE) {
2853 case UE_CONTROL:
2854 pipe->methods = &musbotg_device_ctrl_methods;
2855 break;
2856 case UE_INTERRUPT:
2857 pipe->methods = &musbotg_device_intr_methods;
2858 break;
2859 case UE_ISOCHRONOUS:
2860 pipe->methods = &musbotg_device_isoc_methods;
2861 break;
2862 case UE_BULK:
2863 pipe->methods = &musbotg_device_bulk_methods;
2864 break;
2865 default:
2866 /* do nothing */
2867 break;
2868 }
2869 }
2870}
2871
2872struct usb2_bus_methods musbotg_bus_methods =
2873{
2874 .pipe_init = &musbotg_pipe_init,
2875 .xfer_setup = &musbotg_xfer_setup,
2876 .xfer_unsetup = &musbotg_xfer_unsetup,
2877 .do_poll = &musbotg_do_poll,
2878 .get_hw_ep_profile = &musbotg_get_hw_ep_profile,
2879 .set_stall = &musbotg_set_stall,
2880 .clear_stall = &musbotg_clear_stall,
2881 .vbus_interrupt = &musbotg_vbus_interrupt,
2882 .roothub_exec = &musbotg_root_ctrl_task,
2883};
2710 * NOTE: This driver does not use any of the parameters that
2711 * are computed from the following values. Just set some
2712 * reasonable dummies:
2713 */
2714 parm->hc_max_packet_size = 0x400;
2715 parm->hc_max_frame_size = 0x400;
2716
2717 if ((parm->methods == &musbotg_device_isoc_methods) ||
2718 (parm->methods == &musbotg_device_intr_methods))
2719 parm->hc_max_packet_count = 3;
2720 else
2721 parm->hc_max_packet_count = 1;
2722
2723 usb2_transfer_setup_sub(parm);
2724
2725 /*
2726 * compute maximum number of TDs
2727 */
2728 if (parm->methods == &musbotg_device_ctrl_methods) {
2729
2730 ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC */ ;
2731
2732 } else if (parm->methods == &musbotg_device_bulk_methods) {
2733
2734 ntd = xfer->nframes + 1 /* SYNC */ ;
2735
2736 } else if (parm->methods == &musbotg_device_intr_methods) {
2737
2738 ntd = xfer->nframes + 1 /* SYNC */ ;
2739
2740 } else if (parm->methods == &musbotg_device_isoc_methods) {
2741
2742 ntd = xfer->nframes + 1 /* SYNC */ ;
2743
2744 } else {
2745
2746 ntd = 0;
2747 }
2748
2749 /*
2750 * check if "usb2_transfer_setup_sub" set an error
2751 */
2752 if (parm->err) {
2753 return;
2754 }
2755 /*
2756 * allocate transfer descriptors
2757 */
2758 last_obj = NULL;
2759
2760 /*
2761 * get profile stuff
2762 */
2763 if (ntd) {
2764
2765 ep_no = xfer->endpoint & UE_ADDR;
2766 musbotg_get_hw_ep_profile(parm->udev, &pf, ep_no);
2767
2768 if (pf == NULL) {
2769 /* should not happen */
2770 parm->err = USB_ERR_INVAL;
2771 return;
2772 }
2773 } else {
2774 ep_no = 0;
2775 pf = NULL;
2776 }
2777
2778 /* align data */
2779 parm->size[0] += ((-parm->size[0]) & (USB_HOST_ALIGN - 1));
2780
2781 for (n = 0; n != ntd; n++) {
2782
2783 struct musbotg_td *td;
2784
2785 if (parm->buf) {
2786
2787 td = USB_ADD_BYTES(parm->buf, parm->size[0]);
2788
2789 /* init TD */
2790 td->max_frame_size = xfer->max_frame_size;
2791 td->ep_no = ep_no;
2792 td->obj_next = last_obj;
2793
2794 last_obj = td;
2795 }
2796 parm->size[0] += sizeof(*td);
2797 }
2798
2799 xfer->td_start[0] = last_obj;
2800}
2801
2802static void
2803musbotg_xfer_unsetup(struct usb2_xfer *xfer)
2804{
2805 return;
2806}
2807
2808static void
2809musbotg_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *edesc,
2810 struct usb2_pipe *pipe)
2811{
2812 struct musbotg_softc *sc = MUSBOTG_BUS2SC(udev->bus);
2813
2814 DPRINTFN(2, "pipe=%p, addr=%d, endpt=%d, mode=%d (%d)\n",
2815 pipe, udev->address,
2816 edesc->bEndpointAddress, udev->flags.usb2_mode,
2817 sc->sc_rt_addr);
2818
2819 if (udev->device_index == sc->sc_rt_addr) {
2820
2821 if (udev->flags.usb2_mode != USB_MODE_HOST) {
2822 /* not supported */
2823 return;
2824 }
2825 switch (edesc->bEndpointAddress) {
2826 case USB_CONTROL_ENDPOINT:
2827 pipe->methods = &musbotg_root_ctrl_methods;
2828 break;
2829 case UE_DIR_IN | MUSBOTG_INTR_ENDPT:
2830 pipe->methods = &musbotg_root_intr_methods;
2831 break;
2832 default:
2833 /* do nothing */
2834 break;
2835 }
2836 } else {
2837
2838 if (udev->flags.usb2_mode != USB_MODE_DEVICE) {
2839 /* not supported */
2840 return;
2841 }
2842 if ((udev->speed != USB_SPEED_FULL) &&
2843 (udev->speed != USB_SPEED_HIGH)) {
2844 /* not supported */
2845 return;
2846 }
2847 switch (edesc->bmAttributes & UE_XFERTYPE) {
2848 case UE_CONTROL:
2849 pipe->methods = &musbotg_device_ctrl_methods;
2850 break;
2851 case UE_INTERRUPT:
2852 pipe->methods = &musbotg_device_intr_methods;
2853 break;
2854 case UE_ISOCHRONOUS:
2855 pipe->methods = &musbotg_device_isoc_methods;
2856 break;
2857 case UE_BULK:
2858 pipe->methods = &musbotg_device_bulk_methods;
2859 break;
2860 default:
2861 /* do nothing */
2862 break;
2863 }
2864 }
2865}
2866
2867struct usb2_bus_methods musbotg_bus_methods =
2868{
2869 .pipe_init = &musbotg_pipe_init,
2870 .xfer_setup = &musbotg_xfer_setup,
2871 .xfer_unsetup = &musbotg_xfer_unsetup,
2872 .do_poll = &musbotg_do_poll,
2873 .get_hw_ep_profile = &musbotg_get_hw_ep_profile,
2874 .set_stall = &musbotg_set_stall,
2875 .clear_stall = &musbotg_clear_stall,
2876 .vbus_interrupt = &musbotg_vbus_interrupt,
2877 .roothub_exec = &musbotg_root_ctrl_task,
2878};