1 1.43 riastrad /* $NetBSD: motg.c,v 1.43 2024/04/05 18:57:10 riastradh Exp $ */ 2 1.1 bouyer 3 1.1 bouyer /* 4 1.1 bouyer * Copyright (c) 1998, 2004, 2011, 2012, 2014 The NetBSD Foundation, Inc. 5 1.1 bouyer * All rights reserved. 6 1.1 bouyer * 7 1.1 bouyer * This code is derived from software contributed to The NetBSD Foundation 8 1.1 bouyer * by Lennart Augustsson (lennart (at) augustsson.net) at 9 1.1 bouyer * Carlstedt Research & Technology, Jared D. McNeill (jmcneill (at) invisible.ca), 10 1.42 mrg * Matthew R. Green (mrg (at) eterna23.net), and Manuel Bouyer (bouyer (at) netbsd.org). 11 1.1 bouyer * 12 1.1 bouyer * Redistribution and use in source and binary forms, with or without 13 1.1 bouyer * modification, are permitted provided that the following conditions 14 1.1 bouyer * are met: 15 1.1 bouyer * 1. Redistributions of source code must retain the above copyright 16 1.1 bouyer * notice, this list of conditions and the following disclaimer. 17 1.1 bouyer * 2. Redistributions in binary form must reproduce the above copyright 18 1.1 bouyer * notice, this list of conditions and the following disclaimer in the 19 1.1 bouyer * documentation and/or other materials provided with the distribution. 20 1.1 bouyer * 21 1.1 bouyer * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 1.1 bouyer * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 1.1 bouyer * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 1.1 bouyer * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 1.1 bouyer * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 1.1 bouyer * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 1.1 bouyer * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 1.1 bouyer * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 1.1 bouyer * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 1.1 bouyer * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 1.1 bouyer * POSSIBILITY OF SUCH DAMAGE. 32 1.1 bouyer */ 33 1.1 bouyer 34 1.1 bouyer 35 1.1 bouyer /* 36 1.1 bouyer * This file contains the driver for the Mentor Graphics Inventra USB 37 1.1 bouyer * 2.0 High Speed Dual-Role controller. 38 1.1 bouyer * 39 1.1 bouyer * NOTE: The current implementation only supports Device Side Mode! 40 1.1 bouyer */ 41 1.1 bouyer 42 1.14 skrll #include <sys/cdefs.h> 43 1.43 riastrad __KERNEL_RCSID(0, "$NetBSD: motg.c,v 1.43 2024/04/05 18:57:10 riastradh Exp $"); 44 1.14 skrll 45 1.14 skrll #ifdef _KERNEL_OPT 46 1.14 skrll #include "opt_usb.h" 47 1.14 skrll #endif 48 1.10 jmcneill 49 1.14 skrll #include <sys/param.h> 50 1.1 bouyer 51 1.14 skrll #include <sys/bus.h> 52 1.14 skrll #include <sys/cpu.h> 53 1.14 skrll #include <sys/device.h> 54 1.1 bouyer #include <sys/kernel.h> 55 1.1 bouyer #include <sys/kmem.h> 56 1.1 bouyer #include <sys/proc.h> 57 1.1 bouyer #include <sys/queue.h> 58 1.14 skrll #include <sys/select.h> 59 1.14 skrll #include <sys/sysctl.h> 60 1.14 skrll #include <sys/systm.h> 61 1.1 bouyer 62 1.1 bouyer #include <machine/endian.h> 63 1.1 bouyer 64 1.1 bouyer #include <dev/usb/usb.h> 65 1.1 bouyer #include <dev/usb/usbdi.h> 66 1.1 bouyer #include <dev/usb/usbdivar.h> 67 1.1 bouyer #include <dev/usb/usb_mem.h> 68 1.14 skrll #include <dev/usb/usbhist.h> 69 1.1 bouyer 70 1.1 bouyer #include <dev/usb/motgreg.h> 71 1.1 bouyer #include <dev/usb/motgvar.h> 72 1.14 skrll #include <dev/usb/usbroothub.h> 73 1.14 skrll 74 1.14 skrll #ifdef USB_DEBUG 75 1.14 skrll #ifndef MOTG_DEBUG 76 1.14 skrll #define motgdebug 0 77 1.14 skrll #else 78 1.14 skrll int motgdebug = 0; 79 1.14 skrll 80 1.14 skrll SYSCTL_SETUP(sysctl_hw_motg_setup, "sysctl hw.motg setup") 81 1.14 skrll { 82 1.14 skrll int err; 83 1.14 skrll const struct sysctlnode *rnode; 84 1.14 skrll const struct sysctlnode *cnode; 85 1.14 skrll 86 1.14 skrll err = sysctl_createv(clog, 0, NULL, &rnode, 87 1.14 skrll CTLFLAG_PERMANENT, CTLTYPE_NODE, "motg", 88 1.14 skrll SYSCTL_DESCR("motg global controls"), 89 1.14 skrll NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); 90 1.14 skrll 91 1.14 skrll if (err) 92 1.14 skrll goto fail; 93 1.14 skrll 94 1.14 skrll /* control debugging printfs */ 95 1.14 skrll err = sysctl_createv(clog, 0, &rnode, &cnode, 96 1.14 skrll CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 97 1.14 skrll "debug", SYSCTL_DESCR("Enable debugging output"), 98 1.14 skrll NULL, 0, &motgdebug, sizeof(motgdebug), CTL_CREATE, CTL_EOL); 99 1.14 skrll if (err) 100 1.14 skrll goto fail; 101 1.14 skrll 102 1.14 skrll return; 103 1.14 skrll fail: 104 1.14 skrll aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err); 105 1.14 skrll } 106 1.14 skrll 107 1.14 skrll #endif /* MOTG_DEBUG */ 108 1.14 skrll #endif /* USB_DEBUG */ 109 1.1 bouyer 110 1.1 bouyer #define MD_ROOT 0x0002 111 1.1 bouyer #define MD_CTRL 0x0004 112 1.1 bouyer #define MD_BULK 0x0008 113 1.14 skrll 114 1.14 skrll #define DPRINTF(FMT,A,B,C,D) USBHIST_LOGN(motgdebug,1,FMT,A,B,C,D) 115 1.14 skrll #define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGM(motgdebug,N,FMT,A,B,C,D) 116 1.14 skrll #define MOTGHIST_FUNC() USBHIST_FUNC() 117 1.14 skrll #define MOTGHIST_CALLED(name) USBHIST_CALLED(motgdebug) 118 1.14 skrll 119 1.1 bouyer 120 1.1 bouyer /* various timeouts, for various speeds */ 121 1.1 bouyer /* control NAK timeouts */ 122 1.1 bouyer #define NAK_TO_CTRL 10 /* 1024 frames, about 1s */ 123 1.1 bouyer #define NAK_TO_CTRL_HIGH 13 /* 8k microframes, about 0.8s */ 124 1.1 bouyer 125 1.1 bouyer /* intr/iso polling intervals */ 126 1.1 bouyer #define POLL_TO 100 /* 100 frames, about 0.1s */ 127 1.1 bouyer #define POLL_TO_HIGH 10 /* 100 microframes, about 0.12s */ 128 1.1 bouyer 129 1.1 bouyer /* bulk NAK timeouts */ 130 1.3 bouyer #define NAK_TO_BULK 0 /* disabled */ 131 1.3 bouyer #define NAK_TO_BULK_HIGH 0 132 1.1 bouyer 133 1.1 bouyer static void motg_hub_change(struct motg_softc *); 134 1.1 bouyer 135 1.14 skrll static usbd_status motg_root_intr_transfer(struct usbd_xfer *); 136 1.14 skrll static usbd_status motg_root_intr_start(struct usbd_xfer *); 137 1.14 skrll static void motg_root_intr_abort(struct usbd_xfer *); 138 1.14 skrll static void motg_root_intr_close(struct usbd_pipe *); 139 1.14 skrll static void motg_root_intr_done(struct usbd_xfer *); 140 1.14 skrll 141 1.14 skrll static usbd_status motg_open(struct usbd_pipe *); 142 1.1 bouyer static void motg_poll(struct usbd_bus *); 143 1.1 bouyer static void motg_softintr(void *); 144 1.14 skrll static struct usbd_xfer * 145 1.14 skrll motg_allocx(struct usbd_bus *, unsigned int); 146 1.14 skrll static void motg_freex(struct usbd_bus *, struct usbd_xfer *); 147 1.26 riastrad static bool motg_dying(struct usbd_bus *); 148 1.1 bouyer static void motg_get_lock(struct usbd_bus *, kmutex_t **); 149 1.14 skrll static int motg_roothub_ctrl(struct usbd_bus *, usb_device_request_t *, 150 1.14 skrll void *, int); 151 1.14 skrll 152 1.14 skrll static void motg_noop(struct usbd_pipe *pipe); 153 1.1 bouyer static usbd_status motg_portreset(struct motg_softc*); 154 1.1 bouyer 155 1.14 skrll static usbd_status motg_device_ctrl_transfer(struct usbd_xfer *); 156 1.14 skrll static usbd_status motg_device_ctrl_start(struct usbd_xfer *); 157 1.14 skrll static void motg_device_ctrl_abort(struct usbd_xfer *); 158 1.14 skrll static void motg_device_ctrl_close(struct usbd_pipe *); 159 1.14 skrll static void motg_device_ctrl_done(struct usbd_xfer *); 160 1.1 bouyer static usbd_status motg_device_ctrl_start1(struct motg_softc *); 161 1.14 skrll static void motg_device_ctrl_read(struct usbd_xfer *); 162 1.1 bouyer static void motg_device_ctrl_intr_rx(struct motg_softc *); 163 1.1 bouyer static void motg_device_ctrl_intr_tx(struct motg_softc *); 164 1.1 bouyer 165 1.14 skrll static usbd_status motg_device_data_transfer(struct usbd_xfer *); 166 1.14 skrll static usbd_status motg_device_data_start(struct usbd_xfer *); 167 1.1 bouyer static usbd_status motg_device_data_start1(struct motg_softc *, 168 1.1 bouyer struct motg_hw_ep *); 169 1.14 skrll static void motg_device_data_abort(struct usbd_xfer *); 170 1.14 skrll static void motg_device_data_close(struct usbd_pipe *); 171 1.14 skrll static void motg_device_data_done(struct usbd_xfer *); 172 1.1 bouyer static void motg_device_intr_rx(struct motg_softc *, int); 173 1.1 bouyer static void motg_device_intr_tx(struct motg_softc *, int); 174 1.14 skrll static void motg_device_data_read(struct usbd_xfer *); 175 1.14 skrll static void motg_device_data_write(struct usbd_xfer *); 176 1.1 bouyer 177 1.14 skrll static void motg_device_clear_toggle(struct usbd_pipe *); 178 1.26 riastrad static void motg_abortx(struct usbd_xfer *); 179 1.1 bouyer 180 1.1 bouyer #define UBARR(sc) bus_space_barrier((sc)->sc_iot, (sc)->sc_ioh, 0, (sc)->sc_size, \ 181 1.1 bouyer BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE) 182 1.1 bouyer #define UWRITE1(sc, r, x) \ 183 1.1 bouyer do { UBARR(sc); bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (r), (x)); \ 184 1.1 bouyer } while (/*CONSTCOND*/0) 185 1.1 bouyer #define UWRITE2(sc, r, x) \ 186 1.1 bouyer do { UBARR(sc); bus_space_write_2((sc)->sc_iot, (sc)->sc_ioh, (r), (x)); \ 187 1.1 bouyer } while (/*CONSTCOND*/0) 188 1.1 bouyer #define UWRITE4(sc, r, x) \ 189 1.1 bouyer do { UBARR(sc); bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (r), (x)); \ 190 1.1 bouyer } while (/*CONSTCOND*/0) 191 1.1 bouyer 192 1.1 bouyer static __inline uint32_t 193 1.1 bouyer UREAD1(struct motg_softc *sc, bus_size_t r) 194 1.1 bouyer { 195 1.1 bouyer 196 1.1 bouyer UBARR(sc); 197 1.1 bouyer return bus_space_read_1(sc->sc_iot, sc->sc_ioh, r); 198 1.1 bouyer } 199 1.1 bouyer static __inline uint32_t 200 1.1 bouyer UREAD2(struct motg_softc *sc, bus_size_t r) 201 1.1 bouyer { 202 1.1 bouyer 203 1.1 bouyer UBARR(sc); 204 1.1 bouyer return bus_space_read_2(sc->sc_iot, sc->sc_ioh, r); 205 1.1 bouyer } 206 1.4 joerg 207 1.4 joerg #if 0 208 1.1 bouyer static __inline uint32_t 209 1.1 bouyer UREAD4(struct motg_softc *sc, bus_size_t r) 210 1.1 bouyer { 211 1.1 bouyer 212 1.1 bouyer UBARR(sc); 213 1.1 bouyer return bus_space_read_4(sc->sc_iot, sc->sc_ioh, r); 214 1.1 bouyer } 215 1.4 joerg #endif 216 1.1 bouyer 217 1.1 bouyer static void 218 1.7 skrll musbotg_pull_common(struct motg_softc *sc, uint8_t on) 219 1.1 bouyer { 220 1.14 skrll uint8_t val; 221 1.1 bouyer 222 1.14 skrll val = UREAD1(sc, MUSB2_REG_POWER); 223 1.14 skrll if (on) 224 1.14 skrll val |= MUSB2_MASK_SOFTC; 225 1.14 skrll else 226 1.14 skrll val &= ~MUSB2_MASK_SOFTC; 227 1.1 bouyer 228 1.14 skrll UWRITE1(sc, MUSB2_REG_POWER, val); 229 1.1 bouyer } 230 1.1 bouyer 231 1.1 bouyer const struct usbd_bus_methods motg_bus_methods = { 232 1.14 skrll .ubm_open = motg_open, 233 1.14 skrll .ubm_softint = motg_softintr, 234 1.14 skrll .ubm_dopoll = motg_poll, 235 1.14 skrll .ubm_allocx = motg_allocx, 236 1.14 skrll .ubm_freex = motg_freex, 237 1.26 riastrad .ubm_abortx = motg_abortx, 238 1.26 riastrad .ubm_dying = motg_dying, 239 1.14 skrll .ubm_getlock = motg_get_lock, 240 1.14 skrll .ubm_rhctrl = motg_roothub_ctrl, 241 1.1 bouyer }; 242 1.1 bouyer 243 1.1 bouyer const struct usbd_pipe_methods motg_root_intr_methods = { 244 1.14 skrll .upm_transfer = motg_root_intr_transfer, 245 1.14 skrll .upm_start = motg_root_intr_start, 246 1.14 skrll .upm_abort = motg_root_intr_abort, 247 1.14 skrll .upm_close = motg_root_intr_close, 248 1.14 skrll .upm_cleartoggle = motg_noop, 249 1.14 skrll .upm_done = motg_root_intr_done, 250 1.1 bouyer }; 251 1.1 bouyer 252 1.1 bouyer const struct usbd_pipe_methods motg_device_ctrl_methods = { 253 1.14 skrll .upm_transfer = motg_device_ctrl_transfer, 254 1.14 skrll .upm_start = motg_device_ctrl_start, 255 1.14 skrll .upm_abort = motg_device_ctrl_abort, 256 1.14 skrll .upm_close = motg_device_ctrl_close, 257 1.14 skrll .upm_cleartoggle = motg_noop, 258 1.14 skrll .upm_done = motg_device_ctrl_done, 259 1.1 bouyer }; 260 1.1 bouyer 261 1.1 bouyer const struct usbd_pipe_methods motg_device_data_methods = { 262 1.14 skrll .upm_transfer = motg_device_data_transfer, 263 1.14 skrll .upm_start = motg_device_data_start, 264 1.14 skrll .upm_abort = motg_device_data_abort, 265 1.14 skrll .upm_close = motg_device_data_close, 266 1.14 skrll .upm_cleartoggle = motg_device_clear_toggle, 267 1.14 skrll .upm_done = motg_device_data_done, 268 1.1 bouyer }; 269 1.1 bouyer 270 1.14 skrll int 271 1.1 bouyer motg_init(struct motg_softc *sc) 272 1.1 bouyer { 273 1.1 bouyer uint32_t nrx, ntx, val; 274 1.1 bouyer int dynfifo; 275 1.1 bouyer int offset, i; 276 1.1 bouyer 277 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 278 1.14 skrll 279 1.1 bouyer if (sc->sc_mode == MOTG_MODE_DEVICE) 280 1.14 skrll return ENOTSUP; /* not supported */ 281 1.1 bouyer 282 1.1 bouyer /* disable all interrupts */ 283 1.1 bouyer UWRITE1(sc, MUSB2_REG_INTUSBE, 0); 284 1.1 bouyer UWRITE2(sc, MUSB2_REG_INTTXE, 0); 285 1.1 bouyer UWRITE2(sc, MUSB2_REG_INTRXE, 0); 286 1.1 bouyer /* disable pullup */ 287 1.1 bouyer 288 1.7 skrll musbotg_pull_common(sc, 0); 289 1.1 bouyer 290 1.10 jmcneill #ifdef MUSB2_REG_RXDBDIS 291 1.1 bouyer /* disable double packet buffering XXX what's this ? */ 292 1.1 bouyer UWRITE2(sc, MUSB2_REG_RXDBDIS, 0xFFFF); 293 1.1 bouyer UWRITE2(sc, MUSB2_REG_TXDBDIS, 0xFFFF); 294 1.10 jmcneill #endif 295 1.1 bouyer 296 1.1 bouyer /* enable HighSpeed and ISO Update flags */ 297 1.1 bouyer 298 1.1 bouyer UWRITE1(sc, MUSB2_REG_POWER, 299 1.1 bouyer MUSB2_MASK_HSENAB | MUSB2_MASK_ISOUPD); 300 1.1 bouyer 301 1.1 bouyer if (sc->sc_mode == MOTG_MODE_DEVICE) { 302 1.1 bouyer /* clear Session bit, if set */ 303 1.1 bouyer val = UREAD1(sc, MUSB2_REG_DEVCTL); 304 1.1 bouyer val &= ~MUSB2_MASK_SESS; 305 1.1 bouyer UWRITE1(sc, MUSB2_REG_DEVCTL, val); 306 1.1 bouyer } else { 307 1.1 bouyer /* Enter session for Host mode */ 308 1.1 bouyer val = UREAD1(sc, MUSB2_REG_DEVCTL); 309 1.1 bouyer val |= MUSB2_MASK_SESS; 310 1.1 bouyer UWRITE1(sc, MUSB2_REG_DEVCTL, val); 311 1.1 bouyer } 312 1.1 bouyer delay(1000); 313 1.34 christos DPRINTF("DEVCTL %#jx", UREAD1(sc, MUSB2_REG_DEVCTL), 0, 0, 0); 314 1.1 bouyer 315 1.1 bouyer /* disable testmode */ 316 1.1 bouyer 317 1.1 bouyer UWRITE1(sc, MUSB2_REG_TESTMODE, 0); 318 1.1 bouyer 319 1.10 jmcneill #ifdef MUSB2_REG_MISC 320 1.7 skrll /* set default value */ 321 1.1 bouyer 322 1.1 bouyer UWRITE1(sc, MUSB2_REG_MISC, 0); 323 1.10 jmcneill #endif 324 1.1 bouyer 325 1.7 skrll /* select endpoint index 0 */ 326 1.1 bouyer 327 1.1 bouyer UWRITE1(sc, MUSB2_REG_EPINDEX, 0); 328 1.1 bouyer 329 1.9 jmcneill if (sc->sc_ep_max == 0) { 330 1.9 jmcneill /* read out number of endpoints */ 331 1.9 jmcneill nrx = (UREAD1(sc, MUSB2_REG_EPINFO) / 16); 332 1.1 bouyer 333 1.9 jmcneill ntx = (UREAD1(sc, MUSB2_REG_EPINFO) % 16); 334 1.1 bouyer 335 1.9 jmcneill /* these numbers exclude the control endpoint */ 336 1.1 bouyer 337 1.18 pgoyette DPRINTFN(1,"RX/TX endpoints: %ju/%ju", nrx, ntx, 0, 0); 338 1.1 bouyer 339 1.9 jmcneill sc->sc_ep_max = MAX(nrx, ntx); 340 1.9 jmcneill } else { 341 1.9 jmcneill nrx = ntx = sc->sc_ep_max; 342 1.9 jmcneill } 343 1.1 bouyer if (sc->sc_ep_max == 0) { 344 1.1 bouyer aprint_error_dev(sc->sc_dev, " no endpoints\n"); 345 1.14 skrll return -1; 346 1.1 bouyer } 347 1.1 bouyer KASSERT(sc->sc_ep_max <= MOTG_MAX_HW_EP); 348 1.1 bouyer /* read out configuration data */ 349 1.1 bouyer val = UREAD1(sc, MUSB2_REG_CONFDATA); 350 1.1 bouyer 351 1.35 christos DPRINTF("Config Data: 0x%02jx", val, 0, 0, 0); 352 1.1 bouyer 353 1.1 bouyer dynfifo = (val & MUSB2_MASK_CD_DYNFIFOSZ) ? 1 : 0; 354 1.1 bouyer 355 1.7 skrll if (dynfifo) { 356 1.1 bouyer aprint_normal_dev(sc->sc_dev, "Dynamic FIFO sizing detected, " 357 1.1 bouyer "assuming 16Kbytes of FIFO RAM\n"); 358 1.7 skrll } 359 1.7 skrll 360 1.35 christos DPRINTF("HW version: 0x%04jx\n", UREAD1(sc, MUSB2_REG_HWVERS), 0, 0, 0); 361 1.1 bouyer 362 1.1 bouyer /* initialise endpoint profiles */ 363 1.1 bouyer sc->sc_in_ep[0].ep_fifo_size = 64; 364 1.1 bouyer sc->sc_out_ep[0].ep_fifo_size = 0; /* not used */ 365 1.1 bouyer sc->sc_out_ep[0].ep_number = sc->sc_in_ep[0].ep_number = 0; 366 1.1 bouyer SIMPLEQ_INIT(&sc->sc_in_ep[0].ep_pipes); 367 1.1 bouyer offset = 64; 368 1.1 bouyer 369 1.1 bouyer for (i = 1; i <= sc->sc_ep_max; i++) { 370 1.1 bouyer int fiforx_size, fifotx_size, fifo_size; 371 1.1 bouyer 372 1.7 skrll /* select endpoint */ 373 1.1 bouyer UWRITE1(sc, MUSB2_REG_EPINDEX, i); 374 1.1 bouyer 375 1.11 jmcneill if (sc->sc_ep_fifosize) { 376 1.11 jmcneill fiforx_size = fifotx_size = sc->sc_ep_fifosize; 377 1.11 jmcneill } else { 378 1.11 jmcneill val = UREAD1(sc, MUSB2_REG_FSIZE); 379 1.11 jmcneill fiforx_size = (val & MUSB2_MASK_RX_FSIZE) >> 4; 380 1.11 jmcneill fifotx_size = (val & MUSB2_MASK_TX_FSIZE); 381 1.11 jmcneill } 382 1.1 bouyer 383 1.18 pgoyette DPRINTF("Endpoint %ju FIFO size: IN=%ju, OUT=%ju, DYN=%jd", 384 1.14 skrll i, fifotx_size, fiforx_size, dynfifo); 385 1.1 bouyer 386 1.1 bouyer if (dynfifo) { 387 1.12 jmcneill if (sc->sc_ep_fifosize) { 388 1.12 jmcneill fifo_size = ffs(sc->sc_ep_fifosize) - 1; 389 1.1 bouyer } else { 390 1.12 jmcneill if (i < 3) { 391 1.12 jmcneill fifo_size = 12; /* 4K */ 392 1.12 jmcneill } else if (i < 10) { 393 1.12 jmcneill fifo_size = 10; /* 1K */ 394 1.12 jmcneill } else { 395 1.12 jmcneill fifo_size = 7; /* 128 bytes */ 396 1.12 jmcneill } 397 1.7 skrll } 398 1.1 bouyer if (fiforx_size && (i <= nrx)) { 399 1.1 bouyer fiforx_size = fifo_size; 400 1.1 bouyer if (fifo_size > 7) { 401 1.3 bouyer #if 0 402 1.7 skrll UWRITE1(sc, MUSB2_REG_RXFIFOSZ, 403 1.1 bouyer MUSB2_VAL_FIFOSZ(fifo_size) | 404 1.1 bouyer MUSB2_MASK_FIFODB); 405 1.3 bouyer #else 406 1.7 skrll UWRITE1(sc, MUSB2_REG_RXFIFOSZ, 407 1.3 bouyer MUSB2_VAL_FIFOSZ(fifo_size)); 408 1.3 bouyer #endif 409 1.1 bouyer } else { 410 1.7 skrll UWRITE1(sc, MUSB2_REG_RXFIFOSZ, 411 1.3 bouyer MUSB2_VAL_FIFOSZ(fifo_size)); 412 1.1 bouyer } 413 1.7 skrll UWRITE2(sc, MUSB2_REG_RXFIFOADD, 414 1.1 bouyer offset >> 3); 415 1.1 bouyer offset += (1 << fiforx_size); 416 1.1 bouyer } 417 1.1 bouyer if (fifotx_size && (i <= ntx)) { 418 1.1 bouyer fifotx_size = fifo_size; 419 1.1 bouyer if (fifo_size > 7) { 420 1.3 bouyer #if 0 421 1.7 skrll UWRITE1(sc, MUSB2_REG_TXFIFOSZ, 422 1.7 skrll MUSB2_VAL_FIFOSZ(fifo_size) | 423 1.1 bouyer MUSB2_MASK_FIFODB); 424 1.3 bouyer #else 425 1.7 skrll UWRITE1(sc, MUSB2_REG_TXFIFOSZ, 426 1.7 skrll MUSB2_VAL_FIFOSZ(fifo_size)); 427 1.3 bouyer #endif 428 1.1 bouyer } else { 429 1.7 skrll UWRITE1(sc, MUSB2_REG_TXFIFOSZ, 430 1.7 skrll MUSB2_VAL_FIFOSZ(fifo_size)); 431 1.7 skrll } 432 1.7 skrll 433 1.7 skrll UWRITE2(sc, MUSB2_REG_TXFIFOADD, 434 1.1 bouyer offset >> 3); 435 1.7 skrll 436 1.1 bouyer offset += (1 << fifotx_size); 437 1.1 bouyer } 438 1.1 bouyer } 439 1.1 bouyer if (fiforx_size && (i <= nrx)) { 440 1.1 bouyer sc->sc_in_ep[i].ep_fifo_size = (1 << fiforx_size); 441 1.1 bouyer SIMPLEQ_INIT(&sc->sc_in_ep[i].ep_pipes); 442 1.1 bouyer } 443 1.1 bouyer if (fifotx_size && (i <= ntx)) { 444 1.1 bouyer sc->sc_out_ep[i].ep_fifo_size = (1 << fifotx_size); 445 1.1 bouyer SIMPLEQ_INIT(&sc->sc_out_ep[i].ep_pipes); 446 1.1 bouyer } 447 1.1 bouyer sc->sc_out_ep[i].ep_number = sc->sc_in_ep[i].ep_number = i; 448 1.1 bouyer } 449 1.1 bouyer 450 1.7 skrll 451 1.18 pgoyette DPRINTF("Dynamic FIFO size = %jd bytes", offset, 0, 0, 0); 452 1.1 bouyer 453 1.1 bouyer /* turn on default interrupts */ 454 1.1 bouyer 455 1.1 bouyer if (sc->sc_mode == MOTG_MODE_HOST) { 456 1.1 bouyer UWRITE1(sc, MUSB2_REG_INTUSBE, 0xff); 457 1.1 bouyer UWRITE2(sc, MUSB2_REG_INTTXE, 0xffff); 458 1.1 bouyer UWRITE2(sc, MUSB2_REG_INTRXE, 0xffff); 459 1.1 bouyer } else 460 1.1 bouyer UWRITE1(sc, MUSB2_REG_INTUSBE, MUSB2_MASK_IRESET); 461 1.1 bouyer 462 1.1 bouyer sc->sc_xferpool = pool_cache_init(sizeof(struct motg_xfer), 0, 0, 0, 463 1.1 bouyer "motgxfer", NULL, IPL_USB, NULL, NULL, NULL); 464 1.1 bouyer 465 1.1 bouyer mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); 466 1.13 skrll mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB); 467 1.1 bouyer 468 1.1 bouyer /* Set up the bus struct. */ 469 1.14 skrll sc->sc_bus.ub_methods = &motg_bus_methods; 470 1.14 skrll sc->sc_bus.ub_pipesize= sizeof(struct motg_pipe); 471 1.14 skrll sc->sc_bus.ub_revision = USBREV_2_0; 472 1.14 skrll sc->sc_bus.ub_usedma = false; 473 1.14 skrll sc->sc_bus.ub_hcpriv = sc; 474 1.36 thorpej sc->sc_child = config_found(sc->sc_dev, &sc->sc_bus, usbctlprint, 475 1.37 thorpej CFARGS_NONE); 476 1.14 skrll return 0; 477 1.1 bouyer } 478 1.1 bouyer 479 1.1 bouyer static int 480 1.14 skrll motg_select_ep(struct motg_softc *sc, struct usbd_pipe *pipe) 481 1.1 bouyer { 482 1.14 skrll struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(pipe); 483 1.14 skrll usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc; 484 1.1 bouyer struct motg_hw_ep *ep; 485 1.1 bouyer int i, size; 486 1.1 bouyer 487 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 488 1.14 skrll 489 1.1 bouyer ep = (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN) ? 490 1.1 bouyer sc->sc_in_ep : sc->sc_out_ep; 491 1.14 skrll size = UE_GET_SIZE(UGETW(pipe->up_endpoint->ue_edesc->wMaxPacketSize)); 492 1.1 bouyer 493 1.1 bouyer for (i = sc->sc_ep_max; i >= 1; i--) { 494 1.14 skrll DPRINTF(UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN ? 495 1.18 pgoyette "in_ep[%jd].ep_fifo_size %jd size %jd ref %jd" : 496 1.18 pgoyette "out_ep[%jd].ep_fifo_size %jd size %jd ref %jd", i, 497 1.14 skrll ep[i].ep_fifo_size, size, ep[i].refcount); 498 1.1 bouyer if (ep[i].ep_fifo_size >= size) { 499 1.1 bouyer /* found a suitable endpoint */ 500 1.1 bouyer otgpipe->hw_ep = &ep[i]; 501 1.1 bouyer mutex_enter(&sc->sc_lock); 502 1.1 bouyer if (otgpipe->hw_ep->refcount > 0) { 503 1.1 bouyer /* no luck, try next */ 504 1.1 bouyer mutex_exit(&sc->sc_lock); 505 1.1 bouyer otgpipe->hw_ep = NULL; 506 1.1 bouyer } else { 507 1.1 bouyer otgpipe->hw_ep->refcount++; 508 1.1 bouyer SIMPLEQ_INSERT_TAIL(&otgpipe->hw_ep->ep_pipes, 509 1.1 bouyer otgpipe, ep_pipe_list); 510 1.1 bouyer mutex_exit(&sc->sc_lock); 511 1.1 bouyer return 0; 512 1.1 bouyer } 513 1.1 bouyer } 514 1.1 bouyer } 515 1.1 bouyer return -1; 516 1.1 bouyer } 517 1.1 bouyer 518 1.1 bouyer /* Open a new pipe. */ 519 1.1 bouyer usbd_status 520 1.14 skrll motg_open(struct usbd_pipe *pipe) 521 1.1 bouyer { 522 1.14 skrll struct motg_softc *sc = MOTG_PIPE2SC(pipe); 523 1.14 skrll struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(pipe); 524 1.14 skrll usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc; 525 1.14 skrll uint8_t rhaddr = pipe->up_dev->ud_bus->ub_rhaddr; 526 1.14 skrll 527 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 528 1.14 skrll 529 1.18 pgoyette DPRINTF("pipe=%#jx, addr=%jd, endpt=%jd (%jd)", (uintptr_t)pipe, 530 1.14 skrll pipe->up_dev->ud_addr, ed->bEndpointAddress, rhaddr); 531 1.1 bouyer 532 1.1 bouyer if (sc->sc_dying) 533 1.1 bouyer return USBD_IOERROR; 534 1.1 bouyer 535 1.1 bouyer /* toggle state needed for bulk endpoints */ 536 1.14 skrll otgpipe->nexttoggle = pipe->up_endpoint->ue_toggle; 537 1.1 bouyer 538 1.14 skrll if (pipe->up_dev->ud_addr == rhaddr) { 539 1.1 bouyer switch (ed->bEndpointAddress) { 540 1.1 bouyer case USB_CONTROL_ENDPOINT: 541 1.14 skrll pipe->up_methods = &roothub_ctrl_methods; 542 1.1 bouyer break; 543 1.14 skrll case UE_DIR_IN | USBROOTHUB_INTR_ENDPT: 544 1.14 skrll pipe->up_methods = &motg_root_intr_methods; 545 1.1 bouyer break; 546 1.1 bouyer default: 547 1.14 skrll return USBD_INVAL; 548 1.1 bouyer } 549 1.1 bouyer } else { 550 1.1 bouyer switch (ed->bmAttributes & UE_XFERTYPE) { 551 1.1 bouyer case UE_CONTROL: 552 1.14 skrll pipe->up_methods = &motg_device_ctrl_methods; 553 1.1 bouyer /* always use sc_in_ep[0] for in and out */ 554 1.1 bouyer otgpipe->hw_ep = &sc->sc_in_ep[0]; 555 1.1 bouyer mutex_enter(&sc->sc_lock); 556 1.1 bouyer otgpipe->hw_ep->refcount++; 557 1.1 bouyer SIMPLEQ_INSERT_TAIL(&otgpipe->hw_ep->ep_pipes, 558 1.1 bouyer otgpipe, ep_pipe_list); 559 1.1 bouyer mutex_exit(&sc->sc_lock); 560 1.1 bouyer break; 561 1.1 bouyer case UE_BULK: 562 1.1 bouyer case UE_INTERRUPT: 563 1.7 skrll DPRINTFN(MD_BULK, 564 1.18 pgoyette "type %jd dir %jd pipe wMaxPacketSize %jd", 565 1.14 skrll UE_GET_XFERTYPE(ed->bmAttributes), 566 1.14 skrll UE_GET_DIR(pipe->up_endpoint->ue_edesc->bEndpointAddress), 567 1.14 skrll UGETW(pipe->up_endpoint->ue_edesc->wMaxPacketSize), 0); 568 1.1 bouyer if (motg_select_ep(sc, pipe) != 0) 569 1.1 bouyer goto bad; 570 1.1 bouyer KASSERT(otgpipe->hw_ep != NULL); 571 1.14 skrll pipe->up_methods = &motg_device_data_methods; 572 1.14 skrll otgpipe->nexttoggle = pipe->up_endpoint->ue_toggle; 573 1.1 bouyer break; 574 1.1 bouyer default: 575 1.1 bouyer goto bad; 576 1.1 bouyer #ifdef notyet 577 1.1 bouyer case UE_ISOCHRONOUS: 578 1.1 bouyer ... 579 1.1 bouyer break; 580 1.1 bouyer #endif /* notyet */ 581 1.1 bouyer } 582 1.1 bouyer } 583 1.14 skrll return USBD_NORMAL_COMPLETION; 584 1.1 bouyer 585 1.1 bouyer bad: 586 1.14 skrll return USBD_NOMEM; 587 1.1 bouyer } 588 1.1 bouyer 589 1.1 bouyer void 590 1.1 bouyer motg_softintr(void *v) 591 1.1 bouyer { 592 1.1 bouyer struct usbd_bus *bus = v; 593 1.14 skrll struct motg_softc *sc = MOTG_BUS2SC(bus); 594 1.1 bouyer uint16_t rx_status, tx_status; 595 1.1 bouyer uint8_t ctrl_status; 596 1.1 bouyer uint32_t val; 597 1.1 bouyer int i; 598 1.1 bouyer 599 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 600 1.1 bouyer 601 1.14 skrll KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 602 1.14 skrll 603 1.18 pgoyette DPRINTFN(MD_ROOT | MD_CTRL, "sc %#jx", (uintptr_t)sc, 0 ,0 ,0); 604 1.1 bouyer 605 1.1 bouyer mutex_spin_enter(&sc->sc_intr_lock); 606 1.1 bouyer rx_status = sc->sc_intr_rx_ep; 607 1.1 bouyer sc->sc_intr_rx_ep = 0; 608 1.1 bouyer tx_status = sc->sc_intr_tx_ep; 609 1.1 bouyer sc->sc_intr_tx_ep = 0; 610 1.1 bouyer ctrl_status = sc->sc_intr_ctrl; 611 1.1 bouyer sc->sc_intr_ctrl = 0; 612 1.1 bouyer mutex_spin_exit(&sc->sc_intr_lock); 613 1.1 bouyer 614 1.1 bouyer ctrl_status |= UREAD1(sc, MUSB2_REG_INTUSB); 615 1.1 bouyer 616 1.1 bouyer if (ctrl_status & (MUSB2_MASK_IRESET | 617 1.1 bouyer MUSB2_MASK_IRESUME | MUSB2_MASK_ISUSP | 618 1.1 bouyer MUSB2_MASK_ICONN | MUSB2_MASK_IDISC)) { 619 1.34 christos DPRINTFN(MD_ROOT | MD_CTRL, "bus %#jx", ctrl_status, 0, 0, 0); 620 1.1 bouyer 621 1.1 bouyer if (ctrl_status & MUSB2_MASK_IRESET) { 622 1.1 bouyer sc->sc_isreset = 1; 623 1.1 bouyer sc->sc_port_suspended = 0; 624 1.1 bouyer sc->sc_port_suspended_change = 1; 625 1.1 bouyer sc->sc_connected_changed = 1; 626 1.1 bouyer sc->sc_port_enabled = 1; 627 1.1 bouyer 628 1.1 bouyer val = UREAD1(sc, MUSB2_REG_POWER); 629 1.1 bouyer if (val & MUSB2_MASK_HSMODE) 630 1.1 bouyer sc->sc_high_speed = 1; 631 1.1 bouyer else 632 1.1 bouyer sc->sc_high_speed = 0; 633 1.18 pgoyette DPRINTFN(MD_ROOT | MD_CTRL, "speed %jd", sc->sc_high_speed, 634 1.14 skrll 0, 0, 0); 635 1.1 bouyer 636 1.1 bouyer /* turn off interrupts */ 637 1.1 bouyer val = MUSB2_MASK_IRESET; 638 1.1 bouyer val &= ~MUSB2_MASK_IRESUME; 639 1.1 bouyer val |= MUSB2_MASK_ISUSP; 640 1.1 bouyer UWRITE1(sc, MUSB2_REG_INTUSBE, val); 641 1.1 bouyer UWRITE2(sc, MUSB2_REG_INTTXE, 0); 642 1.1 bouyer UWRITE2(sc, MUSB2_REG_INTRXE, 0); 643 1.1 bouyer } 644 1.1 bouyer if (ctrl_status & MUSB2_MASK_IRESUME) { 645 1.1 bouyer if (sc->sc_port_suspended) { 646 1.1 bouyer sc->sc_port_suspended = 0; 647 1.1 bouyer sc->sc_port_suspended_change = 1; 648 1.1 bouyer val = UREAD1(sc, MUSB2_REG_INTUSBE); 649 1.1 bouyer /* disable resume interrupt */ 650 1.1 bouyer val &= ~MUSB2_MASK_IRESUME; 651 1.1 bouyer /* enable suspend interrupt */ 652 1.1 bouyer val |= MUSB2_MASK_ISUSP; 653 1.1 bouyer UWRITE1(sc, MUSB2_REG_INTUSBE, val); 654 1.1 bouyer } 655 1.1 bouyer } else if (ctrl_status & MUSB2_MASK_ISUSP) { 656 1.1 bouyer if (!sc->sc_port_suspended) { 657 1.1 bouyer sc->sc_port_suspended = 1; 658 1.1 bouyer sc->sc_port_suspended_change = 1; 659 1.1 bouyer 660 1.1 bouyer val = UREAD1(sc, MUSB2_REG_INTUSBE); 661 1.1 bouyer /* disable suspend interrupt */ 662 1.1 bouyer val &= ~MUSB2_MASK_ISUSP; 663 1.1 bouyer /* enable resume interrupt */ 664 1.1 bouyer val |= MUSB2_MASK_IRESUME; 665 1.1 bouyer UWRITE1(sc, MUSB2_REG_INTUSBE, val); 666 1.1 bouyer } 667 1.1 bouyer } 668 1.1 bouyer if (ctrl_status & MUSB2_MASK_ICONN) { 669 1.1 bouyer sc->sc_connected = 1; 670 1.1 bouyer sc->sc_connected_changed = 1; 671 1.1 bouyer sc->sc_isreset = 1; 672 1.1 bouyer sc->sc_port_enabled = 1; 673 1.1 bouyer } else if (ctrl_status & MUSB2_MASK_IDISC) { 674 1.1 bouyer sc->sc_connected = 0; 675 1.1 bouyer sc->sc_connected_changed = 1; 676 1.1 bouyer sc->sc_isreset = 0; 677 1.1 bouyer sc->sc_port_enabled = 0; 678 1.1 bouyer } 679 1.1 bouyer 680 1.1 bouyer /* complete root HUB interrupt endpoint */ 681 1.1 bouyer 682 1.1 bouyer motg_hub_change(sc); 683 1.1 bouyer } 684 1.1 bouyer /* 685 1.1 bouyer * read in interrupt status and mix with the status we 686 1.1 bouyer * got from the wrapper 687 1.1 bouyer */ 688 1.1 bouyer rx_status |= UREAD2(sc, MUSB2_REG_INTRX); 689 1.1 bouyer tx_status |= UREAD2(sc, MUSB2_REG_INTTX); 690 1.1 bouyer 691 1.14 skrll KASSERTMSG((rx_status & 0x01) == 0, "ctrl_rx %08x", rx_status); 692 1.1 bouyer if (tx_status & 0x01) 693 1.1 bouyer motg_device_ctrl_intr_tx(sc); 694 1.1 bouyer for (i = 1; i <= sc->sc_ep_max; i++) { 695 1.1 bouyer if (rx_status & (0x01 << i)) 696 1.1 bouyer motg_device_intr_rx(sc, i); 697 1.1 bouyer if (tx_status & (0x01 << i)) 698 1.1 bouyer motg_device_intr_tx(sc, i); 699 1.1 bouyer } 700 1.1 bouyer return; 701 1.1 bouyer } 702 1.1 bouyer 703 1.1 bouyer void 704 1.1 bouyer motg_poll(struct usbd_bus *bus) 705 1.1 bouyer { 706 1.14 skrll struct motg_softc *sc = MOTG_BUS2SC(bus); 707 1.1 bouyer 708 1.1 bouyer sc->sc_intr_poll(sc->sc_intr_poll_arg); 709 1.1 bouyer mutex_enter(&sc->sc_lock); 710 1.1 bouyer motg_softintr(bus); 711 1.1 bouyer mutex_exit(&sc->sc_lock); 712 1.1 bouyer } 713 1.1 bouyer 714 1.1 bouyer int 715 1.1 bouyer motg_intr(struct motg_softc *sc, uint16_t rx_ep, uint16_t tx_ep, 716 1.2 bouyer uint8_t ctrl) 717 1.1 bouyer { 718 1.1 bouyer KASSERT(mutex_owned(&sc->sc_intr_lock)); 719 1.1 bouyer sc->sc_intr_tx_ep = tx_ep; 720 1.1 bouyer sc->sc_intr_rx_ep = rx_ep; 721 1.1 bouyer sc->sc_intr_ctrl = ctrl; 722 1.1 bouyer 723 1.14 skrll if (!sc->sc_bus.ub_usepolling) { 724 1.1 bouyer usb_schedsoftintr(&sc->sc_bus); 725 1.1 bouyer } 726 1.1 bouyer return 1; 727 1.1 bouyer } 728 1.1 bouyer 729 1.2 bouyer int 730 1.2 bouyer motg_intr_vbus(struct motg_softc *sc, int vbus) 731 1.2 bouyer { 732 1.2 bouyer uint8_t val; 733 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 734 1.14 skrll 735 1.2 bouyer if (sc->sc_mode == MOTG_MODE_HOST && vbus == 0) { 736 1.14 skrll DPRINTF("vbus down, try to re-enable", 0, 0, 0, 0); 737 1.2 bouyer /* try to re-enter session for Host mode */ 738 1.2 bouyer val = UREAD1(sc, MUSB2_REG_DEVCTL); 739 1.2 bouyer val |= MUSB2_MASK_SESS; 740 1.2 bouyer UWRITE1(sc, MUSB2_REG_DEVCTL, val); 741 1.2 bouyer } 742 1.2 bouyer return 1; 743 1.2 bouyer } 744 1.2 bouyer 745 1.14 skrll struct usbd_xfer * 746 1.14 skrll motg_allocx(struct usbd_bus *bus, unsigned int nframes) 747 1.1 bouyer { 748 1.14 skrll struct motg_softc *sc = MOTG_BUS2SC(bus); 749 1.14 skrll struct usbd_xfer *xfer; 750 1.1 bouyer 751 1.19 skrll xfer = pool_cache_get(sc->sc_xferpool, PR_WAITOK); 752 1.1 bouyer if (xfer != NULL) { 753 1.1 bouyer memset(xfer, 0, sizeof(struct motg_xfer)); 754 1.1 bouyer #ifdef DIAGNOSTIC 755 1.14 skrll xfer->ux_state = XFER_BUSY; 756 1.1 bouyer #endif 757 1.1 bouyer } 758 1.14 skrll return xfer; 759 1.1 bouyer } 760 1.1 bouyer 761 1.1 bouyer void 762 1.14 skrll motg_freex(struct usbd_bus *bus, struct usbd_xfer *xfer) 763 1.1 bouyer { 764 1.14 skrll struct motg_softc *sc = MOTG_BUS2SC(bus); 765 1.1 bouyer 766 1.1 bouyer #ifdef DIAGNOSTIC 767 1.25 rin if (xfer->ux_state != XFER_BUSY && 768 1.25 rin xfer->ux_status != USBD_NOT_STARTED) { 769 1.35 christos printf("motg_freex: xfer=%p not busy, 0x%08x\n", xfer, 770 1.14 skrll xfer->ux_state); 771 1.1 bouyer } 772 1.14 skrll xfer->ux_state = XFER_FREE; 773 1.1 bouyer #endif 774 1.1 bouyer pool_cache_put(sc->sc_xferpool, xfer); 775 1.1 bouyer } 776 1.1 bouyer 777 1.26 riastrad static bool 778 1.26 riastrad motg_dying(struct usbd_bus *bus) 779 1.26 riastrad { 780 1.26 riastrad struct motg_softc *sc = MOTG_BUS2SC(bus); 781 1.26 riastrad 782 1.26 riastrad return sc->sc_dying; 783 1.26 riastrad } 784 1.26 riastrad 785 1.1 bouyer static void 786 1.1 bouyer motg_get_lock(struct usbd_bus *bus, kmutex_t **lock) 787 1.1 bouyer { 788 1.14 skrll struct motg_softc *sc = MOTG_BUS2SC(bus); 789 1.1 bouyer 790 1.1 bouyer *lock = &sc->sc_lock; 791 1.1 bouyer } 792 1.1 bouyer 793 1.1 bouyer /* 794 1.14 skrll * Routines to emulate the root hub. 795 1.1 bouyer */ 796 1.14 skrll Static int 797 1.14 skrll motg_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, 798 1.14 skrll void *buf, int buflen) 799 1.14 skrll { 800 1.14 skrll struct motg_softc *sc = MOTG_BUS2SC(bus); 801 1.14 skrll int status, change, totlen = 0; 802 1.14 skrll uint16_t len, value, index; 803 1.1 bouyer usb_port_status_t ps; 804 1.1 bouyer usbd_status err; 805 1.1 bouyer uint32_t val; 806 1.1 bouyer 807 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 808 1.14 skrll 809 1.1 bouyer if (sc->sc_dying) 810 1.14 skrll return -1; 811 1.1 bouyer 812 1.35 christos DPRINTFN(MD_ROOT, "type=0x%02jx request=%02jx", req->bmRequestType, 813 1.14 skrll req->bRequest, 0, 0); 814 1.1 bouyer 815 1.1 bouyer len = UGETW(req->wLength); 816 1.1 bouyer value = UGETW(req->wValue); 817 1.1 bouyer index = UGETW(req->wIndex); 818 1.1 bouyer 819 1.1 bouyer #define C(x,y) ((x) | ((y) << 8)) 820 1.14 skrll switch (C(req->bRequest, req->bmRequestType)) { 821 1.14 skrll case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): 822 1.35 christos DPRINTFN(MD_ROOT, "wValue=0x%04jx", value, 0, 0, 0); 823 1.14 skrll switch (value) { 824 1.14 skrll #define sd ((usb_string_descriptor_t *)buf) 825 1.14 skrll case C(2, UDESC_STRING): 826 1.14 skrll /* Product */ 827 1.14 skrll totlen = usb_makestrdesc(sd, len, "MOTG root hub"); 828 1.1 bouyer break; 829 1.1 bouyer #undef sd 830 1.1 bouyer default: 831 1.14 skrll /* default from usbroothub */ 832 1.14 skrll return buflen; 833 1.1 bouyer } 834 1.1 bouyer break; 835 1.1 bouyer /* Hub requests */ 836 1.1 bouyer case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE): 837 1.1 bouyer break; 838 1.1 bouyer case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER): 839 1.1 bouyer DPRINTFN(MD_ROOT, 840 1.18 pgoyette "UR_CLEAR_PORT_FEATURE port=%jd feature=%jd", index, value, 841 1.14 skrll 0, 0); 842 1.1 bouyer if (index != 1) { 843 1.14 skrll return -1; 844 1.1 bouyer } 845 1.14 skrll switch (value) { 846 1.1 bouyer case UHF_PORT_ENABLE: 847 1.1 bouyer sc->sc_port_enabled = 0; 848 1.1 bouyer break; 849 1.1 bouyer case UHF_PORT_SUSPEND: 850 1.1 bouyer if (sc->sc_port_suspended != 0) { 851 1.1 bouyer val = UREAD1(sc, MUSB2_REG_POWER); 852 1.1 bouyer val &= ~MUSB2_MASK_SUSPMODE; 853 1.1 bouyer val |= MUSB2_MASK_RESUME; 854 1.1 bouyer UWRITE1(sc, MUSB2_REG_POWER, val); 855 1.1 bouyer /* wait 20 milliseconds */ 856 1.1 bouyer usb_delay_ms(&sc->sc_bus, 20); 857 1.1 bouyer val = UREAD1(sc, MUSB2_REG_POWER); 858 1.1 bouyer val &= ~MUSB2_MASK_RESUME; 859 1.1 bouyer UWRITE1(sc, MUSB2_REG_POWER, val); 860 1.1 bouyer sc->sc_port_suspended = 0; 861 1.1 bouyer sc->sc_port_suspended_change = 1; 862 1.1 bouyer } 863 1.1 bouyer break; 864 1.1 bouyer case UHF_PORT_RESET: 865 1.1 bouyer break; 866 1.1 bouyer case UHF_C_PORT_CONNECTION: 867 1.1 bouyer break; 868 1.1 bouyer case UHF_C_PORT_ENABLE: 869 1.1 bouyer break; 870 1.1 bouyer case UHF_C_PORT_OVER_CURRENT: 871 1.1 bouyer break; 872 1.1 bouyer case UHF_C_PORT_RESET: 873 1.1 bouyer sc->sc_isreset = 0; 874 1.14 skrll break; 875 1.1 bouyer case UHF_PORT_POWER: 876 1.1 bouyer /* XXX todo */ 877 1.1 bouyer break; 878 1.1 bouyer case UHF_PORT_CONNECTION: 879 1.1 bouyer case UHF_PORT_OVER_CURRENT: 880 1.1 bouyer case UHF_PORT_LOW_SPEED: 881 1.1 bouyer case UHF_C_PORT_SUSPEND: 882 1.1 bouyer default: 883 1.14 skrll return -1; 884 1.1 bouyer } 885 1.1 bouyer break; 886 1.1 bouyer case C(UR_GET_BUS_STATE, UT_READ_CLASS_OTHER): 887 1.14 skrll return -1; 888 1.1 bouyer case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE): 889 1.1 bouyer if (len == 0) 890 1.1 bouyer break; 891 1.1 bouyer if ((value & 0xff) != 0) { 892 1.14 skrll return -1; 893 1.1 bouyer } 894 1.14 skrll totlen = buflen; 895 1.1 bouyer break; 896 1.1 bouyer case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE): 897 1.1 bouyer if (len != 4) { 898 1.14 skrll return -1; 899 1.1 bouyer } 900 1.1 bouyer memset(buf, 0, len); 901 1.1 bouyer totlen = len; 902 1.1 bouyer break; 903 1.1 bouyer case C(UR_GET_STATUS, UT_READ_CLASS_OTHER): 904 1.1 bouyer if (index != 1) { 905 1.14 skrll return -1; 906 1.1 bouyer } 907 1.1 bouyer if (len != 4) { 908 1.14 skrll return -1; 909 1.1 bouyer } 910 1.1 bouyer status = change = 0; 911 1.1 bouyer if (sc->sc_connected) 912 1.1 bouyer status |= UPS_CURRENT_CONNECT_STATUS; 913 1.1 bouyer if (sc->sc_connected_changed) { 914 1.1 bouyer change |= UPS_C_CONNECT_STATUS; 915 1.1 bouyer sc->sc_connected_changed = 0; 916 1.1 bouyer } 917 1.1 bouyer if (sc->sc_port_enabled) 918 1.1 bouyer status |= UPS_PORT_ENABLED; 919 1.1 bouyer if (sc->sc_port_enabled_changed) { 920 1.1 bouyer change |= UPS_C_PORT_ENABLED; 921 1.1 bouyer sc->sc_port_enabled_changed = 0; 922 1.1 bouyer } 923 1.1 bouyer if (sc->sc_port_suspended) 924 1.1 bouyer status |= UPS_SUSPEND; 925 1.1 bouyer if (sc->sc_high_speed) 926 1.1 bouyer status |= UPS_HIGH_SPEED; 927 1.1 bouyer status |= UPS_PORT_POWER; /* XXX */ 928 1.1 bouyer if (sc->sc_isreset) 929 1.1 bouyer change |= UPS_C_PORT_RESET; 930 1.1 bouyer USETW(ps.wPortStatus, status); 931 1.1 bouyer USETW(ps.wPortChange, change); 932 1.23 riastrad totlen = uimin(len, sizeof(ps)); 933 1.14 skrll memcpy(buf, &ps, totlen); 934 1.1 bouyer break; 935 1.1 bouyer case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE): 936 1.14 skrll return -1; 937 1.1 bouyer case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE): 938 1.1 bouyer break; 939 1.1 bouyer case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER): 940 1.1 bouyer if (index != 1) { 941 1.14 skrll return -1; 942 1.1 bouyer } 943 1.1 bouyer switch(value) { 944 1.1 bouyer case UHF_PORT_ENABLE: 945 1.1 bouyer sc->sc_port_enabled = 1; 946 1.1 bouyer break; 947 1.1 bouyer case UHF_PORT_SUSPEND: 948 1.1 bouyer if (sc->sc_port_suspended == 0) { 949 1.1 bouyer val = UREAD1(sc, MUSB2_REG_POWER); 950 1.1 bouyer val |= MUSB2_MASK_SUSPMODE; 951 1.1 bouyer UWRITE1(sc, MUSB2_REG_POWER, val); 952 1.1 bouyer /* wait 20 milliseconds */ 953 1.1 bouyer usb_delay_ms(&sc->sc_bus, 20); 954 1.1 bouyer sc->sc_port_suspended = 1; 955 1.1 bouyer sc->sc_port_suspended_change = 1; 956 1.1 bouyer } 957 1.1 bouyer break; 958 1.1 bouyer case UHF_PORT_RESET: 959 1.1 bouyer err = motg_portreset(sc); 960 1.14 skrll if (err != USBD_NORMAL_COMPLETION) 961 1.14 skrll return -1; 962 1.14 skrll return 0; 963 1.1 bouyer case UHF_PORT_POWER: 964 1.1 bouyer /* XXX todo */ 965 1.14 skrll return 0; 966 1.1 bouyer case UHF_C_PORT_CONNECTION: 967 1.1 bouyer case UHF_C_PORT_ENABLE: 968 1.1 bouyer case UHF_C_PORT_OVER_CURRENT: 969 1.1 bouyer case UHF_PORT_CONNECTION: 970 1.1 bouyer case UHF_PORT_OVER_CURRENT: 971 1.1 bouyer case UHF_PORT_LOW_SPEED: 972 1.1 bouyer case UHF_C_PORT_SUSPEND: 973 1.1 bouyer case UHF_C_PORT_RESET: 974 1.1 bouyer default: 975 1.14 skrll return -1; 976 1.1 bouyer } 977 1.1 bouyer break; 978 1.1 bouyer default: 979 1.14 skrll /* default from usbroothub */ 980 1.14 skrll return buflen; 981 1.1 bouyer } 982 1.1 bouyer 983 1.14 skrll return totlen; 984 1.1 bouyer } 985 1.1 bouyer 986 1.1 bouyer /* Abort a root interrupt request. */ 987 1.1 bouyer void 988 1.14 skrll motg_root_intr_abort(struct usbd_xfer *xfer) 989 1.1 bouyer { 990 1.14 skrll struct motg_softc *sc = MOTG_XFER2SC(xfer); 991 1.1 bouyer 992 1.1 bouyer KASSERT(mutex_owned(&sc->sc_lock)); 993 1.14 skrll KASSERT(xfer->ux_pipe->up_intrxfer == xfer); 994 1.1 bouyer 995 1.27 riastrad /* If xfer has already completed, nothing to do here. */ 996 1.27 riastrad if (sc->sc_intr_xfer == NULL) 997 1.27 riastrad return; 998 1.1 bouyer 999 1.27 riastrad /* 1000 1.27 riastrad * Otherwise, sc->sc_intr_xfer had better be this transfer. 1001 1.27 riastrad * Cancel it. 1002 1.27 riastrad */ 1003 1.27 riastrad KASSERT(sc->sc_intr_xfer == xfer); 1004 1.27 riastrad KASSERT(xfer->ux_status == USBD_IN_PROGRESS); 1005 1.14 skrll xfer->ux_status = USBD_CANCELLED; 1006 1.1 bouyer usb_transfer_complete(xfer); 1007 1.1 bouyer } 1008 1.1 bouyer 1009 1.1 bouyer usbd_status 1010 1.14 skrll motg_root_intr_transfer(struct usbd_xfer *xfer) 1011 1.1 bouyer { 1012 1.1 bouyer 1013 1.38 riastrad /* Pipe isn't running, start first */ 1014 1.14 skrll return motg_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 1015 1.1 bouyer } 1016 1.1 bouyer 1017 1.1 bouyer /* Start a transfer on the root interrupt pipe */ 1018 1.1 bouyer usbd_status 1019 1.14 skrll motg_root_intr_start(struct usbd_xfer *xfer) 1020 1.1 bouyer { 1021 1.14 skrll struct usbd_pipe *pipe = xfer->ux_pipe; 1022 1.14 skrll struct motg_softc *sc = MOTG_PIPE2SC(pipe); 1023 1.14 skrll 1024 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1025 1.1 bouyer 1026 1.18 pgoyette DPRINTFN(MD_ROOT, "xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, 1027 1.18 pgoyette xfer->ux_length, xfer->ux_flags, 0); 1028 1.1 bouyer 1029 1.40 riastrad KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 1030 1.40 riastrad 1031 1.1 bouyer if (sc->sc_dying) 1032 1.14 skrll return USBD_IOERROR; 1033 1.1 bouyer 1034 1.27 riastrad KASSERT(sc->sc_intr_xfer == NULL); 1035 1.1 bouyer sc->sc_intr_xfer = xfer; 1036 1.27 riastrad xfer->ux_status = USBD_IN_PROGRESS; 1037 1.27 riastrad 1038 1.14 skrll return USBD_IN_PROGRESS; 1039 1.1 bouyer } 1040 1.1 bouyer 1041 1.1 bouyer /* Close the root interrupt pipe. */ 1042 1.1 bouyer void 1043 1.14 skrll motg_root_intr_close(struct usbd_pipe *pipe) 1044 1.1 bouyer { 1045 1.29 riastrad struct motg_softc *sc __diagused = MOTG_PIPE2SC(pipe); 1046 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1047 1.1 bouyer 1048 1.1 bouyer KASSERT(mutex_owned(&sc->sc_lock)); 1049 1.1 bouyer 1050 1.27 riastrad /* 1051 1.27 riastrad * Caller must guarantee the xfer has completed first, by 1052 1.27 riastrad * closing the pipe only after normal completion or an abort. 1053 1.27 riastrad */ 1054 1.27 riastrad KASSERT(sc->sc_intr_xfer == NULL); 1055 1.1 bouyer } 1056 1.1 bouyer 1057 1.1 bouyer void 1058 1.14 skrll motg_root_intr_done(struct usbd_xfer *xfer) 1059 1.1 bouyer { 1060 1.28 skrll struct motg_softc *sc = MOTG_XFER2SC(xfer); 1061 1.27 riastrad MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1062 1.27 riastrad 1063 1.27 riastrad KASSERT(mutex_owned(&sc->sc_lock)); 1064 1.27 riastrad 1065 1.27 riastrad /* Claim the xfer so it doesn't get completed again. */ 1066 1.27 riastrad KASSERT(sc->sc_intr_xfer == xfer); 1067 1.27 riastrad KASSERT(xfer->ux_status != USBD_IN_PROGRESS); 1068 1.27 riastrad sc->sc_intr_xfer = NULL; 1069 1.1 bouyer } 1070 1.1 bouyer 1071 1.1 bouyer void 1072 1.14 skrll motg_noop(struct usbd_pipe *pipe) 1073 1.1 bouyer { 1074 1.1 bouyer } 1075 1.1 bouyer 1076 1.1 bouyer static usbd_status 1077 1.1 bouyer motg_portreset(struct motg_softc *sc) 1078 1.1 bouyer { 1079 1.1 bouyer uint32_t val; 1080 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1081 1.1 bouyer 1082 1.1 bouyer val = UREAD1(sc, MUSB2_REG_POWER); 1083 1.1 bouyer val |= MUSB2_MASK_RESET; 1084 1.1 bouyer UWRITE1(sc, MUSB2_REG_POWER, val); 1085 1.1 bouyer /* Wait for 20 msec */ 1086 1.1 bouyer usb_delay_ms(&sc->sc_bus, 20); 1087 1.1 bouyer 1088 1.1 bouyer val = UREAD1(sc, MUSB2_REG_POWER); 1089 1.1 bouyer val &= ~MUSB2_MASK_RESET; 1090 1.1 bouyer UWRITE1(sc, MUSB2_REG_POWER, val); 1091 1.1 bouyer 1092 1.1 bouyer /* determine line speed */ 1093 1.1 bouyer val = UREAD1(sc, MUSB2_REG_POWER); 1094 1.1 bouyer if (val & MUSB2_MASK_HSMODE) 1095 1.1 bouyer sc->sc_high_speed = 1; 1096 1.1 bouyer else 1097 1.1 bouyer sc->sc_high_speed = 0; 1098 1.18 pgoyette DPRINTFN(MD_ROOT | MD_CTRL, "speed %jd", sc->sc_high_speed, 0, 0, 0); 1099 1.1 bouyer 1100 1.1 bouyer sc->sc_isreset = 1; 1101 1.1 bouyer sc->sc_port_enabled = 1; 1102 1.14 skrll return USBD_NORMAL_COMPLETION; 1103 1.1 bouyer } 1104 1.1 bouyer 1105 1.1 bouyer /* 1106 1.1 bouyer * This routine is executed when an interrupt on the root hub is detected 1107 1.1 bouyer */ 1108 1.1 bouyer static void 1109 1.1 bouyer motg_hub_change(struct motg_softc *sc) 1110 1.1 bouyer { 1111 1.14 skrll struct usbd_xfer *xfer = sc->sc_intr_xfer; 1112 1.14 skrll struct usbd_pipe *pipe; 1113 1.1 bouyer u_char *p; 1114 1.1 bouyer 1115 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1116 1.1 bouyer 1117 1.1 bouyer if (xfer == NULL) 1118 1.1 bouyer return; /* the interrupt pipe is not open */ 1119 1.27 riastrad KASSERT(xfer->ux_status == USBD_IN_PROGRESS); 1120 1.1 bouyer 1121 1.14 skrll pipe = xfer->ux_pipe; 1122 1.14 skrll if (pipe->up_dev == NULL || pipe->up_dev->ud_bus == NULL) 1123 1.1 bouyer return; /* device has detached */ 1124 1.1 bouyer 1125 1.14 skrll p = xfer->ux_buf; 1126 1.1 bouyer p[0] = 1<<1; 1127 1.14 skrll xfer->ux_actlen = 1; 1128 1.14 skrll xfer->ux_status = USBD_NORMAL_COMPLETION; 1129 1.1 bouyer usb_transfer_complete(xfer); 1130 1.1 bouyer } 1131 1.1 bouyer 1132 1.1 bouyer static uint8_t 1133 1.14 skrll motg_speed(uint8_t speed) 1134 1.1 bouyer { 1135 1.1 bouyer switch(speed) { 1136 1.1 bouyer case USB_SPEED_LOW: 1137 1.1 bouyer return MUSB2_MASK_TI_SPEED_LO; 1138 1.1 bouyer case USB_SPEED_FULL: 1139 1.1 bouyer return MUSB2_MASK_TI_SPEED_FS; 1140 1.1 bouyer case USB_SPEED_HIGH: 1141 1.1 bouyer return MUSB2_MASK_TI_SPEED_HS; 1142 1.1 bouyer default: 1143 1.1 bouyer panic("motg: unknown speed %d", speed); 1144 1.1 bouyer /* NOTREACHED */ 1145 1.1 bouyer } 1146 1.1 bouyer } 1147 1.1 bouyer 1148 1.1 bouyer static uint8_t 1149 1.14 skrll motg_type(uint8_t type) 1150 1.1 bouyer { 1151 1.1 bouyer switch(type) { 1152 1.1 bouyer case UE_CONTROL: 1153 1.1 bouyer return MUSB2_MASK_TI_PROTO_CTRL; 1154 1.1 bouyer case UE_ISOCHRONOUS: 1155 1.1 bouyer return MUSB2_MASK_TI_PROTO_ISOC; 1156 1.1 bouyer case UE_BULK: 1157 1.1 bouyer return MUSB2_MASK_TI_PROTO_BULK; 1158 1.1 bouyer case UE_INTERRUPT: 1159 1.1 bouyer return MUSB2_MASK_TI_PROTO_INTR; 1160 1.1 bouyer default: 1161 1.1 bouyer panic("motg: unknown type %d", type); 1162 1.1 bouyer /* NOTREACHED */ 1163 1.1 bouyer } 1164 1.1 bouyer } 1165 1.1 bouyer 1166 1.1 bouyer static void 1167 1.14 skrll motg_setup_endpoint_tx(struct usbd_xfer *xfer) 1168 1.1 bouyer { 1169 1.14 skrll struct motg_softc *sc = MOTG_XFER2SC(xfer); 1170 1.14 skrll struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe); 1171 1.14 skrll struct usbd_device *dev = otgpipe->pipe.up_dev; 1172 1.1 bouyer int epnumber = otgpipe->hw_ep->ep_number; 1173 1.1 bouyer 1174 1.14 skrll UWRITE1(sc, MUSB2_REG_TXFADDR(epnumber), dev->ud_addr); 1175 1.14 skrll if (dev->ud_myhsport) { 1176 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXHADDR(epnumber), 1177 1.14 skrll dev->ud_myhsport->up_parent->ud_addr); 1178 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXHUBPORT(epnumber), 1179 1.14 skrll dev->ud_myhsport->up_portno); 1180 1.1 bouyer } else { 1181 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXHADDR(epnumber), 0); 1182 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXHUBPORT(epnumber), 0); 1183 1.1 bouyer } 1184 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXTI, 1185 1.14 skrll motg_speed(dev->ud_speed) | 1186 1.14 skrll UE_GET_ADDR(xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress) | 1187 1.14 skrll motg_type(UE_GET_XFERTYPE(xfer->ux_pipe->up_endpoint->ue_edesc->bmAttributes)) 1188 1.1 bouyer ); 1189 1.1 bouyer if (epnumber == 0) { 1190 1.1 bouyer if (sc->sc_high_speed) { 1191 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXNAKLIMIT, 1192 1.1 bouyer NAK_TO_CTRL_HIGH); 1193 1.1 bouyer } else { 1194 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXNAKLIMIT, NAK_TO_CTRL); 1195 1.1 bouyer } 1196 1.1 bouyer } else { 1197 1.14 skrll if ((xfer->ux_pipe->up_endpoint->ue_edesc->bmAttributes & UE_XFERTYPE) 1198 1.1 bouyer == UE_BULK) { 1199 1.1 bouyer if (sc->sc_high_speed) { 1200 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXNAKLIMIT, 1201 1.1 bouyer NAK_TO_BULK_HIGH); 1202 1.1 bouyer } else { 1203 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXNAKLIMIT, NAK_TO_BULK); 1204 1.1 bouyer } 1205 1.1 bouyer } else { 1206 1.1 bouyer if (sc->sc_high_speed) { 1207 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXNAKLIMIT, POLL_TO_HIGH); 1208 1.1 bouyer } else { 1209 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXNAKLIMIT, POLL_TO); 1210 1.1 bouyer } 1211 1.1 bouyer } 1212 1.1 bouyer } 1213 1.1 bouyer } 1214 1.1 bouyer 1215 1.1 bouyer static void 1216 1.14 skrll motg_setup_endpoint_rx(struct usbd_xfer *xfer) 1217 1.1 bouyer { 1218 1.14 skrll struct motg_softc *sc = MOTG_XFER2SC(xfer); 1219 1.14 skrll struct usbd_device *dev = xfer->ux_pipe->up_dev; 1220 1.14 skrll struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe); 1221 1.1 bouyer int epnumber = otgpipe->hw_ep->ep_number; 1222 1.1 bouyer 1223 1.14 skrll UWRITE1(sc, MUSB2_REG_RXFADDR(epnumber), dev->ud_addr); 1224 1.14 skrll if (dev->ud_myhsport) { 1225 1.1 bouyer UWRITE1(sc, MUSB2_REG_RXHADDR(epnumber), 1226 1.14 skrll dev->ud_myhsport->up_parent->ud_addr); 1227 1.1 bouyer UWRITE1(sc, MUSB2_REG_RXHUBPORT(epnumber), 1228 1.14 skrll dev->ud_myhsport->up_portno); 1229 1.1 bouyer } else { 1230 1.1 bouyer UWRITE1(sc, MUSB2_REG_RXHADDR(epnumber), 0); 1231 1.1 bouyer UWRITE1(sc, MUSB2_REG_RXHUBPORT(epnumber), 0); 1232 1.1 bouyer } 1233 1.1 bouyer UWRITE1(sc, MUSB2_REG_RXTI, 1234 1.14 skrll motg_speed(dev->ud_speed) | 1235 1.14 skrll UE_GET_ADDR(xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress) | 1236 1.14 skrll motg_type(UE_GET_XFERTYPE(xfer->ux_pipe->up_endpoint->ue_edesc->bmAttributes)) 1237 1.1 bouyer ); 1238 1.1 bouyer if (epnumber == 0) { 1239 1.1 bouyer if (sc->sc_high_speed) { 1240 1.17 jakllsch UWRITE1(sc, MUSB2_REG_RXNAKLIMIT, 1241 1.1 bouyer NAK_TO_CTRL_HIGH); 1242 1.1 bouyer } else { 1243 1.17 jakllsch UWRITE1(sc, MUSB2_REG_RXNAKLIMIT, NAK_TO_CTRL); 1244 1.1 bouyer } 1245 1.1 bouyer } else { 1246 1.14 skrll if ((xfer->ux_pipe->up_endpoint->ue_edesc->bmAttributes & UE_XFERTYPE) 1247 1.1 bouyer == UE_BULK) { 1248 1.1 bouyer if (sc->sc_high_speed) { 1249 1.1 bouyer UWRITE1(sc, MUSB2_REG_RXNAKLIMIT, 1250 1.1 bouyer NAK_TO_BULK_HIGH); 1251 1.1 bouyer } else { 1252 1.1 bouyer UWRITE1(sc, MUSB2_REG_RXNAKLIMIT, NAK_TO_BULK); 1253 1.1 bouyer } 1254 1.1 bouyer } else { 1255 1.1 bouyer if (sc->sc_high_speed) { 1256 1.1 bouyer UWRITE1(sc, MUSB2_REG_RXNAKLIMIT, POLL_TO_HIGH); 1257 1.1 bouyer } else { 1258 1.1 bouyer UWRITE1(sc, MUSB2_REG_RXNAKLIMIT, POLL_TO); 1259 1.1 bouyer } 1260 1.1 bouyer } 1261 1.1 bouyer } 1262 1.1 bouyer } 1263 1.1 bouyer 1264 1.1 bouyer static usbd_status 1265 1.14 skrll motg_device_ctrl_transfer(struct usbd_xfer *xfer) 1266 1.1 bouyer { 1267 1.1 bouyer 1268 1.38 riastrad /* Pipe isn't running, so start it first. */ 1269 1.14 skrll return motg_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 1270 1.1 bouyer } 1271 1.1 bouyer 1272 1.1 bouyer static usbd_status 1273 1.14 skrll motg_device_ctrl_start(struct usbd_xfer *xfer) 1274 1.1 bouyer { 1275 1.14 skrll struct motg_softc *sc = MOTG_XFER2SC(xfer); 1276 1.40 riastrad 1277 1.40 riastrad KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 1278 1.40 riastrad 1279 1.40 riastrad return motg_device_ctrl_start1(sc); 1280 1.1 bouyer } 1281 1.1 bouyer 1282 1.1 bouyer static usbd_status 1283 1.1 bouyer motg_device_ctrl_start1(struct motg_softc *sc) 1284 1.1 bouyer { 1285 1.1 bouyer struct motg_hw_ep *ep = &sc->sc_in_ep[0]; 1286 1.14 skrll struct usbd_xfer *xfer = NULL; 1287 1.1 bouyer struct motg_pipe *otgpipe; 1288 1.1 bouyer usbd_status err = 0; 1289 1.1 bouyer 1290 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1291 1.14 skrll 1292 1.1 bouyer KASSERT(mutex_owned(&sc->sc_lock)); 1293 1.1 bouyer if (sc->sc_dying) 1294 1.14 skrll return USBD_IOERROR; 1295 1.1 bouyer 1296 1.1 bouyer if (!sc->sc_connected) 1297 1.14 skrll return USBD_IOERROR; 1298 1.1 bouyer 1299 1.1 bouyer if (ep->xfer != NULL) { 1300 1.1 bouyer err = USBD_IN_PROGRESS; 1301 1.1 bouyer goto end; 1302 1.1 bouyer } 1303 1.1 bouyer /* locate the first pipe with work to do */ 1304 1.1 bouyer SIMPLEQ_FOREACH(otgpipe, &ep->ep_pipes, ep_pipe_list) { 1305 1.14 skrll xfer = SIMPLEQ_FIRST(&otgpipe->pipe.up_queue); 1306 1.18 pgoyette DPRINTFN(MD_CTRL, "pipe %#jx xfer %#jx status %jd", 1307 1.18 pgoyette (uintptr_t)otgpipe, (uintptr_t)xfer, 1308 1.18 pgoyette (xfer != NULL) ? xfer->ux_status : 0, 0); 1309 1.7 skrll 1310 1.1 bouyer if (xfer != NULL) { 1311 1.1 bouyer /* move this pipe to the end of the list */ 1312 1.1 bouyer SIMPLEQ_REMOVE(&ep->ep_pipes, otgpipe, 1313 1.1 bouyer motg_pipe, ep_pipe_list); 1314 1.1 bouyer SIMPLEQ_INSERT_TAIL(&ep->ep_pipes, 1315 1.1 bouyer otgpipe, ep_pipe_list); 1316 1.1 bouyer break; 1317 1.1 bouyer } 1318 1.1 bouyer } 1319 1.1 bouyer if (xfer == NULL) { 1320 1.1 bouyer err = USBD_NOT_STARTED; 1321 1.1 bouyer goto end; 1322 1.1 bouyer } 1323 1.32 riastrad if (xfer->ux_status == USBD_NOT_STARTED) { 1324 1.43 riastrad xfer->ux_status = USBD_IN_PROGRESS; 1325 1.32 riastrad usbd_xfer_schedule_timeout(xfer); 1326 1.32 riastrad } else { 1327 1.32 riastrad KASSERT(xfer->ux_status == USBD_IN_PROGRESS); 1328 1.32 riastrad } 1329 1.14 skrll KASSERT(otgpipe == MOTG_PIPE2MPIPE(xfer->ux_pipe)); 1330 1.1 bouyer KASSERT(otgpipe->hw_ep == ep); 1331 1.14 skrll KASSERT(xfer->ux_rqflags & URQ_REQUEST); 1332 1.14 skrll // KASSERT(xfer->ux_actlen == 0); 1333 1.14 skrll xfer->ux_actlen = 0; 1334 1.1 bouyer 1335 1.1 bouyer ep->xfer = xfer; 1336 1.14 skrll ep->datalen = xfer->ux_length; 1337 1.1 bouyer if (ep->datalen > 0) 1338 1.14 skrll ep->data = xfer->ux_buf; 1339 1.1 bouyer else 1340 1.1 bouyer ep->data = NULL; 1341 1.14 skrll if ((xfer->ux_flags & USBD_FORCE_SHORT_XFER) && 1342 1.1 bouyer (ep->datalen % 64) == 0) 1343 1.1 bouyer ep->need_short_xfer = 1; 1344 1.1 bouyer else 1345 1.1 bouyer ep->need_short_xfer = 0; 1346 1.1 bouyer /* now we need send this request */ 1347 1.7 skrll DPRINTFN(MD_CTRL, 1348 1.18 pgoyette "xfer %#jx send data %#jx len %jd short %jd", 1349 1.18 pgoyette (uintptr_t)xfer, (uintptr_t)ep->data, ep->datalen, 1350 1.18 pgoyette ep->need_short_xfer); 1351 1.14 skrll DPRINTFN(MD_CTRL, 1352 1.18 pgoyette "xfer %#jx ... speed %jd to %jd", (uintptr_t)xfer, 1353 1.18 pgoyette xfer->ux_pipe->up_dev->ud_speed, 1354 1.18 pgoyette xfer->ux_pipe->up_dev->ud_addr, 0); 1355 1.1 bouyer KASSERT(ep->phase == IDLE); 1356 1.1 bouyer ep->phase = SETUP; 1357 1.1 bouyer /* select endpoint 0 */ 1358 1.1 bouyer UWRITE1(sc, MUSB2_REG_EPINDEX, 0); 1359 1.1 bouyer /* fifo should be empty at this point */ 1360 1.1 bouyer KASSERT((UREAD1(sc, MUSB2_REG_TXCSRL) & MUSB2_MASK_CSR0L_TXPKTRDY) == 0); 1361 1.1 bouyer /* send data */ 1362 1.14 skrll // KASSERT(((vaddr_t)(&xfer->ux_request) & 3) == 0); 1363 1.14 skrll KASSERT(sizeof(xfer->ux_request) == 8); 1364 1.1 bouyer bus_space_write_multi_1(sc->sc_iot, sc->sc_ioh, MUSB2_REG_EPFIFO(0), 1365 1.14 skrll (void *)&xfer->ux_request, sizeof(xfer->ux_request)); 1366 1.1 bouyer 1367 1.1 bouyer motg_setup_endpoint_tx(xfer); 1368 1.1 bouyer /* start transaction */ 1369 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXCSRL, 1370 1.1 bouyer MUSB2_MASK_CSR0L_TXPKTRDY | MUSB2_MASK_CSR0L_SETUPPKT); 1371 1.1 bouyer 1372 1.1 bouyer end: 1373 1.1 bouyer if (err) 1374 1.14 skrll return err; 1375 1.1 bouyer 1376 1.14 skrll return USBD_IN_PROGRESS; 1377 1.1 bouyer } 1378 1.1 bouyer 1379 1.1 bouyer static void 1380 1.14 skrll motg_device_ctrl_read(struct usbd_xfer *xfer) 1381 1.1 bouyer { 1382 1.14 skrll struct motg_softc *sc = MOTG_XFER2SC(xfer); 1383 1.14 skrll struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe); 1384 1.1 bouyer /* assume endpoint already selected */ 1385 1.1 bouyer motg_setup_endpoint_rx(xfer); 1386 1.1 bouyer /* start transaction */ 1387 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXCSRL, MUSB2_MASK_CSR0L_REQPKT); 1388 1.1 bouyer otgpipe->hw_ep->phase = DATA_IN; 1389 1.1 bouyer } 1390 1.1 bouyer 1391 1.1 bouyer static void 1392 1.1 bouyer motg_device_ctrl_intr_rx(struct motg_softc *sc) 1393 1.1 bouyer { 1394 1.1 bouyer struct motg_hw_ep *ep = &sc->sc_in_ep[0]; 1395 1.14 skrll struct usbd_xfer *xfer = ep->xfer; 1396 1.1 bouyer uint8_t csr; 1397 1.1 bouyer int datalen, max_datalen; 1398 1.1 bouyer char *data; 1399 1.1 bouyer bool got_short; 1400 1.3 bouyer usbd_status new_status = USBD_IN_PROGRESS; 1401 1.1 bouyer 1402 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1403 1.14 skrll 1404 1.1 bouyer KASSERT(mutex_owned(&sc->sc_lock)); 1405 1.31 riastrad KASSERT(ep->phase == DATA_IN || ep->phase == STATUS_IN); 1406 1.1 bouyer 1407 1.14 skrll /* select endpoint 0 */ 1408 1.1 bouyer UWRITE1(sc, MUSB2_REG_EPINDEX, 0); 1409 1.1 bouyer 1410 1.1 bouyer /* read out FIFO status */ 1411 1.1 bouyer csr = UREAD1(sc, MUSB2_REG_TXCSRL); 1412 1.34 christos DPRINTFN(MD_CTRL, "phase %jd csr %#jx xfer %#jx status %jd", 1413 1.18 pgoyette ep->phase, csr, (uintptr_t)xfer, 1414 1.18 pgoyette (xfer != NULL) ? xfer->ux_status : 0); 1415 1.1 bouyer 1416 1.1 bouyer if (csr & MUSB2_MASK_CSR0L_NAKTIMO) { 1417 1.1 bouyer csr &= ~MUSB2_MASK_CSR0L_REQPKT; 1418 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXCSRL, csr); 1419 1.1 bouyer 1420 1.1 bouyer csr &= ~MUSB2_MASK_CSR0L_NAKTIMO; 1421 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXCSRL, csr); 1422 1.3 bouyer new_status = USBD_TIMEOUT; /* XXX */ 1423 1.1 bouyer goto complete; 1424 1.1 bouyer } 1425 1.1 bouyer if (csr & (MUSB2_MASK_CSR0L_RXSTALL | MUSB2_MASK_CSR0L_ERROR)) { 1426 1.3 bouyer if (csr & MUSB2_MASK_CSR0L_RXSTALL) 1427 1.3 bouyer new_status = USBD_STALLED; 1428 1.3 bouyer else 1429 1.3 bouyer new_status = USBD_IOERROR; 1430 1.1 bouyer /* clear status */ 1431 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXCSRL, 0); 1432 1.1 bouyer goto complete; 1433 1.1 bouyer } 1434 1.1 bouyer if ((csr & MUSB2_MASK_CSR0L_RXPKTRDY) == 0) 1435 1.1 bouyer return; /* no data yet */ 1436 1.1 bouyer 1437 1.14 skrll if (xfer == NULL || xfer->ux_status != USBD_IN_PROGRESS) 1438 1.1 bouyer goto complete; 1439 1.1 bouyer 1440 1.1 bouyer if (ep->phase == STATUS_IN) { 1441 1.3 bouyer new_status = USBD_NORMAL_COMPLETION; 1442 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXCSRL, 0); 1443 1.1 bouyer goto complete; 1444 1.1 bouyer } 1445 1.1 bouyer datalen = UREAD2(sc, MUSB2_REG_RXCOUNT); 1446 1.18 pgoyette DPRINTFN(MD_CTRL, "phase %jd datalen %jd", ep->phase, datalen, 0, 0); 1447 1.14 skrll KASSERT(UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize) > 0); 1448 1.23 riastrad max_datalen = uimin(UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize), 1449 1.1 bouyer ep->datalen); 1450 1.1 bouyer if (datalen > max_datalen) { 1451 1.3 bouyer new_status = USBD_IOERROR; 1452 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXCSRL, 0); 1453 1.1 bouyer goto complete; 1454 1.1 bouyer } 1455 1.1 bouyer got_short = (datalen < max_datalen); 1456 1.1 bouyer if (datalen > 0) { 1457 1.1 bouyer KASSERT(ep->phase == DATA_IN); 1458 1.1 bouyer data = ep->data; 1459 1.1 bouyer ep->data += datalen; 1460 1.1 bouyer ep->datalen -= datalen; 1461 1.14 skrll xfer->ux_actlen += datalen; 1462 1.1 bouyer if (((vaddr_t)data & 0x3) == 0 && 1463 1.1 bouyer (datalen >> 2) > 0) { 1464 1.18 pgoyette DPRINTFN(MD_CTRL, "r4 data %#jx len %jd", 1465 1.18 pgoyette (uintptr_t)data, datalen, 0, 0); 1466 1.1 bouyer bus_space_read_multi_4(sc->sc_iot, sc->sc_ioh, 1467 1.1 bouyer MUSB2_REG_EPFIFO(0), (void *)data, datalen >> 2); 1468 1.1 bouyer data += (datalen & ~0x3); 1469 1.1 bouyer datalen -= (datalen & ~0x3); 1470 1.1 bouyer } 1471 1.18 pgoyette DPRINTFN(MD_CTRL, "r1 data %#jx len %jd", (uintptr_t)data, 1472 1.18 pgoyette datalen, 0, 0); 1473 1.1 bouyer if (datalen) { 1474 1.1 bouyer bus_space_read_multi_1(sc->sc_iot, sc->sc_ioh, 1475 1.1 bouyer MUSB2_REG_EPFIFO(0), data, datalen); 1476 1.1 bouyer } 1477 1.1 bouyer } 1478 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXCSRL, csr & ~MUSB2_MASK_CSR0L_RXPKTRDY); 1479 1.1 bouyer KASSERT(ep->phase == DATA_IN); 1480 1.1 bouyer if (got_short || (ep->datalen == 0)) { 1481 1.1 bouyer if (ep->need_short_xfer == 0) { 1482 1.1 bouyer ep->phase = STATUS_OUT; 1483 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXCSRH, 1484 1.1 bouyer UREAD1(sc, MUSB2_REG_TXCSRH) | 1485 1.1 bouyer MUSB2_MASK_CSR0H_PING_DIS); 1486 1.1 bouyer motg_setup_endpoint_tx(xfer); 1487 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXCSRL, 1488 1.1 bouyer MUSB2_MASK_CSR0L_STATUSPKT | 1489 1.1 bouyer MUSB2_MASK_CSR0L_TXPKTRDY); 1490 1.1 bouyer return; 1491 1.1 bouyer } 1492 1.1 bouyer ep->need_short_xfer = 0; 1493 1.1 bouyer } 1494 1.1 bouyer motg_device_ctrl_read(xfer); 1495 1.1 bouyer return; 1496 1.1 bouyer complete: 1497 1.1 bouyer ep->phase = IDLE; 1498 1.1 bouyer ep->xfer = NULL; 1499 1.31 riastrad /* 1500 1.31 riastrad * Try to claim this xfer for completion. If it has already 1501 1.31 riastrad * completed or aborted, drop it on the floor. 1502 1.31 riastrad */ 1503 1.31 riastrad if (xfer && usbd_xfer_trycomplete(xfer)) { 1504 1.31 riastrad KASSERT(xfer->ux_status == USBD_IN_PROGRESS); 1505 1.3 bouyer KASSERT(new_status != USBD_IN_PROGRESS); 1506 1.14 skrll xfer->ux_status = new_status; 1507 1.1 bouyer usb_transfer_complete(xfer); 1508 1.3 bouyer } 1509 1.1 bouyer motg_device_ctrl_start1(sc); 1510 1.1 bouyer } 1511 1.1 bouyer 1512 1.1 bouyer static void 1513 1.1 bouyer motg_device_ctrl_intr_tx(struct motg_softc *sc) 1514 1.1 bouyer { 1515 1.1 bouyer struct motg_hw_ep *ep = &sc->sc_in_ep[0]; 1516 1.14 skrll struct usbd_xfer *xfer = ep->xfer; 1517 1.1 bouyer uint8_t csr; 1518 1.1 bouyer int datalen; 1519 1.1 bouyer char *data; 1520 1.3 bouyer usbd_status new_status = USBD_IN_PROGRESS; 1521 1.1 bouyer 1522 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1523 1.14 skrll 1524 1.1 bouyer KASSERT(mutex_owned(&sc->sc_lock)); 1525 1.26 riastrad 1526 1.1 bouyer if (ep->phase == DATA_IN || ep->phase == STATUS_IN) { 1527 1.1 bouyer motg_device_ctrl_intr_rx(sc); 1528 1.1 bouyer return; 1529 1.1 bouyer } 1530 1.1 bouyer 1531 1.14 skrll KASSERT(ep->phase == SETUP || ep->phase == DATA_OUT || 1532 1.14 skrll ep->phase == STATUS_OUT); 1533 1.14 skrll 1534 1.14 skrll /* select endpoint 0 */ 1535 1.1 bouyer UWRITE1(sc, MUSB2_REG_EPINDEX, 0); 1536 1.1 bouyer 1537 1.1 bouyer csr = UREAD1(sc, MUSB2_REG_TXCSRL); 1538 1.34 christos DPRINTFN(MD_CTRL, "phase %jd csr %#jx xfer %#jx status %jd", 1539 1.18 pgoyette ep->phase, csr, (uintptr_t)xfer, 1540 1.18 pgoyette (xfer != NULL) ? xfer->ux_status : 0); 1541 1.1 bouyer 1542 1.1 bouyer if (csr & MUSB2_MASK_CSR0L_RXSTALL) { 1543 1.1 bouyer /* command not accepted */ 1544 1.3 bouyer new_status = USBD_STALLED; 1545 1.1 bouyer /* clear status */ 1546 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXCSRL, 0); 1547 1.1 bouyer goto complete; 1548 1.1 bouyer } 1549 1.1 bouyer if (csr & MUSB2_MASK_CSR0L_NAKTIMO) { 1550 1.3 bouyer new_status = USBD_TIMEOUT; /* XXX */ 1551 1.1 bouyer /* flush fifo */ 1552 1.1 bouyer while (csr & MUSB2_MASK_CSR0L_TXFIFONEMPTY) { 1553 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXCSRH, 1554 1.7 skrll UREAD1(sc, MUSB2_REG_TXCSRH) | 1555 1.1 bouyer MUSB2_MASK_CSR0H_FFLUSH); 1556 1.1 bouyer csr = UREAD1(sc, MUSB2_REG_TXCSRL); 1557 1.1 bouyer } 1558 1.1 bouyer csr &= ~MUSB2_MASK_CSR0L_NAKTIMO; 1559 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXCSRL, csr); 1560 1.1 bouyer goto complete; 1561 1.1 bouyer } 1562 1.1 bouyer if (csr & MUSB2_MASK_CSR0L_ERROR) { 1563 1.3 bouyer new_status = USBD_IOERROR; 1564 1.1 bouyer /* clear status */ 1565 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXCSRL, 0); 1566 1.1 bouyer goto complete; 1567 1.1 bouyer } 1568 1.1 bouyer if (csr & MUSB2_MASK_CSR0L_TXFIFONEMPTY) { 1569 1.1 bouyer /* data still not sent */ 1570 1.1 bouyer return; 1571 1.1 bouyer } 1572 1.31 riastrad if (xfer == NULL || xfer->ux_status != USBD_IN_PROGRESS) 1573 1.1 bouyer goto complete; 1574 1.1 bouyer if (ep->phase == STATUS_OUT) { 1575 1.1 bouyer /* 1576 1.1 bouyer * we have sent status and got no error; 1577 1.1 bouyer * declare transfer complete 1578 1.1 bouyer */ 1579 1.18 pgoyette DPRINTFN(MD_CTRL, "xfer %#jx status %jd complete", 1580 1.18 pgoyette (uintptr_t)xfer, xfer->ux_status, 0, 0); 1581 1.3 bouyer new_status = USBD_NORMAL_COMPLETION; 1582 1.1 bouyer goto complete; 1583 1.1 bouyer } 1584 1.1 bouyer if (ep->datalen == 0) { 1585 1.1 bouyer if (ep->need_short_xfer) { 1586 1.1 bouyer ep->need_short_xfer = 0; 1587 1.1 bouyer /* one more data phase */ 1588 1.14 skrll if (xfer->ux_request.bmRequestType & UT_READ) { 1589 1.18 pgoyette DPRINTFN(MD_CTRL, "xfer %#jx to DATA_IN", 1590 1.18 pgoyette (uintptr_t)xfer, 0, 0, 0); 1591 1.1 bouyer motg_device_ctrl_read(xfer); 1592 1.1 bouyer return; 1593 1.1 bouyer } /* else fall back to DATA_OUT */ 1594 1.1 bouyer } else { 1595 1.34 christos DPRINTFN(MD_CTRL, "xfer %#jx to STATUS_IN, csrh %#jx", 1596 1.18 pgoyette (uintptr_t)xfer, UREAD1(sc, MUSB2_REG_TXCSRH), 1597 1.18 pgoyette 0, 0); 1598 1.1 bouyer ep->phase = STATUS_IN; 1599 1.1 bouyer UWRITE1(sc, MUSB2_REG_RXCSRH, 1600 1.1 bouyer UREAD1(sc, MUSB2_REG_RXCSRH) | 1601 1.1 bouyer MUSB2_MASK_CSR0H_PING_DIS); 1602 1.1 bouyer motg_setup_endpoint_rx(xfer); 1603 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXCSRL, 1604 1.1 bouyer MUSB2_MASK_CSR0L_STATUSPKT | 1605 1.1 bouyer MUSB2_MASK_CSR0L_REQPKT); 1606 1.1 bouyer return; 1607 1.1 bouyer } 1608 1.1 bouyer } 1609 1.14 skrll if (xfer->ux_request.bmRequestType & UT_READ) { 1610 1.1 bouyer motg_device_ctrl_read(xfer); 1611 1.1 bouyer return; 1612 1.1 bouyer } 1613 1.1 bouyer /* setup a dataout phase */ 1614 1.23 riastrad datalen = uimin(ep->datalen, 1615 1.14 skrll UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize)); 1616 1.1 bouyer ep->phase = DATA_OUT; 1617 1.34 christos DPRINTFN(MD_CTRL, "xfer %#jx to DATA_OUT, csrh %#jx", (uintptr_t)xfer, 1618 1.14 skrll UREAD1(sc, MUSB2_REG_TXCSRH), 0, 0); 1619 1.1 bouyer if (datalen) { 1620 1.1 bouyer data = ep->data; 1621 1.1 bouyer ep->data += datalen; 1622 1.1 bouyer ep->datalen -= datalen; 1623 1.14 skrll xfer->ux_actlen += datalen; 1624 1.1 bouyer if (((vaddr_t)data & 0x3) == 0 && 1625 1.1 bouyer (datalen >> 2) > 0) { 1626 1.1 bouyer bus_space_write_multi_4(sc->sc_iot, sc->sc_ioh, 1627 1.1 bouyer MUSB2_REG_EPFIFO(0), (void *)data, datalen >> 2); 1628 1.1 bouyer data += (datalen & ~0x3); 1629 1.1 bouyer datalen -= (datalen & ~0x3); 1630 1.1 bouyer } 1631 1.1 bouyer if (datalen) { 1632 1.1 bouyer bus_space_write_multi_1(sc->sc_iot, sc->sc_ioh, 1633 1.1 bouyer MUSB2_REG_EPFIFO(0), data, datalen); 1634 1.1 bouyer } 1635 1.1 bouyer } 1636 1.1 bouyer /* send data */ 1637 1.1 bouyer motg_setup_endpoint_tx(xfer); 1638 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXCSRL, MUSB2_MASK_CSR0L_TXPKTRDY); 1639 1.1 bouyer return; 1640 1.1 bouyer 1641 1.1 bouyer complete: 1642 1.1 bouyer ep->phase = IDLE; 1643 1.1 bouyer ep->xfer = NULL; 1644 1.31 riastrad /* 1645 1.31 riastrad * Try to claim this xfer for completion. If it has already 1646 1.31 riastrad * completed or aborted, drop it on the floor. 1647 1.31 riastrad */ 1648 1.31 riastrad if (xfer && usbd_xfer_trycomplete(xfer)) { 1649 1.31 riastrad KASSERT(xfer->ux_status == USBD_IN_PROGRESS); 1650 1.3 bouyer KASSERT(new_status != USBD_IN_PROGRESS); 1651 1.14 skrll xfer->ux_status = new_status; 1652 1.1 bouyer usb_transfer_complete(xfer); 1653 1.3 bouyer } 1654 1.1 bouyer motg_device_ctrl_start1(sc); 1655 1.1 bouyer } 1656 1.1 bouyer 1657 1.1 bouyer /* Abort a device control request. */ 1658 1.1 bouyer void 1659 1.14 skrll motg_device_ctrl_abort(struct usbd_xfer *xfer) 1660 1.1 bouyer { 1661 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1662 1.14 skrll 1663 1.26 riastrad usbd_xfer_abort(xfer); 1664 1.1 bouyer } 1665 1.1 bouyer 1666 1.1 bouyer /* Close a device control pipe */ 1667 1.1 bouyer void 1668 1.14 skrll motg_device_ctrl_close(struct usbd_pipe *pipe) 1669 1.1 bouyer { 1670 1.14 skrll struct motg_softc *sc __diagused = MOTG_PIPE2SC(pipe); 1671 1.14 skrll struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(pipe); 1672 1.1 bouyer struct motg_pipe *otgpipeiter; 1673 1.1 bouyer 1674 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1675 1.14 skrll 1676 1.1 bouyer KASSERT(mutex_owned(&sc->sc_lock)); 1677 1.1 bouyer KASSERT(otgpipe->hw_ep->xfer == NULL || 1678 1.14 skrll otgpipe->hw_ep->xfer->ux_pipe != pipe); 1679 1.1 bouyer 1680 1.1 bouyer SIMPLEQ_FOREACH(otgpipeiter, &otgpipe->hw_ep->ep_pipes, ep_pipe_list) { 1681 1.1 bouyer if (otgpipeiter == otgpipe) { 1682 1.1 bouyer /* remove from list */ 1683 1.1 bouyer SIMPLEQ_REMOVE(&otgpipe->hw_ep->ep_pipes, otgpipe, 1684 1.1 bouyer motg_pipe, ep_pipe_list); 1685 1.1 bouyer otgpipe->hw_ep->refcount--; 1686 1.1 bouyer /* we're done */ 1687 1.1 bouyer return; 1688 1.1 bouyer } 1689 1.1 bouyer } 1690 1.1 bouyer panic("motg_device_ctrl_close: not found"); 1691 1.1 bouyer } 1692 1.1 bouyer 1693 1.1 bouyer void 1694 1.14 skrll motg_device_ctrl_done(struct usbd_xfer *xfer) 1695 1.1 bouyer { 1696 1.14 skrll struct motg_pipe *otgpipe __diagused = MOTG_PIPE2MPIPE(xfer->ux_pipe); 1697 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1698 1.14 skrll 1699 1.1 bouyer KASSERT(otgpipe->hw_ep->xfer != xfer); 1700 1.1 bouyer } 1701 1.1 bouyer 1702 1.1 bouyer static usbd_status 1703 1.14 skrll motg_device_data_transfer(struct usbd_xfer *xfer) 1704 1.1 bouyer { 1705 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1706 1.14 skrll 1707 1.38 riastrad /* Pipe isn't running, so start it first. */ 1708 1.14 skrll return motg_device_data_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 1709 1.1 bouyer } 1710 1.1 bouyer 1711 1.1 bouyer static usbd_status 1712 1.14 skrll motg_device_data_start(struct usbd_xfer *xfer) 1713 1.1 bouyer { 1714 1.14 skrll struct motg_softc *sc = MOTG_XFER2SC(xfer); 1715 1.14 skrll struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe); 1716 1.14 skrll 1717 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1718 1.14 skrll 1719 1.18 pgoyette DPRINTF("xfer %#jx status %jd", (uintptr_t)xfer, xfer->ux_status, 0, 0); 1720 1.40 riastrad 1721 1.40 riastrad KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 1722 1.40 riastrad 1723 1.40 riastrad return motg_device_data_start1(sc, otgpipe->hw_ep); 1724 1.1 bouyer } 1725 1.1 bouyer 1726 1.1 bouyer static usbd_status 1727 1.1 bouyer motg_device_data_start1(struct motg_softc *sc, struct motg_hw_ep *ep) 1728 1.1 bouyer { 1729 1.14 skrll struct usbd_xfer *xfer = NULL; 1730 1.1 bouyer struct motg_pipe *otgpipe; 1731 1.1 bouyer usbd_status err = 0; 1732 1.8 skrll uint32_t val __diagused; 1733 1.1 bouyer 1734 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1735 1.14 skrll 1736 1.1 bouyer KASSERT(mutex_owned(&sc->sc_lock)); 1737 1.1 bouyer if (sc->sc_dying) 1738 1.14 skrll return USBD_IOERROR; 1739 1.1 bouyer 1740 1.1 bouyer if (!sc->sc_connected) 1741 1.14 skrll return USBD_IOERROR; 1742 1.1 bouyer 1743 1.1 bouyer if (ep->xfer != NULL) { 1744 1.1 bouyer err = USBD_IN_PROGRESS; 1745 1.1 bouyer goto end; 1746 1.1 bouyer } 1747 1.1 bouyer /* locate the first pipe with work to do */ 1748 1.1 bouyer SIMPLEQ_FOREACH(otgpipe, &ep->ep_pipes, ep_pipe_list) { 1749 1.14 skrll xfer = SIMPLEQ_FIRST(&otgpipe->pipe.up_queue); 1750 1.18 pgoyette DPRINTFN(MD_BULK, "pipe %#jx xfer %#jx status %jd", 1751 1.18 pgoyette (uintptr_t)otgpipe, (uintptr_t)xfer, 1752 1.14 skrll (xfer != NULL) ? xfer->ux_status : 0, 0); 1753 1.1 bouyer if (xfer != NULL) { 1754 1.1 bouyer /* move this pipe to the end of the list */ 1755 1.1 bouyer SIMPLEQ_REMOVE(&ep->ep_pipes, otgpipe, 1756 1.1 bouyer motg_pipe, ep_pipe_list); 1757 1.1 bouyer SIMPLEQ_INSERT_TAIL(&ep->ep_pipes, 1758 1.1 bouyer otgpipe, ep_pipe_list); 1759 1.1 bouyer break; 1760 1.1 bouyer } 1761 1.1 bouyer } 1762 1.1 bouyer if (xfer == NULL) { 1763 1.1 bouyer err = USBD_NOT_STARTED; 1764 1.1 bouyer goto end; 1765 1.1 bouyer } 1766 1.32 riastrad if (xfer->ux_status == USBD_NOT_STARTED) { 1767 1.43 riastrad xfer->ux_status = USBD_IN_PROGRESS; 1768 1.32 riastrad usbd_xfer_schedule_timeout(xfer); 1769 1.32 riastrad } else { 1770 1.32 riastrad KASSERT(xfer->ux_status == USBD_IN_PROGRESS); 1771 1.32 riastrad } 1772 1.14 skrll KASSERT(otgpipe == MOTG_PIPE2MPIPE(xfer->ux_pipe)); 1773 1.1 bouyer KASSERT(otgpipe->hw_ep == ep); 1774 1.14 skrll KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); 1775 1.14 skrll // KASSERT(xfer->ux_actlen == 0); 1776 1.14 skrll xfer->ux_actlen = 0; 1777 1.1 bouyer 1778 1.1 bouyer ep->xfer = xfer; 1779 1.14 skrll ep->datalen = xfer->ux_length; 1780 1.1 bouyer KASSERT(ep->datalen > 0); 1781 1.14 skrll ep->data = xfer->ux_buf; 1782 1.14 skrll if ((xfer->ux_flags & USBD_FORCE_SHORT_XFER) && 1783 1.1 bouyer (ep->datalen % 64) == 0) 1784 1.1 bouyer ep->need_short_xfer = 1; 1785 1.1 bouyer else 1786 1.1 bouyer ep->need_short_xfer = 0; 1787 1.1 bouyer /* now we need send this request */ 1788 1.7 skrll DPRINTFN(MD_BULK, 1789 1.14 skrll UE_GET_DIR(xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress) == UE_DIR_IN ? 1790 1.18 pgoyette "xfer %#jx in data %#jx len %jd short %jd" : 1791 1.18 pgoyette "xfer %#jx out data %#jx len %jd short %jd", 1792 1.18 pgoyette (uintptr_t)xfer, (uintptr_t)ep->data, ep->datalen, 1793 1.18 pgoyette ep->need_short_xfer); 1794 1.18 pgoyette DPRINTFN(MD_BULK, "... speed %jd to %jd", 1795 1.18 pgoyette xfer->ux_pipe->up_dev->ud_speed, 1796 1.14 skrll xfer->ux_pipe->up_dev->ud_addr, 0, 0); 1797 1.1 bouyer KASSERT(ep->phase == IDLE); 1798 1.1 bouyer /* select endpoint */ 1799 1.1 bouyer UWRITE1(sc, MUSB2_REG_EPINDEX, ep->ep_number); 1800 1.14 skrll if (UE_GET_DIR(xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress) 1801 1.1 bouyer == UE_DIR_IN) { 1802 1.1 bouyer val = UREAD1(sc, MUSB2_REG_RXCSRL); 1803 1.1 bouyer KASSERT((val & MUSB2_MASK_CSRL_RXPKTRDY) == 0); 1804 1.1 bouyer motg_device_data_read(xfer); 1805 1.1 bouyer } else { 1806 1.1 bouyer ep->phase = DATA_OUT; 1807 1.1 bouyer val = UREAD1(sc, MUSB2_REG_TXCSRL); 1808 1.1 bouyer KASSERT((val & MUSB2_MASK_CSRL_TXPKTRDY) == 0); 1809 1.1 bouyer motg_device_data_write(xfer); 1810 1.1 bouyer } 1811 1.1 bouyer end: 1812 1.1 bouyer if (err) 1813 1.14 skrll return err; 1814 1.1 bouyer 1815 1.14 skrll return USBD_IN_PROGRESS; 1816 1.1 bouyer } 1817 1.1 bouyer 1818 1.1 bouyer static void 1819 1.14 skrll motg_device_data_read(struct usbd_xfer *xfer) 1820 1.1 bouyer { 1821 1.14 skrll struct motg_softc *sc = MOTG_XFER2SC(xfer); 1822 1.14 skrll struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe); 1823 1.1 bouyer uint32_t val; 1824 1.1 bouyer 1825 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1826 1.14 skrll 1827 1.1 bouyer KASSERT(mutex_owned(&sc->sc_lock)); 1828 1.1 bouyer /* assume endpoint already selected */ 1829 1.1 bouyer motg_setup_endpoint_rx(xfer); 1830 1.1 bouyer /* Max packet size */ 1831 1.1 bouyer UWRITE2(sc, MUSB2_REG_RXMAXP, 1832 1.14 skrll UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize)); 1833 1.1 bouyer /* Data Toggle */ 1834 1.1 bouyer val = UREAD1(sc, MUSB2_REG_RXCSRH); 1835 1.1 bouyer val |= MUSB2_MASK_CSRH_RXDT_WREN; 1836 1.1 bouyer if (otgpipe->nexttoggle) 1837 1.1 bouyer val |= MUSB2_MASK_CSRH_RXDT_VAL; 1838 1.1 bouyer else 1839 1.1 bouyer val &= ~MUSB2_MASK_CSRH_RXDT_VAL; 1840 1.1 bouyer UWRITE1(sc, MUSB2_REG_RXCSRH, val); 1841 1.1 bouyer 1842 1.34 christos DPRINTFN(MD_BULK, "%#jx to DATA_IN on ep %jd, csrh %#jx", 1843 1.18 pgoyette (uintptr_t)xfer, otgpipe->hw_ep->ep_number, 1844 1.18 pgoyette UREAD1(sc, MUSB2_REG_RXCSRH), 0); 1845 1.1 bouyer /* start transaction */ 1846 1.1 bouyer UWRITE1(sc, MUSB2_REG_RXCSRL, MUSB2_MASK_CSRL_RXREQPKT); 1847 1.1 bouyer otgpipe->hw_ep->phase = DATA_IN; 1848 1.1 bouyer } 1849 1.1 bouyer 1850 1.1 bouyer static void 1851 1.14 skrll motg_device_data_write(struct usbd_xfer *xfer) 1852 1.1 bouyer { 1853 1.14 skrll struct motg_softc *sc = MOTG_XFER2SC(xfer); 1854 1.14 skrll struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe); 1855 1.1 bouyer struct motg_hw_ep *ep = otgpipe->hw_ep; 1856 1.1 bouyer int datalen; 1857 1.1 bouyer char *data; 1858 1.1 bouyer uint32_t val; 1859 1.1 bouyer 1860 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1861 1.14 skrll 1862 1.1 bouyer KASSERT(xfer!=NULL); 1863 1.1 bouyer KASSERT(mutex_owned(&sc->sc_lock)); 1864 1.1 bouyer 1865 1.23 riastrad datalen = uimin(ep->datalen, 1866 1.14 skrll UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize)); 1867 1.1 bouyer ep->phase = DATA_OUT; 1868 1.34 christos DPRINTFN(MD_BULK, "%#jx to DATA_OUT on ep %jd, len %jd csrh %#jx", 1869 1.18 pgoyette (uintptr_t)xfer, ep->ep_number, datalen, 1870 1.18 pgoyette UREAD1(sc, MUSB2_REG_TXCSRH)); 1871 1.1 bouyer 1872 1.1 bouyer /* assume endpoint already selected */ 1873 1.1 bouyer /* write data to fifo */ 1874 1.1 bouyer data = ep->data; 1875 1.1 bouyer ep->data += datalen; 1876 1.1 bouyer ep->datalen -= datalen; 1877 1.14 skrll xfer->ux_actlen += datalen; 1878 1.1 bouyer if (((vaddr_t)data & 0x3) == 0 && 1879 1.1 bouyer (datalen >> 2) > 0) { 1880 1.1 bouyer bus_space_write_multi_4(sc->sc_iot, sc->sc_ioh, 1881 1.1 bouyer MUSB2_REG_EPFIFO(ep->ep_number), 1882 1.1 bouyer (void *)data, datalen >> 2); 1883 1.1 bouyer data += (datalen & ~0x3); 1884 1.1 bouyer datalen -= (datalen & ~0x3); 1885 1.1 bouyer } 1886 1.1 bouyer if (datalen) { 1887 1.1 bouyer bus_space_write_multi_1(sc->sc_iot, sc->sc_ioh, 1888 1.1 bouyer MUSB2_REG_EPFIFO(ep->ep_number), data, datalen); 1889 1.1 bouyer } 1890 1.1 bouyer 1891 1.1 bouyer motg_setup_endpoint_tx(xfer); 1892 1.1 bouyer /* Max packet size */ 1893 1.1 bouyer UWRITE2(sc, MUSB2_REG_TXMAXP, 1894 1.14 skrll UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize)); 1895 1.1 bouyer /* Data Toggle */ 1896 1.1 bouyer val = UREAD1(sc, MUSB2_REG_TXCSRH); 1897 1.1 bouyer val |= MUSB2_MASK_CSRH_TXDT_WREN; 1898 1.1 bouyer if (otgpipe->nexttoggle) 1899 1.1 bouyer val |= MUSB2_MASK_CSRH_TXDT_VAL; 1900 1.1 bouyer else 1901 1.1 bouyer val &= ~MUSB2_MASK_CSRH_TXDT_VAL; 1902 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXCSRH, val); 1903 1.1 bouyer 1904 1.1 bouyer /* start transaction */ 1905 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXCSRL, MUSB2_MASK_CSRL_TXPKTRDY); 1906 1.1 bouyer } 1907 1.1 bouyer 1908 1.1 bouyer static void 1909 1.1 bouyer motg_device_intr_rx(struct motg_softc *sc, int epnumber) 1910 1.1 bouyer { 1911 1.1 bouyer struct motg_hw_ep *ep = &sc->sc_in_ep[epnumber]; 1912 1.14 skrll struct usbd_xfer *xfer = ep->xfer; 1913 1.1 bouyer uint8_t csr; 1914 1.1 bouyer int datalen, max_datalen; 1915 1.1 bouyer char *data; 1916 1.1 bouyer bool got_short; 1917 1.3 bouyer usbd_status new_status = USBD_IN_PROGRESS; 1918 1.1 bouyer 1919 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 1920 1.14 skrll 1921 1.1 bouyer KASSERT(mutex_owned(&sc->sc_lock)); 1922 1.1 bouyer KASSERT(ep->ep_number == epnumber); 1923 1.1 bouyer 1924 1.18 pgoyette DPRINTFN(MD_BULK, "on ep %jd", epnumber, 0, 0, 0); 1925 1.14 skrll /* select endpoint */ 1926 1.1 bouyer UWRITE1(sc, MUSB2_REG_EPINDEX, epnumber); 1927 1.1 bouyer 1928 1.1 bouyer /* read out FIFO status */ 1929 1.1 bouyer csr = UREAD1(sc, MUSB2_REG_RXCSRL); 1930 1.34 christos DPRINTFN(MD_BULK, "phase %jd csr %#jx", ep->phase, csr ,0 ,0); 1931 1.1 bouyer 1932 1.1 bouyer if ((csr & (MUSB2_MASK_CSRL_RXNAKTO | MUSB2_MASK_CSRL_RXSTALL | 1933 1.1 bouyer MUSB2_MASK_CSRL_RXERROR | MUSB2_MASK_CSRL_RXPKTRDY)) == 0) 1934 1.1 bouyer return; 1935 1.1 bouyer 1936 1.14 skrll KASSERTMSG(ep->phase == DATA_IN, "phase %d", ep->phase); 1937 1.1 bouyer if (csr & MUSB2_MASK_CSRL_RXNAKTO) { 1938 1.1 bouyer csr &= ~MUSB2_MASK_CSRL_RXREQPKT; 1939 1.1 bouyer UWRITE1(sc, MUSB2_REG_RXCSRL, csr); 1940 1.1 bouyer 1941 1.1 bouyer csr &= ~MUSB2_MASK_CSRL_RXNAKTO; 1942 1.1 bouyer UWRITE1(sc, MUSB2_REG_RXCSRL, csr); 1943 1.3 bouyer new_status = USBD_TIMEOUT; /* XXX */ 1944 1.1 bouyer goto complete; 1945 1.1 bouyer } 1946 1.1 bouyer if (csr & (MUSB2_MASK_CSRL_RXSTALL | MUSB2_MASK_CSRL_RXERROR)) { 1947 1.7 skrll if (csr & MUSB2_MASK_CSRL_RXSTALL) 1948 1.3 bouyer new_status = USBD_STALLED; 1949 1.3 bouyer else 1950 1.3 bouyer new_status = USBD_IOERROR; 1951 1.1 bouyer /* clear status */ 1952 1.1 bouyer UWRITE1(sc, MUSB2_REG_RXCSRL, 0); 1953 1.1 bouyer goto complete; 1954 1.1 bouyer } 1955 1.1 bouyer KASSERT(csr & MUSB2_MASK_CSRL_RXPKTRDY); 1956 1.1 bouyer 1957 1.14 skrll if (xfer == NULL || xfer->ux_status != USBD_IN_PROGRESS) { 1958 1.1 bouyer UWRITE1(sc, MUSB2_REG_RXCSRL, 0); 1959 1.1 bouyer goto complete; 1960 1.1 bouyer } 1961 1.1 bouyer 1962 1.14 skrll struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe); 1963 1.1 bouyer otgpipe->nexttoggle = otgpipe->nexttoggle ^ 1; 1964 1.1 bouyer 1965 1.1 bouyer datalen = UREAD2(sc, MUSB2_REG_RXCOUNT); 1966 1.18 pgoyette DPRINTFN(MD_BULK, "phase %jd datalen %jd", ep->phase, datalen ,0 ,0); 1967 1.14 skrll KASSERT(UE_GET_SIZE(UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize)) > 0); 1968 1.23 riastrad max_datalen = uimin( 1969 1.14 skrll UE_GET_SIZE(UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize)), 1970 1.1 bouyer ep->datalen); 1971 1.1 bouyer if (datalen > max_datalen) { 1972 1.3 bouyer new_status = USBD_IOERROR; 1973 1.1 bouyer UWRITE1(sc, MUSB2_REG_RXCSRL, 0); 1974 1.1 bouyer goto complete; 1975 1.1 bouyer } 1976 1.1 bouyer got_short = (datalen < max_datalen); 1977 1.1 bouyer if (datalen > 0) { 1978 1.1 bouyer KASSERT(ep->phase == DATA_IN); 1979 1.1 bouyer data = ep->data; 1980 1.1 bouyer ep->data += datalen; 1981 1.1 bouyer ep->datalen -= datalen; 1982 1.14 skrll xfer->ux_actlen += datalen; 1983 1.1 bouyer if (((vaddr_t)data & 0x3) == 0 && 1984 1.1 bouyer (datalen >> 2) > 0) { 1985 1.18 pgoyette DPRINTFN(MD_BULK, "r4 data %#jx len %jd", 1986 1.18 pgoyette (uintptr_t)data, datalen, 0, 0); 1987 1.1 bouyer bus_space_read_multi_4(sc->sc_iot, sc->sc_ioh, 1988 1.1 bouyer MUSB2_REG_EPFIFO(ep->ep_number), 1989 1.1 bouyer (void *)data, datalen >> 2); 1990 1.1 bouyer data += (datalen & ~0x3); 1991 1.1 bouyer datalen -= (datalen & ~0x3); 1992 1.1 bouyer } 1993 1.18 pgoyette DPRINTFN(MD_BULK, "r1 data %#jx len %jd", (uintptr_t)data, 1994 1.18 pgoyette datalen ,0 ,0); 1995 1.1 bouyer if (datalen) { 1996 1.1 bouyer bus_space_read_multi_1(sc->sc_iot, sc->sc_ioh, 1997 1.1 bouyer MUSB2_REG_EPFIFO(ep->ep_number), data, datalen); 1998 1.1 bouyer } 1999 1.1 bouyer } 2000 1.1 bouyer UWRITE1(sc, MUSB2_REG_RXCSRL, 0); 2001 1.1 bouyer KASSERT(ep->phase == DATA_IN); 2002 1.1 bouyer if (got_short || (ep->datalen == 0)) { 2003 1.1 bouyer if (ep->need_short_xfer == 0) { 2004 1.3 bouyer new_status = USBD_NORMAL_COMPLETION; 2005 1.1 bouyer goto complete; 2006 1.1 bouyer } 2007 1.1 bouyer ep->need_short_xfer = 0; 2008 1.1 bouyer } 2009 1.1 bouyer motg_device_data_read(xfer); 2010 1.1 bouyer return; 2011 1.1 bouyer complete: 2012 1.18 pgoyette DPRINTFN(MD_BULK, "xfer %#jx complete, status %jd", (uintptr_t)xfer, 2013 1.14 skrll (xfer != NULL) ? xfer->ux_status : 0, 0, 0); 2014 1.1 bouyer ep->phase = IDLE; 2015 1.1 bouyer ep->xfer = NULL; 2016 1.31 riastrad /* 2017 1.31 riastrad * Try to claim this xfer for completion. If it has already 2018 1.31 riastrad * completed or aborted, drop it on the floor. 2019 1.31 riastrad */ 2020 1.31 riastrad if (xfer && usbd_xfer_trycomplete(xfer)) { 2021 1.31 riastrad KASSERT(xfer->ux_status == USBD_IN_PROGRESS); 2022 1.3 bouyer KASSERT(new_status != USBD_IN_PROGRESS); 2023 1.14 skrll xfer->ux_status = new_status; 2024 1.1 bouyer usb_transfer_complete(xfer); 2025 1.3 bouyer } 2026 1.1 bouyer motg_device_data_start1(sc, ep); 2027 1.1 bouyer } 2028 1.1 bouyer 2029 1.1 bouyer static void 2030 1.1 bouyer motg_device_intr_tx(struct motg_softc *sc, int epnumber) 2031 1.1 bouyer { 2032 1.1 bouyer struct motg_hw_ep *ep = &sc->sc_out_ep[epnumber]; 2033 1.14 skrll struct usbd_xfer *xfer = ep->xfer; 2034 1.1 bouyer uint8_t csr; 2035 1.1 bouyer struct motg_pipe *otgpipe; 2036 1.3 bouyer usbd_status new_status = USBD_IN_PROGRESS; 2037 1.1 bouyer 2038 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 2039 1.14 skrll 2040 1.1 bouyer KASSERT(mutex_owned(&sc->sc_lock)); 2041 1.1 bouyer KASSERT(ep->ep_number == epnumber); 2042 1.1 bouyer 2043 1.18 pgoyette DPRINTFN(MD_BULK, " on ep %jd", epnumber, 0, 0, 0); 2044 1.14 skrll /* select endpoint */ 2045 1.1 bouyer UWRITE1(sc, MUSB2_REG_EPINDEX, epnumber); 2046 1.1 bouyer 2047 1.1 bouyer csr = UREAD1(sc, MUSB2_REG_TXCSRL); 2048 1.34 christos DPRINTFN(MD_BULK, "phase %jd csr %#jx", ep->phase, csr, 0, 0); 2049 1.1 bouyer 2050 1.1 bouyer if (csr & (MUSB2_MASK_CSRL_TXSTALLED|MUSB2_MASK_CSRL_TXERROR)) { 2051 1.1 bouyer /* command not accepted */ 2052 1.7 skrll if (csr & MUSB2_MASK_CSRL_TXSTALLED) 2053 1.3 bouyer new_status = USBD_STALLED; 2054 1.3 bouyer else 2055 1.3 bouyer new_status = USBD_IOERROR; 2056 1.1 bouyer /* clear status */ 2057 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXCSRL, 0); 2058 1.1 bouyer goto complete; 2059 1.1 bouyer } 2060 1.1 bouyer if (csr & MUSB2_MASK_CSRL_TXNAKTO) { 2061 1.3 bouyer new_status = USBD_TIMEOUT; /* XXX */ 2062 1.3 bouyer csr &= ~MUSB2_MASK_CSRL_TXNAKTO; 2063 1.3 bouyer UWRITE1(sc, MUSB2_REG_TXCSRL, csr); 2064 1.1 bouyer /* flush fifo */ 2065 1.1 bouyer while (csr & MUSB2_MASK_CSRL_TXFIFONEMPTY) { 2066 1.1 bouyer csr |= MUSB2_MASK_CSRL_TXFFLUSH; 2067 1.3 bouyer csr &= ~MUSB2_MASK_CSRL_TXNAKTO; 2068 1.1 bouyer UWRITE1(sc, MUSB2_REG_TXCSRL, csr); 2069 1.3 bouyer delay(1000); 2070 1.1 bouyer csr = UREAD1(sc, MUSB2_REG_TXCSRL); 2071 1.34 christos DPRINTFN(MD_BULK, "TX fifo flush ep %jd CSR %#jx", 2072 1.14 skrll epnumber, csr, 0, 0); 2073 1.1 bouyer } 2074 1.1 bouyer goto complete; 2075 1.1 bouyer } 2076 1.1 bouyer if (csr & (MUSB2_MASK_CSRL_TXFIFONEMPTY|MUSB2_MASK_CSRL_TXPKTRDY)) { 2077 1.1 bouyer /* data still not sent */ 2078 1.1 bouyer return; 2079 1.1 bouyer } 2080 1.14 skrll if (xfer == NULL || xfer->ux_status != USBD_IN_PROGRESS) 2081 1.1 bouyer goto complete; 2082 1.14 skrll KASSERT(ep->phase == DATA_OUT); 2083 1.7 skrll 2084 1.14 skrll otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe); 2085 1.1 bouyer otgpipe->nexttoggle = otgpipe->nexttoggle ^ 1; 2086 1.1 bouyer 2087 1.1 bouyer if (ep->datalen == 0) { 2088 1.1 bouyer if (ep->need_short_xfer) { 2089 1.1 bouyer ep->need_short_xfer = 0; 2090 1.1 bouyer /* one more data phase */ 2091 1.1 bouyer } else { 2092 1.3 bouyer new_status = USBD_NORMAL_COMPLETION; 2093 1.1 bouyer goto complete; 2094 1.1 bouyer } 2095 1.1 bouyer } 2096 1.1 bouyer motg_device_data_write(xfer); 2097 1.1 bouyer return; 2098 1.1 bouyer 2099 1.1 bouyer complete: 2100 1.18 pgoyette DPRINTFN(MD_BULK, "xfer %#jx complete, status %jd", (uintptr_t)xfer, 2101 1.14 skrll (xfer != NULL) ? xfer->ux_status : 0, 0, 0); 2102 1.1 bouyer ep->phase = IDLE; 2103 1.1 bouyer ep->xfer = NULL; 2104 1.31 riastrad /* 2105 1.31 riastrad * Try to claim this xfer for completion. If it has already 2106 1.31 riastrad * completed or aborted, drop it on the floor. 2107 1.31 riastrad */ 2108 1.31 riastrad if (xfer && usbd_xfer_trycomplete(xfer)) { 2109 1.31 riastrad KASSERT(xfer->ux_status == USBD_IN_PROGRESS); 2110 1.3 bouyer KASSERT(new_status != USBD_IN_PROGRESS); 2111 1.14 skrll xfer->ux_status = new_status; 2112 1.1 bouyer usb_transfer_complete(xfer); 2113 1.3 bouyer } 2114 1.1 bouyer motg_device_data_start1(sc, ep); 2115 1.1 bouyer } 2116 1.1 bouyer 2117 1.1 bouyer /* Abort a device control request. */ 2118 1.1 bouyer void 2119 1.14 skrll motg_device_data_abort(struct usbd_xfer *xfer) 2120 1.1 bouyer { 2121 1.14 skrll struct motg_softc __diagused *sc = MOTG_XFER2SC(xfer); 2122 1.1 bouyer KASSERT(mutex_owned(&sc->sc_lock)); 2123 1.1 bouyer 2124 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 2125 1.14 skrll 2126 1.26 riastrad usbd_xfer_abort(xfer); 2127 1.1 bouyer } 2128 1.1 bouyer 2129 1.1 bouyer /* Close a device control pipe */ 2130 1.1 bouyer void 2131 1.14 skrll motg_device_data_close(struct usbd_pipe *pipe) 2132 1.1 bouyer { 2133 1.14 skrll struct motg_softc *sc __diagused = MOTG_PIPE2SC(pipe); 2134 1.14 skrll struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(pipe); 2135 1.1 bouyer struct motg_pipe *otgpipeiter; 2136 1.1 bouyer 2137 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 2138 1.14 skrll 2139 1.1 bouyer KASSERT(mutex_owned(&sc->sc_lock)); 2140 1.1 bouyer KASSERT(otgpipe->hw_ep->xfer == NULL || 2141 1.14 skrll otgpipe->hw_ep->xfer->ux_pipe != pipe); 2142 1.1 bouyer 2143 1.14 skrll pipe->up_endpoint->ue_toggle = otgpipe->nexttoggle; 2144 1.1 bouyer SIMPLEQ_FOREACH(otgpipeiter, &otgpipe->hw_ep->ep_pipes, ep_pipe_list) { 2145 1.1 bouyer if (otgpipeiter == otgpipe) { 2146 1.1 bouyer /* remove from list */ 2147 1.1 bouyer SIMPLEQ_REMOVE(&otgpipe->hw_ep->ep_pipes, otgpipe, 2148 1.1 bouyer motg_pipe, ep_pipe_list); 2149 1.1 bouyer otgpipe->hw_ep->refcount--; 2150 1.1 bouyer /* we're done */ 2151 1.1 bouyer return; 2152 1.1 bouyer } 2153 1.1 bouyer } 2154 1.1 bouyer panic("motg_device_data_close: not found"); 2155 1.1 bouyer } 2156 1.1 bouyer 2157 1.1 bouyer void 2158 1.14 skrll motg_device_data_done(struct usbd_xfer *xfer) 2159 1.1 bouyer { 2160 1.14 skrll struct motg_pipe *otgpipe __diagused = MOTG_PIPE2MPIPE(xfer->ux_pipe); 2161 1.14 skrll MOTGHIST_FUNC(); MOTGHIST_CALLED(); 2162 1.14 skrll 2163 1.1 bouyer KASSERT(otgpipe->hw_ep->xfer != xfer); 2164 1.1 bouyer } 2165 1.1 bouyer 2166 1.1 bouyer void 2167 1.14 skrll motg_device_clear_toggle(struct usbd_pipe *pipe) 2168 1.1 bouyer { 2169 1.14 skrll struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(pipe); 2170 1.1 bouyer otgpipe->nexttoggle = 0; 2171 1.1 bouyer } 2172 1.3 bouyer 2173 1.3 bouyer /* Abort a device control request. */ 2174 1.3 bouyer static void 2175 1.26 riastrad motg_abortx(struct usbd_xfer *xfer) 2176 1.3 bouyer { 2177 1.22 mrg MOTGHIST_FUNC(); MOTGHIST_CALLED(); 2178 1.3 bouyer uint8_t csr; 2179 1.14 skrll struct motg_softc *sc = MOTG_XFER2SC(xfer); 2180 1.14 skrll struct motg_pipe *otgpipe = MOTG_PIPE2MPIPE(xfer->ux_pipe); 2181 1.22 mrg 2182 1.3 bouyer KASSERT(mutex_owned(&sc->sc_lock)); 2183 1.22 mrg ASSERT_SLEEPABLE(); 2184 1.22 mrg 2185 1.22 mrg /* 2186 1.22 mrg * If we're dying, skip the hardware action and just notify the 2187 1.22 mrg * software that we're done. 2188 1.22 mrg */ 2189 1.22 mrg if (sc->sc_dying) { 2190 1.22 mrg goto dying; 2191 1.3 bouyer } 2192 1.22 mrg 2193 1.3 bouyer if (otgpipe->hw_ep->xfer == xfer) { 2194 1.3 bouyer otgpipe->hw_ep->xfer = NULL; 2195 1.3 bouyer if (otgpipe->hw_ep->ep_number > 0) { 2196 1.7 skrll /* select endpoint */ 2197 1.3 bouyer UWRITE1(sc, MUSB2_REG_EPINDEX, 2198 1.3 bouyer otgpipe->hw_ep->ep_number); 2199 1.3 bouyer if (otgpipe->hw_ep->phase == DATA_OUT) { 2200 1.3 bouyer csr = UREAD1(sc, MUSB2_REG_TXCSRL); 2201 1.3 bouyer while (csr & MUSB2_MASK_CSRL_TXFIFONEMPTY) { 2202 1.3 bouyer csr |= MUSB2_MASK_CSRL_TXFFLUSH; 2203 1.3 bouyer UWRITE1(sc, MUSB2_REG_TXCSRL, csr); 2204 1.3 bouyer csr = UREAD1(sc, MUSB2_REG_TXCSRL); 2205 1.3 bouyer } 2206 1.3 bouyer UWRITE1(sc, MUSB2_REG_TXCSRL, 0); 2207 1.3 bouyer } else if (otgpipe->hw_ep->phase == DATA_IN) { 2208 1.3 bouyer csr = UREAD1(sc, MUSB2_REG_RXCSRL); 2209 1.3 bouyer while (csr & MUSB2_MASK_CSRL_RXPKTRDY) { 2210 1.3 bouyer csr |= MUSB2_MASK_CSRL_RXFFLUSH; 2211 1.3 bouyer UWRITE1(sc, MUSB2_REG_RXCSRL, csr); 2212 1.3 bouyer csr = UREAD1(sc, MUSB2_REG_RXCSRL); 2213 1.3 bouyer } 2214 1.3 bouyer UWRITE1(sc, MUSB2_REG_RXCSRL, 0); 2215 1.3 bouyer } 2216 1.3 bouyer otgpipe->hw_ep->phase = IDLE; 2217 1.3 bouyer } 2218 1.3 bouyer } 2219 1.22 mrg dying: 2220 1.22 mrg KASSERT(mutex_owned(&sc->sc_lock)); 2221 1.3 bouyer } 2222