[BACK]Return to usbf_subr.c CVS log [TXT][DIR] Up to [local] / sys / dev / usb

Annotation of sys/dev/usb/usbf_subr.c, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: usbf_subr.c,v 1.10 2007/07/27 09:16:09 mbalmer Exp $  */
                      2:
                      3: /*
                      4:  * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
                      5:  *
                      6:  * Permission to use, copy, modify, and distribute this software for any
                      7:  * purpose with or without fee is hereby granted, provided that the above
                      8:  * copyright notice and this permission notice appear in all copies.
                      9:  *
                     10:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     11:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     12:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     13:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     14:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     15:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     16:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     17:  */
                     18:
                     19: /*
                     20:  * USB function driver interface subroutines
                     21:  */
                     22:
                     23: #include <sys/param.h>
                     24: #include <sys/malloc.h>
                     25: #include <sys/systm.h>
                     26: #include <sys/timeout.h>
                     27:
                     28: #include <machine/bus.h>
                     29:
                     30: #include <dev/usb/usb.h>
                     31: #include <dev/usb/usbdi.h>
                     32: #include <dev/usb/usbdivar.h>
                     33: #include <dev/usb/usb_mem.h>
                     34: #include <dev/usb/usbf.h>
                     35: #include <dev/usb/usbfvar.h>
                     36:
                     37: #ifndef USBF_DEBUG
                     38: #define DPRINTF(l, x)  do {} while (0)
                     39: #else
                     40: extern int usbfdebug;
                     41: #define DPRINTF(l, x)  if ((l) <= usbfdebug) printf x; else {}
                     42: #endif
                     43:
                     44: void       *usbf_realloc(void **, size_t *, size_t);
                     45: size_t      usbf_get_string(usbf_device_handle, u_int8_t, char *, size_t);
                     46: usbf_status  usbf_open_pipe_ival(usbf_interface_handle, u_int8_t,
                     47:                                 usbf_pipe_handle *, int);
                     48: usbf_status  usbf_setup_pipe(usbf_device_handle, usbf_interface_handle,
                     49:                             struct usbf_endpoint *, int,
                     50:                             usbf_pipe_handle *);
                     51: void        usbf_start_next(usbf_pipe_handle);
                     52: void        usbf_set_endpoint_halt(usbf_endpoint_handle);
                     53: void        usbf_clear_endpoint_halt(usbf_endpoint_handle);
                     54:
                     55: static const char * const usbf_error_strs[] = USBF_ERROR_STRS;
                     56:
                     57: const char *
                     58: usbf_errstr(usbf_status err)
                     59: {
                     60:        static char buffer[5];
                     61:
                     62:        if (err < USBF_ERROR_MAX)
                     63:                return usbf_error_strs[err];
                     64:
                     65:        snprintf(buffer, sizeof buffer, "%d", err);
                     66:        return buffer;
                     67: }
                     68:
                     69: void *
                     70: usbf_realloc(void **pp, size_t *sizep, size_t newsize)
                     71: {
                     72:        void *p;
                     73:        size_t oldsize;
                     74:
                     75:        if (newsize == 0) {
                     76:                if (*sizep > 0)
                     77:                        free(*pp, M_USB);
                     78:                *pp = NULL;
                     79:                *sizep = 0;
                     80:                return NULL;
                     81:        }
                     82:
                     83:        p = malloc(newsize, M_USB, M_NOWAIT);
                     84:        if (p == NULL)
                     85:                return NULL;
                     86:
                     87:        oldsize = MIN(*sizep, newsize);
                     88:        if (oldsize > 0)
                     89:                bcopy(*pp, p, oldsize);
                     90:        *pp = p;
                     91:        *sizep = newsize;
                     92:        return p;
                     93: }
                     94:
                     95: /*
                     96:  * Attach a function driver.
                     97:  */
                     98: static usbf_status
                     99: usbf_probe_and_attach(struct device *parent, usbf_device_handle dev, int port)
                    100: {
                    101:        struct usbf_attach_arg uaa;
                    102:        struct device *dv;
                    103:
                    104:        KASSERT(dev->function == NULL);
                    105:
                    106:        bzero(&uaa, sizeof uaa);
                    107:        uaa.device = dev;
                    108:
                    109:        /*
                    110:         * The softc structure of a USB function driver must begin with a
                    111:         * "struct usbf_function" member (instead of USBBASEDEV), which must
                    112:         * be initialized in the function driver's attach routine.  Also, it
                    113:         * should use usbf_devinfo_setup() to set the device identification.
                    114:         */
                    115:        dv = config_found_sm(parent, &uaa, NULL, NULL);
                    116:        if (dv != NULL) {
                    117:                dev->function = (struct usbf_function *)dv;
                    118:                return USBF_NORMAL_COMPLETION;
                    119:        }
                    120:
                    121:        /*
                    122:         * We failed to attach a function driver for this device, but the
                    123:         * device can still function as a generic USB device without any
                    124:         * interfaces.
                    125:         */
                    126:        return USBF_NORMAL_COMPLETION;
                    127: }
                    128:
                    129: static void
                    130: usbf_remove_device(usbf_device_handle dev, struct usbf_port *up)
                    131: {
                    132:        KASSERT(dev != NULL && dev == up->device);
                    133:
                    134:        if (dev->function != NULL)
                    135:                config_detach((struct device *)dev->function, DETACH_FORCE);
                    136:        if (dev->default_pipe != NULL)
                    137:                usbf_close_pipe(dev->default_pipe);
                    138:        up->device = NULL;
                    139:        free(dev, M_USB);
                    140: }
                    141:
                    142: usbf_status
                    143: usbf_new_device(struct device *parent, usbf_bus_handle bus, int depth,
                    144:     int speed, int port, struct usbf_port *up)
                    145: {
                    146:        struct usbf_device *dev;
                    147:        usb_device_descriptor_t *ud;
                    148:        usbf_status err;
                    149:
                    150: #ifdef DIAGNOSTIC
                    151:        KASSERT(up->device == NULL);
                    152: #endif
                    153:
                    154:        dev = malloc(sizeof(*dev), M_USB, M_NOWAIT);
                    155:        if (dev == NULL)
                    156:                return USBF_NOMEM;
                    157:
                    158:        bzero(dev, sizeof *dev);
                    159:        dev->bus = bus;
                    160:        dev->string_id = USBF_STRING_ID_MIN;
                    161:        SIMPLEQ_INIT(&dev->configs);
                    162:
                    163:        /* Initialize device status. */
                    164:        USETW(dev->status.wStatus, UDS_SELF_POWERED);
                    165:
                    166:        /*
                    167:         * Initialize device descriptor.  The function driver for this
                    168:         * device (attached below) must complete the device descriptor.
                    169:         */
                    170:        ud = &dev->ddesc;
                    171:        ud->bLength = USB_DEVICE_DESCRIPTOR_SIZE;
                    172:        ud->bDescriptorType = UDESC_DEVICE;
                    173:        ud->bMaxPacketSize = bus->ep0_maxp;
                    174:        if (bus->usbrev >= USBREV_2_0)
                    175:                USETW(ud->bcdUSB, UD_USB_2_0);
                    176:        else
                    177:                USETW(ud->bcdUSB, 0x0101);
                    178:
                    179:        /* Set up the default endpoint handle and descriptor. */
                    180:        dev->def_ep.edesc = &dev->def_ep_desc;
                    181:        dev->def_ep_desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE;
                    182:        dev->def_ep_desc.bDescriptorType = UDESC_ENDPOINT;
                    183:        dev->def_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT;
                    184:        dev->def_ep_desc.bmAttributes = UE_CONTROL;
                    185:        USETW(dev->def_ep_desc.wMaxPacketSize, ud->bMaxPacketSize);
                    186:        dev->def_ep_desc.bInterval = 0;
                    187:
                    188:        /* Establish the default pipe. */
                    189:        err = usbf_setup_pipe(dev, NULL, &dev->def_ep, 0,
                    190:            &dev->default_pipe);
                    191:        if (err) {
                    192:                free(dev, M_USB);
                    193:                return err;
                    194:        }
                    195:
                    196:        /* Preallocate xfers for default pipe. */
                    197:        dev->default_xfer = usbf_alloc_xfer(dev);
                    198:        dev->data_xfer = usbf_alloc_xfer(dev);
                    199:        if (dev->default_xfer == NULL || dev->data_xfer == NULL) {
                    200:                if (dev->default_xfer != NULL)
                    201:                        usbf_free_xfer(dev->default_xfer);
                    202:                usbf_close_pipe(dev->default_pipe);
                    203:                free(dev, M_USB);
                    204:                return USBF_NOMEM;
                    205:        }
                    206:
                    207:        /* Insert device request xfer. */
                    208:        usbf_setup_default_xfer(dev->default_xfer, dev->default_pipe,
                    209:            NULL, &dev->def_req, 0, 0, usbf_do_request);
                    210:        err = usbf_transfer(dev->default_xfer);
                    211:        if (err && err != USBF_IN_PROGRESS) {
                    212:                usbf_free_xfer(dev->default_xfer);
                    213:                usbf_free_xfer(dev->data_xfer);
                    214:                usbf_close_pipe(dev->default_pipe);
                    215:                free(dev, M_USB);
                    216:                return err;
                    217:        }
                    218:
                    219:        /* Associate the upstream port with the device. */
                    220:        bzero(up, sizeof *up);
                    221:        up->portno = port;
                    222:        up->device = dev;
                    223:
                    224:        /* Attach function driver. */
                    225:        err = usbf_probe_and_attach(parent, dev, port);
                    226:        if (err)
                    227:                usbf_remove_device(dev, up);
                    228:        return err;
                    229: }
                    230:
                    231: /*
                    232:  * Should be called by the function driver in its attach routine to change
                    233:  * the default device identification according to the particular function.
                    234:  */
                    235: void
                    236: usbf_devinfo_setup(usbf_device_handle dev, u_int8_t devclass,
                    237:     u_int8_t subclass, u_int8_t proto, u_int16_t vendor, u_int16_t product,
                    238:     u_int16_t device, const char *manf, const char *prod, const char *ser)
                    239: {
                    240:        usb_device_descriptor_t *dd;
                    241:
                    242:        dd = usbf_device_descriptor(dev);
                    243:        dd->bDeviceClass = devclass;
                    244:        dd->bDeviceSubClass = subclass;
                    245:        dd->bDeviceProtocol = proto;
                    246:        if (vendor != 0)
                    247:                USETW(dd->idVendor, vendor);
                    248:        if (product != 0)
                    249:                USETW(dd->idProduct, product);
                    250:        if (device != 0)
                    251:                USETW(dd->bcdDevice, device);
                    252:        if (manf != NULL)
                    253:                dd->iManufacturer = usbf_add_string(dev, manf);
                    254:        if (prod != NULL)
                    255:                dd->iProduct = usbf_add_string(dev, prod);
                    256:        if (ser != NULL)
                    257:                dd->iSerialNumber = usbf_add_string(dev, ser);
                    258: }
                    259:
                    260: char *
                    261: usbf_devinfo_alloc(usbf_device_handle dev)
                    262: {
                    263:        char manf[40];
                    264:        char prod[40];
                    265:        usb_device_descriptor_t *dd;
                    266:        size_t len;
                    267:        char *devinfo;
                    268:
                    269:        dd = usbf_device_descriptor(dev);
                    270:        usbf_get_string(dev, dd->iManufacturer, manf, sizeof manf);
                    271:        usbf_get_string(dev, dd->iProduct, prod, sizeof prod);
                    272:
                    273:        len = strlen(manf) + strlen(prod) + 32;
                    274:        devinfo = malloc(len, M_USB, M_NOWAIT);
                    275:        if (devinfo == NULL)
                    276:                return NULL;
                    277:
                    278:        snprintf(devinfo, len, "%s %s, rev %d.%02d/%d.%02d", manf, prod,
                    279:            (UGETW(dd->bcdUSB)>>8) & 0xff, UGETW(dd->bcdUSB) & 0xff,
                    280:            (UGETW(dd->bcdDevice)>>8) & 0xff, UGETW(dd->bcdDevice) & 0xff);
                    281:        return devinfo;
                    282: }
                    283:
                    284: void
                    285: usbf_devinfo_free(char *devinfo)
                    286: {
                    287:        if (devinfo != NULL)
                    288:                free(devinfo, M_USB);
                    289: }
                    290:
                    291: /*
                    292:  * Add a string descriptor to a logical device and return the string's id.
                    293:  *
                    294:  * If there is not enough memory available for the new string descriptor, or
                    295:  * if there is no unused string id left, return the id of the empty string
                    296:  * instead of failing.
                    297:  */
                    298: u_int8_t
                    299: usbf_add_string(usbf_device_handle dev, const char *string)
                    300: {
                    301:        usb_string_descriptor_t *sd;
                    302:        size_t oldsize;
                    303:        size_t newsize;
                    304:        size_t len, i;
                    305:        u_int8_t id;
                    306:
                    307:        if (string == NULL || *string == '\0' ||
                    308:            dev->string_id == USBF_STRING_ID_MAX)
                    309:                return USBF_EMPTY_STRING_ID;
                    310:
                    311:        if ((len = strlen(string)) >= USB_MAX_STRING_LEN)
                    312:                len = USB_MAX_STRING_LEN - 1;
                    313:
                    314:        oldsize = dev->sdesc_size;
                    315:        newsize = oldsize + 2 + 2 * len;
                    316:
                    317:        sd = usbf_realloc((void **)&dev->sdesc, &dev->sdesc_size,
                    318:            newsize);
                    319:        if (sd == NULL)
                    320:                return USBF_EMPTY_STRING_ID;
                    321:
                    322:        sd = (usb_string_descriptor_t *)((char *)sd + oldsize);
                    323:        sd->bLength = newsize - oldsize;
                    324:        sd->bDescriptorType = UDESC_STRING;
                    325:        for (i = 0; string[i] != '\0' && i < len; i++)
                    326:                USETW(sd->bString[i], string[i]);
                    327:
                    328:        id = dev->string_id++;
                    329:        return id;
                    330: }
                    331:
                    332: usb_string_descriptor_t *
                    333: usbf_string_descriptor(usbf_device_handle dev, u_int8_t id)
                    334: {
                    335:        static usb_string_descriptor_t sd0;
                    336:        static usb_string_descriptor_t sd1;
                    337:        usb_string_descriptor_t *sd;
                    338:
                    339:        /* handle the special string ids */
                    340:        switch (id) {
                    341:        case USB_LANGUAGE_TABLE:
                    342:                sd0.bLength = 4;
                    343:                sd0.bDescriptorType = UDESC_STRING;
                    344:                USETW(sd0.bString[0], 0x0409 /* en_US */);
                    345:                return &sd0;
                    346:
                    347:        case USBF_EMPTY_STRING_ID:
                    348:                sd1.bLength = 2;
                    349:                sd1.bDescriptorType = UDESC_STRING;
                    350:                return &sd0;
                    351:        }
                    352:
                    353:        /* check if the string id is valid */
                    354:        if (id > dev->string_id)
                    355:                return NULL;
                    356:
                    357:        /* seek and return the descriptor of a non-empty string */
                    358:        id -= USBF_STRING_ID_MIN;
                    359:        sd = dev->sdesc;
                    360:        while (id-- > 0)
                    361:                sd = (usb_string_descriptor_t *)((char *)sd + sd->bLength);
                    362:        return sd;
                    363: }
                    364:
                    365: size_t
                    366: usbf_get_string(usbf_device_handle dev, u_int8_t id, char *s, size_t size)
                    367: {
                    368:        usb_string_descriptor_t *sd = NULL;
                    369:        size_t i, len;
                    370:
                    371:        if (id != USB_LANGUAGE_TABLE)
                    372:                sd = usbf_string_descriptor(dev, id);
                    373:
                    374:        if (sd == NULL) {
                    375:                if (size > 0)
                    376:                        *s = '\0';
                    377:                return 0;
                    378:        }
                    379:
                    380:        len = (sd->bLength - 2) / 2;
                    381:        if (size < 1)
                    382:                return len;
                    383:
                    384:        for (i = 0; i < (size - 1) && i < len; i++)
                    385:                s[i] = UGETW(sd->bString[i]) & 0xff;
                    386:        s[i] = '\0';
                    387:        return len;
                    388: }
                    389:
                    390: /*
                    391:  * Add a new device configuration to an existing USB logical device.
                    392:  * The new configuration initially has zero interfaces.
                    393:  */
                    394: usbf_status
                    395: usbf_add_config(usbf_device_handle dev, usbf_config_handle *ucp)
                    396: {
                    397:        struct usbf_config *uc;
                    398:        usb_config_descriptor_t *cd;
                    399:
                    400:        uc = malloc(sizeof *uc, M_USB, M_NOWAIT);
                    401:        if (uc == NULL)
                    402:                return USBF_NOMEM;
                    403:
                    404:        cd = malloc(sizeof *cd, M_USB, M_NOWAIT);
                    405:        if (cd == NULL) {
                    406:                free(uc, M_USB);
                    407:                return USBF_NOMEM;
                    408:        }
                    409:
                    410:        bzero(uc, sizeof *uc);
                    411:        uc->uc_device = dev;
                    412:        uc->uc_cdesc = cd;
                    413:        uc->uc_cdesc_size = sizeof *cd;
                    414:        SIMPLEQ_INIT(&uc->iface_head);
                    415:
                    416:        bzero(cd, sizeof *cd);
                    417:        cd->bLength = USB_CONFIG_DESCRIPTOR_SIZE;
                    418:        cd->bDescriptorType = UDESC_CONFIG;
                    419:        USETW(cd->wTotalLength, USB_CONFIG_DESCRIPTOR_SIZE);
                    420:        cd->bConfigurationValue = USB_UNCONFIG_NO + 1 +
                    421:            dev->ddesc.bNumConfigurations;
                    422:        cd->iConfiguration = 0;
                    423:        cd->bmAttributes = UC_BUS_POWERED | UC_SELF_POWERED;
                    424: #if 0
                    425:        cd->bMaxPower = 100 / UC_POWER_FACTOR; /* 100 mA */
                    426: #else
                    427:        cd->bMaxPower = 0; /* XXX 0 mA */
                    428: #endif
                    429:
                    430:        SIMPLEQ_INSERT_TAIL(&dev->configs, uc, next);
                    431:        dev->ddesc.bNumConfigurations++;
                    432:
                    433:        if (ucp != NULL)
                    434:                *ucp = uc;
                    435:        return USBF_NORMAL_COMPLETION;
                    436: }
                    437:
                    438: /*
                    439:  * Allocate memory for a new descriptor at the end of the existing
                    440:  * device configuration descriptor.
                    441:  */
                    442: usbf_status
                    443: usbf_add_config_desc(usbf_config_handle uc, usb_descriptor_t *d,
                    444:     usb_descriptor_t **dp)
                    445: {
                    446:        usb_config_descriptor_t *cd;
                    447:        size_t oldsize;
                    448:        size_t newsize;
                    449:
                    450:        oldsize = uc->uc_cdesc_size;
                    451:        newsize = oldsize + d->bLength;
                    452:        if (d->bLength < sizeof(usb_descriptor_t) || newsize > 65535)
                    453:                return USBF_INVAL;
                    454:
                    455:        cd = usbf_realloc((void **)&uc->uc_cdesc, &uc->uc_cdesc_size,
                    456:            newsize);
                    457:        if (cd == NULL)
                    458:                return USBF_NOMEM;
                    459:
                    460:        bcopy(d, (char *)cd + oldsize, d->bLength);
                    461:        USETW(cd->wTotalLength, newsize);
                    462:        if (dp != NULL)
                    463:                *dp = (usb_descriptor_t *)((char *)cd + oldsize);
                    464:        return USBF_NORMAL_COMPLETION;
                    465: }
                    466:
                    467: usbf_status
                    468: usbf_add_interface(usbf_config_handle uc, u_int8_t bInterfaceClass,
                    469:     u_int8_t bInterfaceSubClass, u_int8_t bInterfaceProtocol,
                    470:     const char *string, usbf_interface_handle *uip)
                    471: {
                    472:        struct usbf_interface *ui;
                    473:        usb_interface_descriptor_t *id;
                    474:
                    475:        if (uc->uc_closed)
                    476:                return USBF_INVAL;
                    477:
                    478:        ui = malloc(sizeof *ui, M_USB, M_NOWAIT);
                    479:        if (ui == NULL)
                    480:                return USBF_NOMEM;
                    481:
                    482:        id = malloc(sizeof *id, M_USB, M_NOWAIT);
                    483:        if (id == NULL) {
                    484:                free(ui, M_USB);
                    485:                return USBF_NOMEM;
                    486:        }
                    487:
                    488:        bzero(ui, sizeof *ui);
                    489:        ui->config = uc;
                    490:        ui->idesc = id;
                    491:        LIST_INIT(&ui->pipes);
                    492:        SIMPLEQ_INIT(&ui->endpoint_head);
                    493:
                    494:        bzero(id, sizeof *id);
                    495:        id->bLength = USB_INTERFACE_DESCRIPTOR_SIZE;
                    496:        id->bDescriptorType = UDESC_INTERFACE;
                    497:        id->bInterfaceNumber = uc->uc_cdesc->bNumInterface;
                    498:        id->bInterfaceClass = bInterfaceClass;
                    499:        id->bInterfaceSubClass = bInterfaceSubClass;
                    500:        id->bInterfaceProtocol = bInterfaceProtocol;
                    501:        id->iInterface = 0; /*usbf_add_string(uc->uc_device, string);*/ /* XXX */
                    502:
                    503:        SIMPLEQ_INSERT_TAIL(&uc->iface_head, ui, next);
                    504:        uc->uc_cdesc->bNumInterface++;
                    505:
                    506:        *uip = ui;
                    507:        return USBF_NORMAL_COMPLETION;
                    508: }
                    509:
                    510: usbf_status
                    511: usbf_add_endpoint(usbf_interface_handle ui, u_int8_t bEndpointAddress,
                    512:     u_int8_t bmAttributes, u_int16_t wMaxPacketSize, u_int8_t bInterval,
                    513:     usbf_endpoint_handle *uep)
                    514: {
                    515:        struct usbf_endpoint *ue;
                    516:        usb_endpoint_descriptor_t *ed;
                    517:
                    518:        if (ui->config->uc_closed)
                    519:                return USBF_INVAL;
                    520:
                    521:        ue = malloc(sizeof *ue, M_USB, M_NOWAIT);
                    522:        if (ue == NULL)
                    523:                return USBF_NOMEM;
                    524:
                    525:        ed = malloc(sizeof *ed, M_USB, M_NOWAIT);
                    526:        if (ed == NULL) {
                    527:                free(ue, M_USB);
                    528:                return USBF_NOMEM;
                    529:        }
                    530:
                    531:        bzero(ue, sizeof *ue);
                    532:        ue->iface = ui;
                    533:        ue->edesc = ed;
                    534:
                    535:        bzero(ed, sizeof *ed);
                    536:        ed->bLength = USB_ENDPOINT_DESCRIPTOR_SIZE;
                    537:        ed->bDescriptorType = UDESC_ENDPOINT;
                    538:        ed->bEndpointAddress = bEndpointAddress;
                    539:        ed->bmAttributes = bmAttributes;
                    540:        USETW(ed->wMaxPacketSize, wMaxPacketSize);
                    541:        ed->bInterval = bInterval;
                    542:
                    543:        SIMPLEQ_INSERT_TAIL(&ui->endpoint_head, ue, next);
                    544:        ui->idesc->bNumEndpoints++;
                    545:
                    546:        *uep = ue;
                    547:        return USBF_NORMAL_COMPLETION;
                    548: }
                    549:
                    550: /*
                    551:  * Close the configuration, thereby combining all descriptors and creating
                    552:  * the real USB configuration descriptor that can be sent to the USB host.
                    553:  */
                    554: usbf_status
                    555: usbf_end_config(usbf_config_handle uc)
                    556: {
                    557:        struct usbf_interface *ui;
                    558:        struct usbf_endpoint *ue;
                    559:        usb_descriptor_t *d;
                    560:        usbf_status err = USBF_NORMAL_COMPLETION;
                    561:
                    562:        if (uc->uc_closed)
                    563:                return USBF_INVAL;
                    564:
                    565:        SIMPLEQ_FOREACH(ui, &uc->iface_head, next) {
                    566:                err = usbf_add_config_desc(uc,
                    567:                    (usb_descriptor_t *)ui->idesc, &d);
                    568:                if (err)
                    569:                        break;
                    570:
                    571:                free(ui->idesc, M_USB);
                    572:                ui->idesc = (usb_interface_descriptor_t *)d;
                    573:
                    574:                SIMPLEQ_FOREACH(ue, &ui->endpoint_head, next) {
                    575:                        err = usbf_add_config_desc(uc,
                    576:                            (usb_descriptor_t *)ue->edesc, &d);
                    577:                        if (err)
                    578:                                break;
                    579:
                    580:                        free(ue->edesc, M_USB);
                    581:                        ue->edesc = (usb_endpoint_descriptor_t *)d;
                    582:                }
                    583:        }
                    584:
                    585:        uc->uc_closed = 1;
                    586:        return err;
                    587: }
                    588:
                    589: usb_device_descriptor_t *
                    590: usbf_device_descriptor(usbf_device_handle dev)
                    591: {
                    592:        return &dev->ddesc;
                    593: }
                    594:
                    595: usb_config_descriptor_t *
                    596: usbf_config_descriptor(usbf_device_handle dev, u_int8_t index)
                    597: {
                    598:        struct usbf_config *uc;
                    599:
                    600:        SIMPLEQ_FOREACH(uc, &dev->configs, next) {
                    601:                if (index-- == 0)
                    602:                        return uc->uc_cdesc;
                    603:        }
                    604:        return NULL;
                    605: }
                    606:
                    607: int
                    608: usbf_interface_number(usbf_interface_handle iface)
                    609: {
                    610:        return iface->idesc->bInterfaceNumber;
                    611: }
                    612:
                    613: u_int8_t
                    614: usbf_endpoint_address(usbf_endpoint_handle endpoint)
                    615: {
                    616:        return endpoint->edesc->bEndpointAddress;
                    617: }
                    618:
                    619: u_int8_t
                    620: usbf_endpoint_attributes(usbf_endpoint_handle endpoint)
                    621: {
                    622:        return endpoint->edesc->bmAttributes;
                    623: }
                    624:
                    625: usbf_status
                    626: usbf_open_pipe(usbf_interface_handle iface, u_int8_t address,
                    627:     usbf_pipe_handle *pipe)
                    628: {
                    629:        return usbf_open_pipe_ival(iface, address, pipe, 0);
                    630: }
                    631:
                    632: usbf_status
                    633: usbf_open_pipe_ival(usbf_interface_handle iface, u_int8_t address,
                    634:     usbf_pipe_handle *pipe, int ival)
                    635: {
                    636:        struct usbf_endpoint *ep;
                    637:        usbf_pipe_handle p;
                    638:        usbf_status err;
                    639:
                    640:        ep = usbf_iface_endpoint(iface, address);
                    641:        if (ep == NULL)
                    642:                return USBF_BAD_ADDRESS;
                    643:
                    644:        err = usbf_setup_pipe(iface->config->uc_device, iface, ep,
                    645:            ival, &p);
                    646:        if (err)
                    647:                return err;
                    648:        LIST_INSERT_HEAD(&iface->pipes, p, next);
                    649:        *pipe = p;
                    650:        return USBF_NORMAL_COMPLETION;
                    651: }
                    652:
                    653: usbf_status
                    654: usbf_setup_pipe(usbf_device_handle dev, usbf_interface_handle iface,
                    655:     struct usbf_endpoint *ep, int ival, usbf_pipe_handle *pipe)
                    656: {
                    657:        struct usbf_pipe *p;
                    658:        usbf_status err;
                    659:
                    660:        p = malloc(dev->bus->pipe_size, M_USB, M_NOWAIT);
                    661:        if (p == NULL)
                    662:                return USBF_NOMEM;
                    663:
                    664:        p->device = dev;
                    665:        p->iface = iface;
                    666:        p->endpoint = ep;
                    667:        ep->refcnt++;
                    668:        p->running = 0;
                    669:        p->refcnt = 1;
                    670:        p->repeat = 0;
                    671:        p->interval = ival;
                    672:        p->methods = NULL;      /* set by bus driver in open_pipe() */
                    673:        SIMPLEQ_INIT(&p->queue);
                    674:        err = dev->bus->methods->open_pipe(p);
                    675:        if (err) {
                    676:                free(p, M_USB);
                    677:                return err;
                    678:        }
                    679:        *pipe = p;
                    680:        return USBF_NORMAL_COMPLETION;
                    681: }
                    682:
                    683: /* Dequeue all pipe operations. */
                    684: void
                    685: usbf_abort_pipe(usbf_pipe_handle pipe)
                    686: {
                    687:        usbf_xfer_handle xfer;
                    688:        int s;
                    689:
                    690:        s = splusb();
                    691:        pipe->repeat = 0;
                    692:        pipe->aborting = 1;
                    693:
                    694:        while ((xfer = SIMPLEQ_FIRST(&pipe->queue)) != NULL) {
                    695:                DPRINTF(0,("usbf_abort_pipe: pipe=%p, xfer=%p\n", pipe,
                    696:                    xfer));
                    697:                /* Make the DC abort it (and invoke the callback). */
                    698:                pipe->methods->abort(xfer);
                    699:        }
                    700:
                    701:        pipe->aborting = 0;
                    702:        splx(s);
                    703: }
                    704:
                    705: /* Abort all pipe operations and close the pipe. */
                    706: void
                    707: usbf_close_pipe(usbf_pipe_handle pipe)
                    708: {
                    709:        usbf_abort_pipe(pipe);
                    710:        pipe->methods->close(pipe);
                    711:        pipe->endpoint->refcnt--;
                    712:        free(pipe, M_USB);
                    713: }
                    714:
                    715: void
                    716: usbf_stall_pipe(usbf_pipe_handle pipe)
                    717: {
                    718:        DPRINTF(0,("usbf_stall_pipe not implemented\n"));
                    719: }
                    720:
                    721: usbf_endpoint_handle
                    722: usbf_iface_endpoint(usbf_interface_handle iface, u_int8_t address)
                    723: {
                    724:        usbf_endpoint_handle ep;
                    725:
                    726:        SIMPLEQ_FOREACH(ep, &iface->endpoint_head, next) {
                    727:                if (ep->edesc->bEndpointAddress == address)
                    728:                        return ep;
                    729:        }
                    730:        return NULL;
                    731: }
                    732:
                    733: usbf_endpoint_handle
                    734: usbf_config_endpoint(usbf_config_handle cfg, u_int8_t address)
                    735: {
                    736:        usbf_interface_handle iface;
                    737:        usbf_endpoint_handle ep;
                    738:
                    739:        SIMPLEQ_FOREACH(iface, &cfg->iface_head, next) {
                    740:                SIMPLEQ_FOREACH(ep, &iface->endpoint_head, next) {
                    741:                        if (ep->edesc->bEndpointAddress == address)
                    742:                                return ep;
                    743:                }
                    744:        }
                    745:        return NULL;
                    746: }
                    747:
                    748: void
                    749: usbf_set_endpoint_halt(usbf_endpoint_handle endpoint)
                    750: {
                    751: }
                    752:
                    753: void
                    754: usbf_clear_endpoint_halt(usbf_endpoint_handle endpoint)
                    755: {
                    756: }
                    757:
                    758: usbf_status
                    759: usbf_set_endpoint_feature(usbf_config_handle cfg, u_int8_t address,
                    760:     u_int16_t value)
                    761: {
                    762:        usbf_endpoint_handle ep;
                    763:
                    764:        DPRINTF(0,("usbf_set_endpoint_feature: cfg=%p address=%#x"
                    765:            " value=%#x\n", cfg, address, value));
                    766:
                    767:        ep = usbf_config_endpoint(cfg, address);
                    768:        if (ep == NULL)
                    769:                return USBF_BAD_ADDRESS;
                    770:
                    771:        switch (value) {
                    772:        case UF_ENDPOINT_HALT:
                    773:                usbf_set_endpoint_halt(ep);
                    774:                return USBF_NORMAL_COMPLETION;
                    775:        default:
                    776:                /* unsupported feature, send STALL in data/status phase */
                    777:                return USBF_STALLED;
                    778:        }
                    779: }
                    780:
                    781: usbf_status
                    782: usbf_clear_endpoint_feature(usbf_config_handle cfg, u_int8_t address,
                    783:     u_int16_t value)
                    784: {
                    785:        usbf_endpoint_handle ep;
                    786:
                    787:        DPRINTF(0,("usbf_clear_endpoint_feature: cfg=%p address=%#x"
                    788:            " value=%#x\n", cfg, address, value));
                    789:
                    790:        ep = usbf_config_endpoint(cfg, address);
                    791:        if (ep == NULL)
                    792:                return USBF_BAD_ADDRESS;
                    793:
                    794:        switch (value) {
                    795:        case UF_ENDPOINT_HALT:
                    796:                usbf_clear_endpoint_halt(ep);
                    797:                return USBF_NORMAL_COMPLETION;
                    798:        default:
                    799:                /* unsupported feature, send STALL in data/status phase */
                    800:                return USBF_STALLED;
                    801:        }
                    802: }
                    803:
                    804: usbf_xfer_handle
                    805: usbf_alloc_xfer(usbf_device_handle dev)
                    806: {
                    807:        struct usbf_xfer *xfer;
                    808:
                    809:        /* allocate zero-filled buffer */
                    810:        xfer = dev->bus->methods->allocx(dev->bus);
                    811:        if (xfer == NULL)
                    812:                return NULL;
                    813:        xfer->device = dev;
                    814:        timeout_set(&xfer->timeout_handle, NULL, NULL);
                    815:        DPRINTF(1,("usbf_alloc_xfer() = %p\n", xfer));
                    816:        return xfer;
                    817: }
                    818:
                    819: void
                    820: usbf_free_xfer(usbf_xfer_handle xfer)
                    821: {
                    822:        DPRINTF(1,("usbf_free_xfer: %p\n", xfer));
                    823:        if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
                    824:                usbf_free_buffer(xfer);
                    825:        xfer->device->bus->methods->freex(xfer->device->bus, xfer);
                    826: }
                    827:
                    828: usbf_status
                    829: usbf_allocmem(usbf_bus_handle bus, size_t size, size_t align, usb_dma_t *p)
                    830: {
                    831:        struct usbd_bus dbus;
                    832:        usbd_status err;
                    833:
                    834:        /* XXX bad idea, fix usb_mem.c instead! */
                    835:        dbus.dmatag = bus->dmatag;
                    836:        err = usb_allocmem(&dbus, size, align, p);
                    837:        return err ? USBF_NOMEM : USBF_NORMAL_COMPLETION;
                    838: }
                    839:
                    840: void
                    841: usbf_freemem(usbf_bus_handle bus, usb_dma_t *p)
                    842: {
                    843:        usb_freemem((usbd_bus_handle)NULL, p);
                    844: }
                    845:
                    846: void *
                    847: usbf_alloc_buffer(usbf_xfer_handle xfer, u_int32_t size)
                    848: {
                    849:        struct usbf_bus *bus = xfer->device->bus;
                    850:        usbf_status err;
                    851:
                    852: #ifdef DIAGNOSTIC
                    853:        if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
                    854:                printf("xfer %p already has a buffer\n", xfer);
                    855: #endif
                    856:
                    857:        err = bus->methods->allocm(bus, &xfer->dmabuf, size);
                    858:        if (err)
                    859:                return NULL;
                    860:
                    861:        xfer->rqflags |= URQ_DEV_DMABUF;
                    862:        return KERNADDR(&xfer->dmabuf, 0);
                    863: }
                    864:
                    865: void
                    866: usbf_free_buffer(usbf_xfer_handle xfer)
                    867: {
                    868: #ifdef DIAGNOSTIC
                    869:        if (!(xfer->rqflags & URQ_DEV_DMABUF)) {
                    870:                printf("usbf_free_buffer: no buffer\n");
                    871:                return;
                    872:        }
                    873: #endif
                    874:        xfer->rqflags &= ~URQ_DEV_DMABUF;
                    875:        xfer->device->bus->methods->freem(xfer->device->bus, &xfer->dmabuf);
                    876: }
                    877:
                    878: #ifdef USBF_DEBUG
                    879: /*
                    880:  * The dump format is similar to Linux' Gadget driver so that we can
                    881:  * easily compare traces.
                    882:  */
                    883: static void
                    884: usbf_dump_buffer(usbf_xfer_handle xfer)
                    885: {
                    886:        struct device *dev = (struct device *)xfer->pipe->device->bus->usbfctl;
                    887:        usbf_endpoint_handle ep = xfer->pipe->endpoint;
                    888:        int index = usbf_endpoint_index(ep);
                    889:        int dir = usbf_endpoint_dir(ep);
                    890:        u_char *p = xfer->buffer;
                    891:        u_int i;
                    892:
                    893:        printf("%s: ep%d-%s, length=%u, %s", dev->dv_xname, index,
                    894:            (xfer->rqflags & URQ_REQUEST) ? "setup" :
                    895:            (index == 0 ? "in" : (dir == UE_DIR_IN ? "in" : "out")),
                    896:            xfer->length, usbf_errstr(xfer->status));
                    897:
                    898:        for (i = 0; i < xfer->length; i++) {
                    899:                if ((i % 16) == 0)
                    900:                        printf("\n%4x:", i);
                    901:                else if ((i % 8) == 0)
                    902:                        printf(" ");
                    903:                printf(" %02x", p[i]);
                    904:        }
                    905:        printf("\n");
                    906: }
                    907: #endif
                    908:
                    909: void
                    910: usbf_setup_xfer(usbf_xfer_handle xfer, usbf_pipe_handle pipe,
                    911:     usbf_private_handle priv, void *buffer, u_int32_t length,
                    912:     u_int16_t flags, u_int32_t timeout, usbf_callback callback)
                    913: {
                    914:        xfer->pipe = pipe;
                    915:        xfer->priv = priv;
                    916:        xfer->buffer = buffer;
                    917:        xfer->length = length;
                    918:        xfer->actlen = 0;
                    919:        xfer->flags = flags;
                    920:        xfer->timeout = timeout;
                    921:        xfer->status = USBF_NOT_STARTED;
                    922:        xfer->callback = callback;
                    923:        xfer->rqflags &= ~URQ_REQUEST;
                    924: }
                    925:
                    926: void
                    927: usbf_setup_default_xfer(usbf_xfer_handle xfer, usbf_pipe_handle pipe,
                    928:     usbf_private_handle priv, usb_device_request_t *req, u_int16_t flags,
                    929:     u_int32_t timeout, usbf_callback callback)
                    930: {
                    931:        xfer->pipe = pipe;
                    932:        xfer->priv = priv;
                    933:        xfer->buffer = req;
                    934:        xfer->length = sizeof *req;
                    935:        xfer->actlen = 0;
                    936:        xfer->flags = flags;
                    937:        xfer->timeout = timeout;
                    938:        xfer->status = USBF_NOT_STARTED;
                    939:        xfer->callback = callback;
                    940:        xfer->rqflags |= URQ_REQUEST;
                    941: }
                    942:
                    943: void
                    944: usbf_get_xfer_status(usbf_xfer_handle xfer, usbf_private_handle *priv,
                    945:     void **buffer, u_int32_t *actlen, usbf_status *status)
                    946: {
                    947:        if (priv != NULL)
                    948:                *priv = xfer->priv;
                    949:        if (buffer != NULL)
                    950:                *buffer = xfer->buffer;
                    951:        if (actlen != NULL)
                    952:                *actlen = xfer->actlen;
                    953:        if (status != NULL)
                    954:                *status = xfer->status;
                    955: }
                    956:
                    957: usbf_status
                    958: usbf_transfer(usbf_xfer_handle xfer)
                    959: {
                    960:        usbf_pipe_handle pipe = xfer->pipe;
                    961:        usbf_status err;
                    962:
                    963:        err = pipe->methods->transfer(xfer);
                    964:        if (err != USBF_IN_PROGRESS && err) {
                    965:                if (xfer->rqflags & URQ_AUTO_DMABUF) {
                    966:                        usbf_free_buffer(xfer);
                    967:                        xfer->rqflags &= ~URQ_AUTO_DMABUF;
                    968:                }
                    969:        }
                    970:        return err;
                    971: }
                    972:
                    973: usbf_status
                    974: usbf_insert_transfer(usbf_xfer_handle xfer)
                    975: {
                    976:        usbf_pipe_handle pipe = xfer->pipe;
                    977:        usbf_status err;
                    978:        int s;
                    979:
                    980:        DPRINTF(1,("usbf_insert_transfer: xfer=%p pipe=%p running=%d\n",
                    981:            xfer, pipe, pipe->running));
                    982:
                    983:        s = splusb();
                    984:        SIMPLEQ_INSERT_TAIL(&pipe->queue, xfer, next);
                    985:        if (pipe->running)
                    986:                err = USBF_IN_PROGRESS;
                    987:        else {
                    988:                pipe->running = 1;
                    989:                err = USBF_NORMAL_COMPLETION;
                    990:        }
                    991:        splx(s);
                    992:        return err;
                    993: }
                    994:
                    995: void
                    996: usbf_start_next(usbf_pipe_handle pipe)
                    997: {
                    998:        usbf_xfer_handle xfer;
                    999:        usbf_status err;
                   1000:
                   1001:        SPLUSBCHECK;
                   1002:
                   1003:        /* Get next request in queue. */
                   1004:        xfer = SIMPLEQ_FIRST(&pipe->queue);
                   1005:        if (xfer == NULL)
                   1006:                pipe->running = 0;
                   1007:        else {
                   1008:                err = pipe->methods->start(xfer);
                   1009:                if (err != USBF_IN_PROGRESS) {
                   1010:                        printf("usbf_start_next: %s\n", usbf_errstr(err));
                   1011:                        pipe->running = 0;
                   1012:                        /* XXX do what? */
                   1013:                }
                   1014:        }
                   1015: }
                   1016:
                   1017: /* Called at splusb() */
                   1018: void
                   1019: usbf_transfer_complete(usbf_xfer_handle xfer)
                   1020: {
                   1021:        usbf_pipe_handle pipe = xfer->pipe;
                   1022:        int repeat = pipe->repeat;
                   1023:
                   1024:        SPLUSBCHECK;
                   1025:        DPRINTF(1,("usbf_transfer_complete: xfer=%p pipe=%p running=%d\n",
                   1026:            xfer, pipe, pipe->running));
                   1027: #ifdef USBF_DEBUG
                   1028:        if (usbfdebug > 0)
                   1029:                usbf_dump_buffer(xfer);
                   1030: #endif
                   1031:
                   1032:        if (!repeat) {
                   1033:                /* Remove request from queue. */
                   1034:                KASSERT(SIMPLEQ_FIRST(&pipe->queue) == xfer);
                   1035:                SIMPLEQ_REMOVE_HEAD(&pipe->queue, next);
                   1036:        }
                   1037:
                   1038:        if (xfer->status == USBF_NORMAL_COMPLETION &&
                   1039:            xfer->actlen < xfer->length &&
                   1040:            !(xfer->flags & USBD_SHORT_XFER_OK)) {
                   1041:                DPRINTF(0,("usbf_transfer_complete: short xfer=%p %u<%u\n",
                   1042:                    xfer, xfer->actlen, xfer->length));
                   1043:                xfer->status = USBF_SHORT_XFER;
                   1044:        }
                   1045:
                   1046:        if (xfer->callback != NULL)
                   1047:                xfer->callback(xfer, xfer->priv, xfer->status);
                   1048:
                   1049:        pipe->methods->done(xfer);
                   1050:
                   1051:        /* XXX wake up any processes waiting for the transfer to complete */
                   1052:
                   1053:        if (!repeat) {
                   1054:                if (xfer->status != USBF_NORMAL_COMPLETION &&
                   1055:                    pipe->iface != NULL) /* not control pipe */
                   1056:                        pipe->running = 0;
                   1057:                else
                   1058:                        usbf_start_next(pipe);
                   1059:        }
                   1060: }
                   1061:
                   1062: /*
                   1063:  * Software interrupts
                   1064:  */
                   1065:
                   1066: usbf_status
                   1067: usbf_softintr_establish(struct usbf_bus *bus)
                   1068: {
                   1069: #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
                   1070:        KASSERT(bus->soft == NULL);
                   1071:        /* XXX we should have our own level */
                   1072:        bus->soft = softintr_establish(IPL_SOFTNET,
                   1073:            bus->methods->soft_intr, bus);
                   1074:        if (bus->soft == NULL)
                   1075:                return USBF_INVAL;
                   1076: #endif
                   1077:        return USBF_NORMAL_COMPLETION;
                   1078: }
                   1079:
                   1080: void
                   1081: usbf_schedsoftintr(struct usbf_bus *bus)
                   1082: {
                   1083: #ifdef __HAVE_GENERIC_SOFT_INTERRUPTS
                   1084:        softintr_schedule(bus->soft);
                   1085: #else
                   1086:        bus->methods->soft_intr(bus);
                   1087: #endif /* __HAVE_GENERIC_SOFT_INTERRUPTS */
                   1088: }

CVSweb