1 1.320 skrll /* $NetBSD: uhci.c,v 1.320 2025/04/26 07:06:53 skrll Exp $ */ 2 1.1 augustss 3 1.1 augustss /* 4 1.303 skrll * Copyright (c) 1998, 2004, 2011, 2012, 2016, 2020 The NetBSD Foundation, Inc. 5 1.1 augustss * All rights reserved. 6 1.1 augustss * 7 1.11 augustss * This code is derived from software contributed to The NetBSD Foundation 8 1.113 augustss * by Lennart Augustsson (lennart (at) augustsson.net) at 9 1.303 skrll * Carlstedt Research & Technology, Jared D. McNeill (jmcneill (at) invisible.ca), 10 1.317 mrg * Matthew R. Green (mrg (at) eterna23.net) and Nick Hudson. 11 1.1 augustss * 12 1.1 augustss * Redistribution and use in source and binary forms, with or without 13 1.1 augustss * modification, are permitted provided that the following conditions 14 1.1 augustss * are met: 15 1.1 augustss * 1. Redistributions of source code must retain the above copyright 16 1.1 augustss * notice, this list of conditions and the following disclaimer. 17 1.1 augustss * 2. Redistributions in binary form must reproduce the above copyright 18 1.1 augustss * notice, this list of conditions and the following disclaimer in the 19 1.1 augustss * documentation and/or other materials provided with the distribution. 20 1.1 augustss * 21 1.1 augustss * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 1.1 augustss * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 1.1 augustss * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 1.1 augustss * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 1.1 augustss * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 1.1 augustss * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 1.1 augustss * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 1.1 augustss * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 1.1 augustss * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 1.1 augustss * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 1.1 augustss * POSSIBILITY OF SUCH DAMAGE. 32 1.1 augustss */ 33 1.1 augustss 34 1.1 augustss /* 35 1.1 augustss * USB Universal Host Controller driver. 36 1.28 augustss * Handles e.g. PIIX3 and PIIX4. 37 1.1 augustss * 38 1.229 uebayasi * UHCI spec: http://www.intel.com/technology/usb/spec.htm 39 1.229 uebayasi * USB spec: http://www.usb.org/developers/docs/ 40 1.71 augustss * PIIXn spec: ftp://download.intel.com/design/intarch/datashts/29055002.pdf 41 1.71 augustss * ftp://download.intel.com/design/intarch/datashts/29056201.pdf 42 1.1 augustss */ 43 1.143 lukem 44 1.143 lukem #include <sys/cdefs.h> 45 1.320 skrll __KERNEL_RCSID(0, "$NetBSD: uhci.c,v 1.320 2025/04/26 07:06:53 skrll Exp $"); 46 1.268 skrll 47 1.273 pooka #ifdef _KERNEL_OPT 48 1.268 skrll #include "opt_usb.h" 49 1.273 pooka #endif 50 1.1 augustss 51 1.1 augustss #include <sys/param.h> 52 1.268 skrll 53 1.268 skrll #include <sys/bus.h> 54 1.268 skrll #include <sys/cpu.h> 55 1.268 skrll #include <sys/device.h> 56 1.1 augustss #include <sys/kernel.h> 57 1.248 mrg #include <sys/kmem.h> 58 1.268 skrll #include <sys/mutex.h> 59 1.1 augustss #include <sys/proc.h> 60 1.1 augustss #include <sys/queue.h> 61 1.268 skrll #include <sys/select.h> 62 1.268 skrll #include <sys/sysctl.h> 63 1.268 skrll #include <sys/systm.h> 64 1.1 augustss 65 1.39 augustss #include <machine/endian.h> 66 1.7 augustss 67 1.1 augustss #include <dev/usb/usb.h> 68 1.1 augustss #include <dev/usb/usbdi.h> 69 1.1 augustss #include <dev/usb/usbdivar.h> 70 1.7 augustss #include <dev/usb/usb_mem.h> 71 1.1 augustss 72 1.1 augustss #include <dev/usb/uhcireg.h> 73 1.1 augustss #include <dev/usb/uhcivar.h> 74 1.268 skrll #include <dev/usb/usbroothub.h> 75 1.268 skrll #include <dev/usb/usbhist.h> 76 1.1 augustss 77 1.125 augustss /* Use bandwidth reclamation for control transfers. Some devices choke on it. */ 78 1.125 augustss /*#define UHCI_CTL_LOOP */ 79 1.125 augustss 80 1.67 augustss #ifdef UHCI_DEBUG 81 1.92 augustss uhci_softc_t *thesc; 82 1.125 augustss int uhcinoloop = 0; 83 1.268 skrll #endif 84 1.268 skrll 85 1.268 skrll #ifdef USB_DEBUG 86 1.268 skrll #ifndef UHCI_DEBUG 87 1.268 skrll #define uhcidebug 0 88 1.59 augustss #else 89 1.268 skrll static int uhcidebug = 0; 90 1.268 skrll 91 1.268 skrll SYSCTL_SETUP(sysctl_hw_uhci_setup, "sysctl hw.uhci setup") 92 1.268 skrll { 93 1.268 skrll int err; 94 1.268 skrll const struct sysctlnode *rnode; 95 1.268 skrll const struct sysctlnode *cnode; 96 1.268 skrll 97 1.268 skrll err = sysctl_createv(clog, 0, NULL, &rnode, 98 1.268 skrll CTLFLAG_PERMANENT, CTLTYPE_NODE, "uhci", 99 1.268 skrll SYSCTL_DESCR("uhci global controls"), 100 1.268 skrll NULL, 0, NULL, 0, CTL_HW, CTL_CREATE, CTL_EOL); 101 1.268 skrll 102 1.268 skrll if (err) 103 1.268 skrll goto fail; 104 1.268 skrll 105 1.268 skrll /* control debugging printfs */ 106 1.268 skrll err = sysctl_createv(clog, 0, &rnode, &cnode, 107 1.268 skrll CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT, 108 1.268 skrll "debug", SYSCTL_DESCR("Enable debugging output"), 109 1.268 skrll NULL, 0, &uhcidebug, sizeof(uhcidebug), CTL_CREATE, CTL_EOL); 110 1.268 skrll if (err) 111 1.268 skrll goto fail; 112 1.268 skrll 113 1.268 skrll return; 114 1.268 skrll fail: 115 1.268 skrll aprint_error("%s: sysctl_createv failed (err = %d)\n", __func__, err); 116 1.268 skrll } 117 1.268 skrll 118 1.268 skrll #endif /* UHCI_DEBUG */ 119 1.268 skrll #endif /* USB_DEBUG */ 120 1.268 skrll 121 1.268 skrll #define DPRINTF(FMT,A,B,C,D) USBHIST_LOGN(uhcidebug,1,FMT,A,B,C,D) 122 1.268 skrll #define DPRINTFN(N,FMT,A,B,C,D) USBHIST_LOGN(uhcidebug,N,FMT,A,B,C,D) 123 1.268 skrll #define UHCIHIST_FUNC() USBHIST_FUNC() 124 1.268 skrll #define UHCIHIST_CALLED(name) USBHIST_CALLED(uhcidebug) 125 1.59 augustss 126 1.39 augustss /* 127 1.39 augustss * The UHCI controller is little endian, so on big endian machines 128 1.181 drochner * the data stored in memory needs to be swapped. 129 1.39 augustss */ 130 1.39 augustss 131 1.1 augustss struct uhci_pipe { 132 1.1 augustss struct usbd_pipe pipe; 133 1.32 augustss int nexttoggle; 134 1.92 augustss 135 1.92 augustss u_char aborting; 136 1.268 skrll struct usbd_xfer *abortstart, abortend; 137 1.92 augustss 138 1.1 augustss /* Info needed for different pipe kinds. */ 139 1.1 augustss union { 140 1.1 augustss /* Control pipe */ 141 1.1 augustss struct { 142 1.1 augustss uhci_soft_qh_t *sqh; 143 1.7 augustss usb_dma_t reqdma; 144 1.268 skrll uhci_soft_td_t *setup; 145 1.268 skrll uhci_soft_td_t *stat; 146 1.268 skrll } ctrl; 147 1.1 augustss /* Interrupt pipe */ 148 1.1 augustss struct { 149 1.1 augustss int npoll; 150 1.1 augustss uhci_soft_qh_t **qhs; 151 1.1 augustss } intr; 152 1.1 augustss /* Bulk pipe */ 153 1.1 augustss struct { 154 1.1 augustss uhci_soft_qh_t *sqh; 155 1.1 augustss } bulk; 156 1.268 skrll /* Isochronous pipe */ 157 1.268 skrll struct isoc { 158 1.16 augustss uhci_soft_td_t **stds; 159 1.48 augustss int next, inuse; 160 1.268 skrll } isoc; 161 1.268 skrll }; 162 1.1 augustss }; 163 1.1 augustss 164 1.268 skrll typedef TAILQ_HEAD(ux_completeq, uhci_xfer) ux_completeq_t; 165 1.268 skrll 166 1.142 augustss Static void uhci_globalreset(uhci_softc_t *); 167 1.166 dsainty Static usbd_status uhci_portreset(uhci_softc_t*, int); 168 1.142 augustss Static void uhci_reset(uhci_softc_t *); 169 1.314 riastrad Static usbd_status uhci_run(uhci_softc_t *, int); 170 1.123 augustss Static uhci_soft_td_t *uhci_alloc_std(uhci_softc_t *); 171 1.119 augustss Static void uhci_free_std(uhci_softc_t *, uhci_soft_td_t *); 172 1.268 skrll Static void uhci_free_std_locked(uhci_softc_t *, uhci_soft_td_t *); 173 1.123 augustss Static uhci_soft_qh_t *uhci_alloc_sqh(uhci_softc_t *); 174 1.119 augustss Static void uhci_free_sqh(uhci_softc_t *, uhci_soft_qh_t *); 175 1.16 augustss #if 0 176 1.119 augustss Static void uhci_enter_ctl_q(uhci_softc_t *, uhci_soft_qh_t *, 177 1.268 skrll uhci_intr_info_t *); 178 1.119 augustss Static void uhci_exit_ctl_q(uhci_softc_t *, uhci_soft_qh_t *); 179 1.16 augustss #endif 180 1.1 augustss 181 1.268 skrll #if 0 182 1.268 skrll Static void uhci_free_std_chain(uhci_softc_t *, uhci_soft_td_t *, 183 1.268 skrll uhci_soft_td_t *); 184 1.268 skrll #endif 185 1.268 skrll Static int uhci_alloc_std_chain(uhci_softc_t *, struct usbd_xfer *, 186 1.268 skrll int, int, uhci_soft_td_t **); 187 1.268 skrll Static void uhci_free_stds(uhci_softc_t *, struct uhci_xfer *); 188 1.268 skrll 189 1.268 skrll Static void uhci_reset_std_chain(uhci_softc_t *, struct usbd_xfer *, 190 1.268 skrll int, int, int *, uhci_soft_td_t **); 191 1.268 skrll 192 1.119 augustss Static void uhci_poll_hub(void *); 193 1.268 skrll Static void uhci_check_intr(uhci_softc_t *, struct uhci_xfer *, 194 1.268 skrll ux_completeq_t *); 195 1.268 skrll Static void uhci_idone(struct uhci_xfer *, ux_completeq_t *); 196 1.119 augustss 197 1.289 riastrad Static void uhci_abortx(struct usbd_xfer *); 198 1.119 augustss 199 1.123 augustss Static void uhci_add_ls_ctrl(uhci_softc_t *, uhci_soft_qh_t *); 200 1.123 augustss Static void uhci_add_hs_ctrl(uhci_softc_t *, uhci_soft_qh_t *); 201 1.119 augustss Static void uhci_add_bulk(uhci_softc_t *, uhci_soft_qh_t *); 202 1.123 augustss Static void uhci_remove_ls_ctrl(uhci_softc_t *,uhci_soft_qh_t *); 203 1.123 augustss Static void uhci_remove_hs_ctrl(uhci_softc_t *,uhci_soft_qh_t *); 204 1.119 augustss Static void uhci_remove_bulk(uhci_softc_t *,uhci_soft_qh_t *); 205 1.268 skrll Static void uhci_add_loop(uhci_softc_t *); 206 1.268 skrll Static void uhci_rem_loop(uhci_softc_t *); 207 1.119 augustss 208 1.268 skrll Static usbd_status uhci_setup_isoc(struct usbd_pipe *); 209 1.119 augustss 210 1.268 skrll Static struct usbd_xfer * 211 1.268 skrll uhci_allocx(struct usbd_bus *, unsigned int); 212 1.268 skrll Static void uhci_freex(struct usbd_bus *, struct usbd_xfer *); 213 1.289 riastrad Static bool uhci_dying(struct usbd_bus *); 214 1.248 mrg Static void uhci_get_lock(struct usbd_bus *, kmutex_t **); 215 1.268 skrll Static int uhci_roothub_ctrl(struct usbd_bus *, 216 1.268 skrll usb_device_request_t *, void *, int); 217 1.119 augustss 218 1.268 skrll Static int uhci_device_ctrl_init(struct usbd_xfer *); 219 1.268 skrll Static void uhci_device_ctrl_fini(struct usbd_xfer *); 220 1.268 skrll Static usbd_status uhci_device_ctrl_transfer(struct usbd_xfer *); 221 1.268 skrll Static usbd_status uhci_device_ctrl_start(struct usbd_xfer *); 222 1.268 skrll Static void uhci_device_ctrl_abort(struct usbd_xfer *); 223 1.268 skrll Static void uhci_device_ctrl_close(struct usbd_pipe *); 224 1.268 skrll Static void uhci_device_ctrl_done(struct usbd_xfer *); 225 1.268 skrll 226 1.268 skrll Static int uhci_device_intr_init(struct usbd_xfer *); 227 1.268 skrll Static void uhci_device_intr_fini(struct usbd_xfer *); 228 1.268 skrll Static usbd_status uhci_device_intr_transfer(struct usbd_xfer *); 229 1.268 skrll Static usbd_status uhci_device_intr_start(struct usbd_xfer *); 230 1.268 skrll Static void uhci_device_intr_abort(struct usbd_xfer *); 231 1.268 skrll Static void uhci_device_intr_close(struct usbd_pipe *); 232 1.268 skrll Static void uhci_device_intr_done(struct usbd_xfer *); 233 1.268 skrll 234 1.268 skrll Static int uhci_device_bulk_init(struct usbd_xfer *); 235 1.268 skrll Static void uhci_device_bulk_fini(struct usbd_xfer *); 236 1.268 skrll Static usbd_status uhci_device_bulk_transfer(struct usbd_xfer *); 237 1.268 skrll Static usbd_status uhci_device_bulk_start(struct usbd_xfer *); 238 1.268 skrll Static void uhci_device_bulk_abort(struct usbd_xfer *); 239 1.268 skrll Static void uhci_device_bulk_close(struct usbd_pipe *); 240 1.268 skrll Static void uhci_device_bulk_done(struct usbd_xfer *); 241 1.268 skrll 242 1.268 skrll Static int uhci_device_isoc_init(struct usbd_xfer *); 243 1.268 skrll Static void uhci_device_isoc_fini(struct usbd_xfer *); 244 1.268 skrll Static usbd_status uhci_device_isoc_transfer(struct usbd_xfer *); 245 1.268 skrll Static void uhci_device_isoc_abort(struct usbd_xfer *); 246 1.268 skrll Static void uhci_device_isoc_close(struct usbd_pipe *); 247 1.268 skrll Static void uhci_device_isoc_done(struct usbd_xfer *); 248 1.268 skrll 249 1.268 skrll Static usbd_status uhci_root_intr_transfer(struct usbd_xfer *); 250 1.268 skrll Static usbd_status uhci_root_intr_start(struct usbd_xfer *); 251 1.268 skrll Static void uhci_root_intr_abort(struct usbd_xfer *); 252 1.268 skrll Static void uhci_root_intr_close(struct usbd_pipe *); 253 1.268 skrll Static void uhci_root_intr_done(struct usbd_xfer *); 254 1.119 augustss 255 1.268 skrll Static usbd_status uhci_open(struct usbd_pipe *); 256 1.119 augustss Static void uhci_poll(struct usbd_bus *); 257 1.133 augustss Static void uhci_softintr(void *); 258 1.119 augustss 259 1.119 augustss Static void uhci_add_intr(uhci_softc_t *, uhci_soft_qh_t *); 260 1.158 augustss Static void uhci_remove_intr(uhci_softc_t *, uhci_soft_qh_t *); 261 1.268 skrll Static usbd_status uhci_device_setintr(uhci_softc_t *, 262 1.268 skrll struct uhci_pipe *, int); 263 1.119 augustss 264 1.268 skrll Static void uhci_device_clear_toggle(struct usbd_pipe *); 265 1.268 skrll Static void uhci_noop(struct usbd_pipe *); 266 1.119 augustss 267 1.268 skrll static inline uhci_soft_qh_t * 268 1.268 skrll uhci_find_prev_qh(uhci_soft_qh_t *, uhci_soft_qh_t *); 269 1.119 augustss 270 1.119 augustss #ifdef UHCI_DEBUG 271 1.119 augustss Static void uhci_dump_all(uhci_softc_t *); 272 1.119 augustss Static void uhci_dumpregs(uhci_softc_t *); 273 1.119 augustss Static void uhci_dump_qhs(uhci_soft_qh_t *); 274 1.119 augustss Static void uhci_dump_qh(uhci_soft_qh_t *); 275 1.119 augustss Static void uhci_dump_tds(uhci_soft_td_t *); 276 1.119 augustss Static void uhci_dump_td(uhci_soft_td_t *); 277 1.268 skrll Static void uhci_dump_ii(struct uhci_xfer *); 278 1.119 augustss void uhci_dump(void); 279 1.1 augustss #endif 280 1.1 augustss 281 1.112 augustss #define UBARR(sc) bus_space_barrier((sc)->iot, (sc)->ioh, 0, (sc)->sc_size, \ 282 1.112 augustss BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE) 283 1.112 augustss #define UWRITE1(sc, r, x) \ 284 1.165 dsainty do { UBARR(sc); bus_space_write_1((sc)->iot, (sc)->ioh, (r), (x)); \ 285 1.165 dsainty } while (/*CONSTCOND*/0) 286 1.112 augustss #define UWRITE2(sc, r, x) \ 287 1.165 dsainty do { UBARR(sc); bus_space_write_2((sc)->iot, (sc)->ioh, (r), (x)); \ 288 1.165 dsainty } while (/*CONSTCOND*/0) 289 1.112 augustss #define UWRITE4(sc, r, x) \ 290 1.165 dsainty do { UBARR(sc); bus_space_write_4((sc)->iot, (sc)->ioh, (r), (x)); \ 291 1.165 dsainty } while (/*CONSTCOND*/0) 292 1.268 skrll 293 1.196 mrg static __inline uint8_t 294 1.196 mrg UREAD1(uhci_softc_t *sc, bus_size_t r) 295 1.196 mrg { 296 1.196 mrg 297 1.196 mrg UBARR(sc); 298 1.196 mrg return bus_space_read_1(sc->iot, sc->ioh, r); 299 1.196 mrg } 300 1.196 mrg 301 1.196 mrg static __inline uint16_t 302 1.196 mrg UREAD2(uhci_softc_t *sc, bus_size_t r) 303 1.196 mrg { 304 1.196 mrg 305 1.196 mrg UBARR(sc); 306 1.196 mrg return bus_space_read_2(sc->iot, sc->ioh, r); 307 1.196 mrg } 308 1.196 mrg 309 1.260 joerg #ifdef UHCI_DEBUG 310 1.196 mrg static __inline uint32_t 311 1.196 mrg UREAD4(uhci_softc_t *sc, bus_size_t r) 312 1.196 mrg { 313 1.196 mrg 314 1.196 mrg UBARR(sc); 315 1.196 mrg return bus_space_read_4(sc->iot, sc->ioh, r); 316 1.196 mrg } 317 1.260 joerg #endif 318 1.1 augustss 319 1.1 augustss #define UHCICMD(sc, cmd) UWRITE2(sc, UHCI_CMD, cmd) 320 1.1 augustss #define UHCISTS(sc) UREAD2(sc, UHCI_STS) 321 1.1 augustss 322 1.142 augustss #define UHCI_RESET_TIMEOUT 100 /* ms, reset timeout */ 323 1.1 augustss 324 1.1 augustss #define UHCI_CURFRAME(sc) (UREAD2(sc, UHCI_FRNUM) & UHCI_FRNUM_MASK) 325 1.1 augustss 326 1.208 drochner const struct usbd_bus_methods uhci_bus_methods = { 327 1.268 skrll .ubm_open = uhci_open, 328 1.268 skrll .ubm_softint = uhci_softintr, 329 1.268 skrll .ubm_dopoll = uhci_poll, 330 1.268 skrll .ubm_allocx = uhci_allocx, 331 1.268 skrll .ubm_freex = uhci_freex, 332 1.289 riastrad .ubm_abortx = uhci_abortx, 333 1.289 riastrad .ubm_dying = uhci_dying, 334 1.268 skrll .ubm_getlock = uhci_get_lock, 335 1.268 skrll .ubm_rhctrl = uhci_roothub_ctrl, 336 1.1 augustss }; 337 1.1 augustss 338 1.208 drochner const struct usbd_pipe_methods uhci_root_intr_methods = { 339 1.268 skrll .upm_transfer = uhci_root_intr_transfer, 340 1.268 skrll .upm_start = uhci_root_intr_start, 341 1.268 skrll .upm_abort = uhci_root_intr_abort, 342 1.268 skrll .upm_close = uhci_root_intr_close, 343 1.268 skrll .upm_cleartoggle = uhci_noop, 344 1.268 skrll .upm_done = uhci_root_intr_done, 345 1.1 augustss }; 346 1.1 augustss 347 1.208 drochner const struct usbd_pipe_methods uhci_device_ctrl_methods = { 348 1.268 skrll .upm_init = uhci_device_ctrl_init, 349 1.268 skrll .upm_fini = uhci_device_ctrl_fini, 350 1.268 skrll .upm_transfer = uhci_device_ctrl_transfer, 351 1.268 skrll .upm_start = uhci_device_ctrl_start, 352 1.268 skrll .upm_abort = uhci_device_ctrl_abort, 353 1.268 skrll .upm_close = uhci_device_ctrl_close, 354 1.268 skrll .upm_cleartoggle = uhci_noop, 355 1.268 skrll .upm_done = uhci_device_ctrl_done, 356 1.1 augustss }; 357 1.1 augustss 358 1.208 drochner const struct usbd_pipe_methods uhci_device_intr_methods = { 359 1.268 skrll .upm_init = uhci_device_intr_init, 360 1.268 skrll .upm_fini = uhci_device_intr_fini, 361 1.268 skrll .upm_transfer = uhci_device_intr_transfer, 362 1.268 skrll .upm_start = uhci_device_intr_start, 363 1.268 skrll .upm_abort = uhci_device_intr_abort, 364 1.268 skrll .upm_close = uhci_device_intr_close, 365 1.268 skrll .upm_cleartoggle = uhci_device_clear_toggle, 366 1.268 skrll .upm_done = uhci_device_intr_done, 367 1.1 augustss }; 368 1.1 augustss 369 1.208 drochner const struct usbd_pipe_methods uhci_device_bulk_methods = { 370 1.268 skrll .upm_init = uhci_device_bulk_init, 371 1.268 skrll .upm_fini = uhci_device_bulk_fini, 372 1.268 skrll .upm_transfer = uhci_device_bulk_transfer, 373 1.268 skrll .upm_start = uhci_device_bulk_start, 374 1.268 skrll .upm_abort = uhci_device_bulk_abort, 375 1.268 skrll .upm_close = uhci_device_bulk_close, 376 1.268 skrll .upm_cleartoggle = uhci_device_clear_toggle, 377 1.268 skrll .upm_done = uhci_device_bulk_done, 378 1.1 augustss }; 379 1.1 augustss 380 1.208 drochner const struct usbd_pipe_methods uhci_device_isoc_methods = { 381 1.268 skrll .upm_init = uhci_device_isoc_init, 382 1.268 skrll .upm_fini = uhci_device_isoc_fini, 383 1.268 skrll .upm_transfer = uhci_device_isoc_transfer, 384 1.268 skrll .upm_abort = uhci_device_isoc_abort, 385 1.268 skrll .upm_close = uhci_device_isoc_close, 386 1.268 skrll .upm_cleartoggle = uhci_noop, 387 1.268 skrll .upm_done = uhci_device_isoc_done, 388 1.16 augustss }; 389 1.16 augustss 390 1.268 skrll static inline void 391 1.268 skrll uhci_add_intr_list(uhci_softc_t *sc, struct uhci_xfer *ux) 392 1.268 skrll { 393 1.268 skrll 394 1.268 skrll TAILQ_INSERT_TAIL(&sc->sc_intrhead, ux, ux_list); 395 1.268 skrll } 396 1.268 skrll 397 1.268 skrll static inline void 398 1.268 skrll uhci_del_intr_list(uhci_softc_t *sc, struct uhci_xfer *ux) 399 1.268 skrll { 400 1.268 skrll 401 1.268 skrll TAILQ_REMOVE(&sc->sc_intrhead, ux, ux_list); 402 1.268 skrll } 403 1.92 augustss 404 1.240 jakllsch static inline uhci_soft_qh_t * 405 1.119 augustss uhci_find_prev_qh(uhci_soft_qh_t *pqh, uhci_soft_qh_t *sqh) 406 1.92 augustss { 407 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 408 1.277 pgoyette DPRINTFN(15, "pqh=%#jx sqh=%#jx", (uintptr_t)pqh, (uintptr_t)sqh, 0, 0); 409 1.92 augustss 410 1.92 augustss for (; pqh->hlink != sqh; pqh = pqh->hlink) { 411 1.152 augustss #if defined(DIAGNOSTIC) || defined(UHCI_DEBUG) 412 1.223 bouyer usb_syncmem(&pqh->dma, 413 1.223 bouyer pqh->offs + offsetof(uhci_qh_t, qh_hlink), 414 1.223 bouyer sizeof(pqh->qh.qh_hlink), 415 1.223 bouyer BUS_DMASYNC_POSTWRITE); 416 1.92 augustss if (le32toh(pqh->qh.qh_hlink) & UHCI_PTR_T) { 417 1.268 skrll printf("%s: QH not found\n", __func__); 418 1.268 skrll return NULL; 419 1.92 augustss } 420 1.92 augustss #endif 421 1.92 augustss } 422 1.268 skrll return pqh; 423 1.92 augustss } 424 1.92 augustss 425 1.1 augustss void 426 1.142 augustss uhci_globalreset(uhci_softc_t *sc) 427 1.1 augustss { 428 1.1 augustss UHCICMD(sc, UHCI_CMD_GRESET); /* global reset */ 429 1.20 augustss usb_delay_ms(&sc->sc_bus, USB_BUS_RESET_DELAY); /* wait a little */ 430 1.1 augustss UHCICMD(sc, 0); /* do nothing */ 431 1.1 augustss } 432 1.1 augustss 433 1.268 skrll int 434 1.119 augustss uhci_init(uhci_softc_t *sc) 435 1.1 augustss { 436 1.1 augustss int i, j; 437 1.123 augustss uhci_soft_qh_t *clsqh, *chsqh, *bsqh, *sqh, *lsqh; 438 1.1 augustss uhci_soft_td_t *std; 439 1.1 augustss 440 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 441 1.1 augustss 442 1.67 augustss #ifdef UHCI_DEBUG 443 1.92 augustss thesc = sc; 444 1.92 augustss 445 1.268 skrll if (uhcidebug >= 2) 446 1.1 augustss uhci_dumpregs(sc); 447 1.1 augustss #endif 448 1.1 augustss 449 1.219 jmcneill sc->sc_suspend = PWR_RESUME; 450 1.219 jmcneill 451 1.1 augustss UWRITE2(sc, UHCI_INTR, 0); /* disable interrupts */ 452 1.142 augustss uhci_globalreset(sc); /* reset the controller */ 453 1.142 augustss uhci_reset(sc); 454 1.24 augustss 455 1.1 augustss /* Allocate and initialize real frame array. */ 456 1.308 skrll int err = usb_allocmem(sc->sc_bus.ub_dmatag, 457 1.268 skrll UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t), 458 1.300 skrll UHCI_FRAMELIST_ALIGN, USBMALLOC_COHERENT, &sc->sc_dma); 459 1.63 augustss if (err) 460 1.268 skrll return err; 461 1.159 augustss sc->sc_pframes = KERNADDR(&sc->sc_dma, 0); 462 1.298 skrll /* set frame number to 0 */ 463 1.298 skrll UWRITE2(sc, UHCI_FRNUM, 0); 464 1.299 skrll /* set frame list */ 465 1.298 skrll UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma, 0)); 466 1.1 augustss 467 1.268 skrll /* Initialise mutex early for uhci_alloc_* */ 468 1.268 skrll mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB); 469 1.268 skrll mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_USB); 470 1.268 skrll 471 1.152 augustss /* 472 1.123 augustss * Allocate a TD, inactive, that hangs from the last QH. 473 1.123 augustss * This is to avoid a bug in the PIIX that makes it run berserk 474 1.123 augustss * otherwise. 475 1.123 augustss */ 476 1.123 augustss std = uhci_alloc_std(sc); 477 1.123 augustss if (std == NULL) 478 1.268 skrll return ENOMEM; 479 1.123 augustss std->link.std = NULL; 480 1.123 augustss std->td.td_link = htole32(UHCI_PTR_T); 481 1.123 augustss std->td.td_status = htole32(0); /* inactive */ 482 1.123 augustss std->td.td_token = htole32(0); 483 1.123 augustss std->td.td_buffer = htole32(0); 484 1.223 bouyer usb_syncmem(&std->dma, std->offs, sizeof(std->td), 485 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 486 1.123 augustss 487 1.123 augustss /* Allocate the dummy QH marking the end and used for looping the QHs.*/ 488 1.123 augustss lsqh = uhci_alloc_sqh(sc); 489 1.123 augustss if (lsqh == NULL) 490 1.268 skrll goto fail1; 491 1.123 augustss lsqh->hlink = NULL; 492 1.123 augustss lsqh->qh.qh_hlink = htole32(UHCI_PTR_T); /* end of QH chain */ 493 1.123 augustss lsqh->elink = std; 494 1.123 augustss lsqh->qh.qh_elink = htole32(std->physaddr | UHCI_PTR_TD); 495 1.123 augustss sc->sc_last_qh = lsqh; 496 1.223 bouyer usb_syncmem(&lsqh->dma, lsqh->offs, sizeof(lsqh->qh), 497 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 498 1.123 augustss 499 1.1 augustss /* Allocate the dummy QH where bulk traffic will be queued. */ 500 1.1 augustss bsqh = uhci_alloc_sqh(sc); 501 1.63 augustss if (bsqh == NULL) 502 1.268 skrll goto fail2; 503 1.123 augustss bsqh->hlink = lsqh; 504 1.123 augustss bsqh->qh.qh_hlink = htole32(lsqh->physaddr | UHCI_PTR_QH); 505 1.121 augustss bsqh->elink = NULL; 506 1.88 tsutsui bsqh->qh.qh_elink = htole32(UHCI_PTR_T); 507 1.1 augustss sc->sc_bulk_start = sc->sc_bulk_end = bsqh; 508 1.223 bouyer usb_syncmem(&bsqh->dma, bsqh->offs, sizeof(bsqh->qh), 509 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 510 1.1 augustss 511 1.123 augustss /* Allocate dummy QH where high speed control traffic will be queued. */ 512 1.123 augustss chsqh = uhci_alloc_sqh(sc); 513 1.123 augustss if (chsqh == NULL) 514 1.268 skrll goto fail3; 515 1.123 augustss chsqh->hlink = bsqh; 516 1.123 augustss chsqh->qh.qh_hlink = htole32(bsqh->physaddr | UHCI_PTR_QH); 517 1.123 augustss chsqh->elink = NULL; 518 1.123 augustss chsqh->qh.qh_elink = htole32(UHCI_PTR_T); 519 1.123 augustss sc->sc_hctl_start = sc->sc_hctl_end = chsqh; 520 1.223 bouyer usb_syncmem(&chsqh->dma, chsqh->offs, sizeof(chsqh->qh), 521 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 522 1.123 augustss 523 1.123 augustss /* Allocate dummy QH where control traffic will be queued. */ 524 1.123 augustss clsqh = uhci_alloc_sqh(sc); 525 1.123 augustss if (clsqh == NULL) 526 1.268 skrll goto fail4; 527 1.220 bouyer clsqh->hlink = chsqh; 528 1.123 augustss clsqh->qh.qh_hlink = htole32(chsqh->physaddr | UHCI_PTR_QH); 529 1.123 augustss clsqh->elink = NULL; 530 1.123 augustss clsqh->qh.qh_elink = htole32(UHCI_PTR_T); 531 1.123 augustss sc->sc_lctl_start = sc->sc_lctl_end = clsqh; 532 1.223 bouyer usb_syncmem(&clsqh->dma, clsqh->offs, sizeof(clsqh->qh), 533 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 534 1.1 augustss 535 1.152 augustss /* 536 1.1 augustss * Make all (virtual) frame list pointers point to the interrupt 537 1.1 augustss * queue heads and the interrupt queue heads at the control 538 1.1 augustss * queue head and point the physical frame list to the virtual. 539 1.1 augustss */ 540 1.267 skrll for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) { 541 1.1 augustss std = uhci_alloc_std(sc); 542 1.1 augustss sqh = uhci_alloc_sqh(sc); 543 1.67 augustss if (std == NULL || sqh == NULL) 544 1.268 skrll return USBD_NOMEM; 545 1.42 augustss std->link.sqh = sqh; 546 1.121 augustss std->td.td_link = htole32(sqh->physaddr | UHCI_PTR_QH); 547 1.88 tsutsui std->td.td_status = htole32(UHCI_TD_IOS); /* iso, inactive */ 548 1.88 tsutsui std->td.td_token = htole32(0); 549 1.88 tsutsui std->td.td_buffer = htole32(0); 550 1.223 bouyer usb_syncmem(&std->dma, std->offs, sizeof(std->td), 551 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 552 1.123 augustss sqh->hlink = clsqh; 553 1.123 augustss sqh->qh.qh_hlink = htole32(clsqh->physaddr | UHCI_PTR_QH); 554 1.121 augustss sqh->elink = NULL; 555 1.88 tsutsui sqh->qh.qh_elink = htole32(UHCI_PTR_T); 556 1.223 bouyer usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), 557 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 558 1.1 augustss sc->sc_vframes[i].htd = std; 559 1.1 augustss sc->sc_vframes[i].etd = std; 560 1.1 augustss sc->sc_vframes[i].hqh = sqh; 561 1.1 augustss sc->sc_vframes[i].eqh = sqh; 562 1.152 augustss for (j = i; 563 1.152 augustss j < UHCI_FRAMELIST_COUNT; 564 1.1 augustss j += UHCI_VFRAMELIST_COUNT) 565 1.88 tsutsui sc->sc_pframes[j] = htole32(std->physaddr); 566 1.1 augustss } 567 1.223 bouyer usb_syncmem(&sc->sc_dma, 0, 568 1.223 bouyer UHCI_FRAMELIST_COUNT * sizeof(uhci_physaddr_t), 569 1.223 bouyer BUS_DMASYNC_PREWRITE); 570 1.223 bouyer 571 1.1 augustss 572 1.268 skrll TAILQ_INIT(&sc->sc_intrhead); 573 1.1 augustss 574 1.253 christos sc->sc_xferpool = pool_cache_init(sizeof(struct uhci_xfer), 0, 0, 0, 575 1.253 christos "uhcixfer", NULL, IPL_USB, NULL, NULL, NULL); 576 1.76 augustss 577 1.248 mrg callout_init(&sc->sc_poll_handle, CALLOUT_MPSAFE); 578 1.290 riastrad callout_setfunc(&sc->sc_poll_handle, uhci_poll_hub, sc); 579 1.248 mrg 580 1.1 augustss /* Set up the bus struct. */ 581 1.268 skrll sc->sc_bus.ub_methods = &uhci_bus_methods; 582 1.268 skrll sc->sc_bus.ub_pipesize = sizeof(struct uhci_pipe); 583 1.268 skrll sc->sc_bus.ub_usedma = true; 584 1.302 skrll sc->sc_bus.ub_dmaflags = USBMALLOC_MULTISEG; 585 1.1 augustss 586 1.190 augustss UHCICMD(sc, UHCI_CMD_MAXP); /* Assume 64 byte packets at frame end */ 587 1.190 augustss 588 1.268 skrll DPRINTF("Enabling...", 0, 0, 0, 0); 589 1.225 bouyer 590 1.314 riastrad err = uhci_run(sc, 1); /* and here we go... */ 591 1.152 augustss UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | UHCI_INTR_RIE | 592 1.1 augustss UHCI_INTR_IOCE | UHCI_INTR_SPIE); /* enable interrupts */ 593 1.225 bouyer return err; 594 1.268 skrll 595 1.268 skrll fail4: 596 1.268 skrll uhci_free_sqh(sc, chsqh); 597 1.268 skrll fail3: 598 1.268 skrll uhci_free_sqh(sc, lsqh); 599 1.268 skrll fail2: 600 1.268 skrll uhci_free_sqh(sc, lsqh); 601 1.268 skrll fail1: 602 1.268 skrll uhci_free_std(sc, std); 603 1.268 skrll 604 1.268 skrll return ENOMEM; 605 1.53 augustss } 606 1.53 augustss 607 1.53 augustss int 608 1.215 dyoung uhci_activate(device_t self, enum devact act) 609 1.53 augustss { 610 1.215 dyoung struct uhci_softc *sc = device_private(self); 611 1.53 augustss 612 1.53 augustss switch (act) { 613 1.53 augustss case DVACT_DEACTIVATE: 614 1.210 kiyohara sc->sc_dying = 1; 615 1.230 dyoung return 0; 616 1.230 dyoung default: 617 1.230 dyoung return EOPNOTSUPP; 618 1.53 augustss } 619 1.53 augustss } 620 1.53 augustss 621 1.215 dyoung void 622 1.215 dyoung uhci_childdet(device_t self, device_t child) 623 1.215 dyoung { 624 1.215 dyoung struct uhci_softc *sc = device_private(self); 625 1.215 dyoung 626 1.215 dyoung KASSERT(sc->sc_child == child); 627 1.215 dyoung sc->sc_child = NULL; 628 1.215 dyoung } 629 1.215 dyoung 630 1.53 augustss int 631 1.119 augustss uhci_detach(struct uhci_softc *sc, int flags) 632 1.53 augustss { 633 1.53 augustss int rv = 0; 634 1.53 augustss 635 1.53 augustss if (sc->sc_child != NULL) 636 1.53 augustss rv = config_detach(sc->sc_child, flags); 637 1.152 augustss 638 1.53 augustss if (rv != 0) 639 1.268 skrll return rv; 640 1.53 augustss 641 1.313 riastrad KASSERT(sc->sc_intr_xfer == NULL); 642 1.226 ad callout_halt(&sc->sc_poll_handle, NULL); 643 1.226 ad callout_destroy(&sc->sc_poll_handle); 644 1.226 ad 645 1.248 mrg mutex_destroy(&sc->sc_lock); 646 1.248 mrg mutex_destroy(&sc->sc_intr_lock); 647 1.248 mrg 648 1.254 christos pool_cache_destroy(sc->sc_xferpool); 649 1.254 christos 650 1.76 augustss /* XXX free other data structures XXX */ 651 1.53 augustss 652 1.268 skrll return rv; 653 1.76 augustss } 654 1.76 augustss 655 1.268 skrll struct usbd_xfer * 656 1.268 skrll uhci_allocx(struct usbd_bus *bus, unsigned int nframes) 657 1.76 augustss { 658 1.268 skrll struct uhci_softc *sc = UHCI_BUS2SC(bus); 659 1.268 skrll struct usbd_xfer *xfer; 660 1.76 augustss 661 1.279 skrll xfer = pool_cache_get(sc->sc_xferpool, PR_WAITOK); 662 1.92 augustss if (xfer != NULL) { 663 1.253 christos memset(xfer, 0, sizeof(struct uhci_xfer)); 664 1.268 skrll 665 1.92 augustss #ifdef DIAGNOSTIC 666 1.268 skrll struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer); 667 1.268 skrll uxfer->ux_isdone = true; 668 1.268 skrll xfer->ux_state = XFER_BUSY; 669 1.92 augustss #endif 670 1.92 augustss } 671 1.268 skrll return xfer; 672 1.76 augustss } 673 1.76 augustss 674 1.76 augustss void 675 1.268 skrll uhci_freex(struct usbd_bus *bus, struct usbd_xfer *xfer) 676 1.76 augustss { 677 1.268 skrll struct uhci_softc *sc = UHCI_BUS2SC(bus); 678 1.268 skrll struct uhci_xfer *uxfer __diagused = UHCI_XFER2UXFER(xfer); 679 1.76 augustss 680 1.288 rin KASSERTMSG(xfer->ux_state == XFER_BUSY || 681 1.288 rin xfer->ux_status == USBD_NOT_STARTED, 682 1.288 rin "xfer %p state %d\n", xfer, xfer->ux_state); 683 1.288 rin KASSERTMSG(uxfer->ux_isdone || xfer->ux_status == USBD_NOT_STARTED, 684 1.288 rin "xfer %p not done\n", xfer); 685 1.93 augustss #ifdef DIAGNOSTIC 686 1.268 skrll xfer->ux_state = XFER_FREE; 687 1.93 augustss #endif 688 1.253 christos pool_cache_put(sc->sc_xferpool, xfer); 689 1.48 augustss } 690 1.48 augustss 691 1.289 riastrad Static bool 692 1.289 riastrad uhci_dying(struct usbd_bus *bus) 693 1.289 riastrad { 694 1.289 riastrad struct uhci_softc *sc = UHCI_BUS2SC(bus); 695 1.289 riastrad 696 1.289 riastrad return sc->sc_dying; 697 1.289 riastrad } 698 1.289 riastrad 699 1.248 mrg Static void 700 1.248 mrg uhci_get_lock(struct usbd_bus *bus, kmutex_t **lock) 701 1.248 mrg { 702 1.268 skrll struct uhci_softc *sc = UHCI_BUS2SC(bus); 703 1.248 mrg 704 1.248 mrg *lock = &sc->sc_lock; 705 1.248 mrg } 706 1.248 mrg 707 1.248 mrg 708 1.72 augustss /* 709 1.212 jmcneill * Handle suspend/resume. 710 1.212 jmcneill * 711 1.212 jmcneill * We need to switch to polling mode here, because this routine is 712 1.212 jmcneill * called from an interrupt context. This is all right since we 713 1.212 jmcneill * are almost suspended anyway. 714 1.72 augustss */ 715 1.212 jmcneill bool 716 1.232 dyoung uhci_resume(device_t dv, const pmf_qual_t *qual) 717 1.72 augustss { 718 1.212 jmcneill uhci_softc_t *sc = device_private(dv); 719 1.212 jmcneill int cmd; 720 1.72 augustss 721 1.212 jmcneill cmd = UREAD2(sc, UHCI_CMD); 722 1.214 smb UWRITE2(sc, UHCI_INTR, 0); 723 1.214 smb uhci_globalreset(sc); 724 1.214 smb uhci_reset(sc); 725 1.212 jmcneill if (cmd & UHCI_CMD_RS) 726 1.314 riastrad uhci_run(sc, 0); 727 1.212 jmcneill 728 1.212 jmcneill /* restore saved state */ 729 1.212 jmcneill UWRITE4(sc, UHCI_FLBASEADDR, DMAADDR(&sc->sc_dma, 0)); 730 1.212 jmcneill UWRITE2(sc, UHCI_FRNUM, sc->sc_saved_frnum); 731 1.212 jmcneill UWRITE1(sc, UHCI_SOF, sc->sc_saved_sof); 732 1.212 jmcneill 733 1.212 jmcneill UHCICMD(sc, cmd | UHCI_CMD_FGR); /* force resume */ 734 1.313 riastrad usb_delay_ms(&sc->sc_bus, USB_RESUME_DELAY); 735 1.212 jmcneill UHCICMD(sc, cmd & ~UHCI_CMD_EGSM); /* back to normal */ 736 1.212 jmcneill UWRITE2(sc, UHCI_INTR, UHCI_INTR_TOCRCIE | 737 1.212 jmcneill UHCI_INTR_RIE | UHCI_INTR_IOCE | UHCI_INTR_SPIE); 738 1.214 smb UHCICMD(sc, UHCI_CMD_MAXP); 739 1.314 riastrad uhci_run(sc, 1); /* and start traffic again */ 740 1.313 riastrad usb_delay_ms(&sc->sc_bus, USB_RESUME_RECOVERY); 741 1.212 jmcneill #ifdef UHCI_DEBUG 742 1.268 skrll if (uhcidebug >= 2) 743 1.212 jmcneill uhci_dumpregs(sc); 744 1.212 jmcneill #endif 745 1.212 jmcneill 746 1.313 riastrad mutex_enter(&sc->sc_lock); 747 1.219 jmcneill sc->sc_suspend = PWR_RESUME; 748 1.313 riastrad if (sc->sc_intr_xfer != NULL) 749 1.313 riastrad callout_schedule(&sc->sc_poll_handle, sc->sc_ival); 750 1.313 riastrad mutex_exit(&sc->sc_lock); 751 1.212 jmcneill 752 1.212 jmcneill return true; 753 1.72 augustss } 754 1.72 augustss 755 1.212 jmcneill bool 756 1.232 dyoung uhci_suspend(device_t dv, const pmf_qual_t *qual) 757 1.30 augustss { 758 1.212 jmcneill uhci_softc_t *sc = device_private(dv); 759 1.30 augustss int cmd; 760 1.30 augustss 761 1.313 riastrad mutex_enter(&sc->sc_lock); 762 1.313 riastrad sc->sc_suspend = PWR_SUSPEND; 763 1.313 riastrad if (sc->sc_intr_xfer != NULL) 764 1.316 riastrad callout_halt(&sc->sc_poll_handle, &sc->sc_lock); 765 1.313 riastrad mutex_exit(&sc->sc_lock); 766 1.212 jmcneill 767 1.30 augustss cmd = UREAD2(sc, UHCI_CMD); 768 1.30 augustss 769 1.212 jmcneill #ifdef UHCI_DEBUG 770 1.268 skrll if (uhcidebug >= 2) 771 1.212 jmcneill uhci_dumpregs(sc); 772 1.212 jmcneill #endif 773 1.219 jmcneill 774 1.314 riastrad uhci_run(sc, 0); /* stop the controller */ 775 1.212 jmcneill cmd &= ~UHCI_CMD_RS; 776 1.212 jmcneill 777 1.212 jmcneill /* save some state if BIOS doesn't */ 778 1.212 jmcneill sc->sc_saved_frnum = UREAD2(sc, UHCI_FRNUM); 779 1.212 jmcneill sc->sc_saved_sof = UREAD1(sc, UHCI_SOF); 780 1.212 jmcneill 781 1.212 jmcneill UWRITE2(sc, UHCI_INTR, 0); /* disable intrs */ 782 1.30 augustss 783 1.212 jmcneill UHCICMD(sc, cmd | UHCI_CMD_EGSM); /* enter suspend */ 784 1.313 riastrad usb_delay_ms(&sc->sc_bus, USB_RESUME_WAIT); 785 1.212 jmcneill 786 1.212 jmcneill return true; 787 1.30 augustss } 788 1.30 augustss 789 1.59 augustss #ifdef UHCI_DEBUG 790 1.101 augustss Static void 791 1.119 augustss uhci_dumpregs(uhci_softc_t *sc) 792 1.1 augustss { 793 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 794 1.277 pgoyette DPRINTF("cmd =%04jx sts =%04jx intr =%04jx frnum =%04jx", 795 1.268 skrll UREAD2(sc, UHCI_CMD), UREAD2(sc, UHCI_STS), 796 1.268 skrll UREAD2(sc, UHCI_INTR), UREAD2(sc, UHCI_FRNUM)); 797 1.277 pgoyette DPRINTF("sof =%04jx portsc1=%04jx portsc2=%04jx flbase=%08jx", 798 1.268 skrll UREAD1(sc, UHCI_SOF), UREAD2(sc, UHCI_PORTSC1), 799 1.268 skrll UREAD2(sc, UHCI_PORTSC2), UREAD4(sc, UHCI_FLBASEADDR)); 800 1.1 augustss } 801 1.1 augustss 802 1.1 augustss void 803 1.119 augustss uhci_dump_td(uhci_soft_td_t *p) 804 1.1 augustss { 805 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 806 1.250 christos 807 1.223 bouyer usb_syncmem(&p->dma, p->offs, sizeof(p->td), 808 1.223 bouyer BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 809 1.268 skrll 810 1.296 christos DPRINTF("TD(%#jx) at 0x%08jx", (uintptr_t)p, p->physaddr, 0, 0); 811 1.296 christos DPRINTF(" link=0x%08jx status=0x%08jx " 812 1.296 christos "token=0x%08x buffer=0x%08x", 813 1.268 skrll le32toh(p->td.td_link), 814 1.268 skrll le32toh(p->td.td_status), 815 1.268 skrll le32toh(p->td.td_token), 816 1.268 skrll le32toh(p->td.td_buffer)); 817 1.268 skrll 818 1.277 pgoyette DPRINTF("bitstuff=%jd crcto =%jd nak =%jd babble =%jd", 819 1.268 skrll !!(le32toh(p->td.td_status) & UHCI_TD_BITSTUFF), 820 1.268 skrll !!(le32toh(p->td.td_status) & UHCI_TD_CRCTO), 821 1.268 skrll !!(le32toh(p->td.td_status) & UHCI_TD_NAK), 822 1.268 skrll !!(le32toh(p->td.td_status) & UHCI_TD_BABBLE)); 823 1.277 pgoyette DPRINTF("dbuffer =%jd stalled =%jd active =%jd ioc =%jd", 824 1.268 skrll !!(le32toh(p->td.td_status) & UHCI_TD_DBUFFER), 825 1.268 skrll !!(le32toh(p->td.td_status) & UHCI_TD_STALLED), 826 1.268 skrll !!(le32toh(p->td.td_status) & UHCI_TD_ACTIVE), 827 1.268 skrll !!(le32toh(p->td.td_status) & UHCI_TD_IOC)); 828 1.277 pgoyette DPRINTF("ios =%jd ls =%jd spd =%jd", 829 1.268 skrll !!(le32toh(p->td.td_status) & UHCI_TD_IOS), 830 1.268 skrll !!(le32toh(p->td.td_status) & UHCI_TD_LS), 831 1.268 skrll !!(le32toh(p->td.td_status) & UHCI_TD_SPD), 0); 832 1.320 skrll DPRINTF("errcnt =%jd actlen =%jd pid=%02jx", 833 1.268 skrll UHCI_TD_GET_ERRCNT(le32toh(p->td.td_status)), 834 1.268 skrll UHCI_TD_GET_ACTLEN(le32toh(p->td.td_status)), 835 1.268 skrll UHCI_TD_GET_PID(le32toh(p->td.td_token)), 0); 836 1.277 pgoyette DPRINTF("addr=%jd endpt=%jd D=%jd maxlen=%jd,", 837 1.268 skrll UHCI_TD_GET_DEVADDR(le32toh(p->td.td_token)), 838 1.268 skrll UHCI_TD_GET_ENDPT(le32toh(p->td.td_token)), 839 1.268 skrll UHCI_TD_GET_DT(le32toh(p->td.td_token)), 840 1.268 skrll UHCI_TD_GET_MAXLEN(le32toh(p->td.td_token))); 841 1.1 augustss } 842 1.1 augustss 843 1.1 augustss void 844 1.119 augustss uhci_dump_qh(uhci_soft_qh_t *sqh) 845 1.1 augustss { 846 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 847 1.268 skrll 848 1.223 bouyer usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), 849 1.223 bouyer BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 850 1.268 skrll 851 1.296 christos DPRINTF("QH(%#jx) at 0x%08jx: hlink=%08jx elink=%08jx", (uintptr_t)sqh, 852 1.88 tsutsui (int)sqh->physaddr, le32toh(sqh->qh.qh_hlink), 853 1.268 skrll le32toh(sqh->qh.qh_elink)); 854 1.268 skrll 855 1.223 bouyer usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_PREREAD); 856 1.1 augustss } 857 1.1 augustss 858 1.13 augustss 859 1.110 augustss #if 1 860 1.1 augustss void 861 1.119 augustss uhci_dump(void) 862 1.1 augustss { 863 1.110 augustss uhci_dump_all(thesc); 864 1.110 augustss } 865 1.110 augustss #endif 866 1.1 augustss 867 1.110 augustss void 868 1.119 augustss uhci_dump_all(uhci_softc_t *sc) 869 1.110 augustss { 870 1.1 augustss uhci_dumpregs(sc); 871 1.110 augustss /*printf("framelist[i].link = %08x\n", sc->sc_framelist[0].link);*/ 872 1.261 skrll uhci_dump_qhs(sc->sc_lctl_start); 873 1.1 augustss } 874 1.1 augustss 875 1.67 augustss 876 1.67 augustss void 877 1.119 augustss uhci_dump_qhs(uhci_soft_qh_t *sqh) 878 1.67 augustss { 879 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 880 1.268 skrll 881 1.67 augustss uhci_dump_qh(sqh); 882 1.67 augustss 883 1.268 skrll /* 884 1.268 skrll * uhci_dump_qhs displays all the QHs and TDs from the given QH onwards 885 1.67 augustss * Traverses sideways first, then down. 886 1.67 augustss * 887 1.67 augustss * QH1 888 1.67 augustss * QH2 889 1.67 augustss * No QH 890 1.67 augustss * TD2.1 891 1.67 augustss * TD2.2 892 1.67 augustss * TD1.1 893 1.67 augustss * etc. 894 1.67 augustss * 895 1.67 augustss * TD2.x being the TDs queued at QH2 and QH1 being referenced from QH1. 896 1.67 augustss */ 897 1.67 augustss 898 1.223 bouyer usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), 899 1.223 bouyer BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 900 1.88 tsutsui if (sqh->hlink != NULL && !(le32toh(sqh->qh.qh_hlink) & UHCI_PTR_T)) 901 1.67 augustss uhci_dump_qhs(sqh->hlink); 902 1.67 augustss else 903 1.268 skrll DPRINTF("No QH", 0, 0, 0, 0); 904 1.223 bouyer usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), BUS_DMASYNC_PREREAD); 905 1.67 augustss 906 1.88 tsutsui if (sqh->elink != NULL && !(le32toh(sqh->qh.qh_elink) & UHCI_PTR_T)) 907 1.67 augustss uhci_dump_tds(sqh->elink); 908 1.67 augustss else 909 1.268 skrll DPRINTF("No QH", 0, 0, 0, 0); 910 1.67 augustss } 911 1.67 augustss 912 1.1 augustss void 913 1.119 augustss uhci_dump_tds(uhci_soft_td_t *std) 914 1.1 augustss { 915 1.67 augustss uhci_soft_td_t *td; 916 1.223 bouyer int stop; 917 1.67 augustss 918 1.267 skrll for (td = std; td != NULL; td = td->link.std) { 919 1.67 augustss uhci_dump_td(td); 920 1.1 augustss 921 1.268 skrll /* 922 1.268 skrll * Check whether the link pointer in this TD marks 923 1.67 augustss * the link pointer as end of queue. This avoids 924 1.67 augustss * printing the free list in case the queue/TD has 925 1.67 augustss * already been moved there (seatbelt). 926 1.67 augustss */ 927 1.223 bouyer usb_syncmem(&td->dma, td->offs + offsetof(uhci_td_t, td_link), 928 1.223 bouyer sizeof(td->td.td_link), 929 1.223 bouyer BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 930 1.223 bouyer stop = (le32toh(td->td.td_link) & UHCI_PTR_T || 931 1.223 bouyer le32toh(td->td.td_link) == 0); 932 1.223 bouyer usb_syncmem(&td->dma, td->offs + offsetof(uhci_td_t, td_link), 933 1.223 bouyer sizeof(td->td.td_link), BUS_DMASYNC_PREREAD); 934 1.223 bouyer if (stop) 935 1.67 augustss break; 936 1.67 augustss } 937 1.1 augustss } 938 1.92 augustss 939 1.101 augustss Static void 940 1.268 skrll uhci_dump_ii(struct uhci_xfer *ux) 941 1.92 augustss { 942 1.268 skrll struct usbd_pipe *pipe; 943 1.95 augustss usb_endpoint_descriptor_t *ed; 944 1.268 skrll struct usbd_device *dev; 945 1.152 augustss 946 1.268 skrll if (ux == NULL) { 947 1.268 skrll printf("ux NULL\n"); 948 1.268 skrll return; 949 1.268 skrll } 950 1.268 skrll pipe = ux->ux_xfer.ux_pipe; 951 1.268 skrll if (pipe == NULL) { 952 1.268 skrll printf("ux %p: done=%d pipe=NULL\n", ux, ux->ux_isdone); 953 1.268 skrll return; 954 1.268 skrll } 955 1.268 skrll if (pipe->up_endpoint == NULL) { 956 1.268 skrll printf("ux %p: done=%d pipe=%p pipe->up_endpoint=NULL\n", 957 1.268 skrll ux, ux->ux_isdone, pipe); 958 1.268 skrll return; 959 1.268 skrll } 960 1.268 skrll if (pipe->up_dev == NULL) { 961 1.268 skrll printf("ux %p: done=%d pipe=%p pipe->up_dev=NULL\n", 962 1.268 skrll ux, ux->ux_isdone, pipe); 963 1.268 skrll return; 964 1.268 skrll } 965 1.268 skrll ed = pipe->up_endpoint->ue_edesc; 966 1.268 skrll dev = pipe->up_dev; 967 1.296 christos printf("ux %p: done=%d dev=%p vid=0x%04x pid=0x%04x addr=%d pipe=%p ep=0x%02x attr=0x%02x\n", 968 1.268 skrll ux, ux->ux_isdone, dev, 969 1.268 skrll UGETW(dev->ud_ddesc.idVendor), 970 1.268 skrll UGETW(dev->ud_ddesc.idProduct), 971 1.268 skrll dev->ud_addr, pipe, 972 1.92 augustss ed->bEndpointAddress, ed->bmAttributes); 973 1.92 augustss } 974 1.92 augustss 975 1.120 augustss void uhci_dump_iis(struct uhci_softc *sc); 976 1.92 augustss void 977 1.119 augustss uhci_dump_iis(struct uhci_softc *sc) 978 1.92 augustss { 979 1.268 skrll struct uhci_xfer *ux; 980 1.92 augustss 981 1.268 skrll printf("interrupt list:\n"); 982 1.268 skrll TAILQ_FOREACH(ux, &sc->sc_intrhead, ux_list) 983 1.268 skrll uhci_dump_ii(ux); 984 1.92 augustss } 985 1.92 augustss 986 1.120 augustss void iidump(void); 987 1.119 augustss void iidump(void) { uhci_dump_iis(thesc); } 988 1.92 augustss 989 1.1 augustss #endif 990 1.1 augustss 991 1.1 augustss /* 992 1.1 augustss * This routine is executed periodically and simulates interrupts 993 1.1 augustss * from the root controller interrupt pipe for port status change. 994 1.1 augustss */ 995 1.1 augustss void 996 1.119 augustss uhci_poll_hub(void *addr) 997 1.1 augustss { 998 1.290 riastrad struct uhci_softc *sc = addr; 999 1.290 riastrad struct usbd_xfer *xfer; 1000 1.1 augustss u_char *p; 1001 1.1 augustss 1002 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 1003 1.1 augustss 1004 1.290 riastrad mutex_enter(&sc->sc_lock); 1005 1.290 riastrad 1006 1.290 riastrad /* 1007 1.290 riastrad * If the intr xfer has completed or been synchronously 1008 1.290 riastrad * aborted, we have nothing to do. 1009 1.290 riastrad */ 1010 1.290 riastrad xfer = sc->sc_intr_xfer; 1011 1.290 riastrad if (xfer == NULL) 1012 1.290 riastrad goto out; 1013 1.293 riastrad KASSERT(xfer->ux_status == USBD_IN_PROGRESS); 1014 1.290 riastrad 1015 1.290 riastrad /* 1016 1.290 riastrad * If the intr xfer for which we were scheduled is done, and 1017 1.290 riastrad * another intr xfer has been submitted, let that one be dealt 1018 1.290 riastrad * with when the callout fires again. 1019 1.290 riastrad * 1020 1.307 andvar * The call to callout_pending is racy, but the transition 1021 1.290 riastrad * from pending to invoking happens atomically. The 1022 1.290 riastrad * callout_ack ensures callout_invoking does not return true 1023 1.290 riastrad * due to this invocation of the callout; the lock ensures the 1024 1.290 riastrad * next invocation of the callout cannot callout_ack (unless it 1025 1.290 riastrad * had already run to completion and nulled sc->sc_intr_xfer, 1026 1.290 riastrad * in which case would have bailed out already). 1027 1.290 riastrad */ 1028 1.290 riastrad callout_ack(&sc->sc_poll_handle); 1029 1.290 riastrad if (callout_pending(&sc->sc_poll_handle) || 1030 1.290 riastrad callout_invoking(&sc->sc_poll_handle)) 1031 1.290 riastrad goto out; 1032 1.41 augustss 1033 1.290 riastrad /* 1034 1.290 riastrad * Check flags for the two interrupt ports, and set them in the 1035 1.290 riastrad * buffer if an interrupt arrived; otherwise arrange . 1036 1.290 riastrad */ 1037 1.268 skrll p = xfer->ux_buf; 1038 1.1 augustss p[0] = 0; 1039 1.1 augustss if (UREAD2(sc, UHCI_PORTSC1) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC)) 1040 1.1 augustss p[0] |= 1<<1; 1041 1.1 augustss if (UREAD2(sc, UHCI_PORTSC2) & (UHCI_PORTSC_CSC|UHCI_PORTSC_OCIC)) 1042 1.1 augustss p[0] |= 1<<2; 1043 1.290 riastrad if (p[0] == 0) { 1044 1.290 riastrad /* 1045 1.290 riastrad * No change -- try again in a while, unless we're 1046 1.290 riastrad * suspending, in which case we'll try again after 1047 1.290 riastrad * resume. 1048 1.290 riastrad */ 1049 1.290 riastrad if (sc->sc_suspend != PWR_SUSPEND) 1050 1.290 riastrad callout_schedule(&sc->sc_poll_handle, sc->sc_ival); 1051 1.290 riastrad goto out; 1052 1.290 riastrad } 1053 1.41 augustss 1054 1.290 riastrad /* 1055 1.290 riastrad * Interrupt completed, and the xfer has not been completed or 1056 1.290 riastrad * synchronously aborted. Complete the xfer now. 1057 1.290 riastrad */ 1058 1.268 skrll xfer->ux_actlen = 1; 1059 1.268 skrll xfer->ux_status = USBD_NORMAL_COMPLETION; 1060 1.292 riastrad #ifdef DIAGNOSTIC 1061 1.292 riastrad UHCI_XFER2UXFER(xfer)->ux_isdone = true; 1062 1.292 riastrad #endif 1063 1.63 augustss usb_transfer_complete(xfer); 1064 1.290 riastrad 1065 1.290 riastrad out: mutex_exit(&sc->sc_lock); 1066 1.41 augustss } 1067 1.41 augustss 1068 1.41 augustss void 1069 1.268 skrll uhci_root_intr_done(struct usbd_xfer *xfer) 1070 1.41 augustss { 1071 1.290 riastrad struct uhci_softc *sc = UHCI_XFER2SC(xfer); 1072 1.290 riastrad 1073 1.290 riastrad KASSERT(mutex_owned(&sc->sc_lock)); 1074 1.290 riastrad 1075 1.290 riastrad /* Claim the xfer so it doesn't get completed again. */ 1076 1.290 riastrad KASSERT(sc->sc_intr_xfer == xfer); 1077 1.290 riastrad KASSERT(xfer->ux_status != USBD_IN_PROGRESS); 1078 1.290 riastrad sc->sc_intr_xfer = NULL; 1079 1.1 augustss } 1080 1.1 augustss 1081 1.123 augustss /* 1082 1.123 augustss * Let the last QH loop back to the high speed control transfer QH. 1083 1.123 augustss * This is what intel calls "bandwidth reclamation" and improves 1084 1.123 augustss * USB performance a lot for some devices. 1085 1.123 augustss * If we are already looping, just count it. 1086 1.123 augustss */ 1087 1.1 augustss void 1088 1.268 skrll uhci_add_loop(uhci_softc_t *sc) 1089 1.268 skrll { 1090 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 1091 1.268 skrll 1092 1.125 augustss #ifdef UHCI_DEBUG 1093 1.125 augustss if (uhcinoloop) 1094 1.125 augustss return; 1095 1.125 augustss #endif 1096 1.123 augustss if (++sc->sc_loops == 1) { 1097 1.268 skrll DPRINTFN(5, "add loop", 0, 0, 0, 0); 1098 1.123 augustss /* Note, we don't loop back the soft pointer. */ 1099 1.152 augustss sc->sc_last_qh->qh.qh_hlink = 1100 1.123 augustss htole32(sc->sc_hctl_start->physaddr | UHCI_PTR_QH); 1101 1.223 bouyer usb_syncmem(&sc->sc_last_qh->dma, 1102 1.223 bouyer sc->sc_last_qh->offs + offsetof(uhci_qh_t, qh_hlink), 1103 1.223 bouyer sizeof(sc->sc_last_qh->qh.qh_hlink), 1104 1.223 bouyer BUS_DMASYNC_PREWRITE); 1105 1.123 augustss } 1106 1.123 augustss } 1107 1.123 augustss 1108 1.123 augustss void 1109 1.268 skrll uhci_rem_loop(uhci_softc_t *sc) 1110 1.268 skrll { 1111 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 1112 1.268 skrll 1113 1.125 augustss #ifdef UHCI_DEBUG 1114 1.125 augustss if (uhcinoloop) 1115 1.125 augustss return; 1116 1.125 augustss #endif 1117 1.123 augustss if (--sc->sc_loops == 0) { 1118 1.268 skrll DPRINTFN(5, "remove loop", 0, 0, 0, 0); 1119 1.123 augustss sc->sc_last_qh->qh.qh_hlink = htole32(UHCI_PTR_T); 1120 1.223 bouyer usb_syncmem(&sc->sc_last_qh->dma, 1121 1.223 bouyer sc->sc_last_qh->offs + offsetof(uhci_qh_t, qh_hlink), 1122 1.223 bouyer sizeof(sc->sc_last_qh->qh.qh_hlink), 1123 1.223 bouyer BUS_DMASYNC_PREWRITE); 1124 1.123 augustss } 1125 1.123 augustss } 1126 1.123 augustss 1127 1.248 mrg /* Add high speed control QH, called with lock held. */ 1128 1.123 augustss void 1129 1.123 augustss uhci_add_hs_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh) 1130 1.1 augustss { 1131 1.42 augustss uhci_soft_qh_t *eqh; 1132 1.1 augustss 1133 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 1134 1.268 skrll 1135 1.248 mrg KASSERT(mutex_owned(&sc->sc_lock)); 1136 1.248 mrg 1137 1.277 pgoyette DPRINTFN(10, "sqh %#jx", (uintptr_t)sqh, 0, 0, 0); 1138 1.123 augustss eqh = sc->sc_hctl_end; 1139 1.223 bouyer usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), 1140 1.223 bouyer sizeof(eqh->qh.qh_hlink), 1141 1.223 bouyer BUS_DMASYNC_POSTWRITE); 1142 1.42 augustss sqh->hlink = eqh->hlink; 1143 1.42 augustss sqh->qh.qh_hlink = eqh->qh.qh_hlink; 1144 1.223 bouyer usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), 1145 1.223 bouyer BUS_DMASYNC_PREWRITE); 1146 1.42 augustss eqh->hlink = sqh; 1147 1.121 augustss eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH); 1148 1.123 augustss sc->sc_hctl_end = sqh; 1149 1.223 bouyer usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), 1150 1.223 bouyer sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE); 1151 1.125 augustss #ifdef UHCI_CTL_LOOP 1152 1.123 augustss uhci_add_loop(sc); 1153 1.125 augustss #endif 1154 1.1 augustss } 1155 1.1 augustss 1156 1.248 mrg /* Remove high speed control QH, called with lock held. */ 1157 1.1 augustss void 1158 1.123 augustss uhci_remove_hs_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh) 1159 1.1 augustss { 1160 1.1 augustss uhci_soft_qh_t *pqh; 1161 1.256 tsutsui uint32_t elink; 1162 1.1 augustss 1163 1.272 christos KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 1164 1.248 mrg 1165 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 1166 1.277 pgoyette DPRINTFN(10, "sqh %#jx", (uintptr_t)sqh, 0, 0, 0); 1167 1.125 augustss #ifdef UHCI_CTL_LOOP 1168 1.123 augustss uhci_rem_loop(sc); 1169 1.125 augustss #endif 1170 1.124 augustss /* 1171 1.124 augustss * The T bit should be set in the elink of the QH so that the HC 1172 1.124 augustss * doesn't follow the pointer. This condition may fail if the 1173 1.124 augustss * the transferred packet was short so that the QH still points 1174 1.124 augustss * at the last used TD. 1175 1.124 augustss * In this case we set the T bit and wait a little for the HC 1176 1.124 augustss * to stop looking at the TD. 1177 1.223 bouyer * Note that if the TD chain is large enough, the controller 1178 1.223 bouyer * may still be looking at the chain at the end of this function. 1179 1.223 bouyer * uhci_free_std_chain() will make sure the controller stops 1180 1.223 bouyer * looking at it quickly, but until then we should not change 1181 1.223 bouyer * sqh->hlink. 1182 1.124 augustss */ 1183 1.223 bouyer usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), 1184 1.223 bouyer sizeof(sqh->qh.qh_elink), 1185 1.223 bouyer BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1186 1.256 tsutsui elink = le32toh(sqh->qh.qh_elink); 1187 1.256 tsutsui usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), 1188 1.256 tsutsui sizeof(sqh->qh.qh_elink), BUS_DMASYNC_PREREAD); 1189 1.256 tsutsui if (!(elink & UHCI_PTR_T)) { 1190 1.124 augustss sqh->qh.qh_elink = htole32(UHCI_PTR_T); 1191 1.223 bouyer usb_syncmem(&sqh->dma, 1192 1.223 bouyer sqh->offs + offsetof(uhci_qh_t, qh_elink), 1193 1.223 bouyer sizeof(sqh->qh.qh_elink), 1194 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1195 1.124 augustss delay(UHCI_QH_REMOVE_DELAY); 1196 1.124 augustss } 1197 1.124 augustss 1198 1.123 augustss pqh = uhci_find_prev_qh(sc->sc_hctl_start, sqh); 1199 1.223 bouyer usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_hlink), 1200 1.223 bouyer sizeof(sqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE); 1201 1.152 augustss pqh->hlink = sqh->hlink; 1202 1.42 augustss pqh->qh.qh_hlink = sqh->qh.qh_hlink; 1203 1.223 bouyer usb_syncmem(&pqh->dma, pqh->offs + offsetof(uhci_qh_t, qh_hlink), 1204 1.272 christos sizeof(pqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE); 1205 1.124 augustss delay(UHCI_QH_REMOVE_DELAY); 1206 1.123 augustss if (sc->sc_hctl_end == sqh) 1207 1.123 augustss sc->sc_hctl_end = pqh; 1208 1.123 augustss } 1209 1.123 augustss 1210 1.248 mrg /* Add low speed control QH, called with lock held. */ 1211 1.123 augustss void 1212 1.123 augustss uhci_add_ls_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh) 1213 1.123 augustss { 1214 1.123 augustss uhci_soft_qh_t *eqh; 1215 1.123 augustss 1216 1.248 mrg KASSERT(mutex_owned(&sc->sc_lock)); 1217 1.248 mrg 1218 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 1219 1.277 pgoyette DPRINTFN(10, "sqh %#jx", (uintptr_t)sqh, 0, 0, 0); 1220 1.268 skrll 1221 1.123 augustss eqh = sc->sc_lctl_end; 1222 1.223 bouyer usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), 1223 1.223 bouyer sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE); 1224 1.152 augustss sqh->hlink = eqh->hlink; 1225 1.123 augustss sqh->qh.qh_hlink = eqh->qh.qh_hlink; 1226 1.223 bouyer usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), 1227 1.223 bouyer BUS_DMASYNC_PREWRITE); 1228 1.152 augustss eqh->hlink = sqh; 1229 1.123 augustss eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH); 1230 1.223 bouyer usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), 1231 1.223 bouyer sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE); 1232 1.123 augustss sc->sc_lctl_end = sqh; 1233 1.123 augustss } 1234 1.123 augustss 1235 1.248 mrg /* Remove low speed control QH, called with lock held. */ 1236 1.123 augustss void 1237 1.123 augustss uhci_remove_ls_ctrl(uhci_softc_t *sc, uhci_soft_qh_t *sqh) 1238 1.123 augustss { 1239 1.123 augustss uhci_soft_qh_t *pqh; 1240 1.256 tsutsui uint32_t elink; 1241 1.123 augustss 1242 1.272 christos KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 1243 1.248 mrg 1244 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 1245 1.277 pgoyette DPRINTFN(10, "sqh %#jx", (uintptr_t)sqh, 0, 0, 0); 1246 1.268 skrll 1247 1.124 augustss /* See comment in uhci_remove_hs_ctrl() */ 1248 1.223 bouyer usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), 1249 1.223 bouyer sizeof(sqh->qh.qh_elink), 1250 1.223 bouyer BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1251 1.256 tsutsui elink = le32toh(sqh->qh.qh_elink); 1252 1.256 tsutsui usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), 1253 1.256 tsutsui sizeof(sqh->qh.qh_elink), BUS_DMASYNC_PREREAD); 1254 1.256 tsutsui if (!(elink & UHCI_PTR_T)) { 1255 1.124 augustss sqh->qh.qh_elink = htole32(UHCI_PTR_T); 1256 1.223 bouyer usb_syncmem(&sqh->dma, 1257 1.223 bouyer sqh->offs + offsetof(uhci_qh_t, qh_elink), 1258 1.223 bouyer sizeof(sqh->qh.qh_elink), 1259 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1260 1.124 augustss delay(UHCI_QH_REMOVE_DELAY); 1261 1.124 augustss } 1262 1.123 augustss pqh = uhci_find_prev_qh(sc->sc_lctl_start, sqh); 1263 1.223 bouyer usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_hlink), 1264 1.223 bouyer sizeof(sqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE); 1265 1.152 augustss pqh->hlink = sqh->hlink; 1266 1.123 augustss pqh->qh.qh_hlink = sqh->qh.qh_hlink; 1267 1.223 bouyer usb_syncmem(&pqh->dma, pqh->offs + offsetof(uhci_qh_t, qh_hlink), 1268 1.223 bouyer sizeof(pqh->qh.qh_hlink), 1269 1.223 bouyer BUS_DMASYNC_PREWRITE); 1270 1.124 augustss delay(UHCI_QH_REMOVE_DELAY); 1271 1.123 augustss if (sc->sc_lctl_end == sqh) 1272 1.123 augustss sc->sc_lctl_end = pqh; 1273 1.1 augustss } 1274 1.1 augustss 1275 1.248 mrg /* Add bulk QH, called with lock held. */ 1276 1.1 augustss void 1277 1.119 augustss uhci_add_bulk(uhci_softc_t *sc, uhci_soft_qh_t *sqh) 1278 1.1 augustss { 1279 1.42 augustss uhci_soft_qh_t *eqh; 1280 1.1 augustss 1281 1.304 skrll KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 1282 1.248 mrg 1283 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 1284 1.277 pgoyette DPRINTFN(10, "sqh %#jx", (uintptr_t)sqh, 0, 0, 0); 1285 1.268 skrll 1286 1.42 augustss eqh = sc->sc_bulk_end; 1287 1.223 bouyer usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), 1288 1.223 bouyer sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE); 1289 1.152 augustss sqh->hlink = eqh->hlink; 1290 1.42 augustss sqh->qh.qh_hlink = eqh->qh.qh_hlink; 1291 1.223 bouyer usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), 1292 1.223 bouyer BUS_DMASYNC_PREWRITE); 1293 1.152 augustss eqh->hlink = sqh; 1294 1.121 augustss eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH); 1295 1.223 bouyer usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), 1296 1.223 bouyer sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE); 1297 1.1 augustss sc->sc_bulk_end = sqh; 1298 1.123 augustss uhci_add_loop(sc); 1299 1.1 augustss } 1300 1.1 augustss 1301 1.248 mrg /* Remove bulk QH, called with lock held. */ 1302 1.1 augustss void 1303 1.119 augustss uhci_remove_bulk(uhci_softc_t *sc, uhci_soft_qh_t *sqh) 1304 1.1 augustss { 1305 1.1 augustss uhci_soft_qh_t *pqh; 1306 1.1 augustss 1307 1.304 skrll KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 1308 1.248 mrg 1309 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 1310 1.277 pgoyette DPRINTFN(10, "sqh %#jx", (uintptr_t)sqh, 0, 0, 0); 1311 1.268 skrll 1312 1.123 augustss uhci_rem_loop(sc); 1313 1.124 augustss /* See comment in uhci_remove_hs_ctrl() */ 1314 1.223 bouyer usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), 1315 1.223 bouyer sizeof(sqh->qh.qh_elink), 1316 1.223 bouyer BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1317 1.124 augustss if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) { 1318 1.124 augustss sqh->qh.qh_elink = htole32(UHCI_PTR_T); 1319 1.223 bouyer usb_syncmem(&sqh->dma, 1320 1.223 bouyer sqh->offs + offsetof(uhci_qh_t, qh_elink), 1321 1.223 bouyer sizeof(sqh->qh.qh_elink), 1322 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1323 1.124 augustss delay(UHCI_QH_REMOVE_DELAY); 1324 1.124 augustss } 1325 1.92 augustss pqh = uhci_find_prev_qh(sc->sc_bulk_start, sqh); 1326 1.223 bouyer usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_hlink), 1327 1.223 bouyer sizeof(sqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE); 1328 1.42 augustss pqh->hlink = sqh->hlink; 1329 1.42 augustss pqh->qh.qh_hlink = sqh->qh.qh_hlink; 1330 1.223 bouyer usb_syncmem(&pqh->dma, pqh->offs + offsetof(uhci_qh_t, qh_hlink), 1331 1.223 bouyer sizeof(pqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE); 1332 1.124 augustss delay(UHCI_QH_REMOVE_DELAY); 1333 1.1 augustss if (sc->sc_bulk_end == sqh) 1334 1.1 augustss sc->sc_bulk_end = pqh; 1335 1.1 augustss } 1336 1.1 augustss 1337 1.141 augustss Static int uhci_intr1(uhci_softc_t *); 1338 1.141 augustss 1339 1.1 augustss int 1340 1.119 augustss uhci_intr(void *arg) 1341 1.1 augustss { 1342 1.44 augustss uhci_softc_t *sc = arg; 1343 1.248 mrg int ret = 0; 1344 1.248 mrg 1345 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 1346 1.268 skrll 1347 1.248 mrg mutex_spin_enter(&sc->sc_intr_lock); 1348 1.146 augustss 1349 1.216 drochner if (sc->sc_dying || !device_has_power(sc->sc_dev)) 1350 1.248 mrg goto done; 1351 1.141 augustss 1352 1.268 skrll if (sc->sc_bus.ub_usepolling || UREAD2(sc, UHCI_INTR) == 0) { 1353 1.268 skrll DPRINTFN(16, "ignored interrupt while polling", 0, 0, 0, 0); 1354 1.248 mrg goto done; 1355 1.141 augustss } 1356 1.179 mycroft 1357 1.248 mrg ret = uhci_intr1(sc); 1358 1.248 mrg 1359 1.248 mrg done: 1360 1.248 mrg mutex_spin_exit(&sc->sc_intr_lock); 1361 1.248 mrg return ret; 1362 1.141 augustss } 1363 1.141 augustss 1364 1.141 augustss int 1365 1.141 augustss uhci_intr1(uhci_softc_t *sc) 1366 1.141 augustss { 1367 1.44 augustss int status; 1368 1.44 augustss int ack; 1369 1.1 augustss 1370 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 1371 1.268 skrll 1372 1.67 augustss #ifdef UHCI_DEBUG 1373 1.268 skrll if (uhcidebug >= 15) { 1374 1.277 pgoyette DPRINTF("sc %#jx", (uintptr_t)sc, 0, 0, 0); 1375 1.1 augustss uhci_dumpregs(sc); 1376 1.1 augustss } 1377 1.1 augustss #endif 1378 1.117 augustss 1379 1.248 mrg KASSERT(mutex_owned(&sc->sc_intr_lock)); 1380 1.248 mrg 1381 1.153 augustss status = UREAD2(sc, UHCI_STS) & UHCI_STS_ALLINTRS; 1382 1.268 skrll /* Check if the interrupt was for us. */ 1383 1.268 skrll if (status == 0) 1384 1.268 skrll return 0; 1385 1.127 soren 1386 1.117 augustss if (sc->sc_suspend != PWR_RESUME) { 1387 1.201 jmcneill #ifdef DIAGNOSTIC 1388 1.117 augustss printf("%s: interrupt while not operating ignored\n", 1389 1.216 drochner device_xname(sc->sc_dev)); 1390 1.201 jmcneill #endif 1391 1.134 augustss UWRITE2(sc, UHCI_STS, status); /* acknowledge the ints */ 1392 1.268 skrll return 0; 1393 1.117 augustss } 1394 1.44 augustss 1395 1.44 augustss ack = 0; 1396 1.44 augustss if (status & UHCI_STS_USBINT) 1397 1.44 augustss ack |= UHCI_STS_USBINT; 1398 1.44 augustss if (status & UHCI_STS_USBEI) 1399 1.44 augustss ack |= UHCI_STS_USBEI; 1400 1.1 augustss if (status & UHCI_STS_RD) { 1401 1.44 augustss ack |= UHCI_STS_RD; 1402 1.118 augustss #ifdef UHCI_DEBUG 1403 1.216 drochner printf("%s: resume detect\n", device_xname(sc->sc_dev)); 1404 1.118 augustss #endif 1405 1.1 augustss } 1406 1.1 augustss if (status & UHCI_STS_HSE) { 1407 1.44 augustss ack |= UHCI_STS_HSE; 1408 1.216 drochner printf("%s: host system error\n", device_xname(sc->sc_dev)); 1409 1.1 augustss } 1410 1.1 augustss if (status & UHCI_STS_HCPE) { 1411 1.44 augustss ack |= UHCI_STS_HCPE; 1412 1.152 augustss printf("%s: host controller process error\n", 1413 1.216 drochner device_xname(sc->sc_dev)); 1414 1.44 augustss } 1415 1.233 msaitoh 1416 1.233 msaitoh /* When HCHalted=1 and Run/Stop=0 , it is normal */ 1417 1.233 msaitoh if ((status & UHCI_STS_HCH) && (UREAD2(sc, UHCI_CMD) & UHCI_CMD_RS)) { 1418 1.44 augustss /* no acknowledge needed */ 1419 1.136 augustss if (!sc->sc_dying) { 1420 1.152 augustss printf("%s: host controller halted\n", 1421 1.216 drochner device_xname(sc->sc_dev)); 1422 1.110 augustss #ifdef UHCI_DEBUG 1423 1.136 augustss uhci_dump_all(sc); 1424 1.110 augustss #endif 1425 1.136 augustss } 1426 1.136 augustss sc->sc_dying = 1; 1427 1.1 augustss } 1428 1.44 augustss 1429 1.132 augustss if (!ack) 1430 1.268 skrll return 0; /* nothing to acknowledge */ 1431 1.132 augustss UWRITE2(sc, UHCI_STS, ack); /* acknowledge the ints */ 1432 1.1 augustss 1433 1.85 augustss usb_schedsoftintr(&sc->sc_bus); 1434 1.85 augustss 1435 1.277 pgoyette DPRINTFN(15, "sc %#jx done", (uintptr_t)sc, 0, 0, 0); 1436 1.85 augustss 1437 1.268 skrll return 1; 1438 1.85 augustss } 1439 1.85 augustss 1440 1.85 augustss void 1441 1.133 augustss uhci_softintr(void *v) 1442 1.85 augustss { 1443 1.216 drochner struct usbd_bus *bus = v; 1444 1.268 skrll uhci_softc_t *sc = UHCI_BUS2SC(bus); 1445 1.268 skrll struct uhci_xfer *ux, *nextux; 1446 1.268 skrll ux_completeq_t cq; 1447 1.85 augustss 1448 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 1449 1.277 pgoyette DPRINTF("sc %#jx", (uintptr_t)sc, 0, 0, 0); 1450 1.248 mrg 1451 1.268 skrll KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 1452 1.50 augustss 1453 1.268 skrll TAILQ_INIT(&cq); 1454 1.1 augustss /* 1455 1.1 augustss * Interrupts on UHCI really suck. When the host controller 1456 1.1 augustss * interrupts because a transfer is completed there is no 1457 1.1 augustss * way of knowing which transfer it was. You can scan down 1458 1.1 augustss * the TDs and QHs of the previous frame to limit the search, 1459 1.1 augustss * but that assumes that the interrupt was not delayed by more 1460 1.1 augustss * than 1 ms, which may not always be true (e.g. after debug 1461 1.1 augustss * output on a slow console). 1462 1.1 augustss * We scan all interrupt descriptors to see if any have 1463 1.1 augustss * completed. 1464 1.1 augustss */ 1465 1.268 skrll TAILQ_FOREACH_SAFE(ux, &sc->sc_intrhead, ux_list, nextux) { 1466 1.268 skrll uhci_check_intr(sc, ux, &cq); 1467 1.268 skrll } 1468 1.268 skrll 1469 1.268 skrll /* 1470 1.268 skrll * We abuse ux_list for the interrupt and complete lists and 1471 1.268 skrll * interrupt transfers will get re-added here so use 1472 1.268 skrll * the _SAFE version of TAILQ_FOREACH. 1473 1.268 skrll */ 1474 1.268 skrll TAILQ_FOREACH_SAFE(ux, &cq, ux_list, nextux) { 1475 1.277 pgoyette DPRINTF("ux %#jx", (uintptr_t)ux, 0, 0, 0); 1476 1.268 skrll usb_transfer_complete(&ux->ux_xfer); 1477 1.178 martin } 1478 1.1 augustss 1479 1.281 mrg KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 1480 1.1 augustss } 1481 1.1 augustss 1482 1.1 augustss /* Check for an interrupt. */ 1483 1.1 augustss void 1484 1.268 skrll uhci_check_intr(uhci_softc_t *sc, struct uhci_xfer *ux, ux_completeq_t *cqp) 1485 1.1 augustss { 1486 1.268 skrll uhci_soft_td_t *std, *fstd = NULL, *lstd = NULL; 1487 1.268 skrll uint32_t status; 1488 1.1 augustss 1489 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 1490 1.277 pgoyette DPRINTFN(15, "ux %#jx", (uintptr_t)ux, 0, 0, 0); 1491 1.268 skrll 1492 1.268 skrll KASSERT(ux != NULL); 1493 1.268 skrll 1494 1.268 skrll struct usbd_xfer *xfer = &ux->ux_xfer; 1495 1.268 skrll if (xfer->ux_status == USBD_CANCELLED || 1496 1.268 skrll xfer->ux_status == USBD_TIMEOUT) { 1497 1.277 pgoyette DPRINTF("aborted xfer %#jx", (uintptr_t)xfer, 0, 0, 0); 1498 1.1 augustss return; 1499 1.1 augustss } 1500 1.268 skrll 1501 1.268 skrll switch (ux->ux_type) { 1502 1.268 skrll case UX_CTRL: 1503 1.268 skrll fstd = ux->ux_setup; 1504 1.268 skrll lstd = ux->ux_stat; 1505 1.268 skrll break; 1506 1.268 skrll case UX_BULK: 1507 1.268 skrll case UX_INTR: 1508 1.268 skrll case UX_ISOC: 1509 1.268 skrll fstd = ux->ux_stdstart; 1510 1.268 skrll lstd = ux->ux_stdend; 1511 1.268 skrll break; 1512 1.268 skrll default: 1513 1.268 skrll KASSERT(false); 1514 1.268 skrll break; 1515 1.268 skrll } 1516 1.268 skrll if (fstd == NULL) 1517 1.155 augustss return; 1518 1.155 augustss 1519 1.268 skrll KASSERT(lstd != NULL); 1520 1.268 skrll 1521 1.223 bouyer usb_syncmem(&lstd->dma, 1522 1.223 bouyer lstd->offs + offsetof(uhci_td_t, td_status), 1523 1.223 bouyer sizeof(lstd->td.td_status), 1524 1.223 bouyer BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1525 1.256 tsutsui status = le32toh(lstd->td.td_status); 1526 1.256 tsutsui usb_syncmem(&lstd->dma, 1527 1.256 tsutsui lstd->offs + offsetof(uhci_td_t, td_status), 1528 1.256 tsutsui sizeof(lstd->td.td_status), 1529 1.256 tsutsui BUS_DMASYNC_PREREAD); 1530 1.258 skrll 1531 1.258 skrll /* If the last TD is not marked active we can complete */ 1532 1.258 skrll if (!(status & UHCI_TD_ACTIVE)) { 1533 1.258 skrll done: 1534 1.277 pgoyette DPRINTFN(12, "ux=%#jx done", (uintptr_t)ux, 0, 0, 0); 1535 1.268 skrll uhci_idone(ux, cqp); 1536 1.258 skrll return; 1537 1.258 skrll } 1538 1.258 skrll 1539 1.258 skrll /* 1540 1.258 skrll * If the last TD is still active we need to check whether there 1541 1.258 skrll * is an error somewhere in the middle, or whether there was a 1542 1.258 skrll * short packet (SPD and not ACTIVE). 1543 1.258 skrll */ 1544 1.277 pgoyette DPRINTFN(12, "active ux=%#jx", (uintptr_t)ux, 0, 0, 0); 1545 1.268 skrll for (std = fstd; std != lstd; std = std->link.std) { 1546 1.258 skrll usb_syncmem(&std->dma, 1547 1.258 skrll std->offs + offsetof(uhci_td_t, td_status), 1548 1.258 skrll sizeof(std->td.td_status), 1549 1.258 skrll BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1550 1.258 skrll status = le32toh(std->td.td_status); 1551 1.258 skrll usb_syncmem(&std->dma, 1552 1.258 skrll std->offs + offsetof(uhci_td_t, td_status), 1553 1.258 skrll sizeof(std->td.td_status), BUS_DMASYNC_PREREAD); 1554 1.258 skrll 1555 1.258 skrll /* If there's an active TD the xfer isn't done. */ 1556 1.258 skrll if (status & UHCI_TD_ACTIVE) { 1557 1.277 pgoyette DPRINTFN(12, "ux=%#jx std=%#jx still active", 1558 1.277 pgoyette (uintptr_t)ux, (uintptr_t)std, 0, 0); 1559 1.258 skrll return; 1560 1.258 skrll } 1561 1.258 skrll 1562 1.258 skrll /* Any kind of error makes the xfer done. */ 1563 1.258 skrll if (status & UHCI_TD_STALLED) 1564 1.258 skrll goto done; 1565 1.258 skrll 1566 1.258 skrll /* 1567 1.258 skrll * If the data phase of a control transfer is short, we need 1568 1.258 skrll * to complete the status stage 1569 1.258 skrll */ 1570 1.258 skrll 1571 1.268 skrll if ((status & UHCI_TD_SPD) && ux->ux_type == UX_CTRL) { 1572 1.258 skrll struct uhci_pipe *upipe = 1573 1.268 skrll UHCI_PIPE2UPIPE(xfer->ux_pipe); 1574 1.268 skrll uhci_soft_qh_t *sqh = upipe->ctrl.sqh; 1575 1.268 skrll uhci_soft_td_t *stat = upipe->ctrl.stat; 1576 1.268 skrll 1577 1.277 pgoyette DPRINTFN(12, "ux=%#jx std=%#jx control status" 1578 1.277 pgoyette "phase needs completion", (uintptr_t)ux, 1579 1.277 pgoyette (uintptr_t)ux->ux_stdstart, 0, 0); 1580 1.258 skrll 1581 1.258 skrll sqh->qh.qh_elink = 1582 1.258 skrll htole32(stat->physaddr | UHCI_PTR_TD); 1583 1.258 skrll usb_syncmem(&sqh->dma, sqh->offs, sizeof(sqh->qh), 1584 1.258 skrll BUS_DMASYNC_PREWRITE); 1585 1.258 skrll break; 1586 1.258 skrll } 1587 1.258 skrll 1588 1.258 skrll /* We want short packets, and it is short: it's done */ 1589 1.258 skrll usb_syncmem(&std->dma, 1590 1.258 skrll std->offs + offsetof(uhci_td_t, td_token), 1591 1.258 skrll sizeof(std->td.td_token), 1592 1.258 skrll BUS_DMASYNC_POSTWRITE); 1593 1.258 skrll 1594 1.258 skrll if ((status & UHCI_TD_SPD) && 1595 1.258 skrll UHCI_TD_GET_ACTLEN(status) < 1596 1.258 skrll UHCI_TD_GET_MAXLEN(le32toh(std->td.td_token))) { 1597 1.258 skrll goto done; 1598 1.18 augustss } 1599 1.1 augustss } 1600 1.1 augustss } 1601 1.1 augustss 1602 1.248 mrg /* Called with USB lock held. */ 1603 1.1 augustss void 1604 1.268 skrll uhci_idone(struct uhci_xfer *ux, ux_completeq_t *cqp) 1605 1.1 augustss { 1606 1.281 mrg UHCIHIST_FUNC(); UHCIHIST_CALLED(); 1607 1.268 skrll struct usbd_xfer *xfer = &ux->ux_xfer; 1608 1.268 skrll uhci_softc_t *sc __diagused = UHCI_XFER2SC(xfer); 1609 1.268 skrll struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); 1610 1.1 augustss uhci_soft_td_t *std; 1611 1.268 skrll uint32_t status = 0, nstatus; 1612 1.26 augustss int actlen; 1613 1.1 augustss 1614 1.304 skrll KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 1615 1.268 skrll 1616 1.277 pgoyette DPRINTFN(12, "ux=%#jx", (uintptr_t)ux, 0, 0, 0); 1617 1.248 mrg 1618 1.281 mrg /* 1619 1.289 riastrad * Try to claim this xfer for completion. If it has already 1620 1.289 riastrad * completed or aborted, drop it on the floor. 1621 1.281 mrg */ 1622 1.289 riastrad if (!usbd_xfer_trycomplete(xfer)) 1623 1.281 mrg return; 1624 1.281 mrg 1625 1.7 augustss #ifdef DIAGNOSTIC 1626 1.92 augustss #ifdef UHCI_DEBUG 1627 1.268 skrll if (ux->ux_isdone) { 1628 1.268 skrll DPRINTF("--- dump start ---", 0, 0, 0, 0); 1629 1.268 skrll uhci_dump_ii(ux); 1630 1.268 skrll DPRINTF("--- dump end ---", 0, 0, 0, 0); 1631 1.268 skrll } 1632 1.92 augustss #endif 1633 1.268 skrll KASSERT(!ux->ux_isdone); 1634 1.268 skrll KASSERTMSG(!ux->ux_isdone, "xfer %p type %d status %d", xfer, 1635 1.268 skrll ux->ux_type, xfer->ux_status); 1636 1.268 skrll ux->ux_isdone = true; 1637 1.7 augustss #endif 1638 1.48 augustss 1639 1.268 skrll if (xfer->ux_nframes != 0) { 1640 1.48 augustss /* Isoc transfer, do things differently. */ 1641 1.268 skrll uhci_soft_td_t **stds = upipe->isoc.stds; 1642 1.126 augustss int i, n, nframes, len; 1643 1.48 augustss 1644 1.277 pgoyette DPRINTFN(5, "ux=%#jx isoc ready", (uintptr_t)ux, 0, 0, 0); 1645 1.48 augustss 1646 1.268 skrll nframes = xfer->ux_nframes; 1647 1.48 augustss actlen = 0; 1648 1.268 skrll n = ux->ux_curframe; 1649 1.48 augustss for (i = 0; i < nframes; i++) { 1650 1.48 augustss std = stds[n]; 1651 1.59 augustss #ifdef UHCI_DEBUG 1652 1.268 skrll if (uhcidebug >= 5) { 1653 1.277 pgoyette DPRINTF("isoc TD %jd", i, 0, 0, 0); 1654 1.268 skrll DPRINTF("--- dump start ---", 0, 0, 0, 0); 1655 1.48 augustss uhci_dump_td(std); 1656 1.268 skrll DPRINTF("--- dump end ---", 0, 0, 0, 0); 1657 1.48 augustss } 1658 1.48 augustss #endif 1659 1.48 augustss if (++n >= UHCI_VFRAMELIST_COUNT) 1660 1.48 augustss n = 0; 1661 1.223 bouyer usb_syncmem(&std->dma, 1662 1.223 bouyer std->offs + offsetof(uhci_td_t, td_status), 1663 1.223 bouyer sizeof(std->td.td_status), 1664 1.223 bouyer BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1665 1.88 tsutsui status = le32toh(std->td.td_status); 1666 1.126 augustss len = UHCI_TD_GET_ACTLEN(status); 1667 1.268 skrll xfer->ux_frlengths[i] = len; 1668 1.126 augustss actlen += len; 1669 1.48 augustss } 1670 1.268 skrll upipe->isoc.inuse -= nframes; 1671 1.268 skrll xfer->ux_actlen = actlen; 1672 1.268 skrll xfer->ux_status = USBD_NORMAL_COMPLETION; 1673 1.140 augustss goto end; 1674 1.48 augustss } 1675 1.48 augustss 1676 1.59 augustss #ifdef UHCI_DEBUG 1677 1.277 pgoyette DPRINTFN(10, "ux=%#jx, xfer=%#jx, pipe=%#jx ready", (uintptr_t)ux, 1678 1.277 pgoyette (uintptr_t)xfer, (uintptr_t)upipe, 0); 1679 1.268 skrll if (uhcidebug >= 10) { 1680 1.268 skrll DPRINTF("--- dump start ---", 0, 0, 0, 0); 1681 1.268 skrll uhci_dump_tds(ux->ux_stdstart); 1682 1.268 skrll DPRINTF("--- dump end ---", 0, 0, 0, 0); 1683 1.268 skrll } 1684 1.48 augustss #endif 1685 1.48 augustss 1686 1.26 augustss /* The transfer is done, compute actual length and status. */ 1687 1.26 augustss actlen = 0; 1688 1.268 skrll for (std = ux->ux_stdstart; std != NULL; std = std->link.std) { 1689 1.223 bouyer usb_syncmem(&std->dma, std->offs, sizeof(std->td), 1690 1.223 bouyer BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1691 1.88 tsutsui nstatus = le32toh(std->td.td_status); 1692 1.64 augustss if (nstatus & UHCI_TD_ACTIVE) 1693 1.26 augustss break; 1694 1.67 augustss 1695 1.64 augustss status = nstatus; 1696 1.88 tsutsui if (UHCI_TD_GET_PID(le32toh(std->td.td_token)) != 1697 1.88 tsutsui UHCI_TD_PID_SETUP) 1698 1.26 augustss actlen += UHCI_TD_GET_ACTLEN(status); 1699 1.176 mycroft else { 1700 1.176 mycroft /* 1701 1.176 mycroft * UHCI will report CRCTO in addition to a STALL or NAK 1702 1.176 mycroft * for a SETUP transaction. See section 3.2.2, "TD 1703 1.176 mycroft * CONTROL AND STATUS". 1704 1.176 mycroft */ 1705 1.176 mycroft if (status & (UHCI_TD_STALLED | UHCI_TD_NAK)) 1706 1.176 mycroft status &= ~UHCI_TD_CRCTO; 1707 1.176 mycroft } 1708 1.1 augustss } 1709 1.38 augustss /* If there are left over TDs we need to update the toggle. */ 1710 1.63 augustss if (std != NULL) 1711 1.88 tsutsui upipe->nexttoggle = UHCI_TD_GET_DT(le32toh(std->td.td_token)); 1712 1.38 augustss 1713 1.1 augustss status &= UHCI_TD_ERROR; 1714 1.295 christos DPRINTFN(10, "actlen=%jd, status=%#jx", actlen, status, 0, 0); 1715 1.268 skrll xfer->ux_actlen = actlen; 1716 1.1 augustss if (status != 0) { 1717 1.122 tv 1718 1.268 skrll DPRINTFN((status == UHCI_TD_STALLED) * 10, 1719 1.296 christos "error, addr=%jd, endpt=0x%02jx", 1720 1.268 skrll xfer->ux_pipe->up_dev->ud_addr, 1721 1.268 skrll xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress, 1722 1.268 skrll 0, 0); 1723 1.268 skrll DPRINTFN((status == UHCI_TD_STALLED) * 10, 1724 1.277 pgoyette "bitstuff=%jd crcto =%jd nak =%jd babble =%jd", 1725 1.268 skrll !!(status & UHCI_TD_BITSTUFF), 1726 1.268 skrll !!(status & UHCI_TD_CRCTO), 1727 1.268 skrll !!(status & UHCI_TD_NAK), 1728 1.268 skrll !!(status & UHCI_TD_BABBLE)); 1729 1.268 skrll DPRINTFN((status == UHCI_TD_STALLED) * 10, 1730 1.277 pgoyette "dbuffer =%jd stalled =%jd active =%jd", 1731 1.268 skrll !!(status & UHCI_TD_DBUFFER), 1732 1.268 skrll !!(status & UHCI_TD_STALLED), 1733 1.268 skrll !!(status & UHCI_TD_ACTIVE), 1734 1.268 skrll 0); 1735 1.122 tv 1736 1.1 augustss if (status == UHCI_TD_STALLED) 1737 1.268 skrll xfer->ux_status = USBD_STALLED; 1738 1.1 augustss else 1739 1.268 skrll xfer->ux_status = USBD_IOERROR; /* more info XXX */ 1740 1.1 augustss } else { 1741 1.268 skrll xfer->ux_status = USBD_NORMAL_COMPLETION; 1742 1.1 augustss } 1743 1.140 augustss 1744 1.140 augustss end: 1745 1.268 skrll uhci_del_intr_list(sc, ux); 1746 1.268 skrll if (cqp) 1747 1.268 skrll TAILQ_INSERT_TAIL(cqp, ux, ux_list); 1748 1.268 skrll 1749 1.304 skrll KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 1750 1.277 pgoyette DPRINTFN(12, "ux=%#jx done", (uintptr_t)ux, 0, 0, 0); 1751 1.1 augustss } 1752 1.1 augustss 1753 1.8 augustss void 1754 1.119 augustss uhci_poll(struct usbd_bus *bus) 1755 1.8 augustss { 1756 1.268 skrll uhci_softc_t *sc = UHCI_BUS2SC(bus); 1757 1.8 augustss 1758 1.248 mrg if (UREAD2(sc, UHCI_STS) & UHCI_STS_USBINT) { 1759 1.248 mrg mutex_spin_enter(&sc->sc_intr_lock); 1760 1.141 augustss uhci_intr1(sc); 1761 1.248 mrg mutex_spin_exit(&sc->sc_intr_lock); 1762 1.248 mrg } 1763 1.8 augustss } 1764 1.8 augustss 1765 1.1 augustss void 1766 1.119 augustss uhci_reset(uhci_softc_t *sc) 1767 1.1 augustss { 1768 1.1 augustss int n; 1769 1.1 augustss 1770 1.1 augustss UHCICMD(sc, UHCI_CMD_HCRESET); 1771 1.1 augustss /* The reset bit goes low when the controller is done. */ 1772 1.152 augustss for (n = 0; n < UHCI_RESET_TIMEOUT && 1773 1.1 augustss (UREAD2(sc, UHCI_CMD) & UHCI_CMD_HCRESET); n++) 1774 1.92 augustss usb_delay_ms(&sc->sc_bus, 1); 1775 1.1 augustss if (n >= UHCI_RESET_TIMEOUT) 1776 1.152 augustss printf("%s: controller did not reset\n", 1777 1.216 drochner device_xname(sc->sc_dev)); 1778 1.1 augustss } 1779 1.1 augustss 1780 1.16 augustss usbd_status 1781 1.314 riastrad uhci_run(uhci_softc_t *sc, int run) 1782 1.1 augustss { 1783 1.248 mrg int n, running; 1784 1.268 skrll uint16_t cmd; 1785 1.268 skrll 1786 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 1787 1.1 augustss 1788 1.1 augustss run = run != 0; 1789 1.268 skrll 1790 1.277 pgoyette DPRINTF("setting run=%jd", run, 0, 0, 0); 1791 1.71 augustss cmd = UREAD2(sc, UHCI_CMD); 1792 1.71 augustss if (run) 1793 1.71 augustss cmd |= UHCI_CMD_RS; 1794 1.71 augustss else 1795 1.71 augustss cmd &= ~UHCI_CMD_RS; 1796 1.71 augustss UHCICMD(sc, cmd); 1797 1.267 skrll for (n = 0; n < 10; n++) { 1798 1.1 augustss running = !(UREAD2(sc, UHCI_STS) & UHCI_STS_HCH); 1799 1.1 augustss /* return when we've entered the state we want */ 1800 1.1 augustss if (run == running) { 1801 1.295 christos DPRINTF("done cmd=%#jx sts=%#jx", 1802 1.268 skrll UREAD2(sc, UHCI_CMD), UREAD2(sc, UHCI_STS), 0, 0); 1803 1.268 skrll return USBD_NORMAL_COMPLETION; 1804 1.1 augustss } 1805 1.315 riastrad usb_delay_ms(&sc->sc_bus, 1); 1806 1.1 augustss } 1807 1.216 drochner printf("%s: cannot %s\n", device_xname(sc->sc_dev), 1808 1.14 augustss run ? "start" : "stop"); 1809 1.268 skrll return USBD_IOERROR; 1810 1.1 augustss } 1811 1.1 augustss 1812 1.1 augustss /* 1813 1.1 augustss * Memory management routines. 1814 1.1 augustss * uhci_alloc_std allocates TDs 1815 1.1 augustss * uhci_alloc_sqh allocates QHs 1816 1.7 augustss * These two routines do their own free list management, 1817 1.1 augustss * partly for speed, partly because allocating DMAable memory 1818 1.268 skrll * has page size granularity so much memory would be wasted if 1819 1.16 augustss * only one TD/QH (32 bytes) was placed in each allocated chunk. 1820 1.1 augustss */ 1821 1.1 augustss 1822 1.1 augustss uhci_soft_td_t * 1823 1.119 augustss uhci_alloc_std(uhci_softc_t *sc) 1824 1.1 augustss { 1825 1.1 augustss uhci_soft_td_t *std; 1826 1.42 augustss int i, offs; 1827 1.7 augustss usb_dma_t dma; 1828 1.1 augustss 1829 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 1830 1.268 skrll 1831 1.268 skrll mutex_enter(&sc->sc_lock); 1832 1.63 augustss if (sc->sc_freetds == NULL) { 1833 1.268 skrll DPRINTFN(2, "allocating chunk", 0, 0, 0, 0); 1834 1.268 skrll mutex_exit(&sc->sc_lock); 1835 1.268 skrll 1836 1.308 skrll int err = usb_allocmem(sc->sc_bus.ub_dmatag, UHCI_STD_SIZE * UHCI_STD_CHUNK, 1837 1.300 skrll UHCI_TD_ALIGN, USBMALLOC_COHERENT, &dma); 1838 1.63 augustss if (err) 1839 1.268 skrll return NULL; 1840 1.268 skrll 1841 1.268 skrll mutex_enter(&sc->sc_lock); 1842 1.248 mrg for (i = 0; i < UHCI_STD_CHUNK; i++) { 1843 1.42 augustss offs = i * UHCI_STD_SIZE; 1844 1.159 augustss std = KERNADDR(&dma, offs); 1845 1.160 augustss std->physaddr = DMAADDR(&dma, offs); 1846 1.223 bouyer std->dma = dma; 1847 1.223 bouyer std->offs = offs; 1848 1.42 augustss std->link.std = sc->sc_freetds; 1849 1.1 augustss sc->sc_freetds = std; 1850 1.1 augustss } 1851 1.1 augustss } 1852 1.1 augustss std = sc->sc_freetds; 1853 1.42 augustss sc->sc_freetds = std->link.std; 1854 1.268 skrll mutex_exit(&sc->sc_lock); 1855 1.268 skrll 1856 1.42 augustss memset(&std->td, 0, sizeof(uhci_td_t)); 1857 1.268 skrll 1858 1.1 augustss return std; 1859 1.1 augustss } 1860 1.1 augustss 1861 1.268 skrll #define TD_IS_FREE 0x12345678 1862 1.268 skrll 1863 1.1 augustss void 1864 1.268 skrll uhci_free_std_locked(uhci_softc_t *sc, uhci_soft_td_t *std) 1865 1.1 augustss { 1866 1.268 skrll KASSERT(mutex_owned(&sc->sc_lock)); 1867 1.268 skrll 1868 1.7 augustss #ifdef DIAGNOSTIC 1869 1.88 tsutsui if (le32toh(std->td.td_token) == TD_IS_FREE) { 1870 1.268 skrll printf("%s: freeing free TD %p\n", __func__, std); 1871 1.7 augustss return; 1872 1.7 augustss } 1873 1.88 tsutsui std->td.td_token = htole32(TD_IS_FREE); 1874 1.7 augustss #endif 1875 1.268 skrll 1876 1.42 augustss std->link.std = sc->sc_freetds; 1877 1.1 augustss sc->sc_freetds = std; 1878 1.1 augustss } 1879 1.1 augustss 1880 1.268 skrll void 1881 1.268 skrll uhci_free_std(uhci_softc_t *sc, uhci_soft_td_t *std) 1882 1.268 skrll { 1883 1.268 skrll mutex_enter(&sc->sc_lock); 1884 1.268 skrll uhci_free_std_locked(sc, std); 1885 1.268 skrll mutex_exit(&sc->sc_lock); 1886 1.268 skrll } 1887 1.268 skrll 1888 1.1 augustss uhci_soft_qh_t * 1889 1.119 augustss uhci_alloc_sqh(uhci_softc_t *sc) 1890 1.1 augustss { 1891 1.1 augustss uhci_soft_qh_t *sqh; 1892 1.1 augustss int i, offs; 1893 1.7 augustss usb_dma_t dma; 1894 1.1 augustss 1895 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 1896 1.268 skrll 1897 1.268 skrll mutex_enter(&sc->sc_lock); 1898 1.63 augustss if (sc->sc_freeqhs == NULL) { 1899 1.268 skrll DPRINTFN(2, "allocating chunk", 0, 0, 0, 0); 1900 1.268 skrll mutex_exit(&sc->sc_lock); 1901 1.268 skrll 1902 1.308 skrll int err = usb_allocmem(sc->sc_bus.ub_dmatag, UHCI_SQH_SIZE * UHCI_SQH_CHUNK, 1903 1.300 skrll UHCI_QH_ALIGN, USBMALLOC_COHERENT, &dma); 1904 1.63 augustss if (err) 1905 1.268 skrll return NULL; 1906 1.268 skrll 1907 1.268 skrll mutex_enter(&sc->sc_lock); 1908 1.267 skrll for (i = 0; i < UHCI_SQH_CHUNK; i++) { 1909 1.42 augustss offs = i * UHCI_SQH_SIZE; 1910 1.159 augustss sqh = KERNADDR(&dma, offs); 1911 1.160 augustss sqh->physaddr = DMAADDR(&dma, offs); 1912 1.223 bouyer sqh->dma = dma; 1913 1.223 bouyer sqh->offs = offs; 1914 1.42 augustss sqh->hlink = sc->sc_freeqhs; 1915 1.1 augustss sc->sc_freeqhs = sqh; 1916 1.1 augustss } 1917 1.1 augustss } 1918 1.1 augustss sqh = sc->sc_freeqhs; 1919 1.42 augustss sc->sc_freeqhs = sqh->hlink; 1920 1.268 skrll mutex_exit(&sc->sc_lock); 1921 1.268 skrll 1922 1.42 augustss memset(&sqh->qh, 0, sizeof(uhci_qh_t)); 1923 1.268 skrll 1924 1.268 skrll return sqh; 1925 1.1 augustss } 1926 1.1 augustss 1927 1.1 augustss void 1928 1.119 augustss uhci_free_sqh(uhci_softc_t *sc, uhci_soft_qh_t *sqh) 1929 1.1 augustss { 1930 1.268 skrll KASSERT(mutex_owned(&sc->sc_lock)); 1931 1.268 skrll 1932 1.42 augustss sqh->hlink = sc->sc_freeqhs; 1933 1.1 augustss sc->sc_freeqhs = sqh; 1934 1.1 augustss } 1935 1.1 augustss 1936 1.268 skrll #if 0 1937 1.1 augustss void 1938 1.119 augustss uhci_free_std_chain(uhci_softc_t *sc, uhci_soft_td_t *std, 1939 1.119 augustss uhci_soft_td_t *stdend) 1940 1.1 augustss { 1941 1.1 augustss uhci_soft_td_t *p; 1942 1.256 tsutsui uint32_t td_link; 1943 1.1 augustss 1944 1.223 bouyer /* 1945 1.223 bouyer * to avoid race condition with the controller which may be looking 1946 1.223 bouyer * at this chain, we need to first invalidate all links, and 1947 1.223 bouyer * then wait for the controller to move to another queue 1948 1.223 bouyer */ 1949 1.223 bouyer for (p = std; p != stdend; p = p->link.std) { 1950 1.223 bouyer usb_syncmem(&p->dma, 1951 1.223 bouyer p->offs + offsetof(uhci_td_t, td_link), 1952 1.223 bouyer sizeof(p->td.td_link), 1953 1.223 bouyer BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 1954 1.256 tsutsui td_link = le32toh(p->td.td_link); 1955 1.256 tsutsui usb_syncmem(&p->dma, 1956 1.256 tsutsui p->offs + offsetof(uhci_td_t, td_link), 1957 1.256 tsutsui sizeof(p->td.td_link), 1958 1.256 tsutsui BUS_DMASYNC_PREREAD); 1959 1.256 tsutsui if ((td_link & UHCI_PTR_T) == 0) { 1960 1.255 tsutsui p->td.td_link = htole32(UHCI_PTR_T); 1961 1.223 bouyer usb_syncmem(&p->dma, 1962 1.223 bouyer p->offs + offsetof(uhci_td_t, td_link), 1963 1.223 bouyer sizeof(p->td.td_link), 1964 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 1965 1.223 bouyer } 1966 1.223 bouyer } 1967 1.223 bouyer delay(UHCI_QH_REMOVE_DELAY); 1968 1.223 bouyer 1969 1.1 augustss for (; std != stdend; std = p) { 1970 1.42 augustss p = std->link.std; 1971 1.1 augustss uhci_free_std(sc, std); 1972 1.1 augustss } 1973 1.1 augustss } 1974 1.268 skrll #endif 1975 1.268 skrll 1976 1.268 skrll int 1977 1.268 skrll uhci_alloc_std_chain(uhci_softc_t *sc, struct usbd_xfer *xfer, int len, 1978 1.268 skrll int rd, uhci_soft_td_t **sp) 1979 1.268 skrll { 1980 1.268 skrll struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer); 1981 1.268 skrll uint16_t flags = xfer->ux_flags; 1982 1.268 skrll uhci_soft_td_t *p; 1983 1.268 skrll 1984 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 1985 1.1 augustss 1986 1.277 pgoyette DPRINTFN(8, "xfer=%#jx pipe=%#jx", (uintptr_t)xfer, 1987 1.277 pgoyette (uintptr_t)xfer->ux_pipe, 0, 0); 1988 1.248 mrg 1989 1.268 skrll ASSERT_SLEEPABLE(); 1990 1.268 skrll KASSERT(sp); 1991 1.248 mrg 1992 1.268 skrll int maxp = UGETW(xfer->ux_pipe->up_endpoint->ue_edesc->wMaxPacketSize); 1993 1.1 augustss if (maxp == 0) { 1994 1.268 skrll printf("%s: maxp=0\n", __func__); 1995 1.268 skrll return EINVAL; 1996 1.1 augustss } 1997 1.297 skrll size_t ntd = howmany(len, maxp); 1998 1.302 skrll /* 1999 1.302 skrll * if our transfer is bigger than PAGE_SIZE and maxp not a factor of 2000 1.302 skrll * PAGE_SIZE then we will need another TD per page. 2001 1.302 skrll */ 2002 1.302 skrll if (len > PAGE_SIZE && (PAGE_SIZE % maxp) != 0) { 2003 1.302 skrll ntd += howmany(len, PAGE_SIZE); 2004 1.302 skrll } 2005 1.302 skrll 2006 1.302 skrll /* 2007 1.302 skrll * Might need one more TD if we're writing a ZLP 2008 1.302 skrll */ 2009 1.268 skrll if (!rd && (flags & USBD_FORCE_SHORT_XFER)) { 2010 1.73 augustss ntd++; 2011 1.268 skrll } 2012 1.277 pgoyette DPRINTFN(10, "maxp=%jd ntd=%jd", maxp, ntd, 0, 0); 2013 1.268 skrll 2014 1.268 skrll uxfer->ux_stds = NULL; 2015 1.268 skrll uxfer->ux_nstd = ntd; 2016 1.73 augustss if (ntd == 0) { 2017 1.268 skrll *sp = NULL; 2018 1.268 skrll DPRINTF("ntd=0", 0, 0, 0, 0); 2019 1.268 skrll return 0; 2020 1.73 augustss } 2021 1.268 skrll uxfer->ux_stds = kmem_alloc(sizeof(uhci_soft_td_t *) * ntd, 2022 1.268 skrll KM_SLEEP); 2023 1.268 skrll 2024 1.276 skrll for (int i = 0; i < ntd; i++) { 2025 1.1 augustss p = uhci_alloc_std(sc); 2026 1.63 augustss if (p == NULL) { 2027 1.276 skrll if (i != 0) { 2028 1.276 skrll uxfer->ux_nstd = i; 2029 1.276 skrll uhci_free_stds(sc, uxfer); 2030 1.276 skrll } 2031 1.268 skrll kmem_free(uxfer->ux_stds, 2032 1.268 skrll sizeof(uhci_soft_td_t *) * ntd); 2033 1.268 skrll return ENOMEM; 2034 1.268 skrll } 2035 1.268 skrll uxfer->ux_stds[i] = p; 2036 1.1 augustss } 2037 1.1 augustss 2038 1.268 skrll *sp = uxfer->ux_stds[0]; 2039 1.268 skrll 2040 1.268 skrll return 0; 2041 1.38 augustss } 2042 1.38 augustss 2043 1.268 skrll Static void 2044 1.268 skrll uhci_free_stds(uhci_softc_t *sc, struct uhci_xfer *ux) 2045 1.38 augustss { 2046 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 2047 1.38 augustss 2048 1.277 pgoyette DPRINTFN(8, "ux=%#jx", (uintptr_t)ux, 0, 0, 0); 2049 1.16 augustss 2050 1.248 mrg mutex_enter(&sc->sc_lock); 2051 1.268 skrll for (size_t i = 0; i < ux->ux_nstd; i++) { 2052 1.268 skrll uhci_soft_td_t *std = ux->ux_stds[i]; 2053 1.268 skrll #ifdef DIAGNOSTIC 2054 1.268 skrll if (le32toh(std->td.td_token) == TD_IS_FREE) { 2055 1.268 skrll printf("%s: freeing free TD %p\n", __func__, std); 2056 1.268 skrll return; 2057 1.268 skrll } 2058 1.268 skrll std->td.td_token = htole32(TD_IS_FREE); 2059 1.268 skrll #endif 2060 1.268 skrll ux->ux_stds[i]->link.std = sc->sc_freetds; 2061 1.268 skrll sc->sc_freetds = std; 2062 1.268 skrll } 2063 1.248 mrg mutex_exit(&sc->sc_lock); 2064 1.268 skrll } 2065 1.52 augustss 2066 1.16 augustss 2067 1.268 skrll Static void 2068 1.268 skrll uhci_reset_std_chain(uhci_softc_t *sc, struct usbd_xfer *xfer, 2069 1.268 skrll int length, int isread, int *toggle, uhci_soft_td_t **lstd) 2070 1.16 augustss { 2071 1.268 skrll struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer); 2072 1.268 skrll struct usbd_pipe *pipe = xfer->ux_pipe; 2073 1.268 skrll usb_dma_t *dma = &xfer->ux_dmabuf; 2074 1.268 skrll uint16_t flags = xfer->ux_flags; 2075 1.268 skrll uhci_soft_td_t *std, *prev; 2076 1.268 skrll int len = length; 2077 1.268 skrll int tog = *toggle; 2078 1.268 skrll int maxp; 2079 1.268 skrll uint32_t status; 2080 1.302 skrll size_t i, offs; 2081 1.268 skrll 2082 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 2083 1.277 pgoyette DPRINTFN(8, "xfer=%#jx len %jd isread %jd toggle %jd", (uintptr_t)xfer, 2084 1.268 skrll len, isread, *toggle); 2085 1.1 augustss 2086 1.268 skrll KASSERT(len != 0 || (!isread && (flags & USBD_FORCE_SHORT_XFER))); 2087 1.1 augustss 2088 1.268 skrll maxp = UGETW(pipe->up_endpoint->ue_edesc->wMaxPacketSize); 2089 1.268 skrll KASSERT(maxp != 0); 2090 1.82 augustss 2091 1.268 skrll int addr = xfer->ux_pipe->up_dev->ud_addr; 2092 1.268 skrll int endpt = xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress; 2093 1.1 augustss 2094 1.268 skrll status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(3) | UHCI_TD_ACTIVE); 2095 1.268 skrll if (pipe->up_dev->ud_speed == USB_SPEED_LOW) 2096 1.268 skrll status |= UHCI_TD_LS; 2097 1.268 skrll if (flags & USBD_SHORT_XFER_OK) 2098 1.268 skrll status |= UHCI_TD_SPD; 2099 1.268 skrll usb_syncmem(dma, 0, len, 2100 1.268 skrll isread ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 2101 1.268 skrll std = prev = NULL; 2102 1.302 skrll for (offs = i = 0; len != 0 && i < uxfer->ux_nstd; i++, prev = std) { 2103 1.268 skrll int l = len; 2104 1.268 skrll std = uxfer->ux_stds[i]; 2105 1.302 skrll 2106 1.302 skrll const bus_addr_t sbp = DMAADDR(dma, offs); 2107 1.302 skrll const bus_addr_t ebp = DMAADDR(dma, offs + l - 1); 2108 1.302 skrll if (((sbp ^ ebp) & ~PAGE_MASK) != 0) 2109 1.302 skrll l = PAGE_SIZE - (DMAADDR(dma, offs) & PAGE_MASK); 2110 1.302 skrll 2111 1.268 skrll if (l > maxp) 2112 1.268 skrll l = maxp; 2113 1.268 skrll 2114 1.268 skrll if (prev) { 2115 1.268 skrll prev->link.std = std; 2116 1.268 skrll prev->td.td_link = htole32( 2117 1.268 skrll std->physaddr | UHCI_PTR_VF | UHCI_PTR_TD 2118 1.268 skrll ); 2119 1.268 skrll usb_syncmem(&prev->dma, prev->offs, sizeof(prev->td), 2120 1.268 skrll BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2121 1.268 skrll } 2122 1.268 skrll 2123 1.268 skrll usb_syncmem(&std->dma, std->offs, sizeof(std->td), 2124 1.268 skrll BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 2125 1.268 skrll 2126 1.268 skrll std->td.td_link = htole32(UHCI_PTR_T | UHCI_PTR_VF | UHCI_PTR_TD); 2127 1.268 skrll std->td.td_status = htole32(status); 2128 1.268 skrll std->td.td_token = htole32( 2129 1.268 skrll UHCI_TD_SET_ENDPT(UE_GET_ADDR(endpt)) | 2130 1.268 skrll UHCI_TD_SET_DEVADDR(addr) | 2131 1.268 skrll UHCI_TD_SET_PID(isread ? UHCI_TD_PID_IN : UHCI_TD_PID_OUT) | 2132 1.268 skrll UHCI_TD_SET_DT(tog) | 2133 1.268 skrll UHCI_TD_SET_MAXLEN(l) 2134 1.268 skrll ); 2135 1.302 skrll std->td.td_buffer = htole32(DMAADDR(dma, offs)); 2136 1.268 skrll 2137 1.268 skrll std->link.std = NULL; 2138 1.268 skrll 2139 1.268 skrll usb_syncmem(&std->dma, std->offs, sizeof(std->td), 2140 1.268 skrll BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2141 1.268 skrll tog ^= 1; 2142 1.268 skrll 2143 1.302 skrll offs += l; 2144 1.268 skrll len -= l; 2145 1.268 skrll } 2146 1.268 skrll KASSERTMSG(len == 0, "xfer %p alen %d len %d mps %d ux_nqtd %zu i %zu", 2147 1.268 skrll xfer, length, len, maxp, uxfer->ux_nstd, i); 2148 1.268 skrll 2149 1.268 skrll if (!isread && 2150 1.268 skrll (flags & USBD_FORCE_SHORT_XFER) && 2151 1.268 skrll length % maxp == 0) { 2152 1.268 skrll /* Force a 0 length transfer at the end. */ 2153 1.268 skrll KASSERTMSG(i < uxfer->ux_nstd, "i=%zu nstd=%zu", i, 2154 1.268 skrll uxfer->ux_nstd); 2155 1.268 skrll std = uxfer->ux_stds[i++]; 2156 1.268 skrll 2157 1.268 skrll std->td.td_link = htole32(UHCI_PTR_T | UHCI_PTR_VF | UHCI_PTR_TD); 2158 1.268 skrll std->td.td_status = htole32(status); 2159 1.268 skrll std->td.td_token = htole32( 2160 1.268 skrll UHCI_TD_SET_ENDPT(UE_GET_ADDR(endpt)) | 2161 1.268 skrll UHCI_TD_SET_DEVADDR(addr) | 2162 1.268 skrll UHCI_TD_SET_PID(UHCI_TD_PID_OUT) | 2163 1.268 skrll UHCI_TD_SET_DT(tog) | 2164 1.268 skrll UHCI_TD_SET_MAXLEN(0) 2165 1.268 skrll ); 2166 1.268 skrll std->td.td_buffer = 0; 2167 1.268 skrll usb_syncmem(&std->dma, std->offs, sizeof(std->td), 2168 1.268 skrll BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2169 1.268 skrll 2170 1.268 skrll std->link.std = NULL; 2171 1.268 skrll if (prev) { 2172 1.268 skrll prev->link.std = std; 2173 1.268 skrll prev->td.td_link = htole32( 2174 1.268 skrll std->physaddr | UHCI_PTR_VF | UHCI_PTR_TD 2175 1.268 skrll ); 2176 1.268 skrll usb_syncmem(&prev->dma, prev->offs, sizeof(prev->td), 2177 1.268 skrll BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2178 1.268 skrll } 2179 1.268 skrll tog ^= 1; 2180 1.268 skrll } 2181 1.268 skrll *lstd = std; 2182 1.268 skrll *toggle = tog; 2183 1.268 skrll } 2184 1.268 skrll 2185 1.268 skrll void 2186 1.268 skrll uhci_device_clear_toggle(struct usbd_pipe *pipe) 2187 1.268 skrll { 2188 1.268 skrll struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe); 2189 1.268 skrll upipe->nexttoggle = 0; 2190 1.268 skrll } 2191 1.268 skrll 2192 1.268 skrll void 2193 1.268 skrll uhci_noop(struct usbd_pipe *pipe) 2194 1.268 skrll { 2195 1.268 skrll } 2196 1.268 skrll 2197 1.268 skrll int 2198 1.268 skrll uhci_device_bulk_init(struct usbd_xfer *xfer) 2199 1.268 skrll { 2200 1.268 skrll uhci_softc_t *sc = UHCI_XFER2SC(xfer); 2201 1.268 skrll struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer); 2202 1.268 skrll usb_endpoint_descriptor_t *ed = xfer->ux_pipe->up_endpoint->ue_edesc; 2203 1.268 skrll int endpt = ed->bEndpointAddress; 2204 1.268 skrll int isread = UE_GET_DIR(endpt) == UE_DIR_IN; 2205 1.268 skrll int len = xfer->ux_bufsize; 2206 1.268 skrll int err = 0; 2207 1.268 skrll 2208 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 2209 1.277 pgoyette DPRINTFN(3, "xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, len, 2210 1.277 pgoyette xfer->ux_flags, 0); 2211 1.268 skrll 2212 1.268 skrll if (sc->sc_dying) 2213 1.268 skrll return USBD_IOERROR; 2214 1.268 skrll 2215 1.268 skrll KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); 2216 1.268 skrll 2217 1.268 skrll uxfer->ux_type = UX_BULK; 2218 1.268 skrll err = uhci_alloc_std_chain(sc, xfer, len, isread, &uxfer->ux_stdstart); 2219 1.268 skrll if (err) 2220 1.268 skrll return err; 2221 1.268 skrll 2222 1.268 skrll #ifdef UHCI_DEBUG 2223 1.268 skrll if (uhcidebug >= 10) { 2224 1.268 skrll DPRINTF("--- dump start ---", 0, 0, 0, 0); 2225 1.268 skrll uhci_dump_tds(uxfer->ux_stdstart); 2226 1.268 skrll DPRINTF("--- dump end ---", 0, 0, 0, 0); 2227 1.268 skrll } 2228 1.268 skrll #endif 2229 1.268 skrll 2230 1.268 skrll return 0; 2231 1.268 skrll } 2232 1.268 skrll 2233 1.268 skrll Static void 2234 1.268 skrll uhci_device_bulk_fini(struct usbd_xfer *xfer) 2235 1.268 skrll { 2236 1.268 skrll uhci_softc_t *sc = UHCI_XFER2SC(xfer); 2237 1.268 skrll struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); 2238 1.268 skrll 2239 1.268 skrll KASSERT(ux->ux_type == UX_BULK); 2240 1.268 skrll 2241 1.276 skrll if (ux->ux_nstd) { 2242 1.276 skrll uhci_free_stds(sc, ux); 2243 1.268 skrll kmem_free(ux->ux_stds, sizeof(uhci_soft_td_t *) * ux->ux_nstd); 2244 1.276 skrll } 2245 1.268 skrll } 2246 1.268 skrll 2247 1.268 skrll usbd_status 2248 1.268 skrll uhci_device_bulk_transfer(struct usbd_xfer *xfer) 2249 1.268 skrll { 2250 1.268 skrll 2251 1.309 riastrad /* Pipe isn't running, so start it first. */ 2252 1.268 skrll return uhci_device_bulk_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 2253 1.268 skrll } 2254 1.248 mrg 2255 1.268 skrll usbd_status 2256 1.268 skrll uhci_device_bulk_start(struct usbd_xfer *xfer) 2257 1.268 skrll { 2258 1.268 skrll struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); 2259 1.268 skrll struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); 2260 1.268 skrll uhci_softc_t *sc = UHCI_XFER2SC(xfer); 2261 1.268 skrll uhci_soft_td_t *data, *dataend; 2262 1.268 skrll uhci_soft_qh_t *sqh; 2263 1.268 skrll int len; 2264 1.268 skrll int endpt; 2265 1.268 skrll int isread; 2266 1.268 skrll 2267 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 2268 1.277 pgoyette DPRINTFN(3, "xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, 2269 1.277 pgoyette xfer->ux_length, xfer->ux_flags, 0); 2270 1.268 skrll 2271 1.311 riastrad KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 2272 1.311 riastrad 2273 1.268 skrll if (sc->sc_dying) 2274 1.268 skrll return USBD_IOERROR; 2275 1.268 skrll 2276 1.268 skrll KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); 2277 1.268 skrll KASSERT(xfer->ux_length <= xfer->ux_bufsize); 2278 1.268 skrll 2279 1.268 skrll len = xfer->ux_length; 2280 1.268 skrll endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; 2281 1.45 augustss isread = UE_GET_DIR(endpt) == UE_DIR_IN; 2282 1.268 skrll sqh = upipe->bulk.sqh; 2283 1.1 augustss 2284 1.268 skrll uhci_reset_std_chain(sc, xfer, len, isread, &upipe->nexttoggle, 2285 1.268 skrll &dataend); 2286 1.268 skrll 2287 1.268 skrll data = ux->ux_stdstart; 2288 1.268 skrll ux->ux_stdend = dataend; 2289 1.88 tsutsui dataend->td.td_status |= htole32(UHCI_TD_IOC); 2290 1.223 bouyer usb_syncmem(&dataend->dma, 2291 1.223 bouyer dataend->offs + offsetof(uhci_td_t, td_status), 2292 1.223 bouyer sizeof(dataend->td.td_status), 2293 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2294 1.223 bouyer 2295 1.59 augustss #ifdef UHCI_DEBUG 2296 1.268 skrll if (uhcidebug >= 10) { 2297 1.268 skrll DPRINTF("--- dump start ---", 0, 0, 0, 0); 2298 1.268 skrll DPRINTFN(10, "before transfer", 0, 0, 0, 0); 2299 1.55 augustss uhci_dump_tds(data); 2300 1.268 skrll DPRINTF("--- dump end ---", 0, 0, 0, 0); 2301 1.1 augustss } 2302 1.1 augustss #endif 2303 1.1 augustss 2304 1.268 skrll KASSERT(ux->ux_isdone); 2305 1.7 augustss #ifdef DIAGNOSTIC 2306 1.268 skrll ux->ux_isdone = false; 2307 1.7 augustss #endif 2308 1.1 augustss 2309 1.55 augustss sqh->elink = data; 2310 1.121 augustss sqh->qh.qh_elink = htole32(data->physaddr | UHCI_PTR_TD); 2311 1.223 bouyer /* uhci_add_bulk() will do usb_syncmem(sqh) */ 2312 1.1 augustss 2313 1.1 augustss uhci_add_bulk(sc, sqh); 2314 1.268 skrll uhci_add_intr_list(sc, ux); 2315 1.318 riastrad xfer->ux_status = USBD_IN_PROGRESS; 2316 1.289 riastrad usbd_xfer_schedule_timeout(xfer); 2317 1.1 augustss 2318 1.268 skrll return USBD_IN_PROGRESS; 2319 1.1 augustss } 2320 1.1 augustss 2321 1.1 augustss /* Abort a device bulk request. */ 2322 1.1 augustss void 2323 1.268 skrll uhci_device_bulk_abort(struct usbd_xfer *xfer) 2324 1.1 augustss { 2325 1.268 skrll uhci_softc_t *sc __diagused = UHCI_XFER2SC(xfer); 2326 1.248 mrg 2327 1.248 mrg KASSERT(mutex_owned(&sc->sc_lock)); 2328 1.248 mrg 2329 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 2330 1.268 skrll 2331 1.289 riastrad usbd_xfer_abort(xfer); 2332 1.33 augustss } 2333 1.33 augustss 2334 1.92 augustss /* 2335 1.281 mrg * To allow the hardware time to notice we simply wait. 2336 1.92 augustss */ 2337 1.289 riastrad Static void 2338 1.289 riastrad uhci_abortx(struct usbd_xfer *xfer) 2339 1.33 augustss { 2340 1.281 mrg UHCIHIST_FUNC(); UHCIHIST_CALLED(); 2341 1.268 skrll struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); 2342 1.268 skrll struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); 2343 1.268 skrll uhci_softc_t *sc = UHCI_XFER2SC(xfer); 2344 1.33 augustss uhci_soft_td_t *std; 2345 1.65 augustss 2346 1.289 riastrad DPRINTFN(1,"xfer=%#jx", (uintptr_t)xfer, 0, 0, 0); 2347 1.33 augustss 2348 1.248 mrg KASSERT(mutex_owned(&sc->sc_lock)); 2349 1.268 skrll ASSERT_SLEEPABLE(); 2350 1.248 mrg 2351 1.289 riastrad KASSERTMSG((xfer->ux_status == USBD_CANCELLED || 2352 1.289 riastrad xfer->ux_status == USBD_TIMEOUT), 2353 1.289 riastrad "bad abort status: %d", xfer->ux_status); 2354 1.92 augustss 2355 1.153 augustss /* 2356 1.281 mrg * If we're dying, skip the hardware action and just notify the 2357 1.281 mrg * software that we're done. 2358 1.188 augustss */ 2359 1.281 mrg if (sc->sc_dying) { 2360 1.281 mrg DPRINTFN(4, "xfer %#jx dying %ju", (uintptr_t)xfer, 2361 1.281 mrg xfer->ux_status, 0, 0); 2362 1.281 mrg goto dying; 2363 1.188 augustss } 2364 1.188 augustss 2365 1.188 augustss /* 2366 1.281 mrg * HC Step 1: Make interrupt routine and hardware ignore xfer. 2367 1.153 augustss */ 2368 1.268 skrll uhci_del_intr_list(sc, ux); 2369 1.268 skrll 2370 1.277 pgoyette DPRINTF("stop ux=%#jx", (uintptr_t)ux, 0, 0, 0); 2371 1.268 skrll for (std = ux->ux_stdstart; std != NULL; std = std->link.std) { 2372 1.223 bouyer usb_syncmem(&std->dma, 2373 1.223 bouyer std->offs + offsetof(uhci_td_t, td_status), 2374 1.223 bouyer sizeof(std->td.td_status), 2375 1.223 bouyer BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 2376 1.92 augustss std->td.td_status &= htole32(~(UHCI_TD_ACTIVE | UHCI_TD_IOC)); 2377 1.223 bouyer usb_syncmem(&std->dma, 2378 1.223 bouyer std->offs + offsetof(uhci_td_t, td_status), 2379 1.223 bouyer sizeof(std->td.td_status), 2380 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2381 1.223 bouyer } 2382 1.92 augustss 2383 1.162 augustss /* 2384 1.281 mrg * HC Step 2: Wait until we know hardware has finished any possible 2385 1.281 mrg * use of the xfer. 2386 1.153 augustss */ 2387 1.248 mrg /* Hardware finishes in 1ms */ 2388 1.268 skrll usb_delay_ms_locked(upipe->pipe.up_dev->ud_bus, 2, &sc->sc_lock); 2389 1.281 mrg dying: 2390 1.100 augustss #ifdef DIAGNOSTIC 2391 1.268 skrll ux->ux_isdone = true; 2392 1.100 augustss #endif 2393 1.281 mrg DPRINTFN(14, "end", 0, 0, 0, 0); 2394 1.281 mrg 2395 1.248 mrg KASSERT(mutex_owned(&sc->sc_lock)); 2396 1.1 augustss } 2397 1.1 augustss 2398 1.1 augustss /* Close a device bulk pipe. */ 2399 1.1 augustss void 2400 1.268 skrll uhci_device_bulk_close(struct usbd_pipe *pipe) 2401 1.1 augustss { 2402 1.268 skrll struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe); 2403 1.268 skrll uhci_softc_t *sc = UHCI_PIPE2SC(pipe); 2404 1.1 augustss 2405 1.248 mrg KASSERT(mutex_owned(&sc->sc_lock)); 2406 1.248 mrg 2407 1.268 skrll uhci_free_sqh(sc, upipe->bulk.sqh); 2408 1.236 drochner 2409 1.268 skrll pipe->up_endpoint->ue_toggle = upipe->nexttoggle; 2410 1.268 skrll } 2411 1.268 skrll 2412 1.268 skrll int 2413 1.268 skrll uhci_device_ctrl_init(struct usbd_xfer *xfer) 2414 1.268 skrll { 2415 1.268 skrll struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer); 2416 1.268 skrll struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); 2417 1.268 skrll usb_device_request_t *req = &xfer->ux_request; 2418 1.268 skrll struct usbd_device *dev = upipe->pipe.up_dev; 2419 1.268 skrll uhci_softc_t *sc = dev->ud_bus->ub_hcpriv; 2420 1.270 joerg uhci_soft_td_t *data = NULL; 2421 1.268 skrll int len; 2422 1.268 skrll usbd_status err; 2423 1.268 skrll int isread; 2424 1.268 skrll 2425 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 2426 1.277 pgoyette DPRINTFN(3, "xfer=%#jx len=%jd, addr=%jd, endpt=%jd", 2427 1.277 pgoyette (uintptr_t)xfer, xfer->ux_bufsize, dev->ud_addr, 2428 1.277 pgoyette upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress); 2429 1.268 skrll 2430 1.268 skrll isread = req->bmRequestType & UT_READ; 2431 1.268 skrll len = xfer->ux_bufsize; 2432 1.268 skrll 2433 1.268 skrll uxfer->ux_type = UX_CTRL; 2434 1.268 skrll /* Set up data transaction */ 2435 1.268 skrll if (len != 0) { 2436 1.268 skrll err = uhci_alloc_std_chain(sc, xfer, len, isread, &data); 2437 1.268 skrll if (err) 2438 1.268 skrll return err; 2439 1.268 skrll } 2440 1.268 skrll /* Set up interrupt info. */ 2441 1.268 skrll uxfer->ux_setup = upipe->ctrl.setup; 2442 1.268 skrll uxfer->ux_stat = upipe->ctrl.stat; 2443 1.268 skrll uxfer->ux_data = data; 2444 1.268 skrll 2445 1.268 skrll return 0; 2446 1.268 skrll } 2447 1.268 skrll 2448 1.268 skrll Static void 2449 1.268 skrll uhci_device_ctrl_fini(struct usbd_xfer *xfer) 2450 1.268 skrll { 2451 1.268 skrll uhci_softc_t *sc = UHCI_XFER2SC(xfer); 2452 1.268 skrll struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); 2453 1.268 skrll 2454 1.268 skrll KASSERT(ux->ux_type == UX_CTRL); 2455 1.268 skrll 2456 1.276 skrll if (ux->ux_nstd) { 2457 1.276 skrll uhci_free_stds(sc, ux); 2458 1.268 skrll kmem_free(ux->ux_stds, sizeof(uhci_soft_td_t *) * ux->ux_nstd); 2459 1.276 skrll } 2460 1.1 augustss } 2461 1.1 augustss 2462 1.1 augustss usbd_status 2463 1.268 skrll uhci_device_ctrl_transfer(struct usbd_xfer *xfer) 2464 1.1 augustss { 2465 1.52 augustss 2466 1.309 riastrad /* Pipe isn't running, so start it first. */ 2467 1.268 skrll return uhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 2468 1.16 augustss } 2469 1.16 augustss 2470 1.16 augustss usbd_status 2471 1.268 skrll uhci_device_ctrl_start(struct usbd_xfer *xfer) 2472 1.16 augustss { 2473 1.268 skrll uhci_softc_t *sc = UHCI_XFER2SC(xfer); 2474 1.268 skrll struct uhci_xfer *uxfer = UHCI_XFER2UXFER(xfer); 2475 1.268 skrll struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); 2476 1.268 skrll usb_device_request_t *req = &xfer->ux_request; 2477 1.268 skrll struct usbd_device *dev = upipe->pipe.up_dev; 2478 1.268 skrll int addr = dev->ud_addr; 2479 1.268 skrll int endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; 2480 1.268 skrll uhci_soft_td_t *setup, *stat, *next, *dataend; 2481 1.268 skrll uhci_soft_qh_t *sqh; 2482 1.268 skrll int len; 2483 1.268 skrll int isread; 2484 1.268 skrll 2485 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 2486 1.1 augustss 2487 1.311 riastrad KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 2488 1.311 riastrad 2489 1.82 augustss if (sc->sc_dying) 2490 1.268 skrll return USBD_IOERROR; 2491 1.268 skrll 2492 1.268 skrll KASSERT(xfer->ux_rqflags & URQ_REQUEST); 2493 1.268 skrll 2494 1.296 christos DPRINTFN(3, "type=0x%02jx, request=0x%02jx, " 2495 1.296 christos "wValue=0x%04jx, wIndex=0x%04jx", 2496 1.268 skrll req->bmRequestType, req->bRequest, UGETW(req->wValue), 2497 1.268 skrll UGETW(req->wIndex)); 2498 1.277 pgoyette DPRINTFN(3, "len=%jd, addr=%jd, endpt=%jd", 2499 1.268 skrll UGETW(req->wLength), dev->ud_addr, endpt, 0); 2500 1.268 skrll 2501 1.268 skrll isread = req->bmRequestType & UT_READ; 2502 1.268 skrll len = UGETW(req->wLength); 2503 1.268 skrll 2504 1.268 skrll setup = upipe->ctrl.setup; 2505 1.268 skrll stat = upipe->ctrl.stat; 2506 1.268 skrll sqh = upipe->ctrl.sqh; 2507 1.268 skrll 2508 1.268 skrll memcpy(KERNADDR(&upipe->ctrl.reqdma, 0), req, sizeof(*req)); 2509 1.268 skrll usb_syncmem(&upipe->ctrl.reqdma, 0, sizeof(*req), BUS_DMASYNC_PREWRITE); 2510 1.268 skrll 2511 1.268 skrll /* Set up data transaction */ 2512 1.268 skrll if (len != 0) { 2513 1.268 skrll upipe->nexttoggle = 1; 2514 1.268 skrll next = uxfer->ux_data; 2515 1.268 skrll uhci_reset_std_chain(sc, xfer, len, isread, 2516 1.268 skrll &upipe->nexttoggle, &dataend); 2517 1.268 skrll dataend->link.std = stat; 2518 1.268 skrll dataend->td.td_link = htole32(stat->physaddr | UHCI_PTR_TD); 2519 1.268 skrll usb_syncmem(&dataend->dma, 2520 1.268 skrll dataend->offs + offsetof(uhci_td_t, td_link), 2521 1.268 skrll sizeof(dataend->td.td_link), 2522 1.268 skrll BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2523 1.268 skrll } else { 2524 1.268 skrll next = stat; 2525 1.268 skrll } 2526 1.82 augustss 2527 1.268 skrll const uint32_t status = UHCI_TD_ZERO_ACTLEN( 2528 1.268 skrll UHCI_TD_SET_ERRCNT(3) | 2529 1.268 skrll UHCI_TD_ACTIVE | 2530 1.268 skrll (dev->ud_speed == USB_SPEED_LOW ? UHCI_TD_LS : 0) 2531 1.268 skrll ); 2532 1.268 skrll setup->link.std = next; 2533 1.268 skrll setup->td.td_link = htole32(next->physaddr | UHCI_PTR_TD); 2534 1.268 skrll setup->td.td_status = htole32(status); 2535 1.268 skrll setup->td.td_token = htole32(UHCI_TD_SETUP(sizeof(*req), endpt, addr)); 2536 1.268 skrll setup->td.td_buffer = htole32(DMAADDR(&upipe->ctrl.reqdma, 0)); 2537 1.268 skrll 2538 1.268 skrll usb_syncmem(&setup->dma, setup->offs, sizeof(setup->td), 2539 1.268 skrll BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2540 1.268 skrll 2541 1.268 skrll stat->link.std = NULL; 2542 1.268 skrll stat->td.td_link = htole32(UHCI_PTR_T); 2543 1.268 skrll stat->td.td_status = htole32(status | UHCI_TD_IOC); 2544 1.268 skrll stat->td.td_token = 2545 1.268 skrll htole32(isread ? UHCI_TD_OUT(0, endpt, addr, 1) : 2546 1.268 skrll UHCI_TD_IN (0, endpt, addr, 1)); 2547 1.268 skrll stat->td.td_buffer = htole32(0); 2548 1.268 skrll usb_syncmem(&stat->dma, stat->offs, sizeof(stat->td), 2549 1.268 skrll BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2550 1.268 skrll 2551 1.268 skrll #ifdef UHCI_DEBUG 2552 1.268 skrll if (uhcidebug >= 10) { 2553 1.268 skrll DPRINTF("--- dump start ---", 0, 0, 0, 0); 2554 1.268 skrll DPRINTF("before transfer", 0, 0, 0, 0); 2555 1.268 skrll uhci_dump_tds(setup); 2556 1.268 skrll DPRINTF("--- dump end ---", 0, 0, 0, 0); 2557 1.268 skrll } 2558 1.268 skrll #endif 2559 1.268 skrll 2560 1.268 skrll /* Set up interrupt info. */ 2561 1.268 skrll uxfer->ux_setup = setup; 2562 1.268 skrll uxfer->ux_stat = stat; 2563 1.268 skrll KASSERT(uxfer->ux_isdone); 2564 1.48 augustss #ifdef DIAGNOSTIC 2565 1.268 skrll uxfer->ux_isdone = false; 2566 1.48 augustss #endif 2567 1.1 augustss 2568 1.268 skrll sqh->elink = setup; 2569 1.268 skrll sqh->qh.qh_elink = htole32(setup->physaddr | UHCI_PTR_TD); 2570 1.268 skrll /* uhci_add_?s_ctrl() will do usb_syncmem(sqh) */ 2571 1.268 skrll 2572 1.268 skrll if (dev->ud_speed == USB_SPEED_LOW) 2573 1.268 skrll uhci_add_ls_ctrl(sc, sqh); 2574 1.268 skrll else 2575 1.268 skrll uhci_add_hs_ctrl(sc, sqh); 2576 1.268 skrll uhci_add_intr_list(sc, uxfer); 2577 1.268 skrll #ifdef UHCI_DEBUG 2578 1.268 skrll if (uhcidebug >= 12) { 2579 1.268 skrll uhci_soft_td_t *std; 2580 1.268 skrll uhci_soft_qh_t *xqh; 2581 1.268 skrll uhci_soft_qh_t *sxqh; 2582 1.268 skrll int maxqh = 0; 2583 1.268 skrll uhci_physaddr_t link; 2584 1.268 skrll DPRINTFN(12, "--- dump start ---", 0, 0, 0, 0); 2585 1.268 skrll DPRINTFN(12, "follow from [0]", 0, 0, 0, 0); 2586 1.268 skrll for (std = sc->sc_vframes[0].htd, link = 0; 2587 1.268 skrll (link & UHCI_PTR_QH) == 0; 2588 1.268 skrll std = std->link.std) { 2589 1.268 skrll link = le32toh(std->td.td_link); 2590 1.268 skrll uhci_dump_td(std); 2591 1.268 skrll } 2592 1.268 skrll sxqh = (uhci_soft_qh_t *)std; 2593 1.268 skrll uhci_dump_qh(sxqh); 2594 1.268 skrll for (xqh = sxqh; 2595 1.268 skrll xqh != NULL; 2596 1.268 skrll xqh = (maxqh++ == 5 || xqh->hlink == sxqh || 2597 1.268 skrll xqh->hlink == xqh ? NULL : xqh->hlink)) { 2598 1.268 skrll uhci_dump_qh(xqh); 2599 1.268 skrll } 2600 1.268 skrll DPRINTFN(12, "Enqueued QH:", 0, 0, 0, 0); 2601 1.268 skrll uhci_dump_qh(sqh); 2602 1.268 skrll uhci_dump_tds(sqh->elink); 2603 1.268 skrll DPRINTF("--- dump end ---", 0, 0, 0, 0); 2604 1.268 skrll } 2605 1.268 skrll #endif 2606 1.318 riastrad xfer->ux_status = USBD_IN_PROGRESS; 2607 1.289 riastrad usbd_xfer_schedule_timeout(xfer); 2608 1.1 augustss 2609 1.268 skrll return USBD_IN_PROGRESS; 2610 1.268 skrll } 2611 1.268 skrll 2612 1.268 skrll int 2613 1.268 skrll uhci_device_intr_init(struct usbd_xfer *xfer) 2614 1.268 skrll { 2615 1.268 skrll uhci_softc_t *sc = UHCI_XFER2SC(xfer); 2616 1.268 skrll struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); 2617 1.268 skrll usb_endpoint_descriptor_t *ed = xfer->ux_pipe->up_endpoint->ue_edesc; 2618 1.268 skrll int endpt = ed->bEndpointAddress; 2619 1.268 skrll int isread = UE_GET_DIR(endpt) == UE_DIR_IN; 2620 1.268 skrll int len = xfer->ux_bufsize; 2621 1.268 skrll int err; 2622 1.268 skrll 2623 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 2624 1.268 skrll 2625 1.277 pgoyette DPRINTFN(3, "xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, 2626 1.277 pgoyette xfer->ux_length, xfer->ux_flags, 0); 2627 1.268 skrll 2628 1.268 skrll KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); 2629 1.268 skrll KASSERT(len != 0); 2630 1.268 skrll 2631 1.268 skrll ux->ux_type = UX_INTR; 2632 1.268 skrll ux->ux_nstd = 0; 2633 1.268 skrll err = uhci_alloc_std_chain(sc, xfer, len, isread, &ux->ux_stdstart); 2634 1.268 skrll 2635 1.268 skrll return err; 2636 1.268 skrll } 2637 1.268 skrll 2638 1.268 skrll Static void 2639 1.268 skrll uhci_device_intr_fini(struct usbd_xfer *xfer) 2640 1.268 skrll { 2641 1.268 skrll uhci_softc_t *sc = UHCI_XFER2SC(xfer); 2642 1.268 skrll struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); 2643 1.268 skrll 2644 1.268 skrll KASSERT(ux->ux_type == UX_INTR); 2645 1.268 skrll 2646 1.276 skrll if (ux->ux_nstd) { 2647 1.276 skrll uhci_free_stds(sc, ux); 2648 1.268 skrll kmem_free(ux->ux_stds, sizeof(uhci_soft_td_t *) * ux->ux_nstd); 2649 1.276 skrll } 2650 1.1 augustss } 2651 1.1 augustss 2652 1.1 augustss usbd_status 2653 1.268 skrll uhci_device_intr_transfer(struct usbd_xfer *xfer) 2654 1.1 augustss { 2655 1.16 augustss 2656 1.309 riastrad /* Pipe isn't running, so start it first. */ 2657 1.268 skrll return uhci_device_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 2658 1.16 augustss } 2659 1.16 augustss 2660 1.16 augustss usbd_status 2661 1.268 skrll uhci_device_intr_start(struct usbd_xfer *xfer) 2662 1.16 augustss { 2663 1.268 skrll struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); 2664 1.268 skrll struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); 2665 1.268 skrll uhci_softc_t *sc = UHCI_XFER2SC(xfer); 2666 1.55 augustss uhci_soft_td_t *data, *dataend; 2667 1.1 augustss uhci_soft_qh_t *sqh; 2668 1.187 skrll int isread, endpt; 2669 1.248 mrg int i; 2670 1.1 augustss 2671 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 2672 1.1 augustss 2673 1.277 pgoyette DPRINTFN(3, "xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, 2674 1.277 pgoyette xfer->ux_length, xfer->ux_flags, 0); 2675 1.1 augustss 2676 1.311 riastrad KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 2677 1.311 riastrad 2678 1.311 riastrad if (sc->sc_dying) 2679 1.311 riastrad return USBD_IOERROR; 2680 1.311 riastrad 2681 1.268 skrll KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); 2682 1.268 skrll KASSERT(xfer->ux_length <= xfer->ux_bufsize); 2683 1.248 mrg 2684 1.268 skrll endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; 2685 1.187 skrll isread = UE_GET_DIR(endpt) == UE_DIR_IN; 2686 1.187 skrll 2687 1.268 skrll data = ux->ux_stdstart; 2688 1.268 skrll 2689 1.268 skrll KASSERT(ux->ux_isdone); 2690 1.268 skrll #ifdef DIAGNOSTIC 2691 1.268 skrll ux->ux_isdone = false; 2692 1.268 skrll #endif 2693 1.187 skrll 2694 1.268 skrll /* Take lock to protect nexttoggle */ 2695 1.268 skrll uhci_reset_std_chain(sc, xfer, xfer->ux_length, isread, 2696 1.268 skrll &upipe->nexttoggle, &dataend); 2697 1.248 mrg 2698 1.88 tsutsui dataend->td.td_status |= htole32(UHCI_TD_IOC); 2699 1.223 bouyer usb_syncmem(&dataend->dma, 2700 1.223 bouyer dataend->offs + offsetof(uhci_td_t, td_status), 2701 1.223 bouyer sizeof(dataend->td.td_status), 2702 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2703 1.268 skrll ux->ux_stdend = dataend; 2704 1.1 augustss 2705 1.59 augustss #ifdef UHCI_DEBUG 2706 1.268 skrll if (uhcidebug >= 10) { 2707 1.268 skrll DPRINTF("--- dump start ---", 0, 0, 0, 0); 2708 1.55 augustss uhci_dump_tds(data); 2709 1.268 skrll uhci_dump_qh(upipe->intr.qhs[0]); 2710 1.268 skrll DPRINTF("--- dump end ---", 0, 0, 0, 0); 2711 1.1 augustss } 2712 1.1 augustss #endif 2713 1.1 augustss 2714 1.277 pgoyette DPRINTFN(10, "qhs[0]=%#jx", (uintptr_t)upipe->intr.qhs[0], 0, 0, 0); 2715 1.268 skrll for (i = 0; i < upipe->intr.npoll; i++) { 2716 1.268 skrll sqh = upipe->intr.qhs[i]; 2717 1.55 augustss sqh->elink = data; 2718 1.121 augustss sqh->qh.qh_elink = htole32(data->physaddr | UHCI_PTR_TD); 2719 1.223 bouyer usb_syncmem(&sqh->dma, 2720 1.223 bouyer sqh->offs + offsetof(uhci_qh_t, qh_elink), 2721 1.223 bouyer sizeof(sqh->qh.qh_elink), 2722 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2723 1.1 augustss } 2724 1.268 skrll uhci_add_intr_list(sc, ux); 2725 1.268 skrll xfer->ux_status = USBD_IN_PROGRESS; 2726 1.1 augustss 2727 1.59 augustss #ifdef UHCI_DEBUG 2728 1.268 skrll if (uhcidebug >= 10) { 2729 1.268 skrll DPRINTF("--- dump start ---", 0, 0, 0, 0); 2730 1.55 augustss uhci_dump_tds(data); 2731 1.268 skrll uhci_dump_qh(upipe->intr.qhs[0]); 2732 1.268 skrll DPRINTF("--- dump end ---", 0, 0, 0, 0); 2733 1.1 augustss } 2734 1.1 augustss #endif 2735 1.1 augustss 2736 1.268 skrll return USBD_IN_PROGRESS; 2737 1.1 augustss } 2738 1.1 augustss 2739 1.1 augustss /* Abort a device control request. */ 2740 1.1 augustss void 2741 1.268 skrll uhci_device_ctrl_abort(struct usbd_xfer *xfer) 2742 1.1 augustss { 2743 1.268 skrll uhci_softc_t *sc __diagused = UHCI_XFER2SC(xfer); 2744 1.248 mrg 2745 1.248 mrg KASSERT(mutex_owned(&sc->sc_lock)); 2746 1.248 mrg 2747 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 2748 1.289 riastrad usbd_xfer_abort(xfer); 2749 1.1 augustss } 2750 1.1 augustss 2751 1.1 augustss /* Close a device control pipe. */ 2752 1.1 augustss void 2753 1.268 skrll uhci_device_ctrl_close(struct usbd_pipe *pipe) 2754 1.1 augustss { 2755 1.268 skrll uhci_softc_t *sc = UHCI_PIPE2SC(pipe); 2756 1.268 skrll struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe); 2757 1.268 skrll 2758 1.268 skrll uhci_free_sqh(sc, upipe->ctrl.sqh); 2759 1.268 skrll uhci_free_std_locked(sc, upipe->ctrl.setup); 2760 1.268 skrll uhci_free_std_locked(sc, upipe->ctrl.stat); 2761 1.268 skrll 2762 1.308 skrll usb_freemem(&upipe->ctrl.reqdma); 2763 1.1 augustss } 2764 1.1 augustss 2765 1.1 augustss /* Abort a device interrupt request. */ 2766 1.1 augustss void 2767 1.268 skrll uhci_device_intr_abort(struct usbd_xfer *xfer) 2768 1.1 augustss { 2769 1.268 skrll uhci_softc_t *sc __diagused = UHCI_XFER2SC(xfer); 2770 1.248 mrg 2771 1.248 mrg KASSERT(mutex_owned(&sc->sc_lock)); 2772 1.248 mrg 2773 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 2774 1.277 pgoyette DPRINTF("xfer=%#jx", (uintptr_t)xfer, 0, 0, 0); 2775 1.264 skrll 2776 1.289 riastrad usbd_xfer_abort(xfer); 2777 1.1 augustss } 2778 1.1 augustss 2779 1.1 augustss /* Close a device interrupt pipe. */ 2780 1.1 augustss void 2781 1.268 skrll uhci_device_intr_close(struct usbd_pipe *pipe) 2782 1.1 augustss { 2783 1.268 skrll struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe); 2784 1.268 skrll uhci_softc_t *sc = UHCI_PIPE2SC(pipe); 2785 1.92 augustss int i, npoll; 2786 1.248 mrg 2787 1.248 mrg KASSERT(mutex_owned(&sc->sc_lock)); 2788 1.1 augustss 2789 1.1 augustss /* Unlink descriptors from controller data structures. */ 2790 1.268 skrll npoll = upipe->intr.npoll; 2791 1.1 augustss for (i = 0; i < npoll; i++) 2792 1.268 skrll uhci_remove_intr(sc, upipe->intr.qhs[i]); 2793 1.1 augustss 2794 1.152 augustss /* 2795 1.1 augustss * We now have to wait for any activity on the physical 2796 1.1 augustss * descriptors to stop. 2797 1.1 augustss */ 2798 1.248 mrg usb_delay_ms_locked(&sc->sc_bus, 2, &sc->sc_lock); 2799 1.1 augustss 2800 1.267 skrll for (i = 0; i < npoll; i++) 2801 1.268 skrll uhci_free_sqh(sc, upipe->intr.qhs[i]); 2802 1.268 skrll kmem_free(upipe->intr.qhs, npoll * sizeof(uhci_soft_qh_t *)); 2803 1.1 augustss } 2804 1.1 augustss 2805 1.268 skrll int 2806 1.268 skrll uhci_device_isoc_init(struct usbd_xfer *xfer) 2807 1.1 augustss { 2808 1.268 skrll struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); 2809 1.248 mrg 2810 1.268 skrll KASSERT(!(xfer->ux_rqflags & URQ_REQUEST)); 2811 1.268 skrll KASSERT(xfer->ux_nframes != 0); 2812 1.268 skrll KASSERT(ux->ux_isdone); 2813 1.1 augustss 2814 1.268 skrll ux->ux_type = UX_ISOC; 2815 1.268 skrll return 0; 2816 1.268 skrll } 2817 1.1 augustss 2818 1.268 skrll Static void 2819 1.268 skrll uhci_device_isoc_fini(struct usbd_xfer *xfer) 2820 1.268 skrll { 2821 1.269 skrll struct uhci_xfer *ux __diagused = UHCI_XFER2UXFER(xfer); 2822 1.1 augustss 2823 1.268 skrll KASSERT(ux->ux_type == UX_ISOC); 2824 1.1 augustss } 2825 1.1 augustss 2826 1.16 augustss usbd_status 2827 1.268 skrll uhci_device_isoc_transfer(struct usbd_xfer *xfer) 2828 1.16 augustss { 2829 1.268 skrll uhci_softc_t *sc = UHCI_XFER2SC(xfer); 2830 1.48 augustss 2831 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 2832 1.277 pgoyette DPRINTFN(5, "xfer=%#jx", (uintptr_t)xfer, 0, 0, 0); 2833 1.48 augustss 2834 1.311 riastrad KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 2835 1.311 riastrad 2836 1.48 augustss /* insert into schedule, */ 2837 1.48 augustss 2838 1.268 skrll struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); 2839 1.268 skrll struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); 2840 1.268 skrll struct isoc *isoc = &upipe->isoc; 2841 1.268 skrll uhci_soft_td_t *std = NULL; 2842 1.268 skrll uint32_t buf, len, status, offs; 2843 1.248 mrg int i, next, nframes; 2844 1.268 skrll int rd = UE_GET_DIR(upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress) == UE_DIR_IN; 2845 1.48 augustss 2846 1.277 pgoyette DPRINTFN(5, "used=%jd next=%jd xfer=%#jx nframes=%jd", 2847 1.277 pgoyette isoc->inuse, isoc->next, (uintptr_t)xfer, xfer->ux_nframes); 2848 1.48 augustss 2849 1.82 augustss if (sc->sc_dying) 2850 1.268 skrll return USBD_IOERROR; 2851 1.82 augustss 2852 1.268 skrll if (xfer->ux_status == USBD_IN_PROGRESS) { 2853 1.48 augustss /* This request has already been entered into the frame list */ 2854 1.268 skrll printf("%s: xfer=%p in frame list\n", __func__, xfer); 2855 1.68 augustss /* XXX */ 2856 1.48 augustss } 2857 1.48 augustss 2858 1.48 augustss #ifdef DIAGNOSTIC 2859 1.268 skrll if (isoc->inuse >= UHCI_VFRAMELIST_COUNT) 2860 1.268 skrll printf("%s: overflow!\n", __func__); 2861 1.19 augustss #endif 2862 1.16 augustss 2863 1.268 skrll KASSERT(xfer->ux_nframes != 0); 2864 1.268 skrll 2865 1.301 skrll if (xfer->ux_length) 2866 1.301 skrll usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, 2867 1.301 skrll rd ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 2868 1.300 skrll 2869 1.268 skrll next = isoc->next; 2870 1.48 augustss if (next == -1) { 2871 1.48 augustss /* Not in use yet, schedule it a few frames ahead. */ 2872 1.48 augustss next = (UREAD2(sc, UHCI_FRNUM) + 3) % UHCI_VFRAMELIST_COUNT; 2873 1.277 pgoyette DPRINTFN(2, "start next=%jd", next, 0, 0, 0); 2874 1.48 augustss } 2875 1.48 augustss 2876 1.268 skrll xfer->ux_status = USBD_IN_PROGRESS; 2877 1.268 skrll ux->ux_curframe = next; 2878 1.48 augustss 2879 1.223 bouyer offs = 0; 2880 1.88 tsutsui status = UHCI_TD_ZERO_ACTLEN(UHCI_TD_SET_ERRCNT(0) | 2881 1.88 tsutsui UHCI_TD_ACTIVE | 2882 1.88 tsutsui UHCI_TD_IOS); 2883 1.268 skrll nframes = xfer->ux_nframes; 2884 1.48 augustss for (i = 0; i < nframes; i++) { 2885 1.302 skrll buf = DMAADDR(&xfer->ux_dmabuf, offs); 2886 1.268 skrll std = isoc->stds[next]; 2887 1.48 augustss if (++next >= UHCI_VFRAMELIST_COUNT) 2888 1.48 augustss next = 0; 2889 1.268 skrll len = xfer->ux_frlengths[i]; 2890 1.302 skrll 2891 1.302 skrll KASSERTMSG(len <= __SHIFTOUT_MASK(UHCI_TD_MAXLEN_MASK), 2892 1.302 skrll "len %d", len); 2893 1.88 tsutsui std->td.td_buffer = htole32(buf); 2894 1.268 skrll usb_syncmem(&xfer->ux_dmabuf, offs, len, 2895 1.223 bouyer rd ? BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); 2896 1.48 augustss if (i == nframes - 1) 2897 1.88 tsutsui status |= UHCI_TD_IOC; 2898 1.88 tsutsui std->td.td_status = htole32(status); 2899 1.88 tsutsui std->td.td_token &= htole32(~UHCI_TD_MAXLEN_MASK); 2900 1.88 tsutsui std->td.td_token |= htole32(UHCI_TD_SET_MAXLEN(len)); 2901 1.223 bouyer usb_syncmem(&std->dma, std->offs, sizeof(std->td), 2902 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2903 1.59 augustss #ifdef UHCI_DEBUG 2904 1.268 skrll if (uhcidebug >= 5) { 2905 1.268 skrll DPRINTF("--- dump start ---", 0, 0, 0, 0); 2906 1.277 pgoyette DPRINTF("TD %jd", i, 0, 0, 0); 2907 1.48 augustss uhci_dump_td(std); 2908 1.268 skrll DPRINTF("--- dump end ---", 0, 0, 0, 0); 2909 1.48 augustss } 2910 1.48 augustss #endif 2911 1.223 bouyer offs += len; 2912 1.302 skrll const bus_addr_t bend __diagused = 2913 1.302 skrll DMAADDR(&xfer->ux_dmabuf, offs - 1); 2914 1.302 skrll 2915 1.302 skrll KASSERT(((buf ^ bend) & ~PAGE_MASK) == 0); 2916 1.48 augustss } 2917 1.268 skrll isoc->next = next; 2918 1.268 skrll isoc->inuse += xfer->ux_nframes; 2919 1.16 augustss 2920 1.268 skrll /* Set up interrupt info. */ 2921 1.268 skrll ux->ux_stdstart = std; 2922 1.268 skrll ux->ux_stdend = std; 2923 1.96 augustss 2924 1.268 skrll KASSERT(ux->ux_isdone); 2925 1.48 augustss #ifdef DIAGNOSTIC 2926 1.268 skrll ux->ux_isdone = false; 2927 1.48 augustss #endif 2928 1.268 skrll uhci_add_intr_list(sc, ux); 2929 1.152 augustss 2930 1.268 skrll return USBD_IN_PROGRESS; 2931 1.16 augustss } 2932 1.16 augustss 2933 1.16 augustss void 2934 1.268 skrll uhci_device_isoc_abort(struct usbd_xfer *xfer) 2935 1.16 augustss { 2936 1.268 skrll uhci_softc_t *sc = UHCI_XFER2SC(xfer); 2937 1.268 skrll struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); 2938 1.268 skrll struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); 2939 1.268 skrll uhci_soft_td_t **stds = upipe->isoc.stds; 2940 1.48 augustss uhci_soft_td_t *std; 2941 1.248 mrg int i, n, nframes, maxlen, len; 2942 1.92 augustss 2943 1.248 mrg KASSERT(mutex_owned(&sc->sc_lock)); 2944 1.92 augustss 2945 1.92 augustss /* Transfer is already done. */ 2946 1.268 skrll if (xfer->ux_status != USBD_NOT_STARTED && 2947 1.268 skrll xfer->ux_status != USBD_IN_PROGRESS) { 2948 1.92 augustss return; 2949 1.92 augustss } 2950 1.48 augustss 2951 1.92 augustss /* Give xfer the requested abort code. */ 2952 1.268 skrll xfer->ux_status = USBD_CANCELLED; 2953 1.48 augustss 2954 1.48 augustss /* make hardware ignore it, */ 2955 1.268 skrll nframes = xfer->ux_nframes; 2956 1.268 skrll n = ux->ux_curframe; 2957 1.92 augustss maxlen = 0; 2958 1.48 augustss for (i = 0; i < nframes; i++) { 2959 1.48 augustss std = stds[n]; 2960 1.223 bouyer usb_syncmem(&std->dma, 2961 1.223 bouyer std->offs + offsetof(uhci_td_t, td_status), 2962 1.223 bouyer sizeof(std->td.td_status), 2963 1.223 bouyer BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 2964 1.88 tsutsui std->td.td_status &= htole32(~(UHCI_TD_ACTIVE | UHCI_TD_IOC)); 2965 1.223 bouyer usb_syncmem(&std->dma, 2966 1.223 bouyer std->offs + offsetof(uhci_td_t, td_status), 2967 1.223 bouyer sizeof(std->td.td_status), 2968 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 2969 1.223 bouyer usb_syncmem(&std->dma, 2970 1.223 bouyer std->offs + offsetof(uhci_td_t, td_token), 2971 1.223 bouyer sizeof(std->td.td_token), 2972 1.223 bouyer BUS_DMASYNC_POSTWRITE); 2973 1.130 tsutsui len = UHCI_TD_GET_MAXLEN(le32toh(std->td.td_token)); 2974 1.92 augustss if (len > maxlen) 2975 1.92 augustss maxlen = len; 2976 1.48 augustss if (++n >= UHCI_VFRAMELIST_COUNT) 2977 1.48 augustss n = 0; 2978 1.48 augustss } 2979 1.48 augustss 2980 1.92 augustss /* and wait until we are sure the hardware has finished. */ 2981 1.92 augustss delay(maxlen); 2982 1.92 augustss 2983 1.96 augustss #ifdef DIAGNOSTIC 2984 1.268 skrll ux->ux_isdone = true; 2985 1.96 augustss #endif 2986 1.268 skrll /* Remove from interrupt list. */ 2987 1.268 skrll uhci_del_intr_list(sc, ux); 2988 1.268 skrll 2989 1.268 skrll /* Run callback. */ 2990 1.92 augustss usb_transfer_complete(xfer); 2991 1.48 augustss 2992 1.248 mrg KASSERT(mutex_owned(&sc->sc_lock)); 2993 1.16 augustss } 2994 1.16 augustss 2995 1.16 augustss void 2996 1.268 skrll uhci_device_isoc_close(struct usbd_pipe *pipe) 2997 1.16 augustss { 2998 1.268 skrll struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe); 2999 1.268 skrll uhci_softc_t *sc = UHCI_PIPE2SC(pipe); 3000 1.48 augustss uhci_soft_td_t *std, *vstd; 3001 1.268 skrll struct isoc *isoc; 3002 1.248 mrg int i; 3003 1.248 mrg 3004 1.248 mrg KASSERT(mutex_owned(&sc->sc_lock)); 3005 1.16 augustss 3006 1.16 augustss /* 3007 1.16 augustss * Make sure all TDs are marked as inactive. 3008 1.16 augustss * Wait for completion. 3009 1.16 augustss * Unschedule. 3010 1.16 augustss * Deallocate. 3011 1.16 augustss */ 3012 1.268 skrll isoc = &upipe->isoc; 3013 1.16 augustss 3014 1.223 bouyer for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) { 3015 1.268 skrll std = isoc->stds[i]; 3016 1.223 bouyer usb_syncmem(&std->dma, 3017 1.223 bouyer std->offs + offsetof(uhci_td_t, td_status), 3018 1.223 bouyer sizeof(std->td.td_status), 3019 1.223 bouyer BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3020 1.223 bouyer std->td.td_status &= htole32(~UHCI_TD_ACTIVE); 3021 1.223 bouyer usb_syncmem(&std->dma, 3022 1.223 bouyer std->offs + offsetof(uhci_td_t, td_status), 3023 1.223 bouyer sizeof(std->td.td_status), 3024 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3025 1.223 bouyer } 3026 1.248 mrg /* wait for completion */ 3027 1.248 mrg usb_delay_ms_locked(&sc->sc_bus, 2, &sc->sc_lock); 3028 1.16 augustss 3029 1.16 augustss for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) { 3030 1.268 skrll std = isoc->stds[i]; 3031 1.48 augustss for (vstd = sc->sc_vframes[i].htd; 3032 1.67 augustss vstd != NULL && vstd->link.std != std; 3033 1.42 augustss vstd = vstd->link.std) 3034 1.16 augustss ; 3035 1.67 augustss if (vstd == NULL) { 3036 1.16 augustss /*panic*/ 3037 1.268 skrll printf("%s: %p not found\n", __func__, std); 3038 1.248 mrg mutex_exit(&sc->sc_lock); 3039 1.16 augustss return; 3040 1.16 augustss } 3041 1.42 augustss vstd->link = std->link; 3042 1.223 bouyer usb_syncmem(&std->dma, 3043 1.223 bouyer std->offs + offsetof(uhci_td_t, td_link), 3044 1.223 bouyer sizeof(std->td.td_link), 3045 1.223 bouyer BUS_DMASYNC_POSTWRITE); 3046 1.42 augustss vstd->td.td_link = std->td.td_link; 3047 1.223 bouyer usb_syncmem(&vstd->dma, 3048 1.223 bouyer vstd->offs + offsetof(uhci_td_t, td_link), 3049 1.223 bouyer sizeof(vstd->td.td_link), 3050 1.223 bouyer BUS_DMASYNC_PREWRITE); 3051 1.268 skrll uhci_free_std_locked(sc, std); 3052 1.16 augustss } 3053 1.16 augustss 3054 1.268 skrll kmem_free(isoc->stds, UHCI_VFRAMELIST_COUNT * sizeof(uhci_soft_td_t *)); 3055 1.16 augustss } 3056 1.16 augustss 3057 1.16 augustss usbd_status 3058 1.268 skrll uhci_setup_isoc(struct usbd_pipe *pipe) 3059 1.16 augustss { 3060 1.268 skrll struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe); 3061 1.268 skrll uhci_softc_t *sc = UHCI_PIPE2SC(pipe); 3062 1.268 skrll int addr = upipe->pipe.up_dev->ud_addr; 3063 1.268 skrll int endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; 3064 1.45 augustss int rd = UE_GET_DIR(endpt) == UE_DIR_IN; 3065 1.48 augustss uhci_soft_td_t *std, *vstd; 3066 1.268 skrll uint32_t token; 3067 1.268 skrll struct isoc *isoc; 3068 1.248 mrg int i; 3069 1.16 augustss 3070 1.268 skrll isoc = &upipe->isoc; 3071 1.268 skrll 3072 1.268 skrll isoc->stds = kmem_alloc( 3073 1.268 skrll UHCI_VFRAMELIST_COUNT * sizeof(uhci_soft_td_t *), KM_SLEEP); 3074 1.268 skrll if (isoc->stds == NULL) 3075 1.248 mrg return USBD_NOMEM; 3076 1.16 augustss 3077 1.88 tsutsui token = rd ? UHCI_TD_IN (0, endpt, addr, 0) : 3078 1.88 tsutsui UHCI_TD_OUT(0, endpt, addr, 0); 3079 1.16 augustss 3080 1.48 augustss /* Allocate the TDs and mark as inactive; */ 3081 1.16 augustss for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) { 3082 1.48 augustss std = uhci_alloc_std(sc); 3083 1.48 augustss if (std == 0) 3084 1.48 augustss goto bad; 3085 1.88 tsutsui std->td.td_status = htole32(UHCI_TD_IOS); /* iso, inactive */ 3086 1.88 tsutsui std->td.td_token = htole32(token); 3087 1.223 bouyer usb_syncmem(&std->dma, std->offs, sizeof(std->td), 3088 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3089 1.268 skrll isoc->stds[i] = std; 3090 1.16 augustss } 3091 1.16 augustss 3092 1.268 skrll mutex_enter(&sc->sc_lock); 3093 1.268 skrll 3094 1.48 augustss /* Insert TDs into schedule. */ 3095 1.16 augustss for (i = 0; i < UHCI_VFRAMELIST_COUNT; i++) { 3096 1.268 skrll std = isoc->stds[i]; 3097 1.48 augustss vstd = sc->sc_vframes[i].htd; 3098 1.223 bouyer usb_syncmem(&vstd->dma, 3099 1.223 bouyer vstd->offs + offsetof(uhci_td_t, td_link), 3100 1.223 bouyer sizeof(vstd->td.td_link), 3101 1.223 bouyer BUS_DMASYNC_POSTWRITE); 3102 1.42 augustss std->link = vstd->link; 3103 1.42 augustss std->td.td_link = vstd->td.td_link; 3104 1.223 bouyer usb_syncmem(&std->dma, 3105 1.223 bouyer std->offs + offsetof(uhci_td_t, td_link), 3106 1.223 bouyer sizeof(std->td.td_link), 3107 1.223 bouyer BUS_DMASYNC_PREWRITE); 3108 1.42 augustss vstd->link.std = std; 3109 1.121 augustss vstd->td.td_link = htole32(std->physaddr | UHCI_PTR_TD); 3110 1.223 bouyer usb_syncmem(&vstd->dma, 3111 1.223 bouyer vstd->offs + offsetof(uhci_td_t, td_link), 3112 1.223 bouyer sizeof(vstd->td.td_link), 3113 1.223 bouyer BUS_DMASYNC_PREWRITE); 3114 1.16 augustss } 3115 1.248 mrg mutex_exit(&sc->sc_lock); 3116 1.16 augustss 3117 1.268 skrll isoc->next = -1; 3118 1.268 skrll isoc->inuse = 0; 3119 1.48 augustss 3120 1.268 skrll return USBD_NORMAL_COMPLETION; 3121 1.16 augustss 3122 1.48 augustss bad: 3123 1.16 augustss while (--i >= 0) 3124 1.268 skrll uhci_free_std(sc, isoc->stds[i]); 3125 1.268 skrll kmem_free(isoc->stds, UHCI_VFRAMELIST_COUNT * sizeof(uhci_soft_td_t *)); 3126 1.268 skrll return USBD_NOMEM; 3127 1.16 augustss } 3128 1.16 augustss 3129 1.16 augustss void 3130 1.268 skrll uhci_device_isoc_done(struct usbd_xfer *xfer) 3131 1.16 augustss { 3132 1.304 skrll uhci_softc_t *sc __diagused = UHCI_XFER2SC(xfer); 3133 1.268 skrll struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); 3134 1.268 skrll struct uhci_xfer *ux = UHCI_XFER2UXFER(xfer); 3135 1.268 skrll int rd = UE_GET_DIR(upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress) == UE_DIR_IN; 3136 1.170 augustss 3137 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 3138 1.296 christos DPRINTFN(4, "length=%jd, ux_state=0x%08jx", 3139 1.268 skrll xfer->ux_actlen, xfer->ux_state, 0, 0); 3140 1.96 augustss 3141 1.304 skrll KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 3142 1.304 skrll 3143 1.93 augustss #ifdef DIAGNOSTIC 3144 1.268 skrll if (ux->ux_stdend == NULL) { 3145 1.268 skrll printf("%s: xfer=%p stdend==NULL\n", __func__, xfer); 3146 1.93 augustss #ifdef UHCI_DEBUG 3147 1.268 skrll DPRINTF("--- dump start ---", 0, 0, 0, 0); 3148 1.268 skrll uhci_dump_ii(ux); 3149 1.268 skrll DPRINTF("--- dump end ---", 0, 0, 0, 0); 3150 1.93 augustss #endif 3151 1.93 augustss return; 3152 1.93 augustss } 3153 1.93 augustss #endif 3154 1.48 augustss 3155 1.48 augustss /* Turn off the interrupt since it is active even if the TD is not. */ 3156 1.268 skrll usb_syncmem(&ux->ux_stdend->dma, 3157 1.268 skrll ux->ux_stdend->offs + offsetof(uhci_td_t, td_status), 3158 1.268 skrll sizeof(ux->ux_stdend->td.td_status), 3159 1.223 bouyer BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3160 1.268 skrll ux->ux_stdend->td.td_status &= htole32(~UHCI_TD_IOC); 3161 1.268 skrll usb_syncmem(&ux->ux_stdend->dma, 3162 1.268 skrll ux->ux_stdend->offs + offsetof(uhci_td_t, td_status), 3163 1.268 skrll sizeof(ux->ux_stdend->td.td_status), 3164 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3165 1.48 augustss 3166 1.319 jakllsch if (xfer->ux_length) 3167 1.319 jakllsch usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, 3168 1.223 bouyer rd ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 3169 1.16 augustss } 3170 1.16 augustss 3171 1.1 augustss void 3172 1.268 skrll uhci_device_intr_done(struct usbd_xfer *xfer) 3173 1.1 augustss { 3174 1.269 skrll uhci_softc_t *sc __diagused = UHCI_XFER2SC(xfer); 3175 1.268 skrll struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); 3176 1.1 augustss uhci_soft_qh_t *sqh; 3177 1.268 skrll int i, npoll; 3178 1.1 augustss 3179 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 3180 1.277 pgoyette DPRINTFN(5, "length=%jd", xfer->ux_actlen, 0, 0, 0); 3181 1.1 augustss 3182 1.268 skrll KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 3183 1.248 mrg 3184 1.268 skrll npoll = upipe->intr.npoll; 3185 1.267 skrll for (i = 0; i < npoll; i++) { 3186 1.268 skrll sqh = upipe->intr.qhs[i]; 3187 1.121 augustss sqh->elink = NULL; 3188 1.88 tsutsui sqh->qh.qh_elink = htole32(UHCI_PTR_T); 3189 1.223 bouyer usb_syncmem(&sqh->dma, 3190 1.223 bouyer sqh->offs + offsetof(uhci_qh_t, qh_elink), 3191 1.223 bouyer sizeof(sqh->qh.qh_elink), 3192 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3193 1.1 augustss } 3194 1.268 skrll const int endpt = upipe->pipe.up_endpoint->ue_edesc->bEndpointAddress; 3195 1.268 skrll const bool isread = UE_GET_DIR(endpt) == UE_DIR_IN; 3196 1.268 skrll usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, 3197 1.223 bouyer isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 3198 1.1 augustss } 3199 1.1 augustss 3200 1.1 augustss /* Deallocate request data structures */ 3201 1.1 augustss void 3202 1.268 skrll uhci_device_ctrl_done(struct usbd_xfer *xfer) 3203 1.1 augustss { 3204 1.268 skrll uhci_softc_t *sc = UHCI_XFER2SC(xfer); 3205 1.268 skrll struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); 3206 1.268 skrll int len = UGETW(xfer->ux_request.wLength); 3207 1.268 skrll int isread = (xfer->ux_request.bmRequestType & UT_READ); 3208 1.1 augustss 3209 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 3210 1.169 augustss 3211 1.304 skrll KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 3212 1.268 skrll KASSERT(xfer->ux_rqflags & URQ_REQUEST); 3213 1.1 augustss 3214 1.268 skrll /* XXXNH move to uhci_idone??? */ 3215 1.268 skrll if (upipe->pipe.up_dev->ud_speed == USB_SPEED_LOW) 3216 1.268 skrll uhci_remove_ls_ctrl(sc, upipe->ctrl.sqh); 3217 1.123 augustss else 3218 1.268 skrll uhci_remove_hs_ctrl(sc, upipe->ctrl.sqh); 3219 1.49 augustss 3220 1.223 bouyer if (len) { 3221 1.268 skrll usb_syncmem(&xfer->ux_dmabuf, 0, len, 3222 1.223 bouyer isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 3223 1.223 bouyer } 3224 1.268 skrll usb_syncmem(&upipe->ctrl.reqdma, 0, 3225 1.223 bouyer sizeof(usb_device_request_t), BUS_DMASYNC_POSTWRITE); 3226 1.223 bouyer 3227 1.277 pgoyette DPRINTF("length=%jd", xfer->ux_actlen, 0, 0, 0); 3228 1.1 augustss } 3229 1.1 augustss 3230 1.1 augustss /* Deallocate request data structures */ 3231 1.1 augustss void 3232 1.268 skrll uhci_device_bulk_done(struct usbd_xfer *xfer) 3233 1.1 augustss { 3234 1.268 skrll uhci_softc_t *sc = UHCI_XFER2SC(xfer); 3235 1.268 skrll struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(xfer->ux_pipe); 3236 1.268 skrll usb_endpoint_descriptor_t *ed = xfer->ux_pipe->up_endpoint->ue_edesc; 3237 1.268 skrll int endpt = ed->bEndpointAddress; 3238 1.268 skrll int isread = UE_GET_DIR(endpt) == UE_DIR_IN; 3239 1.169 augustss 3240 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 3241 1.277 pgoyette DPRINTFN(5, "xfer=%#jx sc=%#jx upipe=%#jx", (uintptr_t)xfer, 3242 1.277 pgoyette (uintptr_t)sc, (uintptr_t)upipe, 0); 3243 1.169 augustss 3244 1.304 skrll KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 3245 1.248 mrg 3246 1.268 skrll uhci_remove_bulk(sc, upipe->bulk.sqh); 3247 1.1 augustss 3248 1.268 skrll if (xfer->ux_length) { 3249 1.268 skrll usb_syncmem(&xfer->ux_dmabuf, 0, xfer->ux_length, 3250 1.268 skrll isread ? BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE); 3251 1.268 skrll } 3252 1.1 augustss 3253 1.277 pgoyette DPRINTFN(5, "length=%jd", xfer->ux_actlen, 0, 0, 0); 3254 1.1 augustss } 3255 1.1 augustss 3256 1.1 augustss /* Add interrupt QH, called with vflock. */ 3257 1.1 augustss void 3258 1.119 augustss uhci_add_intr(uhci_softc_t *sc, uhci_soft_qh_t *sqh) 3259 1.1 augustss { 3260 1.92 augustss struct uhci_vframe *vf = &sc->sc_vframes[sqh->pos]; 3261 1.42 augustss uhci_soft_qh_t *eqh; 3262 1.1 augustss 3263 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 3264 1.277 pgoyette DPRINTFN(4, "n=%jd sqh=%#jx", sqh->pos, (uintptr_t)sqh, 0, 0); 3265 1.92 augustss 3266 1.42 augustss eqh = vf->eqh; 3267 1.223 bouyer usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), 3268 1.287 skrll sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_POSTWRITE); 3269 1.42 augustss sqh->hlink = eqh->hlink; 3270 1.42 augustss sqh->qh.qh_hlink = eqh->qh.qh_hlink; 3271 1.223 bouyer usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_hlink), 3272 1.287 skrll sizeof(sqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE); 3273 1.42 augustss eqh->hlink = sqh; 3274 1.121 augustss eqh->qh.qh_hlink = htole32(sqh->physaddr | UHCI_PTR_QH); 3275 1.223 bouyer usb_syncmem(&eqh->dma, eqh->offs + offsetof(uhci_qh_t, qh_hlink), 3276 1.287 skrll sizeof(eqh->qh.qh_hlink), BUS_DMASYNC_PREWRITE); 3277 1.1 augustss vf->eqh = sqh; 3278 1.1 augustss vf->bandwidth++; 3279 1.1 augustss } 3280 1.1 augustss 3281 1.119 augustss /* Remove interrupt QH. */ 3282 1.1 augustss void 3283 1.119 augustss uhci_remove_intr(uhci_softc_t *sc, uhci_soft_qh_t *sqh) 3284 1.1 augustss { 3285 1.92 augustss struct uhci_vframe *vf = &sc->sc_vframes[sqh->pos]; 3286 1.1 augustss uhci_soft_qh_t *pqh; 3287 1.1 augustss 3288 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 3289 1.277 pgoyette DPRINTFN(4, "n=%jd sqh=%#jx", sqh->pos, (uintptr_t)sqh, 0, 0); 3290 1.1 augustss 3291 1.124 augustss /* See comment in uhci_remove_ctrl() */ 3292 1.223 bouyer 3293 1.223 bouyer usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_elink), 3294 1.223 bouyer sizeof(sqh->qh.qh_elink), 3295 1.223 bouyer BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3296 1.124 augustss if (!(sqh->qh.qh_elink & htole32(UHCI_PTR_T))) { 3297 1.124 augustss sqh->qh.qh_elink = htole32(UHCI_PTR_T); 3298 1.223 bouyer usb_syncmem(&sqh->dma, 3299 1.223 bouyer sqh->offs + offsetof(uhci_qh_t, qh_elink), 3300 1.223 bouyer sizeof(sqh->qh.qh_elink), 3301 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3302 1.124 augustss delay(UHCI_QH_REMOVE_DELAY); 3303 1.124 augustss } 3304 1.124 augustss 3305 1.92 augustss pqh = uhci_find_prev_qh(vf->hqh, sqh); 3306 1.223 bouyer usb_syncmem(&sqh->dma, sqh->offs + offsetof(uhci_qh_t, qh_hlink), 3307 1.223 bouyer sizeof(sqh->qh.qh_hlink), 3308 1.223 bouyer BUS_DMASYNC_POSTWRITE | BUS_DMASYNC_POSTREAD); 3309 1.42 augustss pqh->hlink = sqh->hlink; 3310 1.42 augustss pqh->qh.qh_hlink = sqh->qh.qh_hlink; 3311 1.223 bouyer usb_syncmem(&pqh->dma, pqh->offs + offsetof(uhci_qh_t, qh_hlink), 3312 1.223 bouyer sizeof(pqh->qh.qh_hlink), 3313 1.223 bouyer BUS_DMASYNC_PREWRITE); 3314 1.124 augustss delay(UHCI_QH_REMOVE_DELAY); 3315 1.1 augustss if (vf->eqh == sqh) 3316 1.1 augustss vf->eqh = pqh; 3317 1.1 augustss vf->bandwidth--; 3318 1.1 augustss } 3319 1.1 augustss 3320 1.1 augustss usbd_status 3321 1.119 augustss uhci_device_setintr(uhci_softc_t *sc, struct uhci_pipe *upipe, int ival) 3322 1.1 augustss { 3323 1.1 augustss uhci_soft_qh_t *sqh; 3324 1.248 mrg int i, npoll; 3325 1.1 augustss u_int bestbw, bw, bestoffs, offs; 3326 1.1 augustss 3327 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 3328 1.277 pgoyette DPRINTFN(2, "pipe=%#jx", (uintptr_t)upipe, 0, 0, 0); 3329 1.1 augustss if (ival == 0) { 3330 1.268 skrll printf("%s: 0 interval\n", __func__); 3331 1.268 skrll return USBD_INVAL; 3332 1.1 augustss } 3333 1.1 augustss 3334 1.1 augustss if (ival > UHCI_VFRAMELIST_COUNT) 3335 1.1 augustss ival = UHCI_VFRAMELIST_COUNT; 3336 1.297 skrll npoll = howmany(UHCI_VFRAMELIST_COUNT, ival); 3337 1.277 pgoyette DPRINTF("ival=%jd npoll=%jd", ival, npoll, 0, 0); 3338 1.1 augustss 3339 1.268 skrll upipe->intr.npoll = npoll; 3340 1.268 skrll upipe->intr.qhs = 3341 1.248 mrg kmem_alloc(npoll * sizeof(uhci_soft_qh_t *), KM_SLEEP); 3342 1.1 augustss 3343 1.152 augustss /* 3344 1.1 augustss * Figure out which offset in the schedule that has most 3345 1.1 augustss * bandwidth left over. 3346 1.1 augustss */ 3347 1.1 augustss #define MOD(i) ((i) & (UHCI_VFRAMELIST_COUNT-1)) 3348 1.1 augustss for (bestoffs = offs = 0, bestbw = ~0; offs < ival; offs++) { 3349 1.1 augustss for (bw = i = 0; i < npoll; i++) 3350 1.1 augustss bw += sc->sc_vframes[MOD(i * ival + offs)].bandwidth; 3351 1.1 augustss if (bw < bestbw) { 3352 1.1 augustss bestbw = bw; 3353 1.1 augustss bestoffs = offs; 3354 1.1 augustss } 3355 1.1 augustss } 3356 1.277 pgoyette DPRINTF("bw=%jd offs=%jd", bestbw, bestoffs, 0, 0); 3357 1.267 skrll for (i = 0; i < npoll; i++) { 3358 1.268 skrll upipe->intr.qhs[i] = sqh = uhci_alloc_sqh(sc); 3359 1.121 augustss sqh->elink = NULL; 3360 1.88 tsutsui sqh->qh.qh_elink = htole32(UHCI_PTR_T); 3361 1.223 bouyer usb_syncmem(&sqh->dma, 3362 1.223 bouyer sqh->offs + offsetof(uhci_qh_t, qh_elink), 3363 1.223 bouyer sizeof(sqh->qh.qh_elink), 3364 1.223 bouyer BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD); 3365 1.1 augustss sqh->pos = MOD(i * ival + bestoffs); 3366 1.1 augustss } 3367 1.1 augustss #undef MOD 3368 1.1 augustss 3369 1.268 skrll mutex_enter(&sc->sc_lock); 3370 1.1 augustss /* Enter QHs into the controller data structures. */ 3371 1.267 skrll for (i = 0; i < npoll; i++) 3372 1.268 skrll uhci_add_intr(sc, upipe->intr.qhs[i]); 3373 1.248 mrg mutex_exit(&sc->sc_lock); 3374 1.1 augustss 3375 1.277 pgoyette DPRINTFN(5, "returns %#jx", (uintptr_t)upipe, 0, 0, 0); 3376 1.268 skrll 3377 1.268 skrll return USBD_NORMAL_COMPLETION; 3378 1.1 augustss } 3379 1.1 augustss 3380 1.1 augustss /* Open a new pipe. */ 3381 1.1 augustss usbd_status 3382 1.268 skrll uhci_open(struct usbd_pipe *pipe) 3383 1.1 augustss { 3384 1.268 skrll uhci_softc_t *sc = UHCI_PIPE2SC(pipe); 3385 1.268 skrll struct usbd_bus *bus = pipe->up_dev->ud_bus; 3386 1.268 skrll struct uhci_pipe *upipe = UHCI_PIPE2UPIPE(pipe); 3387 1.268 skrll usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc; 3388 1.79 augustss int ival; 3389 1.1 augustss 3390 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 3391 1.277 pgoyette DPRINTF("pipe=%#jx, addr=%jd, endpt=%jd (%jd)", 3392 1.277 pgoyette (uintptr_t)pipe, pipe->up_dev->ud_addr, ed->bEndpointAddress, 3393 1.277 pgoyette bus->ub_rhaddr); 3394 1.92 augustss 3395 1.248 mrg if (sc->sc_dying) 3396 1.248 mrg return USBD_IOERROR; 3397 1.248 mrg 3398 1.92 augustss upipe->aborting = 0; 3399 1.236 drochner /* toggle state needed for bulk endpoints */ 3400 1.268 skrll upipe->nexttoggle = pipe->up_endpoint->ue_toggle; 3401 1.92 augustss 3402 1.268 skrll if (pipe->up_dev->ud_addr == bus->ub_rhaddr) { 3403 1.1 augustss switch (ed->bEndpointAddress) { 3404 1.1 augustss case USB_CONTROL_ENDPOINT: 3405 1.268 skrll pipe->up_methods = &roothub_ctrl_methods; 3406 1.1 augustss break; 3407 1.268 skrll case UE_DIR_IN | USBROOTHUB_INTR_ENDPT: 3408 1.268 skrll pipe->up_methods = &uhci_root_intr_methods; 3409 1.1 augustss break; 3410 1.1 augustss default: 3411 1.268 skrll return USBD_INVAL; 3412 1.1 augustss } 3413 1.1 augustss } else { 3414 1.1 augustss switch (ed->bmAttributes & UE_XFERTYPE) { 3415 1.1 augustss case UE_CONTROL: 3416 1.268 skrll pipe->up_methods = &uhci_device_ctrl_methods; 3417 1.268 skrll upipe->ctrl.sqh = uhci_alloc_sqh(sc); 3418 1.268 skrll if (upipe->ctrl.sqh == NULL) 3419 1.5 augustss goto bad; 3420 1.268 skrll upipe->ctrl.setup = uhci_alloc_std(sc); 3421 1.268 skrll if (upipe->ctrl.setup == NULL) { 3422 1.268 skrll uhci_free_sqh(sc, upipe->ctrl.sqh); 3423 1.5 augustss goto bad; 3424 1.5 augustss } 3425 1.268 skrll upipe->ctrl.stat = uhci_alloc_std(sc); 3426 1.268 skrll if (upipe->ctrl.stat == NULL) { 3427 1.268 skrll uhci_free_sqh(sc, upipe->ctrl.sqh); 3428 1.268 skrll uhci_free_std(sc, upipe->ctrl.setup); 3429 1.5 augustss goto bad; 3430 1.5 augustss } 3431 1.308 skrll int err = usb_allocmem(sc->sc_bus.ub_dmatag, 3432 1.300 skrll sizeof(usb_device_request_t), 0, 3433 1.300 skrll USBMALLOC_COHERENT, &upipe->ctrl.reqdma); 3434 1.63 augustss if (err) { 3435 1.268 skrll uhci_free_sqh(sc, upipe->ctrl.sqh); 3436 1.268 skrll uhci_free_std(sc, upipe->ctrl.setup); 3437 1.268 skrll uhci_free_std(sc, upipe->ctrl.stat); 3438 1.5 augustss goto bad; 3439 1.5 augustss } 3440 1.1 augustss break; 3441 1.1 augustss case UE_INTERRUPT: 3442 1.268 skrll pipe->up_methods = &uhci_device_intr_methods; 3443 1.268 skrll ival = pipe->up_interval; 3444 1.79 augustss if (ival == USBD_DEFAULT_INTERVAL) 3445 1.79 augustss ival = ed->bInterval; 3446 1.268 skrll return uhci_device_setintr(sc, upipe, ival); 3447 1.1 augustss case UE_ISOCHRONOUS: 3448 1.268 skrll pipe->up_serialise = false; 3449 1.268 skrll pipe->up_methods = &uhci_device_isoc_methods; 3450 1.268 skrll return uhci_setup_isoc(pipe); 3451 1.1 augustss case UE_BULK: 3452 1.268 skrll pipe->up_methods = &uhci_device_bulk_methods; 3453 1.268 skrll upipe->bulk.sqh = uhci_alloc_sqh(sc); 3454 1.268 skrll if (upipe->bulk.sqh == NULL) 3455 1.5 augustss goto bad; 3456 1.1 augustss break; 3457 1.1 augustss } 3458 1.1 augustss } 3459 1.268 skrll return USBD_NORMAL_COMPLETION; 3460 1.5 augustss 3461 1.5 augustss bad: 3462 1.248 mrg return USBD_NOMEM; 3463 1.1 augustss } 3464 1.1 augustss 3465 1.1 augustss /* 3466 1.1 augustss * Data structures and routines to emulate the root hub. 3467 1.1 augustss */ 3468 1.1 augustss /* 3469 1.166 dsainty * The USB hub protocol requires that SET_FEATURE(PORT_RESET) also 3470 1.166 dsainty * enables the port, and also states that SET_FEATURE(PORT_ENABLE) 3471 1.166 dsainty * should not be used by the USB subsystem. As we cannot issue a 3472 1.166 dsainty * SET_FEATURE(PORT_ENABLE) externally, we must ensure that the port 3473 1.166 dsainty * will be enabled as part of the reset. 3474 1.166 dsainty * 3475 1.166 dsainty * On the VT83C572, the port cannot be successfully enabled until the 3476 1.166 dsainty * outstanding "port enable change" and "connection status change" 3477 1.166 dsainty * events have been reset. 3478 1.166 dsainty */ 3479 1.166 dsainty Static usbd_status 3480 1.166 dsainty uhci_portreset(uhci_softc_t *sc, int index) 3481 1.166 dsainty { 3482 1.166 dsainty int lim, port, x; 3483 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 3484 1.166 dsainty 3485 1.166 dsainty if (index == 1) 3486 1.166 dsainty port = UHCI_PORTSC1; 3487 1.166 dsainty else if (index == 2) 3488 1.166 dsainty port = UHCI_PORTSC2; 3489 1.166 dsainty else 3490 1.268 skrll return USBD_IOERROR; 3491 1.166 dsainty 3492 1.166 dsainty x = URWMASK(UREAD2(sc, port)); 3493 1.166 dsainty UWRITE2(sc, port, x | UHCI_PORTSC_PR); 3494 1.166 dsainty 3495 1.166 dsainty usb_delay_ms(&sc->sc_bus, USB_PORT_ROOT_RESET_DELAY); 3496 1.166 dsainty 3497 1.296 christos DPRINTF("uhci port %jd reset, status0 = 0x%04jx", index, 3498 1.268 skrll UREAD2(sc, port), 0, 0); 3499 1.166 dsainty 3500 1.166 dsainty x = URWMASK(UREAD2(sc, port)); 3501 1.222 drochner UWRITE2(sc, port, x & ~(UHCI_PORTSC_PR | UHCI_PORTSC_SUSP)); 3502 1.166 dsainty 3503 1.166 dsainty delay(100); 3504 1.166 dsainty 3505 1.296 christos DPRINTF("uhci port %jd reset, status1 = 0x%04jx", index, 3506 1.268 skrll UREAD2(sc, port), 0, 0); 3507 1.166 dsainty 3508 1.166 dsainty x = URWMASK(UREAD2(sc, port)); 3509 1.166 dsainty UWRITE2(sc, port, x | UHCI_PORTSC_PE); 3510 1.166 dsainty 3511 1.166 dsainty for (lim = 10; --lim > 0;) { 3512 1.166 dsainty usb_delay_ms(&sc->sc_bus, USB_PORT_RESET_DELAY); 3513 1.166 dsainty 3514 1.166 dsainty x = UREAD2(sc, port); 3515 1.296 christos DPRINTF("uhci port %jd iteration %ju, status = 0x%04jx", index, 3516 1.268 skrll lim, x, 0); 3517 1.166 dsainty 3518 1.166 dsainty if (!(x & UHCI_PORTSC_CCS)) { 3519 1.166 dsainty /* 3520 1.166 dsainty * No device is connected (or was disconnected 3521 1.166 dsainty * during reset). Consider the port reset. 3522 1.166 dsainty * The delay must be long enough to ensure on 3523 1.166 dsainty * the initial iteration that the device 3524 1.166 dsainty * connection will have been registered. 50ms 3525 1.166 dsainty * appears to be sufficient, but 20ms is not. 3526 1.166 dsainty */ 3527 1.277 pgoyette DPRINTFN(3, "uhci port %jd loop %ju, device detached", 3528 1.268 skrll index, lim, 0, 0); 3529 1.166 dsainty break; 3530 1.166 dsainty } 3531 1.166 dsainty 3532 1.166 dsainty if (x & (UHCI_PORTSC_POEDC | UHCI_PORTSC_CSC)) { 3533 1.166 dsainty /* 3534 1.166 dsainty * Port enabled changed and/or connection 3535 1.166 dsainty * status changed were set. Reset either or 3536 1.166 dsainty * both raised flags (by writing a 1 to that 3537 1.166 dsainty * bit), and wait again for state to settle. 3538 1.166 dsainty */ 3539 1.166 dsainty UWRITE2(sc, port, URWMASK(x) | 3540 1.166 dsainty (x & (UHCI_PORTSC_POEDC | UHCI_PORTSC_CSC))); 3541 1.166 dsainty continue; 3542 1.166 dsainty } 3543 1.166 dsainty 3544 1.166 dsainty if (x & UHCI_PORTSC_PE) 3545 1.166 dsainty /* Port is enabled */ 3546 1.166 dsainty break; 3547 1.166 dsainty 3548 1.166 dsainty UWRITE2(sc, port, URWMASK(x) | UHCI_PORTSC_PE); 3549 1.166 dsainty } 3550 1.166 dsainty 3551 1.296 christos DPRINTFN(3, "uhci port %jd reset, status2 = 0x%04jx", index, 3552 1.268 skrll UREAD2(sc, port), 0, 0); 3553 1.166 dsainty 3554 1.166 dsainty if (lim <= 0) { 3555 1.277 pgoyette DPRINTF("uhci port %jd reset timed out", index, 3556 1.268 skrll 0, 0, 0); 3557 1.268 skrll return USBD_TIMEOUT; 3558 1.166 dsainty } 3559 1.184 perry 3560 1.166 dsainty sc->sc_isreset = 1; 3561 1.268 skrll return USBD_NORMAL_COMPLETION; 3562 1.166 dsainty } 3563 1.166 dsainty 3564 1.268 skrll Static int 3565 1.268 skrll uhci_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req, 3566 1.268 skrll void *buf, int buflen) 3567 1.1 augustss { 3568 1.268 skrll uhci_softc_t *sc = UHCI_BUS2SC(bus); 3569 1.1 augustss int port, x; 3570 1.268 skrll int status, change, totlen = 0; 3571 1.268 skrll uint16_t len, value, index; 3572 1.1 augustss usb_port_status_t ps; 3573 1.63 augustss usbd_status err; 3574 1.1 augustss 3575 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 3576 1.268 skrll 3577 1.82 augustss if (sc->sc_dying) 3578 1.268 skrll return -1; 3579 1.1 augustss 3580 1.296 christos DPRINTF("type=0x%02jx request=%02jx", req->bmRequestType, 3581 1.268 skrll req->bRequest, 0, 0); 3582 1.1 augustss 3583 1.1 augustss len = UGETW(req->wLength); 3584 1.1 augustss value = UGETW(req->wValue); 3585 1.1 augustss index = UGETW(req->wIndex); 3586 1.49 augustss 3587 1.1 augustss #define C(x,y) ((x) | ((y) << 8)) 3588 1.268 skrll switch (C(req->bRequest, req->bmRequestType)) { 3589 1.1 augustss case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE): 3590 1.296 christos DPRINTF("wValue=0x%04jx", value, 0, 0, 0); 3591 1.195 christos if (len == 0) 3592 1.195 christos break; 3593 1.268 skrll switch (value) { 3594 1.213 drochner #define sd ((usb_string_descriptor_t *)buf) 3595 1.268 skrll case C(2, UDESC_STRING): 3596 1.268 skrll /* Product */ 3597 1.268 skrll totlen = usb_makestrdesc(sd, len, "UHCI root hub"); 3598 1.268 skrll break; 3599 1.213 drochner #undef sd 3600 1.1 augustss default: 3601 1.268 skrll /* default from usbroothub */ 3602 1.268 skrll return buflen; 3603 1.1 augustss } 3604 1.1 augustss break; 3605 1.268 skrll 3606 1.1 augustss /* Hub requests */ 3607 1.1 augustss case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE): 3608 1.1 augustss break; 3609 1.1 augustss case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER): 3610 1.277 pgoyette DPRINTF("UR_CLEAR_PORT_FEATURE port=%jd feature=%jd", index, 3611 1.268 skrll value, 0, 0); 3612 1.1 augustss if (index == 1) 3613 1.1 augustss port = UHCI_PORTSC1; 3614 1.1 augustss else if (index == 2) 3615 1.1 augustss port = UHCI_PORTSC2; 3616 1.1 augustss else { 3617 1.268 skrll return -1; 3618 1.1 augustss } 3619 1.1 augustss switch(value) { 3620 1.1 augustss case UHF_PORT_ENABLE: 3621 1.137 augustss x = URWMASK(UREAD2(sc, port)); 3622 1.1 augustss UWRITE2(sc, port, x & ~UHCI_PORTSC_PE); 3623 1.1 augustss break; 3624 1.1 augustss case UHF_PORT_SUSPEND: 3625 1.137 augustss x = URWMASK(UREAD2(sc, port)); 3626 1.222 drochner if (!(x & UHCI_PORTSC_SUSP)) /* not suspended */ 3627 1.222 drochner break; 3628 1.222 drochner UWRITE2(sc, port, x | UHCI_PORTSC_RD); 3629 1.222 drochner /* see USB2 spec ch. 7.1.7.7 */ 3630 1.222 drochner usb_delay_ms(&sc->sc_bus, 20); 3631 1.1 augustss UWRITE2(sc, port, x & ~UHCI_PORTSC_SUSP); 3632 1.222 drochner /* 10ms resume delay must be provided by caller */ 3633 1.1 augustss break; 3634 1.1 augustss case UHF_PORT_RESET: 3635 1.137 augustss x = URWMASK(UREAD2(sc, port)); 3636 1.1 augustss UWRITE2(sc, port, x & ~UHCI_PORTSC_PR); 3637 1.1 augustss break; 3638 1.1 augustss case UHF_C_PORT_CONNECTION: 3639 1.137 augustss x = URWMASK(UREAD2(sc, port)); 3640 1.1 augustss UWRITE2(sc, port, x | UHCI_PORTSC_CSC); 3641 1.1 augustss break; 3642 1.1 augustss case UHF_C_PORT_ENABLE: 3643 1.137 augustss x = URWMASK(UREAD2(sc, port)); 3644 1.1 augustss UWRITE2(sc, port, x | UHCI_PORTSC_POEDC); 3645 1.1 augustss break; 3646 1.1 augustss case UHF_C_PORT_OVER_CURRENT: 3647 1.137 augustss x = URWMASK(UREAD2(sc, port)); 3648 1.1 augustss UWRITE2(sc, port, x | UHCI_PORTSC_OCIC); 3649 1.1 augustss break; 3650 1.1 augustss case UHF_C_PORT_RESET: 3651 1.1 augustss sc->sc_isreset = 0; 3652 1.268 skrll break; 3653 1.1 augustss case UHF_PORT_CONNECTION: 3654 1.1 augustss case UHF_PORT_OVER_CURRENT: 3655 1.1 augustss case UHF_PORT_POWER: 3656 1.1 augustss case UHF_PORT_LOW_SPEED: 3657 1.1 augustss case UHF_C_PORT_SUSPEND: 3658 1.1 augustss default: 3659 1.268 skrll return -1; 3660 1.1 augustss } 3661 1.1 augustss break; 3662 1.1 augustss case C(UR_GET_BUS_STATE, UT_READ_CLASS_OTHER): 3663 1.1 augustss if (index == 1) 3664 1.1 augustss port = UHCI_PORTSC1; 3665 1.1 augustss else if (index == 2) 3666 1.1 augustss port = UHCI_PORTSC2; 3667 1.1 augustss else { 3668 1.268 skrll return -1; 3669 1.1 augustss } 3670 1.1 augustss if (len > 0) { 3671 1.268 skrll *(uint8_t *)buf = 3672 1.268 skrll UHCI_PORTSC_GET_LS(UREAD2(sc, port)); 3673 1.1 augustss totlen = 1; 3674 1.1 augustss } 3675 1.1 augustss break; 3676 1.1 augustss case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE): 3677 1.195 christos if (len == 0) 3678 1.195 christos break; 3679 1.177 toshii if ((value & 0xff) != 0) { 3680 1.268 skrll return -1; 3681 1.1 augustss } 3682 1.268 skrll usb_hub_descriptor_t hubd; 3683 1.268 skrll 3684 1.283 riastrad totlen = uimin(buflen, sizeof(hubd)); 3685 1.268 skrll memcpy(&hubd, buf, totlen); 3686 1.268 skrll hubd.bNbrPorts = 2; 3687 1.268 skrll memcpy(buf, &hubd, totlen); 3688 1.1 augustss break; 3689 1.1 augustss case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE): 3690 1.1 augustss if (len != 4) { 3691 1.268 skrll return -1; 3692 1.1 augustss } 3693 1.1 augustss memset(buf, 0, len); 3694 1.1 augustss totlen = len; 3695 1.1 augustss break; 3696 1.1 augustss case C(UR_GET_STATUS, UT_READ_CLASS_OTHER): 3697 1.1 augustss if (index == 1) 3698 1.1 augustss port = UHCI_PORTSC1; 3699 1.1 augustss else if (index == 2) 3700 1.1 augustss port = UHCI_PORTSC2; 3701 1.1 augustss else { 3702 1.268 skrll return -1; 3703 1.1 augustss } 3704 1.1 augustss if (len != 4) { 3705 1.268 skrll return -1; 3706 1.1 augustss } 3707 1.1 augustss x = UREAD2(sc, port); 3708 1.1 augustss status = change = 0; 3709 1.142 augustss if (x & UHCI_PORTSC_CCS) 3710 1.1 augustss status |= UPS_CURRENT_CONNECT_STATUS; 3711 1.152 augustss if (x & UHCI_PORTSC_CSC) 3712 1.1 augustss change |= UPS_C_CONNECT_STATUS; 3713 1.152 augustss if (x & UHCI_PORTSC_PE) 3714 1.1 augustss status |= UPS_PORT_ENABLED; 3715 1.152 augustss if (x & UHCI_PORTSC_POEDC) 3716 1.1 augustss change |= UPS_C_PORT_ENABLED; 3717 1.152 augustss if (x & UHCI_PORTSC_OCI) 3718 1.1 augustss status |= UPS_OVERCURRENT_INDICATOR; 3719 1.152 augustss if (x & UHCI_PORTSC_OCIC) 3720 1.1 augustss change |= UPS_C_OVERCURRENT_INDICATOR; 3721 1.152 augustss if (x & UHCI_PORTSC_SUSP) 3722 1.1 augustss status |= UPS_SUSPEND; 3723 1.152 augustss if (x & UHCI_PORTSC_LSDA) 3724 1.1 augustss status |= UPS_LOW_SPEED; 3725 1.1 augustss status |= UPS_PORT_POWER; 3726 1.1 augustss if (sc->sc_isreset) 3727 1.1 augustss change |= UPS_C_PORT_RESET; 3728 1.1 augustss USETW(ps.wPortStatus, status); 3729 1.1 augustss USETW(ps.wPortChange, change); 3730 1.283 riastrad totlen = uimin(len, sizeof(ps)); 3731 1.268 skrll memcpy(buf, &ps, totlen); 3732 1.1 augustss break; 3733 1.1 augustss case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE): 3734 1.268 skrll return -1; 3735 1.1 augustss case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE): 3736 1.1 augustss break; 3737 1.1 augustss case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER): 3738 1.1 augustss if (index == 1) 3739 1.1 augustss port = UHCI_PORTSC1; 3740 1.1 augustss else if (index == 2) 3741 1.1 augustss port = UHCI_PORTSC2; 3742 1.1 augustss else { 3743 1.268 skrll return -1; 3744 1.1 augustss } 3745 1.1 augustss switch(value) { 3746 1.1 augustss case UHF_PORT_ENABLE: 3747 1.137 augustss x = URWMASK(UREAD2(sc, port)); 3748 1.1 augustss UWRITE2(sc, port, x | UHCI_PORTSC_PE); 3749 1.1 augustss break; 3750 1.1 augustss case UHF_PORT_SUSPEND: 3751 1.137 augustss x = URWMASK(UREAD2(sc, port)); 3752 1.1 augustss UWRITE2(sc, port, x | UHCI_PORTSC_SUSP); 3753 1.1 augustss break; 3754 1.1 augustss case UHF_PORT_RESET: 3755 1.166 dsainty err = uhci_portreset(sc, index); 3756 1.268 skrll if (err != USBD_NORMAL_COMPLETION) 3757 1.268 skrll return -1; 3758 1.268 skrll return 0; 3759 1.111 augustss case UHF_PORT_POWER: 3760 1.111 augustss /* Pretend we turned on power */ 3761 1.268 skrll return 0; 3762 1.1 augustss case UHF_C_PORT_CONNECTION: 3763 1.1 augustss case UHF_C_PORT_ENABLE: 3764 1.1 augustss case UHF_C_PORT_OVER_CURRENT: 3765 1.1 augustss case UHF_PORT_CONNECTION: 3766 1.1 augustss case UHF_PORT_OVER_CURRENT: 3767 1.1 augustss case UHF_PORT_LOW_SPEED: 3768 1.1 augustss case UHF_C_PORT_SUSPEND: 3769 1.1 augustss case UHF_C_PORT_RESET: 3770 1.1 augustss default: 3771 1.268 skrll return -1; 3772 1.1 augustss } 3773 1.1 augustss break; 3774 1.1 augustss default: 3775 1.268 skrll /* default from usbroothub */ 3776 1.277 pgoyette DPRINTF("returning %jd (usbroothub default)", 3777 1.268 skrll buflen, 0, 0, 0); 3778 1.268 skrll return buflen; 3779 1.1 augustss } 3780 1.1 augustss 3781 1.277 pgoyette DPRINTF("returning %jd", totlen, 0, 0, 0); 3782 1.1 augustss 3783 1.268 skrll return totlen; 3784 1.1 augustss } 3785 1.1 augustss 3786 1.1 augustss /* Abort a root interrupt request. */ 3787 1.1 augustss void 3788 1.268 skrll uhci_root_intr_abort(struct usbd_xfer *xfer) 3789 1.1 augustss { 3790 1.268 skrll uhci_softc_t *sc = UHCI_XFER2SC(xfer); 3791 1.30 augustss 3792 1.248 mrg KASSERT(mutex_owned(&sc->sc_lock)); 3793 1.268 skrll KASSERT(xfer->ux_pipe->up_intrxfer == xfer); 3794 1.248 mrg 3795 1.290 riastrad /* 3796 1.290 riastrad * Try to stop the callout before it starts. If we got in too 3797 1.290 riastrad * late, too bad; but if the callout had yet to run and time 3798 1.290 riastrad * out the xfer, cancel it ourselves. 3799 1.290 riastrad */ 3800 1.234 dyoung callout_stop(&sc->sc_poll_handle); 3801 1.290 riastrad if (sc->sc_intr_xfer == NULL) 3802 1.290 riastrad return; 3803 1.58 augustss 3804 1.290 riastrad KASSERT(sc->sc_intr_xfer == xfer); 3805 1.291 riastrad KASSERT(xfer->ux_status == USBD_IN_PROGRESS); 3806 1.268 skrll xfer->ux_status = USBD_CANCELLED; 3807 1.96 augustss #ifdef DIAGNOSTIC 3808 1.268 skrll UHCI_XFER2UXFER(xfer)->ux_isdone = true; 3809 1.96 augustss #endif 3810 1.63 augustss usb_transfer_complete(xfer); 3811 1.1 augustss } 3812 1.1 augustss 3813 1.16 augustss usbd_status 3814 1.268 skrll uhci_root_intr_transfer(struct usbd_xfer *xfer) 3815 1.16 augustss { 3816 1.52 augustss 3817 1.309 riastrad /* Pipe isn't running, start first */ 3818 1.268 skrll return uhci_root_intr_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue)); 3819 1.16 augustss } 3820 1.16 augustss 3821 1.1 augustss /* Start a transfer on the root interrupt pipe */ 3822 1.1 augustss usbd_status 3823 1.268 skrll uhci_root_intr_start(struct usbd_xfer *xfer) 3824 1.1 augustss { 3825 1.268 skrll struct usbd_pipe *pipe = xfer->ux_pipe; 3826 1.268 skrll uhci_softc_t *sc = UHCI_PIPE2SC(pipe); 3827 1.174 drochner unsigned int ival; 3828 1.1 augustss 3829 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 3830 1.277 pgoyette DPRINTF("xfer=%#jx len=%jd flags=%jd", (uintptr_t)xfer, xfer->ux_length, 3831 1.268 skrll xfer->ux_flags, 0); 3832 1.82 augustss 3833 1.311 riastrad KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock)); 3834 1.311 riastrad 3835 1.82 augustss if (sc->sc_dying) 3836 1.268 skrll return USBD_IOERROR; 3837 1.1 augustss 3838 1.290 riastrad KASSERT(sc->sc_intr_xfer == NULL); 3839 1.290 riastrad 3840 1.174 drochner /* XXX temporary variable needed to avoid gcc3 warning */ 3841 1.268 skrll ival = xfer->ux_pipe->up_endpoint->ue_edesc->bInterval; 3842 1.174 drochner sc->sc_ival = mstohz(ival); 3843 1.313 riastrad if (sc->sc_suspend == PWR_RESUME) 3844 1.313 riastrad callout_schedule(&sc->sc_poll_handle, sc->sc_ival); 3845 1.96 augustss sc->sc_intr_xfer = xfer; 3846 1.293 riastrad xfer->ux_status = USBD_IN_PROGRESS; 3847 1.290 riastrad 3848 1.293 riastrad return USBD_IN_PROGRESS; 3849 1.1 augustss } 3850 1.1 augustss 3851 1.1 augustss /* Close the root interrupt pipe. */ 3852 1.1 augustss void 3853 1.268 skrll uhci_root_intr_close(struct usbd_pipe *pipe) 3854 1.1 augustss { 3855 1.290 riastrad uhci_softc_t *sc __diagused = UHCI_PIPE2SC(pipe); 3856 1.268 skrll UHCIHIST_FUNC(); UHCIHIST_CALLED(); 3857 1.30 augustss 3858 1.248 mrg KASSERT(mutex_owned(&sc->sc_lock)); 3859 1.248 mrg 3860 1.290 riastrad /* 3861 1.290 riastrad * The caller must arrange to have aborted the pipe already, so 3862 1.290 riastrad * there can be no intr xfer in progress. The callout may 3863 1.290 riastrad * still be pending from a prior intr xfer -- if it has already 3864 1.290 riastrad * fired, it will see there is nothing to do, and do nothing. 3865 1.290 riastrad */ 3866 1.290 riastrad KASSERT(sc->sc_intr_xfer == NULL); 3867 1.290 riastrad KASSERT(!callout_pending(&sc->sc_poll_handle)); 3868 1.1 augustss } 3869