[BACK]Return to pxa27x_udc.c CVS log [TXT][DIR] Up to [local] / sys / arch / arm / xscale

Annotation of sys/arch/arm/xscale/pxa27x_udc.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: pxa27x_udc.c,v 1.22 2007/06/14 06:55:10 mbalmer Exp $ */
                      2:
                      3: /*
                      4:  * Copyright (c) 2007 Dale Rahn <drahn@openbsd.org>
                      5:  * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
                      6:  * Copyright (c) 2005 David Gwynne <dlg@openbsd.org>
                      7:  *
                      8:  * Permission to use, copy, modify, and distribute this software for any
                      9:  * purpose with or without fee is hereby granted, provided that the above
                     10:  * copyright notice and this permission notice appear in all copies.
                     11:  *
                     12:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     13:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     14:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     15:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     16:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     17:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     18:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     19:  */
                     20:
                     21: #include <sys/param.h>
                     22: #include <sys/systm.h>
                     23: #include <sys/device.h>
                     24: #include <sys/kernel.h>
                     25: #include <sys/malloc.h>
                     26: #include <sys/timeout.h>
                     27:
                     28: #include <machine/intr.h>
                     29: #include <machine/bus.h>
                     30:
                     31: #include <dev/usb/usb.h>
                     32: #include <dev/usb/usbdi.h>
                     33: #include <dev/usb/usbdivar.h>
                     34: #include <dev/usb/usbf.h>
                     35: #include <dev/usb/usbfvar.h>
                     36:
                     37: #include <arm/xscale/pxa2x0reg.h>
                     38: #include <arm/xscale/pxa2x0var.h>
                     39: #include <arm/xscale/pxa2x0_gpio.h>
                     40:
                     41: #include <arm/xscale/pxa27x_udcreg.h>
                     42: #define PXAUDC_EP0MAXP 16      /* XXX */
                     43: #define PXAUDC_NEP     24      /* total number of endpoints */
                     44:
                     45: #include <machine/zaurus_reg.h>        /* XXX */
                     46:
                     47: #include "usbf.h"
                     48:
                     49: struct pxaudc_xfer {
                     50:        struct usbf_xfer         xfer;
                     51:        u_int16_t                frmlen;
                     52: };
                     53:
                     54: struct pxaudc_pipe {
                     55:        struct usbf_pipe         pipe;
                     56: //     LIST_ENTRY(pxaudc_pipe)  list;
                     57: };
                     58:
                     59: struct pxaudc_softc {
                     60:        struct usbf_bus          sc_bus;
                     61:        bus_space_tag_t          sc_iot;
                     62:        bus_space_handle_t       sc_ioh;
                     63:        bus_size_t               sc_size;
                     64:        void                    *sc_ih;
                     65:        void                    *sc_conn_ih;
                     66:        void                    *sc_powerhook;
                     67:        SIMPLEQ_HEAD(,usbf_xfer) sc_free_xfers; /* recycled xfers */
                     68:        u_int32_t                sc_icr0;       /* enabled EP interrupts */
                     69:        u_int32_t                sc_icr1;       /* enabled EP interrupts */
                     70:        enum {
                     71:                EP0_SETUP,
                     72:                EP0_IN
                     73:        }                        sc_ep0state;
                     74:        u_int32_t                sc_isr0;       /* XXX deferred interrupts */
                     75:        u_int32_t                sc_isr1;       /* XXX deferred interrupts */
                     76:        u_int32_t                sc_otgisr;     /* XXX deferred interrupts */
                     77:        struct pxaudc_pipe      *sc_pipe[PXAUDC_NEP];
                     78:        int                      sc_npipe;
                     79:
                     80:        int                      sc_cn;
                     81:        int                      sc_in;
                     82:        int                      sc_isn;
                     83:        int8_t                   sc_ep_map[16];
                     84: };
                     85:
                     86: int             pxaudc_match(struct device *, void *, void *);
                     87: void            pxaudc_attach(struct device *, struct device *, void *);
                     88: int             pxaudc_detach(struct device *, int);
                     89: void            pxaudc_power(int, void *);
                     90:
                     91: int             pxaudc_is_host(void);
                     92: int             pxaudc_is_device(void);
                     93: void            pxaudc_setup(struct pxaudc_softc *);
                     94: void            pxaudc_hide(struct pxaudc_softc *);
                     95: void            pxaudc_show(struct pxaudc_softc *);
                     96:
                     97: void            pxaudc_enable(struct pxaudc_softc *);
                     98: void            pxaudc_disable(struct pxaudc_softc *);
                     99: void            pxaudc_read_ep0(struct pxaudc_softc *, usbf_xfer_handle);
                    100: void            pxaudc_read_epN(struct pxaudc_softc *sc, int ep);
                    101: void            pxaudc_write_ep0(struct pxaudc_softc *, usbf_xfer_handle);
                    102: void            pxaudc_write(struct pxaudc_softc *, usbf_xfer_handle);
                    103: void            pxaudc_write_epN(struct pxaudc_softc *sc, int ep);
                    104:
                    105: int             pxaudc_connect_intr(void *);
                    106: int             pxaudc_intr(void *);
                    107: void            pxaudc_intr1(struct pxaudc_softc *);
                    108: void            pxaudc_ep0_intr(struct pxaudc_softc *);
                    109: void            pxaudc_epN_intr(struct pxaudc_softc *sc, int ep, int isr);
                    110:
                    111: usbf_status     pxaudc_open(struct usbf_pipe *);
                    112: void            pxaudc_softintr(void *);
                    113: usbf_status     pxaudc_allocm(struct usbf_bus *, usb_dma_t *, u_int32_t);
                    114: void            pxaudc_freem(struct usbf_bus *, usb_dma_t *);
                    115: usbf_xfer_handle pxaudc_allocx(struct usbf_bus *);
                    116: void            pxaudc_freex(struct usbf_bus *, usbf_xfer_handle);
                    117:
                    118: usbf_status     pxaudc_ctrl_transfer(usbf_xfer_handle);
                    119: usbf_status     pxaudc_ctrl_start(usbf_xfer_handle);
                    120: void            pxaudc_ctrl_abort(usbf_xfer_handle);
                    121: void            pxaudc_ctrl_done(usbf_xfer_handle);
                    122: void            pxaudc_ctrl_close(usbf_pipe_handle);
                    123:
                    124: usbf_status     pxaudc_bulk_transfer(usbf_xfer_handle);
                    125: usbf_status     pxaudc_bulk_start(usbf_xfer_handle);
                    126: void            pxaudc_bulk_abort(usbf_xfer_handle);
                    127: void            pxaudc_bulk_done(usbf_xfer_handle);
                    128: void            pxaudc_bulk_close(usbf_pipe_handle);
                    129:
                    130: struct cfattach pxaudc_ca = {
                    131:        sizeof(struct pxaudc_softc), pxaudc_match, pxaudc_attach,
                    132:        pxaudc_detach
                    133: };
                    134:
                    135: struct cfdriver pxaudc_cd = {
                    136:        NULL, "pxaudc", DV_DULL
                    137: };
                    138:
                    139: #if NUSBF > 0
                    140:
                    141: struct usbf_bus_methods pxaudc_bus_methods = {
                    142:        pxaudc_open,
                    143:        pxaudc_softintr,
                    144:        pxaudc_allocm,
                    145:        pxaudc_freem,
                    146:        pxaudc_allocx,
                    147:        pxaudc_freex
                    148: };
                    149:
                    150: struct usbf_pipe_methods pxaudc_ctrl_methods = {
                    151:        pxaudc_ctrl_transfer,
                    152:        pxaudc_ctrl_start,
                    153:        pxaudc_ctrl_abort,
                    154:        pxaudc_ctrl_done,
                    155:        pxaudc_ctrl_close
                    156: };
                    157:
                    158: struct usbf_pipe_methods pxaudc_bulk_methods = {
                    159:        pxaudc_bulk_transfer,
                    160:        pxaudc_bulk_start,
                    161:        pxaudc_bulk_abort,
                    162:        pxaudc_bulk_done,
                    163:        pxaudc_bulk_close
                    164: };
                    165:
                    166: #endif /* NUSBF > 0 */
                    167:
                    168: #define DEVNAME(sc)    ((sc)->sc_bus.bdev.dv_xname)
                    169:
                    170: #define CSR_READ_4(sc, reg) \
                    171:        bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg))
                    172: #define CSR_WRITE_4(sc, reg, val) \
                    173:        bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
                    174: #define CSR_WRITE_1(sc, reg, val) \
                    175:        bus_space_write_1((sc)->sc_iot, (sc)->sc_ioh, (reg), (val))
                    176: #define CSR_SET_4(sc, reg, val) \
                    177:        CSR_WRITE_4((sc), (reg), CSR_READ_4((sc), (reg)) | (val))
                    178: #define CSR_CLR_4(sc, reg, val) \
                    179:        CSR_WRITE_4((sc), (reg), CSR_READ_4((sc), (reg)) & ~(val))
                    180:
                    181: #ifndef PXAUDC_DEBUG
                    182: #define DPRINTF(l, x)  do {} while (0)
                    183: #else
                    184: int pxaudcdebug = 0;
                    185: #define DPRINTF(l, x)  if ((l) <= pxaudcdebug) printf x; else {}
                    186: #endif
                    187:
                    188: int
                    189: pxaudc_match(struct device *parent, void *match, void *aux)
                    190: {
                    191:        if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) != CPU_ID_PXA27X)
                    192:                return (0);
                    193:
                    194:        return (1);
                    195: }
                    196:
                    197: void
                    198: pxaudc_attach(struct device *parent, struct device *self, void *aux)
                    199: {
                    200:        struct pxaudc_softc             *sc = (struct pxaudc_softc *)self;
                    201:        struct pxaip_attach_args        *pxa = aux;
                    202:        int i;
                    203:
                    204:        sc->sc_iot = pxa->pxa_iot;
                    205:        if (bus_space_map(sc->sc_iot, PXA2X0_USBDC_BASE, PXA2X0_USBDC_SIZE, 0,
                    206:            &sc->sc_ioh)) {
                    207:                printf(": cannot map mem space\n");
                    208:                return;
                    209:        }
                    210:        sc->sc_size = PXA2X0_USBDC_SIZE;
                    211:
                    212:        printf(": USB Device Controller\n");
                    213:
                    214:        bus_space_barrier(sc->sc_iot, sc->sc_ioh, 0, sc->sc_size,
                    215:            BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE);
                    216:
                    217:        /* Set up GPIO pins and disable the controller. */
                    218:        pxaudc_setup(sc);
                    219:        pxaudc_disable(sc);
                    220:
                    221: #if NUSBF > 0
                    222:        /* Establish USB device interrupt. */
                    223:        sc->sc_ih = pxa2x0_intr_establish(PXA2X0_INT_USB, IPL_USB,
                    224:            pxaudc_intr, sc, DEVNAME(sc));
                    225:        if (sc->sc_ih == NULL) {
                    226:                printf(": unable to establish interrupt\n");
                    227:                bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size);
                    228:                sc->sc_size = 0;
                    229:                return;
                    230:        }
                    231:
                    232:        /* Establish device connect interrupt. */
                    233: #if 0
                    234:        sc->sc_conn_ih = pxa2x0_gpio_intr_establish(C3000_USB_DEVICE_PIN, /* XXX */
                    235:            IST_EDGE_BOTH, IPL_USB, pxaudc_connect_intr, sc, "usbc");
                    236: #endif
                    237:        sc->sc_conn_ih = pxa2x0_gpio_intr_establish(C3000_USB_CONNECT_PIN,
                    238:            IST_EDGE_BOTH, IPL_USB, pxaudc_connect_intr, sc, "usbc");
                    239:        if (sc->sc_conn_ih == NULL) {
                    240:                printf(": unable to establish connect interrupt\n");
                    241:                pxa2x0_intr_disestablish(sc->sc_ih);
                    242:                bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size);
                    243:                sc->sc_ioh = NULL;
                    244:                sc->sc_size = 0;
                    245:                return;
                    246:        }
                    247:
                    248:        sc->sc_powerhook = powerhook_establish(pxaudc_power, sc);
                    249:
                    250:        /* Set up the bus struct. */
                    251:        sc->sc_bus.methods = &pxaudc_bus_methods;
                    252:        sc->sc_bus.pipe_size = sizeof(struct pxaudc_pipe);
                    253:        sc->sc_bus.ep0_maxp = PXAUDC_EP0MAXP;
                    254:        sc->sc_bus.usbrev = USBREV_1_1;
                    255:        sc->sc_bus.dmatag = pxa->pxa_dmat;
                    256:        sc->sc_npipe = 0;       /* ep0 is always there. */
                    257:
                    258:        sc->sc_ep_map[0] = 0;
                    259:        /* 16 == max logical endpoints */
                    260:        for (i = 1; i < 16; i++) {
                    261:                sc->sc_ep_map[i] = -1;
                    262:        }
                    263:
                    264:        /* Attach logical device and function. */
                    265:        (void)config_found(self, &sc->sc_bus, NULL);
                    266:
                    267:        /* Enable the controller unless we're now acting as a host. */
                    268:        if (!pxaudc_is_host())
                    269:                pxaudc_enable(sc);
                    270: #endif
                    271: }
                    272:
                    273: int
                    274: pxaudc_detach(struct device *self, int flags)
                    275: {
                    276:        struct pxaudc_softc             *sc = (struct pxaudc_softc *)self;
                    277:
                    278:        if (sc->sc_powerhook != NULL)
                    279:                powerhook_disestablish(sc->sc_powerhook);
                    280:
                    281:        if (sc->sc_conn_ih != NULL)
                    282:                pxa2x0_gpio_intr_disestablish(sc->sc_conn_ih);
                    283:
                    284:        if (sc->sc_ih != NULL)
                    285:                pxa2x0_intr_disestablish(sc->sc_ih);
                    286:
                    287:        if (sc->sc_size) {
                    288:                bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size);
                    289:                sc->sc_size = 0;
                    290:        }
                    291:
                    292:        return (0);
                    293: }
                    294:
                    295: void
                    296: pxaudc_power(int why, void *arg)
                    297: {
                    298:        struct pxaudc_softc             *sc = (struct pxaudc_softc *)arg;
                    299:
                    300:        switch (why) {
                    301:        case PWR_SUSPEND:
                    302:        case PWR_STANDBY:
                    303:                pxaudc_disable(sc);
                    304:                break;
                    305:
                    306:        case PWR_RESUME:
                    307:                pxaudc_enable(sc);
                    308:                break;
                    309:        }
                    310: }
                    311:
                    312: /*
                    313:  * Machine-specific functions
                    314:  */
                    315:
                    316: /* XXX move to machine-specific file */
                    317:
                    318: int
                    319: pxaudc_is_host(void)
                    320: {
                    321:        return (!pxa2x0_gpio_get_bit(C3000_USB_CONNECT_PIN) &&
                    322:                !pxa2x0_gpio_get_bit(C3000_USB_DEVICE_PIN));
                    323: }
                    324:
                    325: int
                    326: pxaudc_is_device(void)
                    327: {
                    328:        return (pxa2x0_gpio_get_bit(C3000_USB_CONNECT_PIN) &&
                    329:                pxa2x0_gpio_get_bit(C3000_USB_DEVICE_PIN));
                    330: }
                    331:
                    332: void
                    333: pxaudc_setup(struct pxaudc_softc *sc)
                    334: {
                    335:        pxa2x0_gpio_set_function(45, GPIO_OUT);
                    336:        pxa2x0_gpio_set_function(C3000_USB_CONNECT_PIN, GPIO_IN); /* 41 */
                    337:        pxa2x0_gpio_set_function(40, GPIO_OUT);
                    338:        pxa2x0_gpio_set_function(39, GPIO_IN);
                    339:        pxa2x0_gpio_set_function(38, GPIO_IN);
                    340:        pxa2x0_gpio_set_function(37, GPIO_OUT);
                    341:        pxa2x0_gpio_set_function(36, GPIO_IN);
                    342:        pxa2x0_gpio_set_function(C3000_USB_DEVICE_PIN, GPIO_IN); /* 35 */
                    343:        pxa2x0_gpio_set_function(34, GPIO_IN);
                    344:        pxa2x0_gpio_set_function(89, GPIO_OUT);
                    345:        pxa2x0_gpio_set_function(120, GPIO_OUT);
                    346: }
                    347:
                    348: /* Hide us from the host. */
                    349: void
                    350: pxaudc_hide(struct pxaudc_softc *sc)
                    351: {
                    352:        pxa2x0_gpio_clear_bit(C3000_USB_PULLUP_PIN);
                    353: }
                    354:
                    355: /* Show us to the host. */
                    356: void
                    357: pxaudc_show(struct pxaudc_softc *sc)
                    358: {
                    359:        pxa2x0_gpio_set_bit(C3000_USB_PULLUP_PIN);
                    360: }
                    361:
                    362: /*
                    363:  * Register manipulation
                    364:  */
                    365:
                    366: #if 0
                    367: static void
                    368: pxaudc_dump_regs(struct pxaudc_softc *sc)
                    369: {
                    370:        printf("UDCCR\t%b\n", CSR_READ_4(sc, USBDC_UDCCR),
                    371:            USBDC_UDCCR_BITS);
                    372:        printf("UDCICR0\t%b\n", CSR_READ_4(sc, USBDC_UDCICR0),
                    373:            USBDC_UDCISR0_BITS);
                    374:        printf("UDCICR1\t%b\n", CSR_READ_4(sc, USBDC_UDCICR1),
                    375:            USBDC_UDCISR1_BITS);
                    376:        printf("OTGICR\t%b\n", CSR_READ_4(sc, USBDC_UDCOTGICR),
                    377:            USBDC_UDCOTGISR_BITS);
                    378: }
                    379: #endif
                    380:
                    381: void
                    382: pxaudc_enable(struct pxaudc_softc *sc)
                    383: {
                    384:        int i;
                    385:
                    386:        DPRINTF(10,("pxaudc_enable\n"));
                    387:
                    388:        /* Start the clocks. */
                    389:        pxa2x0_clkman_config(CKEN_USBDC, 1);
                    390:
                    391: #if 0
                    392:        /* Configure Port 2 for USB device. */
                    393:        CSR_WRITE_4(sc, USBDC_UP2OCR, USBDC_UP2OCR_DMPUE |
                    394:            USBDC_UP2OCR_DPPUE | USBDC_UP2OCR_HXOE);
                    395: #else
                    396:        /* Configure Port 2 for USB device. */
                    397:        CSR_WRITE_4(sc, USBDC_UP2OCR, USBDC_UP2OCR_DPPUE | USBDC_UP2OCR_HXOE);
                    398: #endif
                    399:
                    400:        CSR_SET_4(sc, USBDC_UDCCR, 0);
                    401:        sc->sc_icr0 = 0;
                    402:        sc->sc_icr1 = 0;
                    403:
                    404:        for (i = 1; i < PXAUDC_NEP; i++)
                    405:                CSR_WRITE_4(sc, USBDC_UDCECR(i), 0); /* disable endpoints */
                    406:
                    407:        for (i = 1; i < sc->sc_npipe; i++) {
                    408:                if (sc->sc_pipe[i] != NULL)  {
                    409:                        struct usbf_endpoint *ep =
                    410:                            sc->sc_pipe[i]->pipe.endpoint;
                    411:                        u_int32_t cr;
                    412:                        int dir = usbf_endpoint_dir(ep);
                    413:                        usb_endpoint_descriptor_t *ed = ep->edesc;
                    414:
                    415:                        if (i < 16)
                    416:                                sc->sc_icr0 |= USBDC_UDCICR0_IE(i);
                    417:                        else
                    418:                                sc->sc_icr1 |= USBDC_UDCICR1_IE(i-16);
                    419:
                    420:                        cr = USBDC_UDCECR_EE | USBDC_UDCECR_DE;
                    421:                        cr |= USBDC_UDCECR_ENs(
                    422:                            UE_GET_ADDR(ed->bEndpointAddress));
                    423:                        cr |= USBDC_UDCECR_MPSs(UGETW(ed->wMaxPacketSize));
                    424:                        cr |= USBDC_UDCECR_ETs(ed->bmAttributes & UE_XFERTYPE);
                    425:                        if (dir == UE_DIR_IN)
                    426:                                cr |= USBDC_UDCECR_ED;
                    427:
                    428:                        /* XXX - until pipe has cn/in/ain */
                    429:                        cr |=   USBDC_UDCECR_AISNs(0) | USBDC_UDCECR_INs(0) |
                    430:                            USBDC_UDCECR_CNs(1);
                    431:
                    432:                        CSR_WRITE_4(sc, USBDC_UDCECR(i), cr);
                    433:
                    434:                        /* clear old status */
                    435:                        CSR_WRITE_4(sc, USBDC_UDCCSR(1),
                    436:                            USBDC_UDCCSR_PC | USBDC_UDCCSR_TRN |
                    437:                            USBDC_UDCCSR_SST | USBDC_UDCCSR_FEF);
                    438:                }
                    439:        }
                    440:
                    441:        CSR_WRITE_4(sc, USBDC_UDCISR0, 0xffffffff); /* clear all */
                    442:        CSR_WRITE_4(sc, USBDC_UDCISR1, 0xffffffff); /* clear all */
                    443:        CSR_SET_4(sc, USBDC_UDCCSR0, USBDC_UDCCSR0_ACM);
                    444:
                    445:
                    446:        /* Enable interrupts for configured endpoints. */
                    447:        CSR_WRITE_4(sc, USBDC_UDCICR0, USBDC_UDCICR0_IE(0) |
                    448:            sc->sc_icr0);
                    449:
                    450:        CSR_WRITE_4(sc, USBDC_UDCICR1, USBDC_UDCICR1_IERS |
                    451:            USBDC_UDCICR1_IESU | USBDC_UDCICR1_IERU |
                    452:            USBDC_UDCICR1_IECC | sc->sc_icr1);
                    453:
                    454:        /* Enable the controller. */
                    455:        CSR_CLR_4(sc, USBDC_UDCCR, USBDC_UDCCR_EMCE);
                    456:        CSR_SET_4(sc, USBDC_UDCCR, USBDC_UDCCR_UDE);
                    457:
                    458:        /* Enable USB client on port 2. */
                    459:        pxa2x0_gpio_clear_bit(37); /* USB_P2_8 */
                    460: }
                    461:
                    462: void
                    463: pxaudc_disable(struct pxaudc_softc *sc)
                    464: {
                    465:        DPRINTF(10,("pxaudc_disable\n"));
                    466:
                    467:        /* Disable the controller. */
                    468:        CSR_CLR_4(sc, USBDC_UDCCR, USBDC_UDCCR_UDE);
                    469:
                    470:        /* Disable all interrupts. */
                    471:        CSR_WRITE_4(sc, USBDC_UDCICR0, 0);
                    472:        CSR_WRITE_4(sc, USBDC_UDCICR1, 0);
                    473:        CSR_WRITE_4(sc, USBDC_UDCOTGICR, 0);
                    474:
                    475:        /* Set Port 2 output to "Non-OTG Host with Differential Port". */
                    476:        CSR_WRITE_4(sc, USBDC_UP2OCR, USBDC_UP2OCR_HXS | USBDC_UP2OCR_HXOE);
                    477:
                    478:        /* Set "Host Port 2 Transceiver D­ Pull Down Enable". */
                    479:        CSR_SET_4(sc, USBDC_UP2OCR, USBDC_UP2OCR_DMPDE);
                    480:
                    481:        /* Stop the clocks. */
                    482:        pxa2x0_clkman_config(CKEN_USBDC, 0);
                    483:
                    484:        /* Enable USB host on port 2. */
                    485:        pxa2x0_gpio_set_bit(37); /* USB_P2_8 */
                    486: }
                    487:
                    488: #if NUSBF > 0
                    489:
                    490: /*
                    491:  * Endpoint FIFO handling
                    492:  */
                    493:
                    494: void
                    495: pxaudc_read_ep0(struct pxaudc_softc *sc, usbf_xfer_handle xfer)
                    496: {
                    497:        size_t len;
                    498:        u_int8_t *p;
                    499:
                    500:        xfer->actlen = CSR_READ_4(sc, USBDC_UDCBCR(0));
                    501:        len = MIN(xfer->actlen, xfer->length);
                    502:        p = xfer->buffer;
                    503:
                    504:        while (CSR_READ_4(sc, USBDC_UDCCSR0) & USBDC_UDCCSR0_RNE) {
                    505:                u_int32_t v = CSR_READ_4(sc, USBDC_UDCDR(0));
                    506:
                    507:                if (len > 0) {
                    508:                        if (((unsigned)p & 0x3) == 0)
                    509:                                *(u_int32_t *)p = v;
                    510:                        else {
                    511:                                *(p+0) = v & 0xff;
                    512:                                *(p+1) = (v >> 8) & 0xff;
                    513:                                *(p+2) = (v >> 16) & 0xff;
                    514:                                *(p+3) = (v >> 24) & 0xff;
                    515:                        }
                    516:                        p += 4;
                    517:                        len -= 4;
                    518:                }
                    519:        }
                    520:
                    521:        CSR_WRITE_4(sc, USBDC_UDCCSR0, USBDC_UDCCSR0_SA | USBDC_UDCCSR0_OPC);
                    522:
                    523:        xfer->status = USBF_NORMAL_COMPLETION;
                    524:        usbf_transfer_complete(xfer);
                    525: }
                    526:
                    527: void
                    528: pxaudc_read_epN(struct pxaudc_softc *sc, int ep)
                    529: {
                    530:        size_t len, tlen;
                    531:        u_int8_t *p;
                    532:        struct pxaudc_pipe *ppipe;
                    533:        usbf_pipe_handle pipe = NULL;
                    534:        usbf_xfer_handle xfer = NULL;
                    535:        int count;
                    536:        u_int32_t csr;
                    537:
                    538:        ppipe = sc->sc_pipe[ep];
                    539:
                    540:        if (ppipe == NULL) {
                    541:                return;
                    542:        }
                    543:        pipe = &ppipe->pipe;
                    544: again:
                    545:        xfer = SIMPLEQ_FIRST(&pipe->queue);
                    546:
                    547:        if (xfer == NULL) {
                    548:                printf("pxaudc_read_epN: ep %d, no xfer\n", ep);
                    549:                return;
                    550:        }
                    551:
                    552:        count = CSR_READ_4(sc, USBDC_UDCBCR(ep));
                    553:        tlen = len = MIN(count, xfer->length - xfer->actlen);
                    554:        p = xfer->buffer + xfer->actlen;
                    555:        csr = CSR_READ_4(sc, USBDC_UDCCSR(ep));
                    556:
                    557:        if ((csr & USBDC_UDCCSR_PC) && count == 0)
                    558:        {
                    559: #ifdef DEBUG_RX
                    560:                printf("trans1 complete\n");
                    561: #endif
                    562:                xfer->status = USBF_NORMAL_COMPLETION;
                    563:                usbf_transfer_complete(xfer);
                    564:                CSR_SET_4(sc, USBDC_UDCCSR(ep), USBDC_UDCCSR_PC);
                    565:                return;
                    566:        }
                    567:
                    568: #ifdef DEBUG_RX
                    569:        printf("reading data from endpoint %x, len %x csr %x",
                    570:                ep, count, csr);
                    571: #endif
                    572:
                    573:        while (CSR_READ_4(sc, USBDC_UDCCSR(ep)) & USBDC_UDCCSR_BNE) {
                    574:                u_int32_t v = CSR_READ_4(sc, USBDC_UDCDR(ep));
                    575:
                    576:                /* double buffering? */
                    577:                if (len > 0) {
                    578:                        if (((unsigned)p & 0x3) == 0)
                    579:                                *(u_int32_t *)p = v;
                    580:                        else {
                    581:                                *(p+0) = v & 0xff;
                    582:                                *(p+1) = (v >> 8) & 0xff;
                    583:                                *(p+2) = (v >> 16) & 0xff;
                    584:                                *(p+3) = (v >> 24) & 0xff;
                    585:                        }
                    586:                        p += 4;
                    587:                        len -= 4;
                    588:                        xfer->actlen += 4;
                    589:                }
                    590:                count -= 4;
                    591:        }
                    592:        CSR_SET_4(sc, USBDC_UDCCSR(ep), USBDC_UDCCSR_PC);
                    593:
                    594:
                    595:        if (xfer->length == xfer->actlen || (tlen == 0 && xfer->actlen != 0) ||
                    596:            csr & USBDC_UDCCSR_SP) {
                    597: #ifdef DEBUG_RX
                    598:                printf("trans2 complete\n");
                    599: #endif
                    600:                xfer->status = USBF_NORMAL_COMPLETION;
                    601:                usbf_transfer_complete(xfer);
                    602:        }
                    603:        csr = CSR_READ_4(sc, USBDC_UDCCSR(ep));
                    604: #ifdef DEBUG_RX
                    605:        printf("csr now %x len %x\n",
                    606:            csr, CSR_READ_4(sc, USBDC_UDCBCR(ep)));
                    607: #endif
                    608:        if (csr & USBDC_UDCCSR_PC)
                    609:                goto again;
                    610: }
                    611:
                    612: void
                    613: pxaudc_write_ep0(struct pxaudc_softc *sc, usbf_xfer_handle xfer)
                    614: {
                    615:        struct pxaudc_xfer *lxfer = (struct pxaudc_xfer *)xfer;
                    616:        u_int32_t len;
                    617:        u_int8_t *p;
                    618:
                    619:        if (lxfer->frmlen > 0) {
                    620:                xfer->actlen += lxfer->frmlen;
                    621:                lxfer->frmlen = 0;
                    622:        }
                    623:
                    624:        DPRINTF(11,("%s: ep0 ctrl-in, xfer=%p, len=%u, actlen=%u\n",
                    625:            DEVNAME(sc), xfer, xfer->length, xfer->actlen));
                    626:
                    627:        if (xfer->actlen >= xfer->length) {
                    628:                sc->sc_ep0state = EP0_SETUP;
                    629:                usbf_transfer_complete(xfer);
                    630:                return;
                    631:        }
                    632:
                    633:        sc->sc_ep0state = EP0_IN;
                    634:
                    635:        p = (u_char *)xfer->buffer + xfer->actlen;
                    636:        len = xfer->length - xfer->actlen;
                    637:        len = MIN(len, PXAUDC_EP0MAXP);
                    638:        lxfer->frmlen = len;
                    639:
                    640:        while (len >= 4) {
                    641:                u_int32_t v;
                    642:
                    643:                if (((unsigned)p & 0x3) == 0)
                    644:                        v = *(u_int32_t *)p;
                    645:                else {
                    646:                        v = *(p+0);
                    647:                        v |= *(p+1) << 8;
                    648:                        v |= *(p+2) << 16;
                    649:                        v |= *(p+3) << 24;
                    650:                }
                    651:
                    652:                CSR_WRITE_4(sc, USBDC_UDCDR(0), v);
                    653:                len -= 4;
                    654:                p += 4;
                    655:        }
                    656:
                    657:        while (len > 0) {
                    658:                CSR_WRITE_1(sc, USBDC_UDCDR(0), *p);
                    659:                len--;
                    660:                p++;
                    661:        }
                    662:
                    663:        /* (12.6.7) Set IPR only for short packets. */
                    664:        if (lxfer->frmlen < PXAUDC_EP0MAXP)
                    665:                CSR_SET_4(sc, USBDC_UDCCSR0, USBDC_UDCCSR0_IPR);
                    666: }
                    667:
                    668: void
                    669: pxaudc_write(struct pxaudc_softc *sc, usbf_xfer_handle xfer)
                    670: {
                    671:        u_int8_t *p;
                    672:        int ep = sc->sc_ep_map[usbf_endpoint_index(xfer->pipe->endpoint)];
                    673:        int tlen = 0;
                    674:        int maxp = UGETW(xfer->pipe->endpoint->edesc->wMaxPacketSize);
                    675:        u_int32_t csr, csr_o;
                    676:
                    677: #ifdef DEBUG_TX_PKT
                    678:        if (xfer->actlen == 0)
                    679:                printf("new packet len %x\n", xfer->length);
                    680: #endif
                    681:
                    682: #ifdef DEBUG_TX
                    683:        printf("writing data to endpoint %x, xlen %x xact %x\n",
                    684:                ep, xfer->length, xfer->actlen);
                    685: #endif
                    686:
                    687:
                    688:        if (xfer->actlen == xfer->length) {
                    689:                /*
                    690:                 * If the packet size is wMaxPacketSize byte multiple
                    691:                 * send a zero packet to indicate termiation.
                    692:                 */
                    693:                if ((xfer->actlen % maxp) == 0 &&
                    694:                    xfer->status != USBF_NORMAL_COMPLETION &&
                    695:                    xfer->flags & USBD_FORCE_SHORT_XFER) {
                    696:                        if (CSR_READ_4(sc, USBDC_UDCCSR(ep))
                    697:                            & USBDC_UDCCSR_BNF) {
                    698:                                CSR_SET_4(sc, USBDC_UDCCSR(ep),
                    699:                                    USBDC_UDCCSR_SP);
                    700:                                /*
                    701:                                 * if we send a zero packet, we are 'done', but
                    702:                                 * dont to usbf_transfer_complete() just yet
                    703:                                 * because the short packet will cause another
                    704:                                 * interrupt.
                    705:                                 */
                    706:                                xfer->status = USBF_NORMAL_COMPLETION;
                    707:                                return;
                    708:                        } else  {
                    709:                                printf("fifo full when trying to set short packet\n");
                    710:                        }
                    711:                }
                    712:                xfer->status = USBF_NORMAL_COMPLETION;
                    713: #ifdef DEBUG_TX_PKT
                    714:                printf("packet complete %x\n", xfer->actlen);
                    715: #endif
                    716:                usbf_transfer_complete(xfer);
                    717:                return;
                    718:        }
                    719:
                    720:        p = xfer->buffer + xfer->actlen;
                    721:
                    722:
                    723:
                    724:        csr_o = 0;
                    725:        csr = CSR_READ_4(sc, USBDC_UDCCSR(ep));
                    726:        if (csr & USBDC_UDCCSR_PC)
                    727:                csr_o |= USBDC_UDCCSR_PC;
                    728:        if (csr & USBDC_UDCCSR_TRN)
                    729:                csr_o |= USBDC_UDCCSR_TRN;
                    730:        if (csr & USBDC_UDCCSR_SST)
                    731:                csr_o |= USBDC_UDCCSR_SST;
                    732:        if (csr_o != 0)
                    733:        CSR_WRITE_4(sc, USBDC_UDCCSR(ep), csr_o);
                    734:
                    735:
                    736:        while (CSR_READ_4(sc, USBDC_UDCCSR(ep)) & USBDC_UDCCSR_BNF) {
                    737:                u_int32_t v;
                    738:
                    739:                if (xfer->length - xfer->actlen < 4) {
                    740:                        while (xfer->actlen < xfer->length) {
                    741:                                CSR_WRITE_1(sc, USBDC_UDCDR(ep), *p);
                    742:                                p++;
                    743:                                xfer->actlen++;
                    744:                                tlen++;
                    745:                        }
                    746:                        break;
                    747:                }
                    748:                if (((unsigned)p & 0x3) == 0)
                    749:                        v = *(u_int32_t *)p;
                    750:                else {
                    751:                        v = *(p+0);
                    752:                        v |= *(p+1) << 8;
                    753:                        v |= *(p+2) << 16;
                    754:                        v |= *(p+3) << 24;
                    755:                }
                    756:                CSR_WRITE_4(sc, USBDC_UDCDR(ep), v);
                    757:
                    758:                p += 4;
                    759:                xfer->actlen += 4;
                    760:
                    761:                tlen += 4;
                    762:        }
                    763: #ifdef DEBUG_TX
                    764:        printf(" wrote tlen %x %x\n", tlen, xfer->actlen);
                    765:        if (xfer->actlen == 0) {
                    766:                printf("whoa, write_ep called, but no free space\n");
                    767:        }
                    768: #endif
                    769:        if (xfer->actlen == xfer->length) {
                    770:                if ((xfer->actlen % maxp) != 0) {
                    771:                        if (xfer->flags & USBD_FORCE_SHORT_XFER) {
                    772:                                CSR_SET_4(sc, USBDC_UDCCSR(ep), USBDC_UDCCSR_SP);
                    773: #ifdef DEBUG_TX
                    774:                                printf("setting short packet on %x csr\n", ep,
                    775:                                    CSR_READ_4(sc, USBDC_UDCCSR(ep)));
                    776: #endif
                    777:                        } else {
                    778:                                /* fill buffer to maxpacket size??? */
                    779:                        }
                    780:                }
                    781:        }
                    782: }
                    783:
                    784: /*
                    785:  * Interrupt handling
                    786:  */
                    787:
                    788: int
                    789: pxaudc_connect_intr(void *v)
                    790: {
                    791:        struct pxaudc_softc *sc = v;
                    792:
                    793:        DPRINTF(10,("pxaudc_connect_intr: connect=%d device=%d\n",
                    794:            pxa2x0_gpio_get_bit(C3000_USB_CONNECT_PIN),
                    795:            pxa2x0_gpio_get_bit(C3000_USB_DEVICE_PIN)));
                    796:
                    797:        /* XXX only set a flag here */
                    798:        if (pxaudc_is_host()) {
                    799: #if 0
                    800:                printf("%s:switching to host\n", sc->sc_bus.bdev.dv_xname);
                    801: #endif
                    802:                pxaudc_disable(sc);
                    803:        } else {
                    804: #if 0
                    805:                printf("%s:switching to client\n", sc->sc_bus.bdev.dv_xname);
                    806: #endif
                    807:                pxaudc_enable(sc);
                    808:        }
                    809:
                    810:        /* Claim this interrupt. */
                    811:        return 1;
                    812: }
                    813:
                    814: int
                    815: pxaudc_intr(void *v)
                    816: {
                    817:        struct pxaudc_softc *sc = v;
                    818:        u_int32_t isr0, isr1, otgisr;
                    819:
                    820:        isr0 = CSR_READ_4(sc, USBDC_UDCISR0);
                    821:        isr1 = CSR_READ_4(sc, USBDC_UDCISR1);
                    822:        otgisr = CSR_READ_4(sc, USBDC_UDCOTGISR);
                    823:
                    824:        DPRINTF(10,("pxaudc_intr: isr0=%b, isr1=%b, otgisr=%b\n",
                    825:            isr0, USBDC_UDCISR0_BITS, isr1, USBDC_UDCISR1_BITS,
                    826:            otgisr, USBDC_UDCOTGISR_BITS));
                    827:
                    828:        if (isr0 || isr1 || otgisr) {
                    829:                sc->sc_isr0 |= isr0;
                    830:                sc->sc_isr1 |= isr1;
                    831:                sc->sc_otgisr |= otgisr;
                    832:
                    833:                //usbf_schedsoftintr(&sc->sc_bus);
                    834:                pxaudc_intr1(sc); /* XXX */
                    835:        }
                    836:
                    837:        CSR_WRITE_4(sc, USBDC_UDCISR0, isr0);
                    838:        CSR_WRITE_4(sc, USBDC_UDCISR1, isr1);
                    839:        CSR_WRITE_4(sc, USBDC_UDCOTGISR, otgisr);
                    840:
                    841:        /* Claim this interrupt. */
                    842:        return 1;
                    843: }
                    844: u_int32_t csr1, csr2;
                    845:
                    846: void
                    847: pxaudc_intr1(struct pxaudc_softc *sc)
                    848: {
                    849:        u_int32_t isr0, isr1, otgisr;
                    850:        int i;
                    851:        //int s;
                    852:
                    853:        //s = splhardusb();
                    854:        isr0 = sc->sc_isr0;
                    855:        isr1 = sc->sc_isr1;
                    856:        otgisr = sc->sc_otgisr;
                    857:        sc->sc_isr0 = 0;
                    858:        sc->sc_isr1 = 0;
                    859:        sc->sc_otgisr = 0;
                    860:        //splx(s);
                    861:
                    862:        sc->sc_bus.intr_context++;
                    863:
                    864:        if (isr1 & USBDC_UDCISR1_IRCC) {
                    865:                u_int32_t ccr;
                    866:                 CSR_SET_4(sc, USBDC_UDCCR, USBDC_UDCCR_SMAC);
                    867:
                    868:                /* wait for reconfig to finish (SMAC auto clears) */
                    869:                while (CSR_READ_4(sc, USBDC_UDCCR)  & USBDC_UDCCR_SMAC)
                    870:                        delay(10);
                    871:
                    872:                ccr = CSR_READ_4(sc, USBDC_UDCCR);
                    873:                sc->sc_cn = USBDC_UDCCR_ACNr(ccr);
                    874:                sc->sc_in = USBDC_UDCCR_AINr(ccr);
                    875:                sc->sc_isn = USBDC_UDCCR_AAISNr(ccr);
                    876:                goto ret;
                    877:        }
                    878: #if 0
                    879:        printf("pxaudc_intr: isr0=%b, isr1=%b, otgisr=%b\n",
                    880:            isr0, USBDC_UDCISR0_BITS, isr1, USBDC_UDCISR1_BITS,
                    881:            otgisr, USBDC_UDCOTGISR_BITS);
                    882: #endif
                    883:
                    884:        /* Handle USB RESET condition. */
                    885:        if (isr1 & USBDC_UDCISR1_IRRS) {
                    886:                sc->sc_ep0state = EP0_SETUP;
                    887:                usbf_host_reset(&sc->sc_bus);
                    888:                /* Discard all other interrupts. */
                    889:                goto ret;
                    890:        }
                    891:
                    892:        /* Service control pipe interrupts. */
                    893:        if (isr0 & USBDC_UDCISR0_IR(0))
                    894:                pxaudc_ep0_intr(sc);
                    895:
                    896:        for (i = 1; i < 24; i++) {
                    897:                if (i < 16) {
                    898:                        if (USBDC_UDCISR0_IRs(isr0,i))
                    899:                                pxaudc_epN_intr(sc, i,
                    900:                                    USBDC_UDCISR0_IRs(isr0,i));
                    901:                } else {
                    902:                        if (USBDC_UDCISR1_IRs(isr1,i))
                    903:                                pxaudc_epN_intr(sc, i,
                    904:                                    USBDC_UDCISR1_IRs(isr1,i));
                    905:                }
                    906:        }
                    907:
                    908:        if (isr1 & USBDC_UDCISR1_IRSU) {
                    909:                /* suspend ?? */
                    910:        }
                    911:        if (isr1 & USBDC_UDCISR1_IRRU) {
                    912:                /* resume ?? */
                    913:        }
                    914:
                    915: ret:
                    916:        sc->sc_bus.intr_context--;
                    917: }
                    918:
                    919: void
                    920: pxaudc_epN_intr(struct pxaudc_softc *sc, int ep, int isr)
                    921: {
                    922:        struct pxaudc_pipe *ppipe;
                    923:        usbf_pipe_handle pipe;
                    924:        int dir;
                    925:
                    926:        /* should not occur before device is configured */
                    927:        if (sc->sc_cn == 0)
                    928:                return;
                    929:        if (isr &  2)
                    930:                printf("ep%d: fifo error\n", ep); /* XXX */
                    931:
                    932:        /* faster method of determining direction? */
                    933:        ppipe = sc->sc_pipe[ep];
                    934:
                    935:        if (ppipe == NULL)
                    936:                return;
                    937:        pipe = &ppipe->pipe;
                    938:        dir = usbf_endpoint_dir(pipe->endpoint);
                    939:
                    940:        if (dir == UE_DIR_IN) {
                    941:                pxaudc_write_epN(sc, ep);
                    942:        } else {
                    943:                pxaudc_read_epN(sc, ep);
                    944:        }
                    945:
                    946: }
                    947:
                    948: void
                    949: pxaudc_write_epN(struct pxaudc_softc *sc, int ep)
                    950: {
                    951:        struct pxaudc_pipe *ppipe;
                    952:        usbf_pipe_handle pipe = NULL;
                    953:        usbf_xfer_handle xfer = NULL;
                    954:
                    955:        ppipe = sc->sc_pipe[ep];
                    956:
                    957:        if (ppipe == NULL) {
                    958:                return;
                    959:        }
                    960:        pipe = &ppipe->pipe;
                    961:        xfer = SIMPLEQ_FIRST(&pipe->queue);
                    962:        if (xfer != NULL)
                    963:                pxaudc_write(sc, xfer);
                    964: }
                    965: void
                    966: pxaudc_ep0_intr(struct pxaudc_softc *sc)
                    967: {
                    968:        struct pxaudc_pipe *ppipe;
                    969:        usbf_pipe_handle pipe = NULL;
                    970:        usbf_xfer_handle xfer = NULL;
                    971:        u_int32_t csr0;
                    972:
                    973:        csr0 = CSR_READ_4(sc, USBDC_UDCCSR0);
                    974:        DPRINTF(10,("pxaudc_ep0_intr: csr0=%b\n", csr0, USBDC_UDCCSR0_BITS));
                    975:        delay (25);
                    976:
                    977:        ppipe = sc->sc_pipe[0];
                    978:        if (ppipe != NULL) {
                    979:                pipe = &ppipe->pipe;
                    980:                xfer = SIMPLEQ_FIRST(&pipe->queue);
                    981:        }
                    982:
                    983:        if (sc->sc_ep0state == EP0_SETUP && (csr0 & USBDC_UDCCSR0_OPC)) {
                    984:                if (pipe == NULL) {
                    985:                        DPRINTF(10,("pxaudc_ep0_intr: no control pipe\n"));
                    986:                        return;
                    987:                }
                    988:
                    989:                if (xfer == NULL) {
                    990:                        DPRINTF(10,("pxaudc_ep0_intr: no xfer\n"));
                    991:                        return;
                    992:                }
                    993:
                    994:                pxaudc_read_ep0(sc, xfer);
                    995:        } else if (sc->sc_ep0state == EP0_IN &&
                    996:            (csr0 & USBDC_UDCCSR0_IPR) == 0 && xfer) {
                    997:                pxaudc_write_ep0(sc, xfer);
                    998:        }
                    999: }
                   1000:
                   1001: /*
                   1002:  * Bus methods
                   1003:  */
                   1004:
                   1005: usbf_status
                   1006: pxaudc_open(struct usbf_pipe *pipe)
                   1007: {
                   1008:        struct pxaudc_softc *sc = (struct pxaudc_softc *)pipe->device->bus;
                   1009:        struct pxaudc_pipe *ppipe = (struct pxaudc_pipe *)pipe;
                   1010:        int ep_idx;
                   1011:        int s;
                   1012:
                   1013:        ep_idx = usbf_endpoint_index(pipe->endpoint);
                   1014:        if (ep_idx >= PXAUDC_NEP)
                   1015:                return USBF_BAD_ADDRESS;
                   1016:
                   1017:        DPRINTF(10,("pxaudc_open\n"));
                   1018:        s = splhardusb();
                   1019:
                   1020:        switch (usbf_endpoint_type(pipe->endpoint)) {
                   1021:        case UE_CONTROL:
                   1022:                pipe->methods = &pxaudc_ctrl_methods;
                   1023:                break;
                   1024:
                   1025:        case UE_BULK:
                   1026:                pipe->methods = &pxaudc_bulk_methods;
                   1027:                break;
                   1028:
                   1029:        case UE_ISOCHRONOUS:
                   1030:        case UE_INTERRUPT:
                   1031:        default:
                   1032:                /* XXX */
                   1033:                splx(s);
                   1034:                return USBF_BAD_ADDRESS;
                   1035:        }
                   1036:
                   1037:        if (ep_idx != 0 && sc->sc_ep_map[ep_idx] != -1) {
                   1038:                printf("endpoint %d already used by %c",
                   1039:                    ep_idx, '@'+ sc->sc_ep_map[0]);
                   1040:                return USBF_BAD_ADDRESS;
                   1041:        }
                   1042:        sc->sc_ep_map[ep_idx] = sc->sc_npipe;
                   1043:
                   1044:        sc->sc_pipe[sc->sc_npipe] = ppipe;
                   1045:        sc->sc_npipe++;
                   1046:
                   1047:        splx(s);
                   1048:        return USBF_NORMAL_COMPLETION;
                   1049: }
                   1050:
                   1051: void
                   1052: pxaudc_softintr(void *v)
                   1053: {
                   1054:        struct pxaudc_softc *sc = v;
                   1055:
                   1056:        pxaudc_intr1(sc);
                   1057: }
                   1058:
                   1059: usbf_status
                   1060: pxaudc_allocm(struct usbf_bus *bus, usb_dma_t *dmap, u_int32_t size)
                   1061: {
                   1062:        return usbf_allocmem(bus, size, 0, dmap);
                   1063: }
                   1064:
                   1065: void
                   1066: pxaudc_freem(struct usbf_bus *bus, usb_dma_t *dmap)
                   1067: {
                   1068:        usbf_freemem(bus, dmap);
                   1069: }
                   1070:
                   1071: usbf_xfer_handle
                   1072: pxaudc_allocx(struct usbf_bus *bus)
                   1073: {
                   1074:        struct pxaudc_softc *sc = (struct pxaudc_softc *)bus;
                   1075:        usbf_xfer_handle xfer;
                   1076:
                   1077:        xfer = SIMPLEQ_FIRST(&sc->sc_free_xfers);
                   1078:        if (xfer != NULL)
                   1079:                SIMPLEQ_REMOVE_HEAD(&sc->sc_free_xfers, next);
                   1080:        else
                   1081:                xfer = malloc(sizeof(struct pxaudc_xfer), M_USB, M_NOWAIT);
                   1082:        if (xfer != NULL)
                   1083:                bzero(xfer, sizeof(struct pxaudc_xfer));
                   1084:        return xfer;
                   1085: }
                   1086:
                   1087: void
                   1088: pxaudc_freex(struct usbf_bus *bus, usbf_xfer_handle xfer)
                   1089: {
                   1090:        struct pxaudc_softc *sc = (struct pxaudc_softc *)bus;
                   1091:
                   1092:        SIMPLEQ_INSERT_HEAD(&sc->sc_free_xfers, xfer, next);
                   1093: }
                   1094:
                   1095: /*
                   1096:  * Control pipe methods
                   1097:  */
                   1098:
                   1099: usbf_status
                   1100: pxaudc_ctrl_transfer(usbf_xfer_handle xfer)
                   1101: {
                   1102:        usbf_status err;
                   1103:
                   1104:        /* Insert last in queue. */
                   1105:        err = usbf_insert_transfer(xfer);
                   1106:        if (err)
                   1107:                return err;
                   1108:
                   1109:        /*
                   1110:         * Pipe isn't running (otherwise err would be USBF_IN_PROGRESS),
                   1111:         * so start first.
                   1112:         */
                   1113:        return pxaudc_ctrl_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
                   1114: }
                   1115:
                   1116: usbf_status
                   1117: pxaudc_ctrl_start(usbf_xfer_handle xfer)
                   1118: {
                   1119:        struct usbf_pipe *pipe = xfer->pipe;
                   1120:        struct pxaudc_softc *sc = (struct pxaudc_softc *)pipe->device->bus;
                   1121:        int iswrite = !(xfer->rqflags & URQ_REQUEST);
                   1122:        int s;
                   1123:
                   1124:        s = splusb();
                   1125:        xfer->status = USBF_IN_PROGRESS;
                   1126:        if (iswrite)
                   1127:                pxaudc_write_ep0(sc, xfer);
                   1128:        else {
                   1129:                /* XXX boring message, this case is normally reached if
                   1130:                 * XXX the xfer for a device request is being queued. */
                   1131:                DPRINTF(10,("%s: ep[%x] ctrl-out, xfer=%p, len=%u, "
                   1132:                    "actlen=%u\n", DEVNAME(sc),
                   1133:                    usbf_endpoint_address(xfer->pipe->endpoint),
                   1134:                    xfer, xfer->length,
                   1135:                    xfer->actlen));
                   1136:        }
                   1137:        splx(s);
                   1138:        return USBF_IN_PROGRESS;
                   1139: }
                   1140:
                   1141: /* (also used by bulk pipes) */
                   1142: void
                   1143: pxaudc_ctrl_abort(usbf_xfer_handle xfer)
                   1144: {
                   1145:        int s;
                   1146: #ifdef PXAUDC_DEBUG
                   1147:        struct usbf_pipe *pipe = xfer->pipe;
                   1148:        struct pxaudc_softc *sc = (struct pxaudc_softc *)pipe->device->bus;
                   1149:        int index = usbf_endpoint_index(pipe->endpoint);
                   1150:        int dir = usbf_endpoint_dir(pipe->endpoint);
                   1151:        int type = usbf_endpoint_type(pipe->endpoint);
                   1152: #endif
                   1153:
                   1154:        DPRINTF(10,("%s: ep%d %s-%s abort, xfer=%p\n", DEVNAME(sc), index,
                   1155:            type == UE_CONTROL ? "ctrl" : "bulk", dir == UE_DIR_IN ?
                   1156:            "in" : "out", xfer));
                   1157:
                   1158:        /*
                   1159:         * Step 1: Make soft interrupt routine and hardware ignore the xfer.
                   1160:         */
                   1161:        s = splusb();
                   1162:        xfer->status = USBF_CANCELLED;
                   1163:        timeout_del(&xfer->timeout_handle);
                   1164:        splx(s);
                   1165:
                   1166:        /*
                   1167:         * Step 2: Make sure hardware has finished any possible use of the
                   1168:         * xfer and the soft interrupt routine has run.
                   1169:         */
                   1170:        s = splusb();
                   1171:        /* XXX this does not seem right, what if there
                   1172:         * XXX are two xfers in the FIFO and we only want to
                   1173:         * XXX ignore one? */
                   1174: #ifdef notyet
                   1175:        pxaudc_flush(sc, usbf_endpoint_address(pipe->endpoint));
                   1176: #endif
                   1177:        /* XXX we're not doing DMA and the soft interrupt routine does not
                   1178:           XXX need to clean up anything. */
                   1179:        splx(s);
                   1180:
                   1181:        /*
                   1182:         * Step 3: Execute callback.
                   1183:         */
                   1184:        s = splusb();
                   1185:        usbf_transfer_complete(xfer);
                   1186:        splx(s);
                   1187: }
                   1188:
                   1189: void
                   1190: pxaudc_ctrl_done(usbf_xfer_handle xfer)
                   1191: {
                   1192: }
                   1193:
                   1194: void
                   1195: pxaudc_ctrl_close(usbf_pipe_handle pipe)
                   1196: {
                   1197:        /* XXX */
                   1198: }
                   1199:
                   1200: /*
                   1201:  * Bulk pipe methods
                   1202:  */
                   1203:
                   1204: usbf_status
                   1205: pxaudc_bulk_transfer(usbf_xfer_handle xfer)
                   1206: {
                   1207:        usbf_status err;
                   1208:
                   1209:        /* Insert last in queue. */
                   1210:        err = usbf_insert_transfer(xfer);
                   1211:        if (err)
                   1212:                return err;
                   1213:
                   1214:        /*
                   1215:         * Pipe isn't running (otherwise err would be USBF_IN_PROGRESS),
                   1216:         * so start first.
                   1217:         */
                   1218:        return pxaudc_bulk_start(SIMPLEQ_FIRST(&xfer->pipe->queue));
                   1219: }
                   1220:
                   1221: usbf_status
                   1222: pxaudc_bulk_start(usbf_xfer_handle xfer)
                   1223: {
                   1224:        struct usbf_pipe *pipe = xfer->pipe;
                   1225:        struct pxaudc_softc *sc = (struct pxaudc_softc *)pipe->device->bus;
                   1226:        int iswrite = (usbf_endpoint_dir(pipe->endpoint) == UE_DIR_IN);
                   1227:        int s;
                   1228:
                   1229:        DPRINTF(0,("%s: ep%d bulk-%s start, xfer=%p, len=%u\n", DEVNAME(sc),
                   1230:            usbf_endpoint_index(pipe->endpoint), iswrite ? "in" : "out",
                   1231:            xfer, xfer->length));
                   1232:
                   1233:        s = splusb();
                   1234:        xfer->status = USBF_IN_PROGRESS;
                   1235:        if (iswrite)
                   1236:                pxaudc_write(sc, xfer);
                   1237:        else {
                   1238:                /* enable interrupt */
                   1239:        }
                   1240:        splx(s);
                   1241:        return USBF_IN_PROGRESS;
                   1242: }
                   1243:
                   1244: void
                   1245: pxaudc_bulk_abort(usbf_xfer_handle xfer)
                   1246: {
                   1247:        pxaudc_ctrl_abort(xfer);
                   1248: }
                   1249:
                   1250: void
                   1251: pxaudc_bulk_done(usbf_xfer_handle xfer)
                   1252: {
                   1253: #if 0
                   1254:        int ep = usbf_endpoint_address(xfer->pipe->endpoint);
                   1255:        struct usbf_pipe *pipe = xfer->pipe;
                   1256:        struct pxaudc_softc *sc = (struct pxaudc_softc *)pipe->device->bus;
                   1257:
                   1258: #endif
                   1259: }
                   1260:
                   1261: void
                   1262: pxaudc_bulk_close(usbf_pipe_handle pipe)
                   1263: {
                   1264:        /* XXX */
                   1265: }
                   1266:
                   1267: #endif /* NUSBF > 0 */

CVSweb