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