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