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