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