isp1763.c revision 1.1 1 /* $NetBSD: isp1763.c,v 1.1 2026/10/11 16:09:06 rkujawa Exp $ */
2
3 /*-
4 * Copyright (c) 2026 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Radoslaw Kujawa.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32 /*
33 * ISP1763A USB 2.0 host controller.
34 *
35 * The chip runs transfer descriptors via 16 slots / queue (its own memory).
36 * It's a PIO-only dumb thing, but it's less dumb than, let's say, slhci.
37 *
38 * Control and bulk run via ATL queue, interrupts via INT queue. There's an
39 * internal hub with TT, so full/low speed devices are supported.
40 *
41 * TODO: Isochronous, some other frontend driver than RapidRoad, extensive
42 * testing.
43 */
44
45 #include <sys/cdefs.h>
46 __KERNEL_RCSID(0, "$NetBSD: isp1763.c,v 1.1 2026/10/11 16:09:06 rkujawa Exp $");
47
48 #include <sys/param.h>
49 #include <sys/bus.h>
50 #include <sys/cpu.h>
51 #include <sys/device.h>
52 #include <sys/intr.h>
53 #include <sys/kernel.h>
54 #include <sys/mutex.h>
55 #include <sys/pool.h>
56 #include <sys/queue.h>
57 #include <sys/systm.h>
58
59 #include <dev/usb/usb.h>
60 #include <dev/usb/usbdi.h>
61 #include <dev/usb/usbdivar.h>
62 #include <dev/usb/usbroothub.h>
63
64 #include <dev/ic/isp1763reg.h>
65 #include <dev/ic/isp1763var.h>
66
67 #ifdef ISP1763_DEBUG
68 #define DPRINTF(...) printf(__VA_ARGS__)
69 #else
70 #define DPRINTF(...) __nothing
71 #endif
72
73 #define ISP1763_POLL_TRIES 1000 /* 1 ms each */
74 #define ISP1763_ATL_MEMSIZE 1024
75 #define ISP1763_INT_MEMSIZE 256
76 #define ISP1763_RETIRE_DELAY 250 /* us, 2 microframes */
77 #define ISP1763_SPLIT_RETIRE_DELAY 1000 /* us, full-speed frame */
78 #define ISP1763_PORT_RESET_DONE 2 /* ms */
79 #define ISP1763_USCS_SPLIT 0x1c
80 #define ISP1763_SCRATCH_TEST 0x5aa5
81 #define ISP1763_PTD_STATUS_DW 4 /* DW0-DW3 */
82
83 enum isp1763hc_phase {
84 ISP1763_PHASE_SETUP,
85 ISP1763_PHASE_DATA,
86 ISP1763_PHASE_STATUS
87 };
88
89 struct isp1763hc_pipe {
90 struct usbd_pipe ip_pipe;
91 struct isp1763hc_ptdreq ip_req;
92 struct isp1763hc_queue *ip_queue;
93 bool ip_toggle;
94 bool ip_ping;
95 };
96
97 struct isp1763hc_xfer {
98 struct usbd_xfer ix_xfer;
99 TAILQ_ENTRY(isp1763hc_xfer) ix_wait;
100 struct isp1763hc_queue *ix_queue;
101 enum isp1763hc_phase ix_phase;
102 int ix_slot;
103 uint32_t ix_off;
104 uint16_t ix_round;
105 bool ix_waiting;
106 bool ix_zlp;
107 };
108
109 #define ISP1763_BUS2SC(bus) ((struct isp1763hc_softc *)(bus)->ub_hcpriv)
110 #define ISP1763_PIPE2SC(pipe) ISP1763_BUS2SC((pipe)->up_dev->ud_bus)
111 #define ISP1763_XFER2SC(xfer) ISP1763_BUS2SC((xfer)->ux_bus)
112 #define ISP1763_PIPE2IP(pipe) ((struct isp1763hc_pipe *)(pipe))
113 #define ISP1763_XFER2IX(xfer) ((struct isp1763hc_xfer *)(xfer))
114
115 static uint32_t isp1763hc_read4(struct isp1763hc_softc *, bus_size_t);
116 static void isp1763hc_write4(struct isp1763hc_softc *, bus_size_t,
117 uint32_t);
118 static int isp1763hc_wait4(struct isp1763hc_softc *, bus_size_t,
119 uint32_t, uint32_t);
120 static void isp1763hc_set_mode(struct isp1763hc_softc *, uint16_t);
121 static int isp1763hc_swreset(struct isp1763hc_softc *, uint8_t, bool);
122 static void isp1763hc_mem_clear(struct isp1763hc_softc *);
123 static void isp1763hc_queue_init(struct isp1763hc_queue *, bus_size_t,
124 uint16_t, uint16_t, uint16_t, uint16_t);
125 static int isp1763hc_chip_reset(struct isp1763hc_softc *);
126 static int isp1763hc_chip_start(struct isp1763hc_softc *);
127 static int isp1763hc_chip_init(struct isp1763hc_softc *);
128
129 static int isp1763hc_slot_get(struct isp1763hc_queue *);
130 static void isp1763hc_slot_take(struct isp1763hc_queue *,
131 struct isp1763hc_xfer *, int);
132 static void isp1763hc_slot_put(struct isp1763hc_softc *,
133 struct isp1763hc_queue *, int);
134 static void isp1763hc_release(struct isp1763hc_softc *,
135 struct isp1763hc_xfer *);
136 static void isp1763hc_ptd_write(struct isp1763hc_softc *,
137 struct isp1763hc_queue *, int, const uint32_t *);
138 static void isp1763hc_arm(struct isp1763hc_softc *,
139 struct isp1763hc_xfer *);
140 static void isp1763hc_kick(struct isp1763hc_softc *,
141 struct isp1763hc_queue *);
142 static void isp1763hc_finish(struct isp1763hc_softc *,
143 struct isp1763hc_xfer *, usbd_status);
144 static bool isp1763hc_zlp_owed(struct isp1763hc_xfer *, u_int);
145 static bool isp1763hc_round_failed(uint32_t);
146 static bool isp1763hc_round_stalled(uint32_t);
147 static uint32_t isp1763hc_round_account(struct isp1763hc_softc *,
148 struct isp1763hc_xfer *, const uint32_t *);
149 static void isp1763hc_round_next(struct isp1763hc_softc *,
150 struct isp1763hc_xfer *, uint32_t);
151 static void isp1763hc_round_done(struct isp1763hc_softc *,
152 struct isp1763hc_xfer *, const uint32_t *);
153 static void isp1763hc_scan(struct isp1763hc_softc *,
154 struct isp1763hc_queue *);
155
156 static usbd_status isp1763hc_open(struct usbd_pipe *);
157 static void isp1763hc_softintr(void *);
158 static void isp1763hc_intr_soft(void *);
159 static void isp1763hc_poll(struct usbd_bus *);
160 static struct usbd_xfer *isp1763hc_allocx(struct usbd_bus *, unsigned int);
161 static void isp1763hc_freex(struct usbd_bus *, struct usbd_xfer *);
162 static void isp1763hc_abortx(struct usbd_xfer *);
163 static void isp1763hc_ptd_retire(struct isp1763hc_softc *,
164 struct isp1763hc_xfer *);
165 static bool isp1763hc_dying(struct usbd_bus *);
166 static void isp1763hc_get_lock(struct usbd_bus *, kmutex_t **);
167 static int isp1763hc_roothub_ctrl(struct usbd_bus *,
168 usb_device_request_t *, void *, int);
169 static int isp1763hc_roothub_ctrl_locked(struct usbd_bus *,
170 usb_device_request_t *, void *, int);
171 static int isp1763hc_roothub_hubdesc(void *, int);
172 static int isp1763hc_roothub_port_status(struct isp1763hc_softc *,
173 void *, int);
174 static int isp1763hc_roothub_port_clear(struct isp1763hc_softc *, int);
175 static int isp1763hc_roothub_port_set(struct isp1763hc_softc *, int);
176 static void isp1763hc_portsc_modify(struct isp1763hc_softc *, uint32_t,
177 uint32_t);
178 static int isp1763hc_port_reset(struct isp1763hc_softc *);
179
180 static usbd_status isp1763hc_root_intr_transfer(struct usbd_xfer *);
181 static usbd_status isp1763hc_root_intr_start(struct usbd_xfer *);
182 static void isp1763hc_root_intr_abort(struct usbd_xfer *);
183 static void isp1763hc_root_intr_close(struct usbd_pipe *);
184 static void isp1763hc_root_intr_done(struct usbd_xfer *);
185
186 static usbd_status isp1763hc_device_transfer(struct usbd_xfer *);
187 static usbd_status isp1763hc_device_start(struct usbd_xfer *);
188 static void isp1763hc_device_abort(struct usbd_xfer *);
189 static void isp1763hc_device_close(struct usbd_pipe *);
190 static void isp1763hc_device_clear_toggle(struct usbd_pipe *);
191 static void isp1763hc_device_done(struct usbd_xfer *);
192
193 static const struct usbd_bus_methods isp1763hc_bus_methods = {
194 .ubm_open = isp1763hc_open,
195 .ubm_softint = isp1763hc_softintr,
196 .ubm_dopoll = isp1763hc_poll,
197 .ubm_allocx = isp1763hc_allocx,
198 .ubm_freex = isp1763hc_freex,
199 .ubm_abortx = isp1763hc_abortx,
200 .ubm_dying = isp1763hc_dying,
201 .ubm_getlock = isp1763hc_get_lock,
202 .ubm_rhctrl = isp1763hc_roothub_ctrl,
203 };
204
205 static const struct usbd_pipe_methods isp1763hc_root_intr_methods = {
206 .upm_transfer = isp1763hc_root_intr_transfer,
207 .upm_start = isp1763hc_root_intr_start,
208 .upm_abort = isp1763hc_root_intr_abort,
209 .upm_close = isp1763hc_root_intr_close,
210 .upm_cleartoggle = isp1763hc_device_clear_toggle,
211 .upm_done = isp1763hc_root_intr_done,
212 };
213
214 static const struct usbd_pipe_methods isp1763hc_device_methods = {
215 .upm_transfer = isp1763hc_device_transfer,
216 .upm_start = isp1763hc_device_start,
217 .upm_abort = isp1763hc_device_abort,
218 .upm_close = isp1763hc_device_close,
219 .upm_cleartoggle = isp1763hc_device_clear_toggle,
220 .upm_done = isp1763hc_device_done,
221 };
222
223 static const uint8_t isp1763hc_zero[64];
224
225 static uint32_t
226 isp1763hc_read4(struct isp1763hc_softc *sc, bus_size_t reg)
227 {
228 uint32_t lo;
229
230 lo = ISP_READ2(sc, reg);
231
232 return lo | ((uint32_t)ISP_READ2(sc, reg + 2) << 16);
233 }
234
235 static void
236 isp1763hc_write4(struct isp1763hc_softc *sc, bus_size_t reg, uint32_t val)
237 {
238
239 ISP_WRITE2(sc, reg, val & 0xffff);
240 ISP_WRITE2(sc, reg + 2, val >> 16);
241 }
242
243 static int
244 isp1763hc_wait4(struct isp1763hc_softc *sc, bus_size_t reg, uint32_t mask,
245 uint32_t want)
246 {
247 int i;
248
249 for (i = 0; i < ISP1763_POLL_TRIES; i++) {
250 if ((isp1763hc_read4(sc, reg) & mask) == want)
251 return 0;
252 delay(1000);
253 }
254
255 return ETIMEDOUT;
256 }
257
258 static void
259 isp1763hc_set_mode(struct isp1763hc_softc *sc, uint16_t extra)
260 {
261 uint16_t mode;
262
263 mode = sc->sc_hwmode | ISP1763_HWMODE_INTFLOCK |
264 ISP1763_HWMODE_INTPOL | extra;
265
266 ISP_WRITE1(sc, ISP1763_HWMODE, mode & 0xff);
267 ISP_WRITE2(sc, ISP1763_HWMODE, mode);
268 }
269
270 static int
271 isp1763hc_swreset(struct isp1763hc_softc *sc, uint8_t bit, bool pulse)
272 {
273 int i;
274
275 ISP_WRITE1(sc, ISP1763_SWRESET, bit);
276 ISP_WRITE1(sc, ISP1763_SWRESET, bit);
277 if (pulse) {
278 delay(10000);
279 ISP_WRITE1(sc, ISP1763_SWRESET, 0);
280 ISP_WRITE1(sc, ISP1763_SWRESET, 0);
281 }
282
283 for (i = 0; i < ISP1763_POLL_TRIES; i++) {
284 if (((ISP_READ1(sc, ISP1763_SWRESET) |
285 ISP_READ1(sc, ISP1763_SWRESET)) & bit) == 0)
286 return 0;
287 delay(1000);
288 }
289
290 return ETIMEDOUT;
291 }
292
293 static void
294 isp1763hc_mem_clear(struct isp1763hc_softc *sc)
295 {
296 uint16_t a;
297
298 for (a = ISP1763_ISO_PTD_BASE; a < ISP1763_MEM_END;
299 a += sizeof(isp1763hc_zero))
300 ISP_MEMWRITE(sc, a, isp1763hc_zero, sizeof(isp1763hc_zero));
301 }
302
303 static void
304 isp1763hc_queue_init(struct isp1763hc_queue *q, bus_size_t regdone,
305 uint16_t irq, uint16_t ptdbase, uint16_t membase, uint16_t memsize)
306 {
307
308 memset(q, 0, sizeof(*q));
309 TAILQ_INIT(&q->q_wait);
310
311 q->q_regdone = regdone;
312 q->q_regskip = regdone + 2;
313 q->q_reglast = regdone + 4;
314 q->q_irq = irq;
315 q->q_ptdbase = ptdbase;
316 q->q_membase = membase;
317 q->q_memsize = memsize;
318 q->q_skip = 0xffff;
319 }
320
321 static int
322 isp1763hc_chip_reset(struct isp1763hc_softc *sc)
323 {
324 uint32_t id;
325
326 /* reset everything */
327 if (isp1763hc_swreset(sc, ISP1763_SWRESET_ALL, true) != 0 ||
328 isp1763hc_swreset(sc, ISP1763_SWRESET_HC, false) != 0) {
329 aprint_error_dev(sc->sc_dev, "software reset timed out\n");
330 return ETIMEDOUT;
331 }
332
333 ISP_WRITE1(sc, ISP1763_SWRESET, ISP1763_SWRESET_ATX);
334 ISP_WRITE1(sc, ISP1763_SWRESET, ISP1763_SWRESET_ATX);
335 delay(1000);
336 ISP_WRITE1(sc, ISP1763_SWRESET, 0);
337 ISP_WRITE1(sc, ISP1763_SWRESET, 0);
338 isp1763hc_set_mode(sc, 0);
339
340 id = isp1763hc_read4(sc, ISP1763_CHIPID);
341 ISP_WRITE2(sc, ISP1763_SCRATCH, ISP1763_SCRATCH_TEST);
342 (void)isp1763hc_read4(sc, ISP1763_CHIPID);
343
344 /* make sure chip is alive */
345 if (id != ISP1763_CHIPID_VALUE ||
346 ISP_READ2(sc, ISP1763_SCRATCH) != ISP1763_SCRATCH_TEST) {
347 aprint_error_dev(sc->sc_dev, "chip id 0x%08x, bad scratch\n",
348 id);
349 return ENXIO;
350 }
351
352 isp1763hc_write4(sc, ISP1763_USBCMD, ISP1763_USBCMD_HCRESET);
353 if (isp1763hc_wait4(sc, ISP1763_USBCMD, ISP1763_USBCMD_HCRESET,
354 0) != 0) {
355 aprint_error_dev(sc->sc_dev, "controller reset timed out\n");
356 return ETIMEDOUT;
357 }
358
359 return 0;
360 }
361
362 static int
363 isp1763hc_chip_start(struct isp1763hc_softc *sc)
364 {
365
366 isp1763hc_set_mode(sc, 0);
367 ISP_WRITE2(sc, ISP1763_BUFSTS, 0);
368 isp1763hc_mem_clear(sc);
369
370 ISP_WRITE2(sc, ISP1763_ISO_SKIP, 0xffff);
371 ISP_WRITE2(sc, ISP1763_INT_SKIP, 0xffff);
372 ISP_WRITE2(sc, ISP1763_ATL_SKIP, 0xffff);
373 ISP_WRITE2(sc, ISP1763_ISO_LAST, isp1763hc_last_map(0));
374 ISP_WRITE2(sc, ISP1763_INT_LAST, isp1763hc_last_map(0));
375 ISP_WRITE2(sc, ISP1763_ATL_LAST, isp1763hc_last_map(0));
376 (void)ISP_READ2(sc, ISP1763_INT_DONE);
377 (void)ISP_READ2(sc, ISP1763_ATL_DONE);
378
379 isp1763hc_write4(sc, ISP1763_USBSTS,
380 ISP1763_USBSTS_PCD | ISP1763_USBSTS_FLR);
381 isp1763hc_write4(sc, ISP1763_USBINTR, 0);
382 ISP_WRITE2(sc, ISP1763_HCINT, ISP1763_HCINT_ALL);
383 ISP_WRITE2(sc, ISP1763_HCINTEN, ISP1763_HCINT_ATL | ISP1763_HCINT_INT);
384 ISP_WRITE2(sc, ISP1763_INT_ORMASK, 0xffff);
385 ISP_WRITE2(sc, ISP1763_ATL_ORMASK, 0xffff);
386 ISP_WRITE2(sc, ISP1763_INT_ANDMASK, 0);
387 ISP_WRITE2(sc, ISP1763_ATL_ANDMASK, 0);
388 ISP_WRITE2(sc, ISP1763_BUFSTS, ISP1763_BUFSTS_ATL | ISP1763_BUFSTS_INT);
389
390 ISP_WRITE2(sc, ISP1763_OTGCTL_SET, ISP1763_OTGCTL_OTGDIS);
391 ISP_WRITE2(sc, ISP1763_OTGCTL_CLR, ISP1763_OTGCTL_SWSELHC);
392 ISP_WRITE2(sc, ISP1763_OTGCTL_CLR, ISP1763_OTGCTL_HC2DIS);
393
394 isp1763hc_write4(sc, ISP1763_USBCMD, ISP1763_USBCMD_RS);
395 delay(10000);
396 isp1763hc_write4(sc, ISP1763_CONFIGFLAG, ISP1763_CONFIGFLAG_CF);
397 delay(1000);
398 isp1763hc_write4(sc, ISP1763_PORTSC1, ISP1763_PORTSC_PP);
399 delay(50000);
400
401 /* internal hub sits on the root port */
402 if (isp1763hc_wait4(sc, ISP1763_PORTSC1, ISP1763_PORTSC_ECCS,
403 ISP1763_PORTSC_ECCS) != 0) {
404 aprint_error_dev(sc->sc_dev, "internal hub not connected\n");
405 return ETIMEDOUT;
406 }
407
408 isp1763hc_set_mode(sc, ISP1763_HWMODE_GLINTEN);
409
410 return 0;
411 }
412
413 static int
414 isp1763hc_chip_init(struct isp1763hc_softc *sc)
415 {
416 int error;
417
418 error = isp1763hc_chip_reset(sc);
419 if (error != 0)
420 return error;
421
422 return isp1763hc_chip_start(sc);
423 }
424
425 int
426 isp1763hc_attach(struct isp1763hc_softc *sc)
427 {
428 int error;
429
430 mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_SOFTUSB);
431 mutex_init(&sc->sc_rhlock, MUTEX_DEFAULT, IPL_NONE);
432
433 isp1763hc_queue_init(&sc->sc_atl, ISP1763_ATL_DONE,
434 ISP1763_HCINT_ATL, ISP1763_ATL_PTD_BASE, ISP1763_PAYLOAD_BASE,
435 ISP1763_ATL_MEMSIZE);
436 isp1763hc_queue_init(&sc->sc_int, ISP1763_INT_DONE,
437 ISP1763_HCINT_INT, ISP1763_INT_PTD_BASE,
438 ISP1763_PAYLOAD_BASE + ISP1763_NSLOTS * ISP1763_ATL_MEMSIZE,
439 ISP1763_INT_MEMSIZE);
440
441 error = isp1763hc_chip_init(sc);
442 if (error != 0) {
443 mutex_destroy(&sc->sc_rhlock);
444 mutex_destroy(&sc->sc_lock);
445 return error;
446 }
447
448 sc->sc_xferpool = pool_cache_init(sizeof(struct isp1763hc_xfer), 0,
449 0, 0, "isp1763xfer", NULL, IPL_USB, NULL, NULL, NULL);
450 sc->sc_softint = softint_establish(SOFTINT_USB | SOFTINT_MPSAFE,
451 isp1763hc_intr_soft, sc);
452
453 sc->sc_bus.ub_methods = &isp1763hc_bus_methods;
454 sc->sc_bus.ub_pipesize = sizeof(struct isp1763hc_pipe);
455 sc->sc_bus.ub_revision = USBREV_2_0;
456 sc->sc_bus.ub_usedma = false;
457 sc->sc_bus.ub_hcpriv = sc;
458
459 sc->sc_child = config_found(sc->sc_dev, &sc->sc_bus, usbctlprint,
460 CFARGS_NONE);
461
462 ISP_INTR_ENABLE(sc, true);
463
464 return 0;
465 }
466
467 int
468 isp1763hc_detach(struct isp1763hc_softc *sc, int flags)
469 {
470 int error;
471
472 if (sc->sc_child != NULL) {
473 error = config_detach(sc->sc_child, flags);
474 if (error != 0)
475 return error;
476 }
477
478 mutex_enter(&sc->sc_lock);
479 sc->sc_dying = true;
480 mutex_exit(&sc->sc_lock);
481
482 isp1763hc_shutdown(sc);
483
484 softint_disestablish(sc->sc_softint);
485 pool_cache_destroy(sc->sc_xferpool);
486 mutex_destroy(&sc->sc_rhlock);
487 mutex_destroy(&sc->sc_lock);
488
489 return 0;
490 }
491
492 int
493 isp1763hc_activate(device_t self, enum devact act)
494 {
495 struct isp1763hc_softc *sc = device_private(self);
496
497 switch (act) {
498 case DVACT_DEACTIVATE:
499 sc->sc_dying = true;
500 return 0;
501 default:
502 return EOPNOTSUPP;
503 }
504 }
505
506 void
507 isp1763hc_childdet(device_t self, device_t child)
508 {
509 struct isp1763hc_softc *sc = device_private(self);
510
511 KASSERT(sc->sc_child == child);
512 sc->sc_child = NULL;
513 }
514
515 void
516 isp1763hc_shutdown(struct isp1763hc_softc *sc)
517 {
518
519 ISP_INTR_ENABLE(sc, false);
520 isp1763hc_set_mode(sc, 0);
521 isp1763hc_write4(sc, ISP1763_USBCMD, ISP1763_USBCMD_HCRESET);
522 }
523
524 void
525 isp1763hc_intr(struct isp1763hc_softc *sc)
526 {
527
528 kpreempt_disable();
529 softint_schedule(sc->sc_softint);
530 kpreempt_enable();
531 }
532
533 static void
534 isp1763hc_intr_soft(void *arg)
535 {
536 struct isp1763hc_softc *sc = arg;
537
538 mutex_enter(&sc->sc_lock);
539 isp1763hc_softintr(&sc->sc_bus);
540 mutex_exit(&sc->sc_lock);
541 }
542
543 static int
544 isp1763hc_slot_get(struct isp1763hc_queue *q)
545 {
546 int slot;
547
548 for (slot = 0; slot < ISP1763_NSLOTS; slot++) {
549 if ((q->q_busy & __BIT(slot)) == 0)
550 return slot;
551 }
552
553 return -1;
554 }
555
556 static void
557 isp1763hc_slot_take(struct isp1763hc_queue *q, struct isp1763hc_xfer *ix,
558 int slot)
559 {
560
561 ix->ix_slot = slot;
562 q->q_xfer[slot] = ix;
563 q->q_busy |= __BIT(slot);
564 }
565
566 static void
567 isp1763hc_slot_put(struct isp1763hc_softc *sc, struct isp1763hc_queue *q,
568 int slot)
569 {
570
571 q->q_xfer[slot] = NULL;
572 q->q_busy &= ~__BIT(slot);
573 q->q_skip |= __BIT(slot);
574 if (sc->sc_dying)
575 return;
576
577 ISP_WRITE2(sc, q->q_regskip, q->q_skip);
578 ISP_WRITE2(sc, q->q_reglast, isp1763hc_last_map(q->q_busy));
579 }
580
581 static void
582 isp1763hc_release(struct isp1763hc_softc *sc, struct isp1763hc_xfer *ix)
583 {
584 struct isp1763hc_queue *q = ix->ix_queue;
585
586 isp1763hc_slot_put(sc, q, ix->ix_slot);
587 ix->ix_slot = -1;
588 isp1763hc_kick(sc, q);
589 }
590
591 static void
592 isp1763hc_ptd_write(struct isp1763hc_softc *sc, struct isp1763hc_queue *q,
593 int slot, const uint32_t *dw)
594 {
595 uint8_t buf[ISP1763_PTD_SIZE];
596 uint16_t ptd;
597
598 ptd = q->q_ptdbase + slot * ISP1763_PTD_SIZE;
599 isp1763hc_ptd_encode(dw, buf, ISP1763_PTD_SIZE / 4);
600
601 /* slot is skipped while its descriptor is written */
602 q->q_skip |= __BIT(slot);
603 ISP_WRITE2(sc, q->q_regskip, q->q_skip);
604
605 ISP_MEMWRITE(sc, ptd + 4, buf + 4, ISP1763_PTD_SIZE - 4);
606 ISP_MEMWRITE(sc, ptd, buf, 4);
607 ISP_WRITE2(sc, q->q_reglast, isp1763hc_last_map(q->q_busy));
608
609 q->q_skip &= ~__BIT(slot);
610 ISP_WRITE2(sc, q->q_regskip, q->q_skip);
611 }
612
613 static void
614 isp1763hc_arm(struct isp1763hc_softc *sc, struct isp1763hc_xfer *ix)
615 {
616 struct usbd_xfer *xfer = &ix->ix_xfer;
617 struct isp1763hc_pipe *ip = ISP1763_PIPE2IP(xfer->ux_pipe);
618 struct isp1763hc_queue *q = ix->ix_queue;
619 usb_endpoint_descriptor_t *ed;
620 struct isp1763hc_ptdreq pr;
621 uint32_t dw[ISP1763_PTD_SIZE / 4];
622 bool isread;
623
624 ed = xfer->ux_pipe->up_endpoint->ue_edesc;
625 isread = usbd_xfer_isread(xfer);
626
627 pr = ip->ip_req;
628 pr.pr_addr = xfer->ux_pipe->up_dev->ud_addr;
629 pr.pr_mps = UE_GET_SIZE(UGETW(ed->wMaxPacketSize));
630 pr.pr_mem = q->q_membase + ix->ix_slot * q->q_memsize;
631
632 switch (ix->ix_phase) {
633 case ISP1763_PHASE_SETUP:
634 pr.pr_token = ISP1763_TOKEN_SETUP;
635 pr.pr_len = sizeof(xfer->ux_request);
636 ISP_MEMWRITE(sc, pr.pr_mem, &xfer->ux_request, pr.pr_len);
637 break;
638 case ISP1763_PHASE_DATA:
639 pr.pr_token = isread ? ISP1763_TOKEN_IN : ISP1763_TOKEN_OUT;
640 pr.pr_len = MIN(xfer->ux_length - ix->ix_off, q->q_memsize);
641 pr.pr_toggle = ip->ip_toggle;
642 pr.pr_ping = ip->ip_ping && !isread;
643 if (!isread && pr.pr_len > 0) {
644 ISP_MEMWRITE(sc, pr.pr_mem,
645 (uint8_t *)xfer->ux_buf + ix->ix_off, pr.pr_len);
646 }
647 break;
648 case ISP1763_PHASE_STATUS:
649 pr.pr_token = isread && xfer->ux_length > 0 ?
650 ISP1763_TOKEN_OUT : ISP1763_TOKEN_IN;
651 pr.pr_len = 0;
652 pr.pr_toggle = true;
653 break;
654 }
655 ix->ix_round = pr.pr_len;
656
657 isp1763hc_ptd_build(&pr, dw);
658 isp1763hc_ptd_write(sc, q, ix->ix_slot, dw);
659 }
660
661 /* Give free slots to waiting transfers. */
662 static void
663 isp1763hc_kick(struct isp1763hc_softc *sc, struct isp1763hc_queue *q)
664 {
665 struct isp1763hc_xfer *ix;
666 int slot;
667
668 while ((ix = TAILQ_FIRST(&q->q_wait)) != NULL &&
669 (slot = isp1763hc_slot_get(q)) >= 0) {
670 TAILQ_REMOVE(&q->q_wait, ix, ix_wait);
671 ix->ix_waiting = false;
672 isp1763hc_slot_take(q, ix, slot);
673 isp1763hc_arm(sc, ix);
674 }
675 }
676
677 static void
678 isp1763hc_finish(struct isp1763hc_softc *sc, struct isp1763hc_xfer *ix,
679 usbd_status status)
680 {
681 struct usbd_xfer *xfer = &ix->ix_xfer;
682
683 isp1763hc_release(sc, ix);
684
685 if (!usbd_xfer_trycomplete(xfer))
686 return;
687 xfer->ux_actlen = ix->ix_off;
688 xfer->ux_status = status;
689 usb_transfer_complete(xfer);
690 }
691
692 static bool
693 isp1763hc_zlp_owed(struct isp1763hc_xfer *ix, u_int mps)
694 {
695 struct usbd_xfer *xfer = &ix->ix_xfer;
696
697 if (ix->ix_zlp || usbd_xfer_isread(xfer))
698 return false;
699 if ((xfer->ux_flags & USBD_FORCE_SHORT_XFER) == 0)
700 return false;
701
702 return xfer->ux_length % mps == 0;
703 }
704
705 /* Something messed up. */
706 static bool
707 isp1763hc_round_failed(uint32_t dw3)
708 {
709
710 return (dw3 & (ISP1763_PTD_DW3_H | ISP1763_PTD_DW3_X |
711 ISP1763_PTD_DW3_B)) != 0;
712 }
713
714 static bool
715 isp1763hc_round_stalled(uint32_t dw3)
716 {
717
718 return (dw3 & ISP1763_PTD_DW3_H) != 0 &&
719 (dw3 & (ISP1763_PTD_DW3_X | ISP1763_PTD_DW3_B)) == 0 &&
720 __SHIFTOUT(dw3, ISP1763_PTD_DW3_CERR) != 0;
721 }
722
723 static uint32_t
724 isp1763hc_round_account(struct isp1763hc_softc *sc, struct isp1763hc_xfer *ix,
725 const uint32_t *dw)
726 {
727 struct usbd_xfer *xfer = &ix->ix_xfer;
728 struct isp1763hc_pipe *ip = ISP1763_PIPE2IP(xfer->ux_pipe);
729 struct isp1763hc_queue *q = ix->ix_queue;
730 uint32_t n;
731
732 ip->ip_toggle = (dw[3] & ISP1763_PTD_DW3_DT) != 0;
733 ip->ip_ping = q == &sc->sc_atl && !ip->ip_req.pr_split &&
734 (dw[3] & ISP1763_PTD_DW3_PING) != 0;
735 if (ix->ix_phase != ISP1763_PHASE_DATA)
736 return 0;
737
738 if (ip->ip_req.pr_split)
739 n = __SHIFTOUT(dw[3], ISP1763_PTD_DW3_NDONE_SPLIT);
740 else
741 n = __SHIFTOUT(dw[3], ISP1763_PTD_DW3_NDONE);
742 n = MIN(n, ix->ix_round);
743
744 if (usbd_xfer_isread(xfer) && n > 0) {
745 ISP_MEMREAD(sc, q->q_membase + ix->ix_slot * q->q_memsize,
746 (uint8_t *)xfer->ux_buf + ix->ix_off, n);
747 }
748 ix->ix_off += n;
749
750 return n;
751 }
752
753 static void
754 isp1763hc_round_next(struct isp1763hc_softc *sc, struct isp1763hc_xfer *ix,
755 uint32_t n)
756 {
757 struct usbd_xfer *xfer = &ix->ix_xfer;
758 struct isp1763hc_pipe *ip = ISP1763_PIPE2IP(xfer->ux_pipe);
759 usb_endpoint_descriptor_t *ed;
760
761 switch (ix->ix_phase) {
762 case ISP1763_PHASE_SETUP:
763 ip->ip_toggle = true;
764 ix->ix_phase = xfer->ux_length > 0 ?
765 ISP1763_PHASE_DATA : ISP1763_PHASE_STATUS;
766 isp1763hc_arm(sc, ix);
767 return;
768 case ISP1763_PHASE_STATUS:
769 isp1763hc_finish(sc, ix, USBD_NORMAL_COMPLETION);
770 return;
771 case ISP1763_PHASE_DATA:
772 break;
773 }
774
775 if (n == ix->ix_round && ix->ix_off < xfer->ux_length) {
776 isp1763hc_arm(sc, ix);
777 return;
778 }
779
780 ed = xfer->ux_pipe->up_endpoint->ue_edesc;
781 if (UE_GET_XFERTYPE(ed->bmAttributes) == UE_CONTROL) {
782 ix->ix_phase = ISP1763_PHASE_STATUS;
783 isp1763hc_arm(sc, ix);
784 return;
785 }
786 if (isp1763hc_zlp_owed(ix, UE_GET_SIZE(UGETW(ed->wMaxPacketSize)))) {
787 ix->ix_zlp = true;
788 isp1763hc_arm(sc, ix);
789 return;
790 }
791
792 isp1763hc_finish(sc, ix, USBD_NORMAL_COMPLETION);
793 }
794
795 static void
796 isp1763hc_round_done(struct isp1763hc_softc *sc, struct isp1763hc_xfer *ix,
797 const uint32_t *dw)
798 {
799 uint32_t n;
800
801 if (isp1763hc_round_failed(dw[3])) {
802 DPRINTF("%s: error dw3 0x%08x\n", device_xname(sc->sc_dev),
803 dw[3]);
804 isp1763hc_finish(sc, ix, isp1763hc_round_stalled(dw[3]) ?
805 USBD_STALLED : USBD_IOERROR);
806 return;
807 }
808
809 n = isp1763hc_round_account(sc, ix, dw);
810
811 /* chip gave up round up */
812 if ((dw[3] & ISP1763_PTD_DW3_A) != 0) {
813 isp1763hc_arm(sc, ix);
814 return;
815 }
816
817 isp1763hc_round_next(sc, ix, n);
818 }
819
820 static void
821 isp1763hc_scan(struct isp1763hc_softc *sc, struct isp1763hc_queue *q)
822 {
823 uint8_t buf[ISP1763_PTD_STATUS_DW * 4];
824 uint32_t dw[ISP1763_PTD_STATUS_DW];
825 int slot;
826
827 /* Read back the done maps (but they are a hint only). */
828 for (slot = 0; slot < ISP1763_NSLOTS; slot++) {
829 if ((q->q_busy & __BIT(slot)) == 0)
830 continue;
831
832 ISP_MEMREAD(sc, q->q_ptdbase + slot * ISP1763_PTD_SIZE, buf,
833 sizeof(buf));
834 isp1763hc_ptd_decode(buf, dw, ISP1763_PTD_STATUS_DW);
835 if ((dw[0] & ISP1763_PTD_DW0_V) != 0)
836 continue;
837
838 isp1763hc_round_done(sc, q->q_xfer[slot], dw);
839 }
840 }
841
842 static void
843 isp1763hc_softintr(void *v)
844 {
845 struct usbd_bus *bus = v;
846 struct isp1763hc_softc *sc = ISP1763_BUS2SC(bus);
847 uint16_t atldone, hcint, intdone;
848
849 KASSERT(bus->ub_usepolling || mutex_owned(&sc->sc_lock));
850
851 if (sc->sc_dying)
852 return;
853
854 hcint = ISP_READ2(sc, ISP1763_HCINT);
855 intdone = ISP_READ2(sc, ISP1763_INT_DONE);
856 atldone = ISP_READ2(sc, ISP1763_ATL_DONE);
857 if (hcint != 0)
858 ISP_WRITE2(sc, ISP1763_HCINT, hcint);
859
860 if ((hcint & sc->sc_atl.q_irq) != 0 || atldone != 0 ||
861 bus->ub_usepolling)
862 isp1763hc_scan(sc, &sc->sc_atl);
863 if ((hcint & sc->sc_int.q_irq) != 0 || intdone != 0 ||
864 bus->ub_usepolling)
865 isp1763hc_scan(sc, &sc->sc_int);
866
867 ISP_INTR_ENABLE(sc, true);
868 }
869
870 static void
871 isp1763hc_poll(struct usbd_bus *bus)
872 {
873
874 isp1763hc_softintr(bus);
875 }
876
877 static usbd_status
878 isp1763hc_open(struct usbd_pipe *pipe)
879 {
880 struct isp1763hc_softc *sc = ISP1763_PIPE2SC(pipe);
881 struct isp1763hc_pipe *ip = ISP1763_PIPE2IP(pipe);
882 struct usbd_device *dev = pipe->up_dev;
883 usb_endpoint_descriptor_t *ed = pipe->up_endpoint->ue_edesc;
884 struct isp1763hc_ptdreq *pr = &ip->ip_req;
885 u_int mps, mult;
886 int ival;
887
888 if (sc->sc_dying)
889 return USBD_IOERROR;
890
891 if (dev->ud_addr == dev->ud_bus->ub_rhaddr) {
892 switch (ed->bEndpointAddress) {
893 case USB_CONTROL_ENDPOINT:
894 pipe->up_methods = &roothub_ctrl_methods;
895 return USBD_NORMAL_COMPLETION;
896 case UE_DIR_IN | USBROOTHUB_INTR_ENDPT:
897 pipe->up_methods = &isp1763hc_root_intr_methods;
898 return USBD_NORMAL_COMPLETION;
899 default:
900 return USBD_INVAL;
901 }
902 }
903
904 memset(pr, 0, sizeof(*pr));
905 pr->pr_ep = UE_GET_ADDR(ed->bEndpointAddress);
906 mps = UE_GET_SIZE(UGETW(ed->wMaxPacketSize));
907 mult = UE_GET_TRANS(UGETW(ed->wMaxPacketSize)) + 1;
908
909 if (dev->ud_speed != USB_SPEED_HIGH) {
910 if (dev->ud_myhsport == NULL)
911 return USBD_INVAL;
912 pr->pr_split = true;
913 pr->pr_hub = dev->ud_myhsport->up_parent->ud_addr;
914 pr->pr_port = dev->ud_myhsport->up_portno;
915 pr->pr_se = dev->ud_speed == USB_SPEED_LOW ?
916 ISP1763_SE_LOW : ISP1763_SE_FULL;
917 } else {
918 pr->pr_mult = mult;
919 }
920
921 switch (UE_GET_XFERTYPE(ed->bmAttributes)) {
922 case UE_CONTROL:
923 pr->pr_eptype = ISP1763_EPTYPE_CTRL;
924 ip->ip_queue = &sc->sc_atl;
925 break;
926 case UE_BULK:
927 pr->pr_eptype = ISP1763_EPTYPE_BULK;
928 ip->ip_queue = &sc->sc_atl;
929 break;
930 case UE_INTERRUPT:
931 if (mps * mult > ISP1763_INT_MEMSIZE)
932 return USBD_INVAL;
933 pr->pr_eptype = ISP1763_EPTYPE_INTR;
934 ival = pipe->up_interval;
935 if (ival == USBD_DEFAULT_INTERVAL)
936 ival = ed->bInterval;
937 isp1763hc_intr_sched(!pr->pr_split, ival, &pr->pr_uframe,
938 &pr->pr_usa);
939 if (pr->pr_split)
940 pr->pr_uscs = ISP1763_USCS_SPLIT;
941 ip->ip_queue = &sc->sc_int;
942 break;
943 default:
944 return USBD_INVAL;
945 }
946
947 ip->ip_toggle = pipe->up_endpoint->ue_toggle != 0;
948 ip->ip_ping = false;
949 pipe->up_methods = &isp1763hc_device_methods;
950
951 return USBD_NORMAL_COMPLETION;
952 }
953
954 static struct usbd_xfer *
955 isp1763hc_allocx(struct usbd_bus *bus, unsigned int nframes)
956 {
957 struct isp1763hc_softc *sc = ISP1763_BUS2SC(bus);
958 struct usbd_xfer *xfer;
959
960 xfer = pool_cache_get(sc->sc_xferpool, PR_WAITOK);
961 if (xfer != NULL) {
962 memset(xfer, 0, sizeof(struct isp1763hc_xfer));
963 ISP1763_XFER2IX(xfer)->ix_slot = -1;
964 #ifdef DIAGNOSTIC
965 xfer->ux_state = XFER_BUSY;
966 #endif
967 }
968
969 return xfer;
970 }
971
972 static void
973 isp1763hc_freex(struct usbd_bus *bus, struct usbd_xfer *xfer)
974 {
975 struct isp1763hc_softc *sc = ISP1763_BUS2SC(bus);
976
977 KASSERTMSG(xfer->ux_state == XFER_BUSY ||
978 xfer->ux_status == USBD_NOT_STARTED,
979 "xfer %p state %d\n", xfer, xfer->ux_state);
980 #ifdef DIAGNOSTIC
981 xfer->ux_state = XFER_FREE;
982 #endif
983
984 pool_cache_put(sc->sc_xferpool, xfer);
985 }
986
987 /* Get descriptor off the chip. */
988 static void
989 isp1763hc_ptd_retire(struct isp1763hc_softc *sc, struct isp1763hc_xfer *ix)
990 {
991 struct isp1763hc_pipe *ip = ISP1763_PIPE2IP(ix->ix_xfer.ux_pipe);
992 struct isp1763hc_queue *q = ix->ix_queue;
993 uint8_t buf[ISP1763_PTD_STATUS_DW * 4];
994 uint32_t dw[ISP1763_PTD_STATUS_DW];
995 uint16_t ptd;
996
997 ptd = q->q_ptdbase + ix->ix_slot * ISP1763_PTD_SIZE;
998
999 if (q == &sc->sc_atl && ip->ip_req.pr_split) {
1000 ISP_MEMREAD(sc, ptd + 4, buf, 4);
1001
1002 isp1763hc_ptd_decode(buf, dw, 1);
1003 dw[0] |= ISP1763_PTD_DW1_RETIRE;
1004 isp1763hc_ptd_encode(dw, buf, 1);
1005
1006 ISP_MEMWRITE(sc, ptd + 4, buf, 4);
1007
1008 delay(ISP1763_SPLIT_RETIRE_DELAY);
1009 }
1010
1011 q->q_skip |= __BIT(ix->ix_slot);
1012 ISP_WRITE2(sc, q->q_regskip, q->q_skip);
1013
1014 ISP_MEMREAD(sc, ptd, buf, sizeof(buf));
1015 isp1763hc_ptd_decode(buf, dw, ISP1763_PTD_STATUS_DW);
1016 ip->ip_toggle = (dw[3] & ISP1763_PTD_DW3_DT) != 0;
1017 dw[0] &= ~ISP1763_PTD_DW0_V;
1018 isp1763hc_ptd_encode(dw, buf, 1);
1019 ISP_MEMWRITE(sc, ptd, buf, 4);
1020
1021 delay(ISP1763_RETIRE_DELAY);
1022 }
1023
1024 /* Get a transfer off the queue. */
1025 static void
1026 isp1763hc_abortx(struct usbd_xfer *xfer)
1027 {
1028 struct isp1763hc_softc *sc = ISP1763_XFER2SC(xfer);
1029 struct isp1763hc_xfer *ix = ISP1763_XFER2IX(xfer);
1030 struct isp1763hc_queue *q = ix->ix_queue;
1031
1032 KASSERT(mutex_owned(&sc->sc_lock));
1033 KASSERTMSG(xfer->ux_status == USBD_CANCELLED ||
1034 xfer->ux_status == USBD_TIMEOUT,
1035 "bad abort status: %d", xfer->ux_status);
1036
1037 if (ix->ix_waiting) {
1038 TAILQ_REMOVE(&q->q_wait, ix, ix_wait);
1039 ix->ix_waiting = false;
1040 return;
1041 }
1042 if (ix->ix_slot < 0)
1043 return;
1044
1045 if (!sc->sc_dying)
1046 isp1763hc_ptd_retire(sc, ix);
1047
1048 isp1763hc_release(sc, ix);
1049 }
1050
1051 static bool
1052 isp1763hc_dying(struct usbd_bus *bus)
1053 {
1054 struct isp1763hc_softc *sc = ISP1763_BUS2SC(bus);
1055
1056 return sc->sc_dying;
1057 }
1058
1059 static void
1060 isp1763hc_get_lock(struct usbd_bus *bus, kmutex_t **lock)
1061 {
1062 struct isp1763hc_softc *sc = ISP1763_BUS2SC(bus);
1063
1064 *lock = &sc->sc_lock;
1065 }
1066
1067 static int
1068 isp1763hc_roothub_ctrl(struct usbd_bus *bus, usb_device_request_t *req,
1069 void *buf, int buflen)
1070 {
1071 struct isp1763hc_softc *sc = ISP1763_BUS2SC(bus);
1072 int actlen;
1073
1074 mutex_enter(&sc->sc_rhlock);
1075 actlen = isp1763hc_roothub_ctrl_locked(bus, req, buf, buflen);
1076 mutex_exit(&sc->sc_rhlock);
1077
1078 return actlen;
1079 }
1080
1081 static int
1082 isp1763hc_port_reset(struct isp1763hc_softc *sc)
1083 {
1084 uint32_t v;
1085
1086 mutex_enter(&sc->sc_lock);
1087 v = isp1763hc_read4(sc, ISP1763_PORTSC1) &
1088 ~(ISP1763_PORTSC_PED | ISP1763_PORTSC_ECSC);
1089 isp1763hc_write4(sc, ISP1763_PORTSC1, v | ISP1763_PORTSC_PR);
1090 mutex_exit(&sc->sc_lock);
1091
1092 usb_delay_ms(&sc->sc_bus, USB_PORT_ROOT_RESET_DELAY);
1093 if (sc->sc_dying)
1094 return -1;
1095
1096 mutex_enter(&sc->sc_lock);
1097 v = isp1763hc_read4(sc, ISP1763_PORTSC1) & ~ISP1763_PORTSC_ECSC;
1098 isp1763hc_write4(sc, ISP1763_PORTSC1, v & ~ISP1763_PORTSC_PR);
1099 mutex_exit(&sc->sc_lock);
1100
1101 usb_delay_ms(&sc->sc_bus, ISP1763_PORT_RESET_DONE);
1102 if (sc->sc_dying)
1103 return -1;
1104
1105 mutex_enter(&sc->sc_lock);
1106 v = isp1763hc_read4(sc, ISP1763_PORTSC1);
1107 mutex_exit(&sc->sc_lock);
1108
1109 if ((v & (ISP1763_PORTSC_PR | ISP1763_PORTSC_PED)) !=
1110 ISP1763_PORTSC_PED) {
1111 aprint_error_dev(sc->sc_dev, "root port reset failed: "
1112 "portsc 0x%08x\n", v);
1113 return -1;
1114 }
1115 sc->sc_isreset = true;
1116
1117 return 0;
1118 }
1119
1120 static void
1121 isp1763hc_portsc_modify(struct isp1763hc_softc *sc, uint32_t set,
1122 uint32_t clr)
1123 {
1124 uint32_t v;
1125
1126 mutex_enter(&sc->sc_lock);
1127 v = isp1763hc_read4(sc, ISP1763_PORTSC1) & ~ISP1763_PORTSC_ECSC;
1128 isp1763hc_write4(sc, ISP1763_PORTSC1, (v & ~clr) | set);
1129 mutex_exit(&sc->sc_lock);
1130 }
1131
1132 static int
1133 isp1763hc_roothub_hubdesc(void *buf, int buflen)
1134 {
1135 usb_hub_descriptor_t hubd;
1136 int totlen;
1137
1138 totlen = uimin(buflen, sizeof(hubd));
1139 memcpy(&hubd, buf, totlen);
1140 hubd.bNbrPorts = 1;
1141 USETW(hubd.wHubCharacteristics, UHD_PWR_INDIVIDUAL);
1142 hubd.bPwrOn2PwrGood = 10;
1143 hubd.DeviceRemovable[0] = __BIT(1);
1144 hubd.bDescLength = USB_HUB_DESCRIPTOR_SIZE + 1;
1145 totlen = uimin(totlen, hubd.bDescLength);
1146 memcpy(buf, &hubd, totlen);
1147
1148 return totlen;
1149 }
1150
1151 static int
1152 isp1763hc_roothub_port_status(struct isp1763hc_softc *sc, void *buf, int len)
1153 {
1154 usb_port_status_t ps;
1155 uint32_t v;
1156 int status, change, totlen;
1157
1158 mutex_enter(&sc->sc_lock);
1159 v = isp1763hc_read4(sc, ISP1763_PORTSC1);
1160 mutex_exit(&sc->sc_lock);
1161
1162 status = UPS_HIGH_SPEED;
1163 if ((v & ISP1763_PORTSC_ECCS) != 0)
1164 status |= UPS_CURRENT_CONNECT_STATUS;
1165 if ((v & ISP1763_PORTSC_PED) != 0)
1166 status |= UPS_PORT_ENABLED;
1167 if ((v & ISP1763_PORTSC_SUSP) != 0)
1168 status |= UPS_SUSPEND;
1169 if ((v & ISP1763_PORTSC_PR) != 0)
1170 status |= UPS_RESET;
1171 if ((v & ISP1763_PORTSC_PP) != 0)
1172 status |= UPS_PORT_POWER;
1173
1174 change = 0;
1175 if ((v & ISP1763_PORTSC_ECSC) != 0)
1176 change |= UPS_C_CONNECT_STATUS;
1177 if (sc->sc_isreset)
1178 change |= UPS_C_PORT_RESET;
1179
1180 USETW(ps.wPortStatus, status);
1181 USETW(ps.wPortChange, change);
1182 totlen = uimin(len, sizeof(ps));
1183 memcpy(buf, &ps, totlen);
1184
1185 return totlen;
1186 }
1187
1188 static int
1189 isp1763hc_roothub_port_clear(struct isp1763hc_softc *sc, int feature)
1190 {
1191
1192 switch (feature) {
1193 case UHF_PORT_ENABLE:
1194 isp1763hc_portsc_modify(sc, 0, ISP1763_PORTSC_PED);
1195 return 0;
1196 case UHF_PORT_POWER:
1197 isp1763hc_portsc_modify(sc, 0, ISP1763_PORTSC_PP);
1198 return 0;
1199 case UHF_C_PORT_CONNECTION:
1200 isp1763hc_portsc_modify(sc, ISP1763_PORTSC_ECSC, 0);
1201 return 0;
1202 case UHF_C_PORT_RESET:
1203 sc->sc_isreset = false;
1204 return 0;
1205 case UHF_PORT_SUSPEND:
1206 case UHF_PORT_TEST:
1207 case UHF_PORT_INDICATOR:
1208 case UHF_C_PORT_ENABLE:
1209 case UHF_C_PORT_SUSPEND:
1210 case UHF_C_PORT_OVER_CURRENT:
1211 return 0;
1212 default:
1213 return -1;
1214 }
1215 }
1216
1217 static int
1218 isp1763hc_roothub_port_set(struct isp1763hc_softc *sc, int feature)
1219 {
1220
1221 switch (feature) {
1222 case UHF_PORT_RESET:
1223 return isp1763hc_port_reset(sc);
1224 case UHF_PORT_POWER:
1225 isp1763hc_portsc_modify(sc, ISP1763_PORTSC_PP, 0);
1226 return 0;
1227 case UHF_PORT_ENABLE:
1228 case UHF_PORT_SUSPEND:
1229 case UHF_PORT_TEST:
1230 case UHF_PORT_INDICATOR:
1231 return 0;
1232 default:
1233 return -1;
1234 }
1235 }
1236
1237 static int
1238 isp1763hc_roothub_ctrl_locked(struct usbd_bus *bus, usb_device_request_t *req,
1239 void *buf, int buflen)
1240 {
1241 struct isp1763hc_softc *sc = ISP1763_BUS2SC(bus);
1242 uint16_t len, value, index;
1243
1244 KASSERT(mutex_owned(&sc->sc_rhlock));
1245
1246 if (sc->sc_dying)
1247 return -1;
1248
1249 len = UGETW(req->wLength);
1250 value = UGETW(req->wValue);
1251 index = UGETW(req->wIndex);
1252
1253 /* Meh */
1254 #define C(x, y) ((x) | ((y) << 8))
1255 switch (C(req->bRequest, req->bmRequestType)) {
1256 case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
1257 if (len == 0)
1258 return 0;
1259 if (value != C(2, UDESC_STRING))
1260 return buflen;
1261 return usb_makestrdesc((usb_string_descriptor_t *)buf, len,
1262 "ISP1763 root hub");
1263 case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
1264 if (len == 0)
1265 return 0;
1266 if ((value & 0xff) != 0)
1267 return -1;
1268 return isp1763hc_roothub_hubdesc(buf, buflen);
1269 case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
1270 if (len != 4)
1271 return -1;
1272 memset(buf, 0, len);
1273 return len;
1274 case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
1275 if (index != 1 || len != 4)
1276 return -1;
1277 return isp1763hc_roothub_port_status(sc, buf, len);
1278 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
1279 case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
1280 return 0;
1281 case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
1282 if (index != 1)
1283 return -1;
1284 return isp1763hc_roothub_port_clear(sc, value);
1285 case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
1286 if (index != 1)
1287 return -1;
1288 return isp1763hc_roothub_port_set(sc, value);
1289 case C(UR_CLEAR_TT_BUFFER, UT_WRITE_CLASS_OTHER):
1290 case C(UR_RESET_TT, UT_WRITE_CLASS_OTHER):
1291 case C(UR_GET_TT_STATE, UT_READ_CLASS_OTHER):
1292 case C(UR_STOP_TT, UT_WRITE_CLASS_OTHER):
1293 return 0;
1294 default:
1295 return buflen;
1296 }
1297 #undef C
1298 }
1299
1300 static usbd_status
1301 isp1763hc_root_intr_transfer(struct usbd_xfer *xfer)
1302 {
1303
1304 return isp1763hc_root_intr_start(SIMPLEQ_FIRST(
1305 &xfer->ux_pipe->up_queue));
1306 }
1307
1308 static usbd_status
1309 isp1763hc_root_intr_start(struct usbd_xfer *xfer)
1310 {
1311 struct isp1763hc_softc *sc = ISP1763_XFER2SC(xfer);
1312
1313 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
1314
1315 if (sc->sc_dying)
1316 return USBD_IOERROR;
1317
1318 KASSERT(sc->sc_intrxfer == NULL);
1319 sc->sc_intrxfer = xfer;
1320 xfer->ux_status = USBD_IN_PROGRESS;
1321
1322 return USBD_IN_PROGRESS;
1323 }
1324
1325 static void
1326 isp1763hc_root_intr_abort(struct usbd_xfer *xfer)
1327 {
1328 struct isp1763hc_softc *sc = ISP1763_XFER2SC(xfer);
1329
1330 KASSERT(mutex_owned(&sc->sc_lock));
1331 KASSERT(xfer->ux_pipe->up_intrxfer == xfer);
1332
1333 if (sc->sc_intrxfer == NULL)
1334 return;
1335
1336 KASSERT(sc->sc_intrxfer == xfer);
1337 KASSERT(xfer->ux_status == USBD_IN_PROGRESS);
1338 xfer->ux_status = USBD_CANCELLED;
1339 usb_transfer_complete(xfer);
1340 }
1341
1342 static void
1343 isp1763hc_root_intr_close(struct usbd_pipe *pipe)
1344 {
1345 struct isp1763hc_softc *sc __diagused = ISP1763_PIPE2SC(pipe);
1346
1347 KASSERT(mutex_owned(&sc->sc_lock));
1348 KASSERT(sc->sc_intrxfer == NULL);
1349 }
1350
1351 static void
1352 isp1763hc_root_intr_done(struct usbd_xfer *xfer)
1353 {
1354 struct isp1763hc_softc *sc = ISP1763_XFER2SC(xfer);
1355
1356 KASSERT(mutex_owned(&sc->sc_lock));
1357 KASSERT(sc->sc_intrxfer == xfer);
1358 KASSERT(xfer->ux_status != USBD_IN_PROGRESS);
1359 sc->sc_intrxfer = NULL;
1360 }
1361
1362 static usbd_status
1363 isp1763hc_device_transfer(struct usbd_xfer *xfer)
1364 {
1365
1366 return isp1763hc_device_start(SIMPLEQ_FIRST(&xfer->ux_pipe->up_queue));
1367 }
1368
1369 static usbd_status
1370 isp1763hc_device_start(struct usbd_xfer *xfer)
1371 {
1372 struct isp1763hc_softc *sc = ISP1763_XFER2SC(xfer);
1373 struct isp1763hc_xfer *ix = ISP1763_XFER2IX(xfer);
1374 struct isp1763hc_pipe *ip = ISP1763_PIPE2IP(xfer->ux_pipe);
1375 usb_endpoint_descriptor_t *ed = xfer->ux_pipe->up_endpoint->ue_edesc;
1376 struct isp1763hc_queue *q = ip->ip_queue;
1377 int slot;
1378
1379 KASSERT(sc->sc_bus.ub_usepolling || mutex_owned(&sc->sc_lock));
1380
1381 if (sc->sc_dying)
1382 return USBD_IOERROR;
1383
1384 ix->ix_queue = q;
1385 ix->ix_slot = -1;
1386 ix->ix_off = 0;
1387 ix->ix_waiting = false;
1388 ix->ix_zlp = xfer->ux_length == 0;
1389 ix->ix_phase = UE_GET_XFERTYPE(ed->bmAttributes) == UE_CONTROL ?
1390 ISP1763_PHASE_SETUP : ISP1763_PHASE_DATA;
1391
1392 xfer->ux_status = USBD_IN_PROGRESS;
1393 usbd_xfer_schedule_timeout(xfer);
1394
1395 slot = isp1763hc_slot_get(q);
1396 if (slot < 0) {
1397 TAILQ_INSERT_TAIL(&q->q_wait, ix, ix_wait);
1398 ix->ix_waiting = true;
1399 return USBD_IN_PROGRESS;
1400 }
1401 isp1763hc_slot_take(q, ix, slot);
1402 isp1763hc_arm(sc, ix);
1403
1404 return USBD_IN_PROGRESS;
1405 }
1406
1407 static void
1408 isp1763hc_device_abort(struct usbd_xfer *xfer)
1409 {
1410
1411 usbd_xfer_abort(xfer);
1412 }
1413
1414 static void
1415 isp1763hc_device_close(struct usbd_pipe *pipe)
1416 {
1417 struct isp1763hc_pipe *ip = ISP1763_PIPE2IP(pipe);
1418
1419 pipe->up_endpoint->ue_toggle = ip->ip_toggle;
1420 }
1421
1422 static void
1423 isp1763hc_device_clear_toggle(struct usbd_pipe *pipe)
1424 {
1425 struct isp1763hc_pipe *ip = ISP1763_PIPE2IP(pipe);
1426
1427 ip->ip_toggle = false;
1428 }
1429
1430 static void
1431 isp1763hc_device_done(struct usbd_xfer *xfer)
1432 {
1433 /* nothing left */
1434 }
1435
1436