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