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