sl811hs.c revision 1.2 1 1.2 isaki /* $NetBSD: sl811hs.c,v 1.2 2002/09/08 07:58:14 isaki Exp $ */
2 1.1 isaki
3 1.1 isaki /*
4 1.1 isaki * Copyright (c) 2001 The NetBSD Foundation, Inc.
5 1.1 isaki * All rights reserved.
6 1.1 isaki *
7 1.1 isaki * This code is derived from software contributed to The NetBSD Foundation
8 1.1 isaki * by Tetsuya Isaki.
9 1.1 isaki *
10 1.1 isaki * Redistribution and use in source and binary forms, with or without
11 1.1 isaki * modification, are permitted provided that the following conditions
12 1.1 isaki * are met:
13 1.1 isaki * 1. Redistributions of source code must retain the above copyright
14 1.1 isaki * notice, this list of conditions and the following disclaimer.
15 1.1 isaki * 2. Redistributions in binary form must reproduce the above copyright
16 1.1 isaki * notice, this list of conditions and the following disclaimer in the
17 1.1 isaki * documentation and/or other materials provided with the distribution.
18 1.1 isaki * 3. All advertising materials mentioning features or use of this software
19 1.1 isaki * must display the following acknowledgement:
20 1.1 isaki * This product includes software developed by the NetBSD
21 1.1 isaki * Foundation, Inc. and its contributors.
22 1.1 isaki * 4. Neither the name of The NetBSD Foundation nor the names of its
23 1.1 isaki * contributors may be used to endorse or promote products derived
24 1.1 isaki * from this software without specific prior written permission.
25 1.1 isaki *
26 1.1 isaki * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 1.1 isaki * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 1.1 isaki * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 1.1 isaki * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 1.1 isaki * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 1.1 isaki * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 1.1 isaki * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 1.1 isaki * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 1.1 isaki * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 1.1 isaki * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 1.1 isaki * POSSIBILITY OF SUCH DAMAGE.
37 1.1 isaki */
38 1.1 isaki
39 1.1 isaki /*
40 1.1 isaki * ScanLogic SL811HS/T USB Host Controller
41 1.1 isaki */
42 1.1 isaki /*
43 1.1 isaki * !! HIGHLY EXPERIMENTAL CODE !!
44 1.1 isaki */
45 1.1 isaki
46 1.1 isaki #include <sys/cdefs.h>
47 1.2 isaki __KERNEL_RCSID(0, "$NetBSD: sl811hs.c,v 1.2 2002/09/08 07:58:14 isaki Exp $");
48 1.1 isaki
49 1.1 isaki #include "opt_slhci.h"
50 1.1 isaki
51 1.1 isaki #include <sys/param.h>
52 1.1 isaki #include <sys/systm.h>
53 1.1 isaki #include <sys/kernel.h>
54 1.1 isaki #include <sys/proc.h>
55 1.1 isaki #include <sys/device.h>
56 1.1 isaki #include <sys/malloc.h>
57 1.1 isaki
58 1.1 isaki #include <machine/bus.h>
59 1.1 isaki #include <machine/cpu.h>
60 1.1 isaki
61 1.1 isaki #include <dev/usb/usb.h>
62 1.1 isaki #include <dev/usb/usbdi.h>
63 1.1 isaki #include <dev/usb/usbdivar.h>
64 1.1 isaki #include <dev/usb/usb_mem.h>
65 1.1 isaki #include <dev/usb/usbdevs.h>
66 1.1 isaki
67 1.1 isaki #include <dev/ic/sl811hsreg.h>
68 1.1 isaki #include <dev/ic/sl811hsvar.h>
69 1.1 isaki
70 1.1 isaki static inline u_int8_t sl11read(struct slhci_softc *, int);
71 1.1 isaki static inline void sl11write(struct slhci_softc *, int, u_int8_t);
72 1.1 isaki static inline void sl11read_region(struct slhci_softc *, u_char *, int, int);
73 1.1 isaki static inline void sl11write_region(struct slhci_softc *, int, u_char *, int);
74 1.1 isaki
75 1.1 isaki static void sl11_reset(struct slhci_softc *);
76 1.1 isaki static void sl11_speed(struct slhci_softc *);
77 1.1 isaki
78 1.1 isaki static usbd_status slhci_open(usbd_pipe_handle);
79 1.1 isaki static void slhci_softintr(void *);
80 1.1 isaki static void slhci_poll(struct usbd_bus *);
81 1.1 isaki static void slhci_poll_hub(void *);
82 1.1 isaki static void slhci_poll_device(void *arg);
83 1.1 isaki static usbd_status slhci_allocm(struct usbd_bus *, usb_dma_t *, u_int32_t);
84 1.1 isaki static void slhci_freem(struct usbd_bus *, usb_dma_t *);
85 1.1 isaki static usbd_xfer_handle slhci_allocx(struct usbd_bus *);
86 1.1 isaki static void slhci_freex(struct usbd_bus *, usbd_xfer_handle);
87 1.1 isaki
88 1.1 isaki static int slhci_str(usb_string_descriptor_t *, int, char *);
89 1.1 isaki
90 1.1 isaki static usbd_status slhci_root_ctrl_transfer(usbd_xfer_handle);
91 1.1 isaki static usbd_status slhci_root_ctrl_start(usbd_xfer_handle);
92 1.1 isaki static void slhci_root_ctrl_abort(usbd_xfer_handle);
93 1.1 isaki static void slhci_root_ctrl_close(usbd_pipe_handle);
94 1.1 isaki static void slhci_root_ctrl_done(usbd_xfer_handle);
95 1.1 isaki
96 1.1 isaki static usbd_status slhci_root_intr_transfer(usbd_xfer_handle);
97 1.1 isaki static usbd_status slhci_root_intr_start(usbd_xfer_handle);
98 1.1 isaki static void slhci_root_intr_abort(usbd_xfer_handle);
99 1.1 isaki static void slhci_root_intr_close(usbd_pipe_handle);
100 1.1 isaki static void slhci_root_intr_done(usbd_xfer_handle);
101 1.1 isaki
102 1.1 isaki static usbd_status slhci_device_ctrl_transfer(usbd_xfer_handle);
103 1.1 isaki static usbd_status slhci_device_ctrl_start(usbd_xfer_handle);
104 1.1 isaki static void slhci_device_ctrl_abort(usbd_xfer_handle);
105 1.1 isaki static void slhci_device_ctrl_close(usbd_pipe_handle);
106 1.1 isaki static void slhci_device_ctrl_done(usbd_xfer_handle);
107 1.1 isaki
108 1.1 isaki static usbd_status slhci_device_intr_transfer(usbd_xfer_handle);
109 1.1 isaki static usbd_status slhci_device_intr_start(usbd_xfer_handle);
110 1.1 isaki static void slhci_device_intr_abort(usbd_xfer_handle);
111 1.1 isaki static void slhci_device_intr_close(usbd_pipe_handle);
112 1.1 isaki static void slhci_device_intr_done(usbd_xfer_handle);
113 1.1 isaki
114 1.1 isaki static usbd_status slhci_device_isoc_transfer(usbd_xfer_handle);
115 1.1 isaki static usbd_status slhci_device_isoc_start(usbd_xfer_handle);
116 1.1 isaki static void slhci_device_isoc_abort(usbd_xfer_handle);
117 1.1 isaki static void slhci_device_isoc_close(usbd_pipe_handle);
118 1.1 isaki static void slhci_device_isoc_done(usbd_xfer_handle);
119 1.1 isaki
120 1.1 isaki static usbd_status slhci_device_bulk_transfer(usbd_xfer_handle);
121 1.1 isaki static usbd_status slhci_device_bulk_start(usbd_xfer_handle);
122 1.1 isaki static void slhci_device_bulk_abort(usbd_xfer_handle);
123 1.1 isaki static void slhci_device_bulk_close(usbd_pipe_handle);
124 1.1 isaki static void slhci_device_bulk_done(usbd_xfer_handle);
125 1.1 isaki
126 1.1 isaki static int slhci_transaction(struct slhci_softc *,
127 1.1 isaki usbd_pipe_handle, u_int8_t, int, u_char *, u_int8_t);
128 1.1 isaki static void slhci_noop(usbd_pipe_handle);
129 1.1 isaki static void slhci_abort_xfer(usbd_xfer_handle, usbd_status);
130 1.1 isaki static void slhci_device_clear_toggle(usbd_pipe_handle);
131 1.1 isaki
132 1.1 isaki extern int usbdebug;
133 1.1 isaki int slhci_dummy;
134 1.1 isaki
135 1.1 isaki /* For root hub */
136 1.1 isaki #define SLHCI_INTR_ENDPT (1)
137 1.1 isaki
138 1.1 isaki #ifdef SLHCI_DEBUG
139 1.1 isaki #define D_TRACE (0x0001) /* function trace */
140 1.1 isaki #define D_MSG (0x0002) /* debug messages */
141 1.1 isaki #define D_XFER (0x0004) /* transfer messages (noisy!) */
142 1.1 isaki #define D_MEM (0x0008) /* memory allocation */
143 1.1 isaki
144 1.1 isaki int slhci_debug = D_MSG | D_XFER;
145 1.1 isaki #define DPRINTF(z,x) if((slhci_debug&(z))!=0)printf x
146 1.1 isaki void print_req(usb_device_request_t *);
147 1.1 isaki void print_req_hub(usb_device_request_t *);
148 1.1 isaki void print_dumpreg(struct slhci_softc *);
149 1.1 isaki void print_xfer(usbd_xfer_handle);
150 1.1 isaki #else
151 1.1 isaki #define DPRINTF(z,x)
152 1.1 isaki #endif
153 1.1 isaki
154 1.1 isaki
155 1.1 isaki /* XXX: sync with argument */
156 1.1 isaki static char *sltypestr [] = {
157 1.1 isaki "SL11H/T",
158 1.1 isaki "SL811HS/T",
159 1.1 isaki };
160 1.1 isaki
161 1.1 isaki
162 1.1 isaki struct usbd_bus_methods slhci_bus_methods = {
163 1.1 isaki slhci_open,
164 1.1 isaki slhci_softintr,
165 1.1 isaki slhci_poll,
166 1.1 isaki slhci_allocm,
167 1.1 isaki slhci_freem,
168 1.1 isaki slhci_allocx,
169 1.1 isaki slhci_freex,
170 1.1 isaki };
171 1.1 isaki
172 1.1 isaki struct usbd_pipe_methods slhci_root_ctrl_methods = {
173 1.1 isaki slhci_root_ctrl_transfer,
174 1.1 isaki slhci_root_ctrl_start,
175 1.1 isaki slhci_root_ctrl_abort,
176 1.1 isaki slhci_root_ctrl_close,
177 1.1 isaki slhci_noop,
178 1.1 isaki slhci_root_ctrl_done,
179 1.1 isaki };
180 1.1 isaki
181 1.1 isaki struct usbd_pipe_methods slhci_root_intr_methods = {
182 1.1 isaki slhci_root_intr_transfer,
183 1.1 isaki slhci_root_intr_start,
184 1.1 isaki slhci_root_intr_abort,
185 1.1 isaki slhci_root_intr_close,
186 1.1 isaki slhci_noop,
187 1.1 isaki slhci_root_intr_done,
188 1.1 isaki };
189 1.1 isaki
190 1.1 isaki struct usbd_pipe_methods slhci_device_ctrl_methods = {
191 1.1 isaki slhci_device_ctrl_transfer,
192 1.1 isaki slhci_device_ctrl_start,
193 1.1 isaki slhci_device_ctrl_abort,
194 1.1 isaki slhci_device_ctrl_close,
195 1.1 isaki slhci_noop,
196 1.1 isaki slhci_device_ctrl_done,
197 1.1 isaki };
198 1.1 isaki
199 1.1 isaki struct usbd_pipe_methods slhci_device_intr_methods = {
200 1.1 isaki slhci_device_intr_transfer,
201 1.1 isaki slhci_device_intr_start,
202 1.1 isaki slhci_device_intr_abort,
203 1.1 isaki slhci_device_intr_close,
204 1.1 isaki slhci_device_clear_toggle,
205 1.1 isaki slhci_device_intr_done,
206 1.1 isaki };
207 1.1 isaki
208 1.1 isaki struct usbd_pipe_methods slhci_device_isoc_methods = {
209 1.1 isaki slhci_device_isoc_transfer,
210 1.1 isaki slhci_device_isoc_start,
211 1.1 isaki slhci_device_isoc_abort,
212 1.1 isaki slhci_device_isoc_close,
213 1.1 isaki slhci_noop,
214 1.1 isaki slhci_device_isoc_done,
215 1.1 isaki };
216 1.1 isaki
217 1.1 isaki struct usbd_pipe_methods slhci_device_bulk_methods = {
218 1.1 isaki slhci_device_bulk_transfer,
219 1.1 isaki slhci_device_bulk_start,
220 1.1 isaki slhci_device_bulk_abort,
221 1.1 isaki slhci_device_bulk_close,
222 1.1 isaki slhci_noop,
223 1.1 isaki slhci_device_bulk_done,
224 1.1 isaki };
225 1.1 isaki
226 1.1 isaki struct slhci_pipe {
227 1.1 isaki struct usbd_pipe pipe;
228 1.1 isaki };
229 1.1 isaki
230 1.1 isaki
231 1.1 isaki /*
232 1.1 isaki * SL811HS Register read/write routine
233 1.1 isaki */
234 1.1 isaki static inline u_int8_t
235 1.1 isaki sl11read(struct slhci_softc *sc, int reg)
236 1.1 isaki {
237 1.1 isaki bus_space_write_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_ADDR, reg);
238 1.1 isaki return bus_space_read_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_DATA);
239 1.1 isaki }
240 1.1 isaki
241 1.1 isaki static inline void
242 1.1 isaki sl11write(struct slhci_softc *sc, int reg, u_int8_t data)
243 1.1 isaki {
244 1.1 isaki bus_space_write_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_ADDR, reg);
245 1.1 isaki bus_space_write_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_DATA, data);
246 1.1 isaki }
247 1.1 isaki
248 1.1 isaki static inline void
249 1.1 isaki sl11read_region(struct slhci_softc *sc, u_char *buf, int reg, int len)
250 1.1 isaki {
251 1.1 isaki int i;
252 1.1 isaki bus_space_write_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_ADDR, reg);
253 1.1 isaki for (i = 0; i < len; i++)
254 1.1 isaki buf[i] = bus_space_read_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_DATA);
255 1.1 isaki }
256 1.1 isaki
257 1.1 isaki static inline void
258 1.1 isaki sl11write_region(struct slhci_softc *sc, int reg, u_char *buf, int len)
259 1.1 isaki {
260 1.1 isaki int i;
261 1.1 isaki bus_space_write_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_ADDR, reg);
262 1.1 isaki for (i = 0; i < len; i++)
263 1.1 isaki bus_space_write_1(sc->sc_iot, sc->sc_ioh, SL11_IDX_DATA, buf[i]);
264 1.1 isaki }
265 1.1 isaki
266 1.1 isaki /*
267 1.1 isaki * USB bus reset. From sl811hs_appnote.pdf, p22
268 1.1 isaki */
269 1.1 isaki static void
270 1.1 isaki sl11_reset(struct slhci_softc *sc)
271 1.1 isaki {
272 1.1 isaki u_int8_t r;
273 1.1 isaki
274 1.1 isaki DPRINTF(D_TRACE, ("%s() ", __FUNCTION__));
275 1.1 isaki r = sl11read(sc, SL11_CTRL);
276 1.1 isaki sl11write(sc, SL11_CTRL, r | SL11_CTRL_RESETENGINE);
277 1.1 isaki delay_ms(250);
278 1.1 isaki sl11write(sc, SL11_CTRL, r | SL11_CTRL_RESETENGINE | SL11_CTRL_SUSPEND);
279 1.1 isaki delay_ms(150);
280 1.1 isaki sl11write(sc, SL11_CTRL, r | SL11_CTRL_RESETENGINE);
281 1.1 isaki delay_ms(10);
282 1.1 isaki sl11write(sc, SL11_CTRL, r);
283 1.1 isaki }
284 1.1 isaki
285 1.1 isaki /*
286 1.1 isaki * Detect the speed of attached device.
287 1.1 isaki */
288 1.1 isaki static void
289 1.1 isaki sl11_speed(struct slhci_softc *sc)
290 1.1 isaki {
291 1.1 isaki u_int8_t r;
292 1.1 isaki
293 1.1 isaki sl11write(sc, SL11_ISR, 0xff);
294 1.1 isaki r = sl11read(sc, SL11_ISR);
295 1.1 isaki if ((r & SL11_ISR_RESET)) {
296 1.1 isaki DPRINTF(D_MSG, ("NC "));
297 1.1 isaki sl11write(sc, SL11_ISR, SL11_ISR_RESET);
298 1.1 isaki sc->sc_connect = 0;
299 1.1 isaki }
300 1.1 isaki
301 1.1 isaki if ((sl11read(sc, SL11_ISR) & SL11_ISR_RESET)) {
302 1.1 isaki sl11write(sc, SL11_ISR, 0xff);
303 1.1 isaki } else {
304 1.1 isaki u_int8_t pol = 0, ctrl = 0;
305 1.1 isaki
306 1.1 isaki sc->sc_connect = 1;
307 1.1 isaki if (r & SL11_ISR_DATA) {
308 1.1 isaki DPRINTF(D_MSG, ("FS "));
309 1.1 isaki pol = 0;
310 1.1 isaki ctrl = SL11_CTRL_EOF2;
311 1.1 isaki sc->sc_fullspeed = 1;
312 1.1 isaki } else {
313 1.1 isaki DPRINTF(D_MSG, ("LS "));
314 1.1 isaki pol = SL811_CSOF_POLARITY;
315 1.1 isaki ctrl = SL11_CTRL_LOWSPEED;
316 1.1 isaki sc->sc_fullspeed = 0;
317 1.1 isaki }
318 1.1 isaki sl11write(sc, SL811_CSOF, pol | SL811_CSOF_MASTER | 0x2e);
319 1.1 isaki sl11write(sc, SL11_DATA, 0xe0);
320 1.1 isaki sl11write(sc, SL11_CTRL, ctrl | SL11_CTRL_ENABLESOF);
321 1.1 isaki }
322 1.1 isaki
323 1.1 isaki sl11write(sc, SL11_E0PID, (SL11_PID_SOF << 4) + 0);
324 1.1 isaki sl11write(sc, SL11_E0DEV, 0);
325 1.1 isaki sl11write(sc, SL11_E0CTRL, SL11_EPCTRL_ARM);
326 1.1 isaki delay_ms(30);
327 1.1 isaki }
328 1.1 isaki
329 1.1 isaki /*
330 1.1 isaki * If detect some known controller, return the type.
331 1.1 isaki * If does not, return -1.
332 1.1 isaki */
333 1.1 isaki int
334 1.1 isaki sl811hs_find(struct slhci_softc *sc)
335 1.1 isaki {
336 1.1 isaki int rev;
337 1.1 isaki
338 1.1 isaki sc->sc_sltype = -1;
339 1.1 isaki rev = sl11read(sc, SL11_REV) >> 4;
340 1.1 isaki if (rev >= SLTYPE_SL11H && rev <= SLTYPE_SL811HS_R14)
341 1.1 isaki sc->sc_sltype = rev;
342 1.1 isaki return sc->sc_sltype;
343 1.1 isaki }
344 1.1 isaki
345 1.1 isaki /*
346 1.1 isaki * Attach SL11H/SL811HS. Return 0 if success.
347 1.1 isaki */
348 1.1 isaki int
349 1.1 isaki slhci_attach(struct slhci_softc *sc, struct device *self)
350 1.1 isaki {
351 1.1 isaki int rev;
352 1.1 isaki
353 1.1 isaki /* Detect and check the controller type */
354 1.1 isaki rev = sl811hs_find(sc);
355 1.1 isaki if (rev == -1)
356 1.1 isaki return -1;
357 1.1 isaki
358 1.1 isaki printf("%s: ScanLogic %s USB Host Controller",
359 1.1 isaki sc->sc_bus.bdev.dv_xname, sltypestr[(rev > 0)]);
360 1.1 isaki switch (rev) {
361 1.1 isaki case SLTYPE_SL11H:
362 1.1 isaki break;
363 1.1 isaki case SLTYPE_SL811HS_R12:
364 1.1 isaki printf(" (rev 1.2)");
365 1.1 isaki break;
366 1.1 isaki case SLTYPE_SL811HS_R14:
367 1.1 isaki printf(" (rev 1.4)");
368 1.1 isaki break;
369 1.1 isaki default:
370 1.1 isaki printf(" (unknown revision)");
371 1.1 isaki break;
372 1.1 isaki }
373 1.1 isaki printf("\n");
374 1.1 isaki
375 1.1 isaki /* Initialize sc */
376 1.1 isaki sc->sc_bus.usbrev = USBREV_1_1;
377 1.1 isaki sc->sc_bus.methods = &slhci_bus_methods;
378 1.1 isaki sc->sc_bus.pipe_size = sizeof(struct slhci_pipe);
379 1.1 isaki sc->sc_bus.dmatag = sc->sc_dmat;
380 1.1 isaki
381 1.1 isaki SIMPLEQ_INIT(&sc->sc_free_xfers);
382 1.1 isaki
383 1.1 isaki usb_callout_init(sc->sc_poll_handle);
384 1.1 isaki
385 1.1 isaki /* Initialize controller */
386 1.1 isaki sl11write(sc, SL811_CSOF, SL811_CSOF_MASTER | 0x2e);
387 1.1 isaki sl11write(sc, SL11_ISR, 0xff);
388 1.1 isaki
389 1.1 isaki /* Disable interrupt, then wait 40msec */
390 1.1 isaki sl11write(sc, SL11_IER, 0x00);
391 1.1 isaki delay_ms(40);
392 1.1 isaki
393 1.1 isaki /* Reset USB engine */
394 1.1 isaki sl11write(sc, SL11_CTRL, SL11_CTRL_RESETENGINE | SL11_CTRL_SUSPEND);
395 1.1 isaki delay_ms(40);
396 1.1 isaki sl11write(sc, SL11_CTRL, 0x00);
397 1.1 isaki delay_ms(10);
398 1.1 isaki
399 1.1 isaki /* USB Bus reset for GET_PORT_STATUS */
400 1.1 isaki sl11_reset(sc);
401 1.1 isaki
402 1.1 isaki /* Enable interrupt */
403 1.1 isaki sl11write(sc, SL11_IER, SL11_IER_INSERT);
404 1.1 isaki /* x68k Nereid USB controller needs it */
405 1.1 isaki if (sc->sc_enable_intr)
406 1.1 isaki sc->sc_enable_intr(sc->sc_arg, INTR_ON);
407 1.1 isaki
408 1.1 isaki #ifdef USB_DEBUG
409 1.1 isaki usbdebug = 0;
410 1.1 isaki #endif
411 1.1 isaki
412 1.1 isaki /* Attach USB devices */
413 1.1 isaki sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint);
414 1.1 isaki
415 1.1 isaki return 0;
416 1.1 isaki }
417 1.1 isaki
418 1.1 isaki int
419 1.1 isaki slhci_intr(void *arg)
420 1.1 isaki {
421 1.1 isaki struct slhci_softc *sc = arg;
422 1.1 isaki u_int8_t r;
423 1.1 isaki #ifdef SLHCI_DEBUG
424 1.1 isaki char bitbuf[256];
425 1.1 isaki #endif
426 1.1 isaki
427 1.1 isaki r = sl11read(sc, SL11_ISR);
428 1.1 isaki
429 1.1 isaki sl11write(sc, SL11_ISR, SL11_ISR_DATA | SL11_ISR_SOFTIMER);
430 1.1 isaki
431 1.1 isaki if ((r & SL11_ISR_RESET)) {
432 1.1 isaki sc->sc_flags |= SLF_RESET;
433 1.1 isaki sl11write(sc, SL11_ISR, SL11_ISR_RESET);
434 1.1 isaki }
435 1.1 isaki if ((r & SL11_ISR_INSERT)) {
436 1.1 isaki sc->sc_flags |= SLF_INSERT;
437 1.1 isaki sl11write(sc, SL11_ISR, SL11_ISR_INSERT);
438 1.1 isaki }
439 1.1 isaki
440 1.1 isaki #ifdef SLHCI_DEBUG
441 1.1 isaki bitmask_snprintf(r,
442 1.1 isaki (sl11read(sc, SL11_CTRL) & SL11_CTRL_SUSPEND)
443 1.1 isaki ? "\20\x8""D+\7RESUME\6INSERT\5SOF\4res\3""BABBLE\2USBB\1USBA"
444 1.1 isaki : "\20\x8""D+\7RESET\6INSERT\5SOF\4res\3""BABBLE\2USBB\1USBA",
445 1.1 isaki bitbuf, sizeof(bitbuf));
446 1.1 isaki DPRINTF(D_XFER, ("I=%s ", bitbuf));
447 1.1 isaki #endif /* SLHCI_DEBUG */
448 1.1 isaki
449 1.1 isaki return 0;
450 1.1 isaki }
451 1.1 isaki
452 1.1 isaki usbd_status
453 1.1 isaki slhci_open(usbd_pipe_handle pipe)
454 1.1 isaki {
455 1.1 isaki usbd_device_handle dev = pipe->device;
456 1.1 isaki struct slhci_softc *sc = (struct slhci_softc *)dev->bus;
457 1.1 isaki usb_endpoint_descriptor_t *ed = pipe->endpoint->edesc;
458 1.1 isaki
459 1.1 isaki DPRINTF(D_TRACE, ("slhci_open(addr=%d,ep=%d,scaddr=%d)",
460 1.1 isaki dev->address, ed->bEndpointAddress, sc->sc_addr));
461 1.1 isaki
462 1.1 isaki if (dev->address == sc->sc_addr) {
463 1.1 isaki switch (ed->bEndpointAddress) {
464 1.1 isaki case USB_CONTROL_ENDPOINT:
465 1.1 isaki pipe->methods = &slhci_root_ctrl_methods;
466 1.1 isaki break;
467 1.1 isaki case UE_DIR_IN | SLHCI_INTR_ENDPT:
468 1.1 isaki pipe->methods = &slhci_root_intr_methods;
469 1.1 isaki break;
470 1.1 isaki default:
471 1.1 isaki printf("open:endpointErr!\n");
472 1.1 isaki return USBD_INVAL;
473 1.1 isaki }
474 1.1 isaki } else {
475 1.1 isaki switch (ed->bmAttributes & UE_XFERTYPE) {
476 1.1 isaki case UE_CONTROL:
477 1.1 isaki DPRINTF(D_MSG, ("control "));
478 1.1 isaki pipe->methods = &slhci_device_ctrl_methods;
479 1.1 isaki break;
480 1.1 isaki case UE_INTERRUPT:
481 1.1 isaki DPRINTF(D_MSG, ("interrupt "));
482 1.1 isaki pipe->methods = &slhci_device_intr_methods;
483 1.1 isaki break;
484 1.1 isaki case UE_ISOCHRONOUS:
485 1.1 isaki DPRINTF(D_MSG, ("isochronous "));
486 1.1 isaki pipe->methods = &slhci_device_isoc_methods;
487 1.1 isaki break;
488 1.1 isaki case UE_BULK:
489 1.1 isaki DPRINTF(D_MSG, ("bluk "));
490 1.1 isaki pipe->methods = &slhci_device_bulk_methods;
491 1.1 isaki break;
492 1.1 isaki }
493 1.1 isaki }
494 1.1 isaki return USBD_NORMAL_COMPLETION;
495 1.1 isaki }
496 1.1 isaki
497 1.1 isaki void
498 1.1 isaki slhci_softintr(void *arg)
499 1.1 isaki {
500 1.1 isaki DPRINTF(D_TRACE, ("%s()", __FUNCTION__));
501 1.1 isaki }
502 1.1 isaki
503 1.1 isaki void
504 1.1 isaki slhci_poll(struct usbd_bus *bus)
505 1.1 isaki {
506 1.1 isaki DPRINTF(D_TRACE, ("%s()", __FUNCTION__));
507 1.1 isaki }
508 1.1 isaki
509 1.1 isaki /*
510 1.1 isaki * Emulation of interrupt transfer for status change endpoint
511 1.1 isaki * of root hub.
512 1.1 isaki */
513 1.1 isaki void
514 1.1 isaki slhci_poll_hub(void *arg)
515 1.1 isaki {
516 1.1 isaki usbd_xfer_handle xfer = arg;
517 1.1 isaki usbd_pipe_handle pipe = xfer->pipe;
518 1.1 isaki struct slhci_softc *sc = (struct slhci_softc *)pipe->device->bus;
519 1.1 isaki int s;
520 1.1 isaki u_char *p;
521 1.1 isaki
522 1.1 isaki usb_callout(sc->sc_poll_handle, sc->sc_interval, slhci_poll_hub, xfer);
523 1.1 isaki
524 1.1 isaki /* USB spec 11.13.3 (p.260) */
525 1.1 isaki p = KERNADDR(&xfer->dmabuf, 0);
526 1.1 isaki p[0] = 0;
527 1.1 isaki if ((sc->sc_flags & (SLF_INSERT | SLF_RESET))) {
528 1.1 isaki p[0] = 2;
529 1.1 isaki DPRINTF(D_TRACE, ("!"));
530 1.1 isaki }
531 1.1 isaki
532 1.1 isaki /* no change, return NAK */
533 1.1 isaki if (p[0] == 0)
534 1.1 isaki return;
535 1.1 isaki
536 1.1 isaki xfer->actlen = 1;
537 1.1 isaki xfer->status = USBD_NORMAL_COMPLETION;
538 1.1 isaki s = splusb();
539 1.1 isaki xfer->device->bus->intr_context++;
540 1.1 isaki usb_transfer_complete(xfer);
541 1.1 isaki xfer->device->bus->intr_context--;
542 1.1 isaki splx(s);
543 1.1 isaki }
544 1.1 isaki
545 1.1 isaki usbd_status
546 1.1 isaki slhci_allocm(struct usbd_bus *bus, usb_dma_t *dma, u_int32_t size)
547 1.1 isaki {
548 1.1 isaki struct slhci_softc *sc = (struct slhci_softc *)bus;
549 1.1 isaki
550 1.1 isaki DPRINTF(D_MEM, ("SLallocm"));
551 1.1 isaki return usb_allocmem(&sc->sc_bus, size, 0, dma);
552 1.1 isaki }
553 1.1 isaki
554 1.1 isaki void
555 1.1 isaki slhci_freem(struct usbd_bus *bus, usb_dma_t *dma)
556 1.1 isaki {
557 1.1 isaki struct slhci_softc *sc = (struct slhci_softc *)bus;
558 1.1 isaki
559 1.1 isaki DPRINTF(D_MEM, ("SLfreem"));
560 1.1 isaki usb_freemem(&sc->sc_bus, dma);
561 1.1 isaki }
562 1.1 isaki
563 1.1 isaki usbd_xfer_handle
564 1.1 isaki slhci_allocx(struct usbd_bus *bus)
565 1.1 isaki {
566 1.1 isaki struct slhci_softc *sc = (struct slhci_softc *)bus;
567 1.1 isaki usbd_xfer_handle xfer;
568 1.1 isaki
569 1.1 isaki DPRINTF(D_MEM, ("SLallocx"));
570 1.1 isaki
571 1.1 isaki xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
572 1.2 isaki if (xfer) {
573 1.1 isaki SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
574 1.2 isaki #ifdef DIAGNOSTIC
575 1.2 isaki if (xfer->busy_free != XFER_FREE) {
576 1.2 isaki printf("slhci_allocx: xfer=%p not free, 0x%08x\n",
577 1.2 isaki xfer, xfer->busy_free);
578 1.2 isaki }
579 1.2 isaki #endif
580 1.2 isaki } else {
581 1.1 isaki xfer = malloc(sizeof(*xfer), M_USB, M_NOWAIT);
582 1.2 isaki }
583 1.1 isaki
584 1.2 isaki if (xfer) {
585 1.1 isaki memset(xfer, 0, sizeof(*xfer));
586 1.2 isaki #ifdef DIAGNOSTIC
587 1.2 isaki xfer->busy_free = XFER_BUSY;
588 1.2 isaki #endif
589 1.2 isaki }
590 1.1 isaki
591 1.1 isaki return xfer;
592 1.1 isaki }
593 1.1 isaki
594 1.1 isaki void
595 1.1 isaki slhci_freex(struct usbd_bus *bus, usbd_xfer_handle xfer)
596 1.1 isaki {
597 1.1 isaki struct slhci_softc *sc = (struct slhci_softc *)bus;
598 1.1 isaki
599 1.1 isaki DPRINTF(D_MEM, ("SLfreex"));
600 1.2 isaki
601 1.2 isaki #ifdef DIAGNOSTIC
602 1.2 isaki if (xfer->busy_free != XFER_BUSY) {
603 1.2 isaki printf("slhci_freex: xfer=%p not busy, 0x%08x\n",
604 1.2 isaki xfer, xfer->busy_free);
605 1.2 isaki return;
606 1.2 isaki }
607 1.2 isaki xfer->busy_free = XFER_FREE;
608 1.2 isaki #endif
609 1.1 isaki SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
610 1.1 isaki }
611 1.1 isaki
612 1.1 isaki void
613 1.1 isaki slhci_noop(usbd_pipe_handle pipe)
614 1.1 isaki {
615 1.1 isaki DPRINTF(D_TRACE, ("%s()", __FUNCTION__));
616 1.1 isaki }
617 1.1 isaki
618 1.1 isaki /*
619 1.1 isaki * Data structures and routines to emulate the root hub.
620 1.1 isaki */
621 1.1 isaki usb_device_descriptor_t slhci_devd = {
622 1.1 isaki USB_DEVICE_DESCRIPTOR_SIZE,
623 1.1 isaki UDESC_DEVICE, /* type */
624 1.1 isaki {0x01, 0x01}, /* USB version */
625 1.1 isaki UDCLASS_HUB, /* class */
626 1.1 isaki UDSUBCLASS_HUB, /* subclass */
627 1.1 isaki 0, /* protocol */
628 1.1 isaki 64, /* max packet */
629 1.1 isaki {USB_VENDOR_SCANLOGIC & 0xff, /* vendor ID (low) */
630 1.1 isaki USB_VENDOR_SCANLOGIC >> 8 }, /* vendor ID (high) */
631 1.1 isaki {0} /* ? */, /* product ID */
632 1.1 isaki {0}, /* device */
633 1.1 isaki 1, /* index to manufacturer */
634 1.1 isaki 2, /* index to product */
635 1.1 isaki 0, /* index to serial number */
636 1.1 isaki 1 /* number of configurations */
637 1.1 isaki };
638 1.1 isaki
639 1.1 isaki usb_config_descriptor_t slhci_confd = {
640 1.1 isaki USB_CONFIG_DESCRIPTOR_SIZE,
641 1.1 isaki UDESC_CONFIG,
642 1.1 isaki {USB_CONFIG_DESCRIPTOR_SIZE +
643 1.1 isaki USB_INTERFACE_DESCRIPTOR_SIZE +
644 1.1 isaki USB_ENDPOINT_DESCRIPTOR_SIZE},
645 1.1 isaki 1, /* number of interfaces */
646 1.1 isaki 1, /* configuration value */
647 1.1 isaki 0, /* index to configuration */
648 1.1 isaki UC_SELF_POWERED, /* attributes */
649 1.1 isaki 15 /* max current is 30mA... */
650 1.1 isaki };
651 1.1 isaki
652 1.1 isaki usb_interface_descriptor_t slhci_ifcd = {
653 1.1 isaki USB_INTERFACE_DESCRIPTOR_SIZE,
654 1.1 isaki UDESC_INTERFACE,
655 1.1 isaki 0, /* interface number */
656 1.1 isaki 0, /* alternate setting */
657 1.1 isaki 1, /* number of endpoint */
658 1.1 isaki UICLASS_HUB, /* class */
659 1.1 isaki UISUBCLASS_HUB, /* subclass */
660 1.1 isaki 0, /* protocol */
661 1.1 isaki 0 /* index to interface */
662 1.1 isaki };
663 1.1 isaki
664 1.1 isaki usb_endpoint_descriptor_t slhci_endpd = {
665 1.1 isaki USB_ENDPOINT_DESCRIPTOR_SIZE,
666 1.1 isaki UDESC_ENDPOINT,
667 1.1 isaki UE_DIR_IN | SLHCI_INTR_ENDPT, /* endpoint address */
668 1.1 isaki UE_INTERRUPT, /* attributes */
669 1.1 isaki {8}, /* max packet size */
670 1.1 isaki 255 /* interval */
671 1.1 isaki };
672 1.1 isaki
673 1.1 isaki usb_hub_descriptor_t slhci_hubd = {
674 1.1 isaki USB_HUB_DESCRIPTOR_SIZE,
675 1.1 isaki UDESC_HUB,
676 1.1 isaki 1, /* number of ports */
677 1.1 isaki {UHD_PWR_INDIVIDUAL | UHD_OC_NONE, 0}, /* hub characteristics */
678 1.1 isaki 20 /* ? */, /* 5:power on to power good */
679 1.1 isaki 50, /* 6:maximum current */
680 1.1 isaki { 0x00 }, /* both ports are removable */
681 1.1 isaki { 0x00 } /* port power control mask */
682 1.1 isaki };
683 1.1 isaki
684 1.1 isaki static int
685 1.1 isaki slhci_str(usb_string_descriptor_t *p, int l, char *s)
686 1.1 isaki {
687 1.1 isaki int i;
688 1.1 isaki
689 1.1 isaki if (l == 0)
690 1.1 isaki return 0;
691 1.1 isaki p->bLength = 2 * strlen(s) + 2;
692 1.1 isaki if (l == 1)
693 1.1 isaki return 1;
694 1.1 isaki p->bDescriptorType = UDESC_STRING;
695 1.1 isaki l -= 2;
696 1.1 isaki for (i = 0; s[i] && l > 1; i++, l -= 2)
697 1.1 isaki USETW2(p->bString[i], 0, s[i]);
698 1.1 isaki return 2 * i + 2;
699 1.1 isaki }
700 1.1 isaki
701 1.1 isaki usbd_status
702 1.1 isaki slhci_root_ctrl_transfer(usbd_xfer_handle xfer)
703 1.1 isaki {
704 1.1 isaki usbd_status error;
705 1.1 isaki
706 1.1 isaki DPRINTF(D_TRACE, ("SLRCtrans "));
707 1.1 isaki
708 1.1 isaki /* Insert last in queue */
709 1.1 isaki error = usb_insert_transfer(xfer);
710 1.1 isaki if (error) {
711 1.1 isaki DPRINTF(D_MSG, ("usb_insert_transfer returns err! "));
712 1.1 isaki return error;
713 1.1 isaki }
714 1.1 isaki
715 1.1 isaki /*
716 1.1 isaki * Pipe isn't running (otherwise error would be USBD_INPROG),
717 1.1 isaki * so start it first.
718 1.1 isaki */
719 1.1 isaki return slhci_root_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
720 1.1 isaki }
721 1.1 isaki
722 1.1 isaki usbd_status
723 1.1 isaki slhci_root_ctrl_start(usbd_xfer_handle xfer)
724 1.1 isaki {
725 1.1 isaki struct slhci_softc *sc = (struct slhci_softc *)xfer->pipe->device->bus;
726 1.1 isaki usb_device_request_t *req;
727 1.1 isaki int len, value, index, l, s, status;
728 1.1 isaki int totlen = 0;
729 1.1 isaki void *buf = NULL;
730 1.1 isaki usb_port_status_t ps;
731 1.1 isaki usbd_status error;
732 1.1 isaki char slbuf[50];
733 1.1 isaki u_int8_t r;
734 1.1 isaki
735 1.1 isaki DPRINTF(D_TRACE, ("SLRCstart "));
736 1.1 isaki
737 1.1 isaki req = &xfer->request;
738 1.1 isaki
739 1.1 isaki len = UGETW(req->wLength);
740 1.1 isaki value = UGETW(req->wValue);
741 1.1 isaki index = UGETW(req->wIndex);
742 1.1 isaki
743 1.1 isaki if (len)
744 1.1 isaki buf = KERNADDR(&xfer->dmabuf, 0);
745 1.1 isaki
746 1.1 isaki #ifdef SLHCI_DEBUG
747 1.1 isaki if ((slhci_debud & D_TRACE))
748 1.1 isaki print_req_hub(req);
749 1.1 isaki #endif
750 1.1 isaki
751 1.1 isaki #define C(x,y) ((x) | ((y) << 8))
752 1.1 isaki switch (C(req->bRequest, req->bmRequestType)) {
753 1.1 isaki case C(UR_CLEAR_FEATURE, UT_WRITE_DEVICE):
754 1.1 isaki case C(UR_CLEAR_FEATURE, UT_WRITE_INTERFACE):
755 1.1 isaki case C(UR_CLEAR_FEATURE, UT_WRITE_ENDPOINT):
756 1.1 isaki DPRINTF(D_MSG, ("UR_CLEAR_FEATURE "));
757 1.1 isaki break;
758 1.1 isaki case C(UR_GET_CONFIG, UT_READ_DEVICE):
759 1.1 isaki DPRINTF(D_MSG, ("UR_GET_CONFIG "));
760 1.1 isaki if (len > 0) {
761 1.1 isaki *(u_int8_t *)buf = sc->sc_conf;
762 1.1 isaki totlen = 1;
763 1.1 isaki }
764 1.1 isaki break;
765 1.1 isaki case C(UR_GET_DESCRIPTOR, UT_READ_DEVICE):
766 1.1 isaki switch (value >> 8) {
767 1.1 isaki case UDESC_DEVICE:
768 1.1 isaki DPRINTF(D_MSG, ("UDESC_DEVICE "));
769 1.1 isaki if ((value & 0xff) != 0) {
770 1.1 isaki error = USBD_IOERROR;
771 1.1 isaki goto ret;
772 1.1 isaki }
773 1.1 isaki totlen = l = min(len, USB_DEVICE_DESCRIPTOR_SIZE);
774 1.1 isaki memcpy(buf, &slhci_devd, l);
775 1.1 isaki break;
776 1.1 isaki case UDESC_CONFIG:
777 1.1 isaki DPRINTF(D_MSG, ("UDESC_CONFIG "));
778 1.1 isaki if ((value & 0xff) != 0) {
779 1.1 isaki error = USBD_IOERROR;
780 1.1 isaki goto ret;
781 1.1 isaki }
782 1.1 isaki totlen = l = min(len, USB_CONFIG_DESCRIPTOR_SIZE);
783 1.1 isaki memcpy(buf, &slhci_confd, l);
784 1.1 isaki buf = (char *)buf + l;
785 1.1 isaki len -= l;
786 1.1 isaki
787 1.1 isaki l = min(len, USB_INTERFACE_DESCRIPTOR_SIZE);
788 1.1 isaki totlen += l;
789 1.1 isaki memcpy(buf, &slhci_ifcd, l);
790 1.1 isaki buf = (char *)buf + l;
791 1.1 isaki len -= l;
792 1.1 isaki
793 1.1 isaki l = min(len, USB_ENDPOINT_DESCRIPTOR_SIZE);
794 1.1 isaki totlen += l;
795 1.1 isaki memcpy(buf, &slhci_endpd, l);
796 1.1 isaki break;
797 1.1 isaki case UDESC_STRING:
798 1.1 isaki DPRINTF(D_MSG, ("UDESC_STR "));
799 1.1 isaki if (len == 0)
800 1.1 isaki break;
801 1.1 isaki *(u_int8_t *)buf = 0;
802 1.1 isaki totlen = 1;
803 1.1 isaki switch (value & 0xff) {
804 1.1 isaki case 0:
805 1.1 isaki break;
806 1.1 isaki case 1: /* Vendor */
807 1.1 isaki totlen = slhci_str(buf, len, "ScanLogic");
808 1.1 isaki break;
809 1.1 isaki case 2: /* Product */
810 1.1 isaki sprintf(slbuf, "%s root hub", sltypestr[sc->sc_sltype]);
811 1.1 isaki totlen = slhci_str(buf, len, slbuf);
812 1.1 isaki break;
813 1.1 isaki default:
814 1.1 isaki printf("strerr%d ", value & 0xff);
815 1.1 isaki break;
816 1.1 isaki }
817 1.1 isaki break;
818 1.1 isaki default:
819 1.1 isaki printf("unknownGetDescriptor=%x", value);
820 1.1 isaki error = USBD_IOERROR;
821 1.1 isaki break;
822 1.1 isaki }
823 1.1 isaki break;
824 1.1 isaki case C(UR_GET_INTERFACE, UT_READ_INTERFACE):
825 1.1 isaki /* Get Interface, 9.4.4 */
826 1.1 isaki if (len > 0) {
827 1.1 isaki *(u_int8_t *)buf = 0;
828 1.1 isaki totlen = 1;
829 1.1 isaki }
830 1.1 isaki break;
831 1.1 isaki case C(UR_GET_STATUS, UT_READ_DEVICE):
832 1.1 isaki /* Get Status from device, 9.4.5 */
833 1.1 isaki if (len > 1) {
834 1.1 isaki USETW(((usb_status_t *)buf)->wStatus, UDS_SELF_POWERED);
835 1.1 isaki totlen = 2;
836 1.1 isaki }
837 1.1 isaki break;
838 1.1 isaki case C(UR_GET_STATUS, UT_READ_INTERFACE):
839 1.1 isaki case C(UR_GET_STATUS, UT_READ_ENDPOINT):
840 1.1 isaki /* Get Status from interface, endpoint, 9.4.5 */
841 1.1 isaki if (len > 1) {
842 1.1 isaki USETW(((usb_status_t *)buf)->wStatus, 0);
843 1.1 isaki totlen = 2;
844 1.1 isaki }
845 1.1 isaki break;
846 1.1 isaki case C(UR_SET_ADDRESS, UT_WRITE_DEVICE):
847 1.1 isaki /* Set Address, 9.4.6 */
848 1.1 isaki DPRINTF(D_MSG, ("UR_SET_ADDRESS "));
849 1.1 isaki if (value >= USB_MAX_DEVICES) {
850 1.1 isaki error = USBD_IOERROR;
851 1.1 isaki goto ret;
852 1.1 isaki }
853 1.1 isaki sc->sc_addr = value;
854 1.1 isaki break;
855 1.1 isaki case C(UR_SET_CONFIG, UT_WRITE_DEVICE):
856 1.1 isaki /* Set Configuration, 9.4.7 */
857 1.1 isaki DPRINTF(D_MSG, ("UR_SET_CONFIG "));
858 1.1 isaki if (value != 0 && value != 1) {
859 1.1 isaki error = USBD_IOERROR;
860 1.1 isaki goto ret;
861 1.1 isaki }
862 1.1 isaki sc->sc_conf = value;
863 1.1 isaki break;
864 1.1 isaki case C(UR_SET_DESCRIPTOR, UT_WRITE_DEVICE):
865 1.1 isaki /* Set Descriptor, 9.4.8, not supported */
866 1.1 isaki DPRINTF(D_MSG, ("UR_SET_DESCRIPTOR,WRITE_DEVICE not supported\n"));
867 1.1 isaki break;
868 1.1 isaki case C(UR_SET_FEATURE, UT_WRITE_DEVICE):
869 1.1 isaki case C(UR_SET_FEATURE, UT_WRITE_INTERFACE):
870 1.1 isaki case C(UR_SET_FEATURE, UT_WRITE_ENDPOINT):
871 1.1 isaki /* Set Feature, 9.4.9, not supported */
872 1.1 isaki DPRINTF(D_MSG, ("UR_SET_FEATURE not supported\n"));
873 1.1 isaki error = USBD_IOERROR;
874 1.1 isaki break;
875 1.1 isaki case C(UR_SET_INTERFACE, UT_WRITE_INTERFACE):
876 1.1 isaki /* Set Interface, 9.4.10, not supported */
877 1.1 isaki break;
878 1.1 isaki case C(UR_SYNCH_FRAME, UT_WRITE_ENDPOINT):
879 1.1 isaki /* Synch Frame, 9.4.11, not supported */
880 1.1 isaki break;
881 1.1 isaki
882 1.1 isaki /*
883 1.1 isaki * Hub specific requests
884 1.1 isaki */
885 1.1 isaki case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_DEVICE):
886 1.1 isaki /* Clear Hub Feature, 11.16.2.1, not supported */
887 1.1 isaki DPRINTF(D_MSG, ("ClearHubFeature not supported\n"));
888 1.1 isaki break;
889 1.1 isaki case C(UR_CLEAR_FEATURE, UT_WRITE_CLASS_OTHER):
890 1.1 isaki /* Clear Port Feature, 11.16.2.2 */
891 1.1 isaki if (index != 1) {
892 1.1 isaki error = USBD_IOERROR;
893 1.1 isaki goto ret;
894 1.1 isaki }
895 1.1 isaki switch (value) {
896 1.1 isaki case UHF_PORT_POWER:
897 1.1 isaki DPRINTF(D_MSG, ("POWER_OFF "));
898 1.1 isaki sc->sc_powerstat = POWER_OFF;
899 1.1 isaki /* x68k Nereid USB controller needs it */
900 1.1 isaki if (sc->sc_enable_power)
901 1.1 isaki sc->sc_enable_power(sc, sc->sc_powerstat);
902 1.1 isaki break;
903 1.1 isaki case UHF_PORT_SUSPEND:
904 1.1 isaki DPRINTF(D_MSG, ("SUSPEND "));
905 1.1 isaki sl11write(sc, SL11_CTRL,
906 1.1 isaki sl11read(sc, SL11_CTRL) & ~SL11_CTRL_SUSPEND);
907 1.1 isaki break;
908 1.1 isaki case UHF_C_PORT_CONNECTION:
909 1.1 isaki sc->sc_change &= ~UPS_C_CONNECT_STATUS;
910 1.1 isaki break;
911 1.1 isaki case UHF_C_PORT_RESET:
912 1.1 isaki sc->sc_change &= ~UPS_C_PORT_RESET;
913 1.1 isaki break;
914 1.1 isaki case UHF_PORT_ENABLE:
915 1.1 isaki break;
916 1.1 isaki case UHF_C_PORT_SUSPEND:
917 1.1 isaki case UHF_C_PORT_ENABLE:
918 1.1 isaki case UHF_C_PORT_OVER_CURRENT:
919 1.1 isaki default:
920 1.1 isaki printf("ClrPortFeatERR:value=0x%x ", value);
921 1.1 isaki error = USBD_IOERROR;
922 1.1 isaki break;
923 1.1 isaki }
924 1.1 isaki //DPRINTF(D_XFER, ("CH=%04x ", sc->sc_change));
925 1.1 isaki break;
926 1.1 isaki case C(UR_GET_BUS_STATE, UT_READ_CLASS_OTHER):
927 1.1 isaki /* Get Bus State, 11.16.2.3, not supported */
928 1.1 isaki /* shall return a STALL... */
929 1.1 isaki break;
930 1.1 isaki case C(UR_GET_DESCRIPTOR, UT_READ_CLASS_DEVICE):
931 1.1 isaki /* Get Hub Descriptor, 11.16.2.4 */
932 1.1 isaki if (value != 0) {
933 1.1 isaki error = USBD_IOERROR;
934 1.1 isaki goto ret;
935 1.1 isaki }
936 1.1 isaki l = min(len, USB_HUB_DESCRIPTOR_SIZE);
937 1.1 isaki totlen = l;
938 1.1 isaki memcpy(buf, &slhci_hubd, l);
939 1.1 isaki break;
940 1.1 isaki case C(UR_GET_STATUS, UT_READ_CLASS_DEVICE):
941 1.1 isaki /* Get Hub Status, 11.16.2.5 */
942 1.1 isaki DPRINTF(D_MSG, ("UR_GET_STATUS RCD"));
943 1.1 isaki if (len != 4) {
944 1.1 isaki error = USBD_IOERROR;
945 1.1 isaki goto ret;
946 1.1 isaki }
947 1.1 isaki memset(buf, 0, len);
948 1.1 isaki totlen = len;
949 1.1 isaki break;
950 1.1 isaki case C(UR_GET_STATUS, UT_READ_CLASS_OTHER):
951 1.1 isaki /* Get Port Status, 11.16.2.6 */
952 1.1 isaki if (index != 1 || len != 4) {
953 1.1 isaki printf("index=%d,len=%d ", index, len);
954 1.1 isaki error = USBD_IOERROR;
955 1.1 isaki goto ret;
956 1.1 isaki }
957 1.1 isaki /*
958 1.1 isaki * change
959 1.1 isaki * o port is always enabled.
960 1.1 isaki * o cannot detect over current.
961 1.1 isaki */
962 1.1 isaki s = splusb();
963 1.1 isaki sc->sc_change &= ~(UPS_C_CONNECT_STATUS | UPS_C_PORT_RESET);
964 1.1 isaki if ((sc->sc_flags & SLF_INSERT)) {
965 1.1 isaki sc->sc_flags &= ~SLF_INSERT;
966 1.1 isaki sc->sc_change |= UPS_C_CONNECT_STATUS;
967 1.1 isaki }
968 1.1 isaki if ((sc->sc_flags & SLF_RESET)) {
969 1.1 isaki sc->sc_flags &= ~SLF_RESET;
970 1.1 isaki sc->sc_change |= UPS_C_PORT_RESET;
971 1.1 isaki }
972 1.1 isaki splx(s);
973 1.1 isaki /*
974 1.1 isaki * XXX It can recognize that device is detached,
975 1.1 isaki * while there is sl11_speed() here.
976 1.1 isaki */
977 1.1 isaki if (sc->sc_change)
978 1.1 isaki sl11_speed(sc);
979 1.1 isaki /*
980 1.1 isaki * status
981 1.1 isaki * o port is always enabled.
982 1.1 isaki * o cannot detect over current.
983 1.1 isaki */
984 1.1 isaki status = 0;
985 1.1 isaki if (sc->sc_connect)
986 1.1 isaki status |= UPS_CURRENT_CONNECT_STATUS | UPS_PORT_ENABLED;
987 1.1 isaki r = sl11read(sc, SL11_CTRL);
988 1.1 isaki if (r & SL11_CTRL_SUSPEND)
989 1.1 isaki status |= UPS_SUSPEND;
990 1.1 isaki if (sc->sc_powerstat)
991 1.1 isaki status |= UPS_PORT_POWER;
992 1.1 isaki if (!sc->sc_fullspeed)
993 1.1 isaki status |= UPS_LOW_SPEED;
994 1.1 isaki
995 1.1 isaki //DPRINTF(D_XFER, ("ST=%04x,CH=%04x ", status, sc->sc_change));
996 1.1 isaki USETW(ps.wPortStatus, status);
997 1.1 isaki USETW(ps.wPortChange, sc->sc_change);
998 1.1 isaki l = min(len, sizeof(ps));
999 1.1 isaki memcpy(buf, &ps, l);
1000 1.1 isaki totlen = l;
1001 1.1 isaki break;
1002 1.1 isaki case C(UR_SET_DESCRIPTOR, UT_WRITE_CLASS_DEVICE):
1003 1.1 isaki /* Set Hub Descriptor, 11.16.2.7, not supported */
1004 1.1 isaki /* STALL ? */
1005 1.1 isaki error = USBD_IOERROR;
1006 1.1 isaki break;
1007 1.1 isaki case C(UR_SET_FEATURE, UT_WRITE_CLASS_DEVICE):
1008 1.1 isaki /* Set Hub Feature, 11.16.2.8, not supported */
1009 1.1 isaki break;
1010 1.1 isaki case C(UR_SET_FEATURE, UT_WRITE_CLASS_OTHER):
1011 1.1 isaki /* Set Port Feature, 11.16.2.9 */
1012 1.1 isaki if (index != 1) {
1013 1.1 isaki printf("index=%d ", index);
1014 1.1 isaki error = USBD_IOERROR;
1015 1.1 isaki goto ret;
1016 1.1 isaki }
1017 1.1 isaki switch (value) {
1018 1.1 isaki case UHF_PORT_RESET:
1019 1.1 isaki DPRINTF(D_MSG, ("PORT_RESET "));
1020 1.1 isaki sl11_reset(sc);
1021 1.1 isaki sl11_speed(sc);
1022 1.1 isaki sc->sc_change = 0;
1023 1.1 isaki break;
1024 1.1 isaki case UHF_PORT_POWER:
1025 1.1 isaki DPRINTF(D_MSG, ("PORT_POWER "));
1026 1.1 isaki sc->sc_powerstat = POWER_ON;
1027 1.1 isaki /* x68k Nereid USB controller needs it */
1028 1.1 isaki if (sc->sc_enable_power)
1029 1.1 isaki sc->sc_enable_power(sc, sc->sc_powerstat);
1030 1.1 isaki delay_ms(25);
1031 1.1 isaki break;
1032 1.1 isaki default:
1033 1.1 isaki printf("SetPortFeatERR=0x%x ", value);
1034 1.1 isaki error = USBD_IOERROR;
1035 1.1 isaki break;
1036 1.1 isaki }
1037 1.1 isaki break;
1038 1.1 isaki default:
1039 1.1 isaki DPRINTF(D_MSG, ("ioerr(UR=%02x,UT=%02x) ",
1040 1.1 isaki req->bRequest, req->bmRequestType));
1041 1.1 isaki error = USBD_IOERROR;
1042 1.1 isaki goto ret;
1043 1.1 isaki }
1044 1.1 isaki xfer->actlen = totlen;
1045 1.1 isaki error = USBD_NORMAL_COMPLETION;
1046 1.1 isaki ret:
1047 1.1 isaki xfer->status = error;
1048 1.1 isaki s = splusb();
1049 1.1 isaki usb_transfer_complete(xfer);
1050 1.1 isaki splx(s);
1051 1.1 isaki return USBD_IN_PROGRESS;
1052 1.1 isaki }
1053 1.1 isaki
1054 1.1 isaki void
1055 1.1 isaki slhci_root_ctrl_abort(usbd_xfer_handle xfer)
1056 1.1 isaki {
1057 1.1 isaki DPRINTF(D_TRACE, ("SLRCabort "));
1058 1.1 isaki }
1059 1.1 isaki
1060 1.1 isaki void
1061 1.1 isaki slhci_root_ctrl_close(usbd_pipe_handle pipe)
1062 1.1 isaki {
1063 1.1 isaki DPRINTF(D_TRACE, ("SLRCclose "));
1064 1.1 isaki }
1065 1.1 isaki
1066 1.1 isaki void
1067 1.1 isaki slhci_root_ctrl_done(usbd_xfer_handle xfer)
1068 1.1 isaki {
1069 1.1 isaki DPRINTF(D_TRACE, ("SLRCdone\n"));
1070 1.1 isaki }
1071 1.1 isaki
1072 1.1 isaki static usbd_status
1073 1.1 isaki slhci_root_intr_transfer(usbd_xfer_handle xfer)
1074 1.1 isaki {
1075 1.1 isaki usbd_status error;
1076 1.1 isaki
1077 1.1 isaki DPRINTF(D_TRACE, ("SLRItransfer "));
1078 1.1 isaki
1079 1.1 isaki /* Insert last in queue */
1080 1.1 isaki error = usb_insert_transfer(xfer);
1081 1.1 isaki if (error)
1082 1.1 isaki return error;
1083 1.1 isaki
1084 1.1 isaki /*
1085 1.1 isaki * Pipe isn't running (otherwise error would be USBD_INPROG),
1086 1.1 isaki * start first.
1087 1.1 isaki */
1088 1.1 isaki return slhci_root_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
1089 1.1 isaki }
1090 1.1 isaki
1091 1.1 isaki static usbd_status
1092 1.1 isaki slhci_root_intr_start(usbd_xfer_handle xfer)
1093 1.1 isaki {
1094 1.1 isaki usbd_pipe_handle pipe = xfer->pipe;
1095 1.1 isaki struct slhci_softc *sc = (struct slhci_softc *)pipe->device->bus;
1096 1.1 isaki
1097 1.1 isaki DPRINTF(D_TRACE, ("SLRIstart "));
1098 1.1 isaki
1099 1.1 isaki sc->sc_interval = MS_TO_TICKS(xfer->pipe->endpoint->edesc->bInterval);
1100 1.1 isaki usb_callout(sc->sc_poll_handle, sc->sc_interval, slhci_poll_hub, xfer);
1101 1.1 isaki sc->sc_intr_xfer = xfer;
1102 1.1 isaki return USBD_IN_PROGRESS;
1103 1.1 isaki }
1104 1.1 isaki
1105 1.1 isaki static void
1106 1.1 isaki slhci_root_intr_abort(usbd_xfer_handle xfer)
1107 1.1 isaki {
1108 1.1 isaki DPRINTF(D_TRACE, ("SLRIabort "));
1109 1.1 isaki }
1110 1.1 isaki
1111 1.1 isaki static void
1112 1.1 isaki slhci_root_intr_close(usbd_pipe_handle pipe)
1113 1.1 isaki {
1114 1.1 isaki struct slhci_softc *sc = (struct slhci_softc *)pipe->device->bus;
1115 1.1 isaki
1116 1.1 isaki DPRINTF(D_TRACE, ("SLRIclose "));
1117 1.1 isaki
1118 1.1 isaki usb_uncallout(sc->sc_poll_handle, slhci_poll_hub, sc->sc_intr_xfer);
1119 1.1 isaki sc->sc_intr_xfer = NULL;
1120 1.1 isaki }
1121 1.1 isaki
1122 1.1 isaki static void
1123 1.1 isaki slhci_root_intr_done(usbd_xfer_handle xfer)
1124 1.1 isaki {
1125 1.1 isaki //DPRINTF(D_XFER, ("RIdn "));
1126 1.1 isaki }
1127 1.1 isaki
1128 1.1 isaki static usbd_status
1129 1.1 isaki slhci_device_ctrl_transfer(usbd_xfer_handle xfer)
1130 1.1 isaki {
1131 1.1 isaki usbd_status error;
1132 1.1 isaki
1133 1.1 isaki DPRINTF(D_TRACE, ("C"));
1134 1.1 isaki
1135 1.1 isaki error = usb_insert_transfer(xfer);
1136 1.1 isaki if (error)
1137 1.1 isaki return error;
1138 1.1 isaki
1139 1.1 isaki return slhci_device_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
1140 1.1 isaki }
1141 1.1 isaki
1142 1.1 isaki static usbd_status
1143 1.1 isaki slhci_device_ctrl_start(usbd_xfer_handle xfer)
1144 1.1 isaki {
1145 1.1 isaki usb_device_request_t *req = &xfer->request;
1146 1.1 isaki usbd_pipe_handle pipe = xfer->pipe;
1147 1.1 isaki struct slhci_softc *sc = (struct slhci_softc *)pipe->device->bus;
1148 1.1 isaki usbd_status status = USBD_NORMAL_COMPLETION;
1149 1.1 isaki void *buf;
1150 1.1 isaki int pid = SL11_PID_OUT;
1151 1.1 isaki int len, actlen, size;
1152 1.1 isaki int s;
1153 1.1 isaki u_int8_t toggle = 0;
1154 1.1 isaki
1155 1.1 isaki DPRINTF(D_TRACE, ("st "));
1156 1.1 isaki #ifdef SLHCI_DEBUG
1157 1.1 isaki if ((slhci_debug & D_TRACE))
1158 1.1 isaki print_req_hub(req));
1159 1.1 isaki #endif
1160 1.1 isaki
1161 1.1 isaki /* SETUP transaction */
1162 1.1 isaki if (slhci_transaction(sc, pipe, SL11_PID_SETUP,
1163 1.1 isaki sizeof(*req), (u_char*)req, toggle) == -1) {
1164 1.1 isaki status = USBD_IOERROR;
1165 1.1 isaki goto ret;
1166 1.1 isaki }
1167 1.1 isaki toggle ^= SL11_EPCTRL_DATATOGGLE;
1168 1.1 isaki
1169 1.1 isaki /* DATA transaction */
1170 1.1 isaki actlen = 0;
1171 1.1 isaki len = UGETW(req->wLength);
1172 1.1 isaki if (len) {
1173 1.1 isaki buf = KERNADDR(&xfer->dmabuf, 0);
1174 1.1 isaki if (req->bmRequestType & UT_READ)
1175 1.1 isaki pid = SL11_PID_IN;
1176 1.1 isaki for (; actlen < len; ) {
1177 1.1 isaki size = min(len - actlen, 8/* Minimum size */);
1178 1.1 isaki if (slhci_transaction(sc, pipe, pid, size, buf, toggle) == -1)
1179 1.1 isaki break;
1180 1.1 isaki toggle ^= SL11_EPCTRL_DATATOGGLE;
1181 1.1 isaki (u_char*)buf += size;
1182 1.1 isaki actlen += size;
1183 1.1 isaki }
1184 1.1 isaki }
1185 1.1 isaki xfer->actlen = actlen;
1186 1.1 isaki
1187 1.1 isaki /* ACK (status) */
1188 1.1 isaki if (pid == SL11_PID_IN)
1189 1.1 isaki pid = SL11_PID_OUT;
1190 1.1 isaki else
1191 1.1 isaki pid = SL11_PID_IN;
1192 1.1 isaki if (slhci_transaction(sc, pipe, pid, 0, NULL, toggle) == -1)
1193 1.1 isaki status = USBD_IOERROR;
1194 1.1 isaki
1195 1.1 isaki ret:
1196 1.1 isaki xfer->status = status;
1197 1.1 isaki
1198 1.1 isaki #ifdef SLHCI_DEBUG
1199 1.1 isaki if((slhci_debug & D_TRACE) && UGETW(req->wLength) > 0){
1200 1.1 isaki int i;
1201 1.1 isaki for(i=0; i < UGETW(req->wLength); i++)
1202 1.1 isaki printf("%02x", *(unsigned char*)(KERNADDR(&xfer->dmabuf, i)));
1203 1.1 isaki printf(" ");
1204 1.1 isaki }
1205 1.1 isaki #endif
1206 1.1 isaki s = splusb();
1207 1.1 isaki usb_transfer_complete(xfer);
1208 1.1 isaki splx(s);
1209 1.1 isaki return USBD_IN_PROGRESS;
1210 1.1 isaki }
1211 1.1 isaki
1212 1.1 isaki static void
1213 1.1 isaki slhci_device_ctrl_abort(usbd_xfer_handle xfer)
1214 1.1 isaki {
1215 1.1 isaki DPRINTF(D_TRACE, ("Cab "));
1216 1.1 isaki slhci_abort_xfer(xfer, USBD_CANCELLED);
1217 1.1 isaki }
1218 1.1 isaki
1219 1.1 isaki static void
1220 1.1 isaki slhci_device_ctrl_close(usbd_pipe_handle pipe)
1221 1.1 isaki {
1222 1.1 isaki DPRINTF(D_TRACE, ("Ccl "));
1223 1.1 isaki }
1224 1.1 isaki
1225 1.1 isaki static void
1226 1.1 isaki slhci_device_ctrl_done(usbd_xfer_handle xfer)
1227 1.1 isaki {
1228 1.1 isaki DPRINTF(D_TRACE, ("Cdn "));
1229 1.1 isaki }
1230 1.1 isaki
1231 1.1 isaki static usbd_status
1232 1.1 isaki slhci_device_intr_transfer(usbd_xfer_handle xfer)
1233 1.1 isaki {
1234 1.1 isaki usbd_status error;
1235 1.1 isaki
1236 1.1 isaki DPRINTF(D_TRACE, ("INTRtrans "));
1237 1.1 isaki
1238 1.1 isaki error = usb_insert_transfer(xfer);
1239 1.1 isaki if (error)
1240 1.1 isaki return error;
1241 1.1 isaki
1242 1.1 isaki return slhci_device_intr_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
1243 1.1 isaki }
1244 1.1 isaki
1245 1.1 isaki static usbd_status
1246 1.1 isaki slhci_device_intr_start(usbd_xfer_handle xfer)
1247 1.1 isaki {
1248 1.1 isaki usbd_pipe_handle pipe = xfer->pipe;
1249 1.1 isaki struct slhci_xfer *sx;
1250 1.1 isaki
1251 1.1 isaki DPRINTF(D_TRACE, ("INTRstart "));
1252 1.1 isaki
1253 1.1 isaki sx = malloc(sizeof(*sx), M_USB, M_NOWAIT);
1254 1.1 isaki if (sx == NULL)
1255 1.1 isaki goto reterr;
1256 1.1 isaki memset(sx, 0, sizeof(*sx));
1257 1.1 isaki sx->sx_xfer = xfer;
1258 1.1 isaki xfer->hcpriv = sx;
1259 1.1 isaki
1260 1.1 isaki /* initialize callout */
1261 1.1 isaki usb_callout_init(sx->sx_callout_t);
1262 1.1 isaki usb_callout(sx->sx_callout_t,
1263 1.1 isaki MS_TO_TICKS(pipe->endpoint->edesc->bInterval),
1264 1.1 isaki slhci_poll_device, sx);
1265 1.1 isaki
1266 1.1 isaki /* ACK */
1267 1.1 isaki return USBD_IN_PROGRESS;
1268 1.1 isaki
1269 1.1 isaki reterr:
1270 1.1 isaki return USBD_IOERROR;
1271 1.1 isaki }
1272 1.1 isaki
1273 1.1 isaki static void
1274 1.1 isaki slhci_poll_device(void *arg)
1275 1.1 isaki {
1276 1.1 isaki struct slhci_xfer *sx = (struct slhci_xfer *)arg;
1277 1.1 isaki usbd_xfer_handle xfer = sx->sx_xfer;
1278 1.1 isaki usbd_pipe_handle pipe = xfer->pipe;
1279 1.1 isaki struct slhci_softc *sc = (struct slhci_softc *)pipe->device->bus;
1280 1.1 isaki void *buf;
1281 1.1 isaki int pid;
1282 1.1 isaki int r;
1283 1.1 isaki int s;
1284 1.1 isaki
1285 1.1 isaki DPRINTF(D_TRACE, ("pldev"));
1286 1.1 isaki
1287 1.1 isaki usb_callout(sx->sx_callout_t,
1288 1.1 isaki MS_TO_TICKS(pipe->endpoint->edesc->bInterval),
1289 1.1 isaki slhci_poll_device, sx);
1290 1.1 isaki
1291 1.1 isaki /* interrupt transfer */
1292 1.1 isaki pid = (UE_GET_DIR(pipe->endpoint->edesc->bEndpointAddress) == UE_DIR_IN)
1293 1.1 isaki ? SL11_PID_IN : SL11_PID_OUT;
1294 1.1 isaki buf = KERNADDR(&xfer->dmabuf, 0);
1295 1.1 isaki
1296 1.1 isaki r = slhci_transaction(sc, pipe, pid, xfer->length, buf, 0/*toggle*/);
1297 1.1 isaki if (r < 0) {
1298 1.1 isaki DPRINTF(D_MSG, ("%s error", __FUNCTION__));
1299 1.1 isaki return;
1300 1.1 isaki }
1301 1.1 isaki /* no change, return NAK */
1302 1.1 isaki if (r == 0)
1303 1.1 isaki return;
1304 1.1 isaki
1305 1.1 isaki xfer->status = USBD_NORMAL_COMPLETION;
1306 1.1 isaki s = splusb();
1307 1.1 isaki xfer->device->bus->intr_context++;
1308 1.1 isaki usb_transfer_complete(xfer);
1309 1.1 isaki xfer->device->bus->intr_context--;
1310 1.1 isaki splx(s);
1311 1.1 isaki }
1312 1.1 isaki
1313 1.1 isaki static void
1314 1.1 isaki slhci_device_intr_abort(usbd_xfer_handle xfer)
1315 1.1 isaki {
1316 1.1 isaki struct slhci_xfer *sx;
1317 1.1 isaki
1318 1.1 isaki DPRINTF(D_TRACE, ("INTRabort "));
1319 1.1 isaki
1320 1.1 isaki sx = xfer->hcpriv;
1321 1.1 isaki if (sx) {
1322 1.1 isaki usb_uncallout(sx->sx_callout_t, slhci_poll_device, sx);
1323 1.1 isaki free(sx, M_USB);
1324 1.1 isaki xfer->hcpriv = NULL;
1325 1.1 isaki } else {
1326 1.1 isaki printf("%s: sx == NULL!\n", __FUNCTION__);
1327 1.1 isaki }
1328 1.1 isaki slhci_abort_xfer(xfer, USBD_CANCELLED);
1329 1.1 isaki }
1330 1.1 isaki
1331 1.1 isaki static void
1332 1.1 isaki slhci_device_intr_close(usbd_pipe_handle pipe)
1333 1.1 isaki {
1334 1.1 isaki DPRINTF(D_TRACE, ("INTRclose "));
1335 1.1 isaki }
1336 1.1 isaki
1337 1.1 isaki static void
1338 1.1 isaki slhci_device_intr_done(usbd_xfer_handle xfer)
1339 1.1 isaki {
1340 1.1 isaki DPRINTF(D_TRACE, ("INTRdone "));
1341 1.1 isaki }
1342 1.1 isaki
1343 1.1 isaki static usbd_status
1344 1.1 isaki slhci_device_isoc_transfer(usbd_xfer_handle xfer)
1345 1.1 isaki {
1346 1.1 isaki DPRINTF(D_TRACE, ("S"));
1347 1.1 isaki return USBD_NORMAL_COMPLETION;
1348 1.1 isaki }
1349 1.1 isaki
1350 1.1 isaki static usbd_status
1351 1.1 isaki slhci_device_isoc_start(usbd_xfer_handle xfer)
1352 1.1 isaki {
1353 1.1 isaki DPRINTF(D_TRACE, ("st "));
1354 1.1 isaki return USBD_NORMAL_COMPLETION;
1355 1.1 isaki }
1356 1.1 isaki
1357 1.1 isaki static void
1358 1.1 isaki slhci_device_isoc_abort(usbd_xfer_handle xfer)
1359 1.1 isaki {
1360 1.1 isaki DPRINTF(D_TRACE, ("Sab "));
1361 1.1 isaki }
1362 1.1 isaki
1363 1.1 isaki static void
1364 1.1 isaki slhci_device_isoc_close(usbd_pipe_handle pipe)
1365 1.1 isaki {
1366 1.1 isaki DPRINTF(D_TRACE, ("Scl "));
1367 1.1 isaki }
1368 1.1 isaki
1369 1.1 isaki static void
1370 1.1 isaki slhci_device_isoc_done(usbd_xfer_handle xfer)
1371 1.1 isaki {
1372 1.1 isaki DPRINTF(D_TRACE, ("Sdn "));
1373 1.1 isaki }
1374 1.1 isaki
1375 1.1 isaki static usbd_status
1376 1.1 isaki slhci_device_bulk_transfer(usbd_xfer_handle xfer)
1377 1.1 isaki {
1378 1.1 isaki DPRINTF(D_TRACE, ("B"));
1379 1.1 isaki return USBD_NORMAL_COMPLETION;
1380 1.1 isaki }
1381 1.1 isaki
1382 1.1 isaki static usbd_status
1383 1.1 isaki slhci_device_bulk_start(usbd_xfer_handle xfer)
1384 1.1 isaki {
1385 1.1 isaki DPRINTF(D_TRACE, ("st "));
1386 1.1 isaki return USBD_NORMAL_COMPLETION;
1387 1.1 isaki }
1388 1.1 isaki
1389 1.1 isaki static void
1390 1.1 isaki slhci_device_bulk_abort(usbd_xfer_handle xfer)
1391 1.1 isaki {
1392 1.1 isaki DPRINTF(D_TRACE, ("Bab "));
1393 1.1 isaki }
1394 1.1 isaki
1395 1.1 isaki static void
1396 1.1 isaki slhci_device_bulk_close(usbd_pipe_handle pipe)
1397 1.1 isaki {
1398 1.1 isaki DPRINTF(D_TRACE, ("Bcl "));
1399 1.1 isaki }
1400 1.1 isaki
1401 1.1 isaki static void
1402 1.1 isaki slhci_device_bulk_done(usbd_xfer_handle xfer)
1403 1.1 isaki {
1404 1.1 isaki DPRINTF(D_TRACE, ("Bdn "));
1405 1.1 isaki }
1406 1.1 isaki
1407 1.1 isaki #define DATA0_RD (0x03)
1408 1.1 isaki #define DATA0_WR (0x07)
1409 1.1 isaki #define SLHCI_TIMEOUT (5000)
1410 1.1 isaki
1411 1.1 isaki /*
1412 1.1 isaki * Do a transaction.
1413 1.1 isaki * return 1 if ACK, 0 if NAK, -1 if error.
1414 1.1 isaki */
1415 1.1 isaki static int
1416 1.1 isaki slhci_transaction(struct slhci_softc *sc, usbd_pipe_handle pipe,
1417 1.1 isaki u_int8_t pid, int len, u_char *buf, u_int8_t toggle)
1418 1.1 isaki {
1419 1.1 isaki #ifdef SLHCI_DEBUG
1420 1.1 isaki char str[64];
1421 1.1 isaki int i;
1422 1.1 isaki #endif
1423 1.1 isaki int timeout;
1424 1.1 isaki int ls_via_hub = 0;
1425 1.1 isaki int pl;
1426 1.1 isaki u_int8_t isr;
1427 1.1 isaki u_int8_t result = 0;
1428 1.1 isaki u_int8_t devaddr = pipe->device->address;
1429 1.1 isaki u_int8_t endpointaddr = pipe->endpoint->edesc->bEndpointAddress;
1430 1.1 isaki u_int8_t endpoint;
1431 1.1 isaki u_int8_t cmd = DATA0_RD;
1432 1.1 isaki
1433 1.1 isaki endpoint = UE_GET_ADDR(endpointaddr);
1434 1.1 isaki DPRINTF(D_XFER, ("\n(%x,%d%s%d,%d) ",
1435 1.1 isaki pid, len, (pid == SL11_PID_IN) ? "<-" : "->", devaddr, endpoint));
1436 1.1 isaki
1437 1.1 isaki /* Set registers */
1438 1.1 isaki sl11write(sc, SL11_E0ADDR, 0x40);
1439 1.1 isaki sl11write(sc, SL11_E0LEN, len);
1440 1.1 isaki sl11write(sc, SL11_E0PID, (pid << 4) + endpoint);
1441 1.1 isaki sl11write(sc, SL11_E0DEV, devaddr);
1442 1.1 isaki
1443 1.1 isaki /* Set buffer unless PID_IN */
1444 1.1 isaki if (pid != SL11_PID_IN) {
1445 1.1 isaki if (len > 0)
1446 1.1 isaki sl11write_region(sc, 0x40, buf, len);
1447 1.1 isaki cmd = DATA0_WR;
1448 1.1 isaki }
1449 1.1 isaki
1450 1.1 isaki /* timing ? */
1451 1.1 isaki pl = (len >> 3) + 3;
1452 1.1 isaki
1453 1.1 isaki /* Low speed device via HUB */
1454 1.1 isaki /* XXX does not work... */
1455 1.1 isaki if ((sc->sc_fullspeed) && pipe->device->speed == USB_SPEED_LOW) {
1456 1.1 isaki pl = len + 16;
1457 1.1 isaki cmd |= SL11_EPCTRL_PREAMBLE;
1458 1.1 isaki
1459 1.1 isaki /*
1460 1.1 isaki * SL811HS/T rev 1.2 has a bug, when it got PID_IN
1461 1.1 isaki * from LowSpeed device via HUB.
1462 1.1 isaki */
1463 1.1 isaki if (sc->sc_sltype == SLTYPE_SL811HS_R12 && pid == SL11_PID_IN) {
1464 1.1 isaki ls_via_hub = 1;
1465 1.1 isaki DPRINTF(D_MSG, ("LSvH "));
1466 1.1 isaki }
1467 1.1 isaki }
1468 1.1 isaki
1469 1.1 isaki /* timing ? */
1470 1.1 isaki if (sl11read(sc, SL811_CSOF) <= (u_int8_t)pl)
1471 1.1 isaki cmd |= SL11_EPCTRL_SOF;
1472 1.1 isaki
1473 1.1 isaki /* Transfer */
1474 1.1 isaki sl11write(sc, SL11_ISR, 0xff);
1475 1.1 isaki sl11write(sc, SL11_E0CTRL, cmd | toggle);
1476 1.1 isaki
1477 1.1 isaki /* Polling */
1478 1.1 isaki for (timeout = SLHCI_TIMEOUT; timeout; timeout--) {
1479 1.1 isaki isr = sl11read(sc, SL11_ISR);
1480 1.1 isaki if ((isr & SL11_ISR_USBA))
1481 1.1 isaki break;
1482 1.1 isaki }
1483 1.1 isaki
1484 1.1 isaki /* Check result status */
1485 1.1 isaki result = sl11read(sc, SL11_E0STAT);
1486 1.1 isaki if (!(result & SL11_EPSTAT_NAK) && ls_via_hub) {
1487 1.1 isaki /* Resend PID_IN within 20usec */
1488 1.1 isaki sl11write(sc, SL11_ISR, 0xff);
1489 1.1 isaki sl11write(sc, SL11_E0CTRL, SL11_EPCTRL_ARM);
1490 1.1 isaki }
1491 1.1 isaki
1492 1.1 isaki sl11write(sc, SL11_ISR, 0xff);
1493 1.1 isaki
1494 1.1 isaki DPRINTF(D_XFER, ("t=%d i=%x ", SLHCI_TIMEOUT - timeout, isr));
1495 1.1 isaki #if SLHCI_DEBUG
1496 1.1 isaki bitmask_snprintf(result,
1497 1.1 isaki "\20\x8STALL\7NAK\6OV\5SETUP\4DATA1\3TIMEOUT\2ERR\1ACK",
1498 1.1 isaki str, sizeof(str));
1499 1.1 isaki DPRINTF(D_XFER, ("STAT=%s ", str));
1500 1.1 isaki #endif
1501 1.1 isaki
1502 1.1 isaki if ((result & SL11_EPSTAT_ERROR))
1503 1.1 isaki return -1;
1504 1.1 isaki
1505 1.1 isaki if ((result & SL11_EPSTAT_NAK))
1506 1.1 isaki return 0;
1507 1.1 isaki
1508 1.1 isaki /* Read buffer if PID_IN */
1509 1.1 isaki if (pid == SL11_PID_IN && len > 0) {
1510 1.1 isaki sl11read_region(sc, buf, 0x40, len);
1511 1.1 isaki #if SLHCI_DEBUG
1512 1.1 isaki for (i = 0; i < len; i++)
1513 1.1 isaki DPRINTF(D_XFER, ("%02X ", buf[i]));
1514 1.1 isaki #endif
1515 1.1 isaki }
1516 1.1 isaki
1517 1.1 isaki return 1;
1518 1.1 isaki }
1519 1.1 isaki
1520 1.1 isaki void
1521 1.1 isaki slhci_abort_xfer(usbd_xfer_handle xfer, usbd_status status)
1522 1.1 isaki {
1523 1.1 isaki xfer->status = status;
1524 1.1 isaki usb_transfer_complete(xfer);
1525 1.1 isaki }
1526 1.1 isaki
1527 1.1 isaki void
1528 1.1 isaki slhci_device_clear_toggle(usbd_pipe_handle pipe)
1529 1.1 isaki {
1530 1.1 isaki DPRINTF(D_TRACE, ("SLdevice_clear_toggle "));
1531 1.1 isaki }
1532 1.1 isaki
1533 1.1 isaki #ifdef SLHCI_DEBUG
1534 1.1 isaki void
1535 1.1 isaki print_req(usb_device_request_t *r)
1536 1.1 isaki {
1537 1.1 isaki char *xmes[]={
1538 1.1 isaki "GETSTAT",
1539 1.1 isaki "CLRFEAT",
1540 1.1 isaki "res",
1541 1.1 isaki "SETFEAT",
1542 1.1 isaki "res",
1543 1.1 isaki "SETADDR",
1544 1.1 isaki "GETDESC",
1545 1.1 isaki "SETDESC",
1546 1.1 isaki "GETCONF",
1547 1.1 isaki "SETCONF",
1548 1.1 isaki "GETIN/F",
1549 1.1 isaki "SETIN/F",
1550 1.1 isaki "SYNC_FR"
1551 1.1 isaki };
1552 1.1 isaki int req, type, value, index, len;
1553 1.1 isaki
1554 1.1 isaki req = r->bRequest;
1555 1.1 isaki type = r->bmRequestType;
1556 1.1 isaki value = UGETW(r->wValue);
1557 1.1 isaki index = UGETW(r->wIndex);
1558 1.1 isaki len = UGETW(r->wLength);
1559 1.1 isaki
1560 1.1 isaki printf("%x,%s,v=%d,i=%d,l=%d ",
1561 1.1 isaki type, xmes[req], value, index, len);
1562 1.1 isaki }
1563 1.1 isaki
1564 1.1 isaki void
1565 1.1 isaki print_req_hub(usb_device_request_t *r)
1566 1.1 isaki {
1567 1.1 isaki struct {
1568 1.1 isaki int req;
1569 1.1 isaki int type;
1570 1.1 isaki char *str;
1571 1.1 isaki } conf[] = {
1572 1.1 isaki { 1, 0x20, "ClrHubFeat" },
1573 1.1 isaki { 1, 0x23, "ClrPortFeat" },
1574 1.1 isaki { 2, 0xa3, "GetBusState" },
1575 1.1 isaki { 6, 0xa0, "GetHubDesc" },
1576 1.1 isaki { 0, 0xa0, "GetHubStat" },
1577 1.1 isaki { 0, 0xa3, "GetPortStat" },
1578 1.1 isaki { 7, 0x20, "SetHubDesc" },
1579 1.1 isaki { 3, 0x20, "SetHubFeat" },
1580 1.1 isaki { 3, 0x23, "SetPortFeat" },
1581 1.1 isaki {-1, 0, NULL},
1582 1.1 isaki };
1583 1.1 isaki int i;
1584 1.1 isaki int value, index, len;
1585 1.1 isaki
1586 1.1 isaki value = UGETW(r->wValue);
1587 1.1 isaki index = UGETW(r->wIndex);
1588 1.1 isaki len = UGETW(r->wLength);
1589 1.1 isaki for (i = 0; ; i++) {
1590 1.1 isaki if (conf[i].req == -1 )
1591 1.1 isaki return print_req(r);
1592 1.1 isaki if (r->bmRequestType == conf[i].type && r->bRequest == conf[i].req) {
1593 1.1 isaki printf("%s", conf[i].str);
1594 1.1 isaki break;
1595 1.1 isaki }
1596 1.1 isaki }
1597 1.1 isaki printf(",v=%d,i=%d,l=%d ", value, index, len);
1598 1.1 isaki }
1599 1.1 isaki
1600 1.1 isaki void
1601 1.1 isaki print_dumpreg(struct slhci_softc *sc)
1602 1.1 isaki {
1603 1.1 isaki printf("00=%02x,01=%02x,02=%02x,03=%02x,04=%02x,"
1604 1.1 isaki "08=%02x,09=%02x,0A=%02x,0B=%02x,0C=%02x,",
1605 1.1 isaki sl11read(sc, 0), sl11read(sc, 1),
1606 1.1 isaki sl11read(sc, 2), sl11read(sc, 3),
1607 1.1 isaki sl11read(sc, 4), sl11read(sc, 8),
1608 1.1 isaki sl11read(sc, 9), sl11read(sc, 10),
1609 1.1 isaki sl11read(sc, 11), sl11read(sc, 12)
1610 1.1 isaki );
1611 1.1 isaki printf("CR1=%02x,IER=%02x,0D=%02x,0E=%02x,0F=%02x ",
1612 1.1 isaki sl11read(sc, 5), sl11read(sc, 6),
1613 1.1 isaki sl11read(sc, 13), sl11read(sc, 14), sl11read(sc, 15)
1614 1.1 isaki );
1615 1.1 isaki }
1616 1.1 isaki
1617 1.1 isaki void
1618 1.1 isaki print_xfer(usbd_xfer_handle xfer)
1619 1.1 isaki {
1620 1.1 isaki printf("xfer: length=%d, actlen=%d, flags=%x, timeout=%d,",
1621 1.1 isaki xfer->length, xfer->actlen, xfer->flags, xfer->timeout);
1622 1.1 isaki printf("request{ ");
1623 1.1 isaki print_req_hub(&xfer->request);
1624 1.1 isaki printf("} ");
1625 1.1 isaki }
1626 1.1 isaki #endif /* SLHCI_DEBUG */
1627