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

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

1.1       nbrk        1: /*     $OpenBSD: uvisor.c,v 1.35 2007/06/14 10:11:16 mbalmer Exp $     */
                      2: /*     $NetBSD: uvisor.c,v 1.21 2003/08/03 21:59:26 nathanw Exp $      */
                      3:
                      4: /*
                      5:  * Copyright (c) 2000 The NetBSD Foundation, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to The NetBSD Foundation
                      9:  * by Lennart Augustsson (lennart@augustsson.net) at
                     10:  * Carlstedt Research & Technology.
                     11:  *
                     12:  * Redistribution and use in source and binary forms, with or without
                     13:  * modification, are permitted provided that the following conditions
                     14:  * are met:
                     15:  * 1. Redistributions of source code must retain the above copyright
                     16:  *    notice, this list of conditions and the following disclaimer.
                     17:  * 2. Redistributions in binary form must reproduce the above copyright
                     18:  *    notice, this list of conditions and the following disclaimer in the
                     19:  *    documentation and/or other materials provided with the distribution.
                     20:  * 3. All advertising materials mentioning features or use of this software
                     21:  *    must display the following acknowledgement:
                     22:  *        This product includes software developed by the NetBSD
                     23:  *        Foundation, Inc. and its contributors.
                     24:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     25:  *    contributors may be used to endorse or promote products derived
                     26:  *    from this software without specific prior written permission.
                     27:  *
                     28:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     29:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     30:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     31:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     32:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     33:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     34:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     35:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     36:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     37:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     38:  * POSSIBILITY OF SUCH DAMAGE.
                     39:  */
                     40:
                     41: /*
                     42:  * Handspring Visor (Palmpilot compatible PDA) driver
                     43:  */
                     44:
                     45: #include <sys/param.h>
                     46: #include <sys/systm.h>
                     47: #include <sys/kernel.h>
                     48: #include <sys/device.h>
                     49: #include <sys/conf.h>
                     50: #include <sys/tty.h>
                     51:
                     52: #include <dev/usb/usb.h>
                     53: #include <dev/usb/usbhid.h>
                     54:
                     55: #include <dev/usb/usbdi.h>
                     56: #include <dev/usb/usbdi_util.h>
                     57: #include <dev/usb/usbdevs.h>
                     58:
                     59: #include <dev/usb/ucomvar.h>
                     60:
                     61: #ifdef UVISOR_DEBUG
                     62: #define DPRINTF(x)     if (uvisordebug) printf x
                     63: #define DPRINTFN(n,x)  if (uvisordebug>(n)) printf x
                     64: int uvisordebug = 0;
                     65: #else
                     66: #define DPRINTF(x)
                     67: #define DPRINTFN(n,x)
                     68: #endif
                     69:
                     70: #define UVISOR_CONFIG_INDEX    0
                     71: #define UVISOR_IFACE_INDEX     0
                     72:
                     73: /* From the Linux driver */
                     74: /*
                     75:  * UVISOR_REQUEST_BYTES_AVAILABLE asks the visor for the number of bytes that
                     76:  * are available to be transfered to the host for the specified endpoint.
                     77:  * Currently this is not used, and always returns 0x0001
                     78:  */
                     79: #define UVISOR_REQUEST_BYTES_AVAILABLE         0x01
                     80:
                     81: /*
                     82:  * UVISOR_CLOSE_NOTIFICATION is set to the device to notify it that the host
                     83:  * is now closing the pipe. An empty packet is sent in response.
                     84:  */
                     85: #define UVISOR_CLOSE_NOTIFICATION              0x02
                     86:
                     87: /*
                     88:  * UVISOR_GET_CONNECTION_INFORMATION is sent by the host during enumeration to
                     89:  * get the endpoints used by the connection.
                     90:  */
                     91: #define UVISOR_GET_CONNECTION_INFORMATION      0x03
                     92:
                     93:
                     94: /*
                     95:  * UVISOR_GET_CONNECTION_INFORMATION returns data in the following format
                     96:  */
                     97: #define UVISOR_MAX_CONN 8
                     98: struct uvisor_connection_info {
                     99:        uWord   num_ports;
                    100:        struct {
                    101:                uByte   port_function_id;
                    102:                uByte   port;
                    103:        } connections[UVISOR_MAX_CONN];
                    104: };
                    105: #define UVISOR_CONNECTION_INFO_SIZE 18
                    106:
                    107: /* struct uvisor_connection_info.connection[x].port_function_id defines: */
                    108: #define UVISOR_FUNCTION_GENERIC                0x00
                    109: #define UVISOR_FUNCTION_DEBUGGER       0x01
                    110: #define UVISOR_FUNCTION_HOTSYNC                0x02
                    111: #define UVISOR_FUNCTION_CONSOLE                0x03
                    112: #define UVISOR_FUNCTION_REMOTE_FILE_SYS        0x04
                    113:
                    114: /*
                    115:  * Unknown PalmOS stuff.
                    116:  */
                    117: #define UVISOR_GET_PALM_INFORMATION            0x04
                    118: #define UVISOR_GET_PALM_INFORMATION_LEN                0x44
                    119:
                    120: struct uvisor_palm_connection_info {
                    121:        uByte   num_ports;
                    122:        uByte   endpoint_numbers_different;
                    123:        uWord   reserved1;
                    124:        struct {
                    125:                uDWord  port_function_id;
                    126:                uByte   port;
                    127:                uByte   end_point_info;
                    128:                uWord   reserved;
                    129:        } connections[UVISOR_MAX_CONN];
                    130: };
                    131:
                    132: #define UVISORIBUFSIZE 64
                    133: #define UVISOROBUFSIZE 1024
                    134:
                    135: struct uvisor_softc {
                    136:        struct device           sc_dev;         /* base device */
                    137:        usbd_device_handle      sc_udev;        /* device */
                    138:        usbd_interface_handle   sc_iface;       /* interface */
                    139: /*
                    140:  * added sc_vendor for later interrogation in failed initialisations
                    141:  */
                    142:        int                     sc_vendor;      /* USB device vendor */
                    143:
                    144:        struct device           *sc_subdevs[UVISOR_MAX_CONN];
                    145:        int                     sc_numcon;
                    146:
                    147:        u_int16_t               sc_flags;
                    148:
                    149:        u_char                  sc_dying;
                    150: };
                    151:
                    152: usbd_status uvisor_init(struct uvisor_softc *,
                    153:                               struct uvisor_connection_info *,
                    154:                               struct uvisor_palm_connection_info *);
                    155:
                    156: void uvisor_close(void *, int);
                    157:
                    158:
                    159: struct ucom_methods uvisor_methods = {
                    160:        NULL,
                    161:        NULL,
                    162:        NULL,
                    163:        NULL,
                    164:        NULL,
                    165:        uvisor_close,
                    166:        NULL,
                    167:        NULL,
                    168: };
                    169:
                    170: struct uvisor_type {
                    171:        struct usb_devno        uv_dev;
                    172:        u_int16_t               uv_flags;
                    173: #define PALM4  0x0001
                    174: #define VISOR  0x0002
                    175: #define NOFRE  0x0004
                    176: #define CLIE4  (VISOR|NOFRE)
                    177: };
                    178: static const struct uvisor_type uvisor_devs[] = {
                    179:        {{ USB_VENDOR_ACEECA, USB_PRODUCT_ACEECA_MEZ1000 }, PALM4 },
                    180:        {{ USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_VISOR }, VISOR },
                    181:        {{ USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO }, PALM4 },
                    182:        {{ USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO600 }, VISOR },
                    183:        {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M500 }, PALM4 },
                    184:        {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M505 }, PALM4 },
                    185:        {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M515 }, PALM4 },
                    186:        {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_I705 }, PALM4 },
                    187:        {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M125 }, PALM4 },
                    188:        {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M130 }, PALM4 },
                    189:        {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_Z }, PALM4 },
                    190:        {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_T }, PALM4 },
                    191:        {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE }, PALM4 },
                    192:        {{ USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE_31 }, PALM4 },
                    193:        {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40 }, PALM4 },
                    194:        {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_41 }, PALM4 },
                    195:        {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_S360 }, PALM4 },
                    196:        {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_NX60 }, PALM4 },
                    197:        {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_TJ25 }, PALM4 },
                    198: /*     {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_25 }, PALM4 },*/
                    199:        {{ USB_VENDOR_GARMIN, USB_PRODUCT_GARMIN_IQUE3600 }, PALM4 },
                    200:        {{ USB_VENDOR_TAPWAVE, USB_PRODUCT_TAPWAVE_ZODIAC }, PALM4 },
                    201: };
                    202: #define uvisor_lookup(v, p) ((struct uvisor_type *)usb_lookup(uvisor_devs, v, p))
                    203:
                    204: int uvisor_match(struct device *, void *, void *);
                    205: void uvisor_attach(struct device *, struct device *, void *);
                    206: int uvisor_detach(struct device *, int);
                    207: int uvisor_activate(struct device *, enum devact);
                    208:
                    209: struct cfdriver uvisor_cd = {
                    210:        NULL, "uvisor", DV_DULL
                    211: };
                    212:
                    213: const struct cfattach uvisor_ca = {
                    214:        sizeof(struct uvisor_softc),
                    215:        uvisor_match,
                    216:        uvisor_attach,
                    217:        uvisor_detach,
                    218:        uvisor_activate,
                    219: };
                    220:
                    221: int
                    222: uvisor_match(struct device *parent, void *match, void *aux)
                    223: {
                    224:        struct usb_attach_arg *uaa = aux;
                    225:
                    226:        if (uaa->iface != NULL)
                    227:                return (UMATCH_NONE);
                    228:
                    229:        DPRINTFN(20,("uvisor: vendor=0x%x, product=0x%x\n",
                    230:                     uaa->vendor, uaa->product));
                    231:
                    232:        return (uvisor_lookup(uaa->vendor, uaa->product) != NULL ?
                    233:                UMATCH_VENDOR_PRODUCT : UMATCH_NONE);
                    234: }
                    235:
                    236: void
                    237: uvisor_attach(struct device *parent, struct device *self, void *aux)
                    238: {
                    239:        struct uvisor_softc *sc = (struct uvisor_softc *)self;
                    240:        struct usb_attach_arg *uaa = aux;
                    241:        usbd_device_handle dev = uaa->device;
                    242:        usbd_interface_handle iface;
                    243:        usb_interface_descriptor_t *id;
                    244:        struct uvisor_connection_info coninfo;
                    245:        struct uvisor_palm_connection_info palmconinfo;
                    246:        usb_endpoint_descriptor_t *ed;
                    247:        char *devinfop;
                    248:        char *devname = sc->sc_dev.dv_xname;
                    249:        int i, j, hasin, hasout, port;
                    250:        usbd_status err;
                    251:        struct ucom_attach_args uca;
                    252:
                    253:        DPRINTFN(10,("\nuvisor_attach: sc=%p\n", sc));
                    254:
                    255:        /* Move the device into the configured state. */
                    256:        err = usbd_set_config_index(dev, UVISOR_CONFIG_INDEX, 1);
                    257:        if (err) {
                    258:                printf("\n%s: failed to set configuration, err=%s\n",
                    259:                       devname, usbd_errstr(err));
                    260:                goto bad;
                    261:        }
                    262:
                    263:        err = usbd_device2interface_handle(dev, UVISOR_IFACE_INDEX, &iface);
                    264:        if (err) {
                    265:                printf("\n%s: failed to get interface, err=%s\n",
                    266:                       devname, usbd_errstr(err));
                    267:                goto bad;
                    268:        }
                    269:
                    270:        devinfop = usbd_devinfo_alloc(dev, 0);
                    271:        printf("\n%s: %s\n", devname, devinfop);
                    272:        usbd_devinfo_free(devinfop);
                    273:
                    274:        sc->sc_flags = uvisor_lookup(uaa->vendor, uaa->product)->uv_flags;
                    275:        sc->sc_vendor = uaa->vendor;
                    276:
                    277:        if ((sc->sc_flags & (VISOR | PALM4)) == 0) {
                    278:                printf("%s: device is neither visor nor palm\n",
                    279:                    sc->sc_dev.dv_xname);
                    280:                goto bad;
                    281:        }
                    282:
                    283:        id = usbd_get_interface_descriptor(iface);
                    284:
                    285:        sc->sc_udev = dev;
                    286:        sc->sc_iface = iface;
                    287:
                    288:        uca.ibufsize = UVISORIBUFSIZE;
                    289:        uca.obufsize = UVISOROBUFSIZE;
                    290:        uca.ibufsizepad = UVISORIBUFSIZE;
                    291:        uca.opkthdrlen = 0;
                    292:        uca.device = dev;
                    293:        uca.iface = iface;
                    294:        uca.methods = &uvisor_methods;
                    295:        uca.arg = sc;
                    296:
                    297:        err = uvisor_init(sc, &coninfo, &palmconinfo);
                    298:        if (err) {
                    299:                printf("%s: init failed, %s\n", sc->sc_dev.dv_xname,
                    300:                       usbd_errstr(err));
                    301:                goto bad;
                    302:        }
                    303:
                    304:        usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
                    305:                           &sc->sc_dev);
                    306:
                    307:        if (sc->sc_flags & VISOR) {
                    308:                sc->sc_numcon = UGETW(coninfo.num_ports);
                    309:                if (sc->sc_numcon > UVISOR_MAX_CONN)
                    310:                        sc->sc_numcon = UVISOR_MAX_CONN;
                    311:
                    312:                /* Attach a ucom for each connection. */
                    313:                for (i = 0; i < sc->sc_numcon; ++i) {
                    314:                        switch (coninfo.connections[i].port_function_id) {
                    315:                        case UVISOR_FUNCTION_GENERIC:
                    316:                                uca.info = "Generic";
                    317:                                break;
                    318:                        case UVISOR_FUNCTION_DEBUGGER:
                    319:                                uca.info = "Debugger";
                    320:                                break;
                    321:                        case UVISOR_FUNCTION_HOTSYNC:
                    322:                                uca.info = "HotSync";
                    323:                                break;
                    324:                        case UVISOR_FUNCTION_REMOTE_FILE_SYS:
                    325:                                uca.info = "Remote File System";
                    326:                                break;
                    327:                        default:
                    328:                                uca.info = "unknown";
                    329:                                break;
                    330:                        }
                    331:                        port = coninfo.connections[i].port;
                    332:                        uca.portno = port;
                    333:                        uca.bulkin = port | UE_DIR_IN;
                    334:                        uca.bulkout = port | UE_DIR_OUT;
                    335:                        /* Verify that endpoints exist. */
                    336:                        hasin = 0;
                    337:                        hasout = 0;
                    338:                        for (j = 0; j < id->bNumEndpoints; j++) {
                    339:                                ed = usbd_interface2endpoint_descriptor(iface, j);
                    340:                                if (ed == NULL)
                    341:                                        break;
                    342:                                if (UE_GET_ADDR(ed->bEndpointAddress) == port &&
                    343:                                    (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
                    344:                                        if (UE_GET_DIR(ed->bEndpointAddress)
                    345:                                            == UE_DIR_IN)
                    346:                                                hasin++;
                    347:                                        else
                    348:                                                hasout++;
                    349:                                }
                    350:                        }
                    351:                        if (hasin == 1 && hasout == 1)
                    352:                                sc->sc_subdevs[i] = config_found_sm(self, &uca,
                    353:                                    ucomprint, ucomsubmatch);
                    354:                        else
                    355:                                printf("%s: no proper endpoints for port %d (%d,%d)\n",
                    356:                                    sc->sc_dev.dv_xname, port, hasin, hasout);
                    357:                }
                    358:        } else {
                    359:                sc->sc_numcon = palmconinfo.num_ports;
                    360:                if (sc->sc_numcon > UVISOR_MAX_CONN)
                    361:                        sc->sc_numcon = UVISOR_MAX_CONN;
                    362:
                    363:                /* Attach a ucom for each connection. */
                    364:                for (i = 0; i < sc->sc_numcon; ++i) {
                    365:                        /*
                    366:                         * XXX this should copy out 4-char string from the
                    367:                         * XXX port_function_id, but where would the string go?
                    368:                         * XXX uca.info is a const char *, not an array.
                    369:                         */
                    370:                        uca.info = "sync";
                    371:                        uca.portno = i;
                    372:                        if (palmconinfo.endpoint_numbers_different) {
                    373:                                port = palmconinfo.connections[i].end_point_info;
                    374:                                uca.bulkin = (port >> 4) | UE_DIR_IN;
                    375:                                uca.bulkout = (port & 0xf) | UE_DIR_OUT;
                    376:                        } else {
                    377:                                port = palmconinfo.connections[i].port;
                    378:                                uca.bulkin = port | UE_DIR_IN;
                    379:                                uca.bulkout = port | UE_DIR_OUT;
                    380:                        }
                    381:                        sc->sc_subdevs[i] = config_found_sm(self, &uca,
                    382:                            ucomprint, ucomsubmatch);
                    383:                }
                    384:        }
                    385:
                    386:        return;
                    387:
                    388: bad:
                    389:        DPRINTF(("uvisor_attach: ATTACH ERROR\n"));
                    390:        sc->sc_dying = 1;
                    391: }
                    392:
                    393: int
                    394: uvisor_activate(struct device *self, enum devact act)
                    395: {
                    396:        struct uvisor_softc *sc = (struct uvisor_softc *)self;
                    397:        int rv = 0;
                    398:        int i;
                    399:
                    400:        switch (act) {
                    401:        case DVACT_ACTIVATE:
                    402:                break;
                    403:
                    404:        case DVACT_DEACTIVATE:
                    405:                for (i = 0; i < sc->sc_numcon; i++)
                    406:                        if (sc->sc_subdevs[i] != NULL)
                    407:                                rv = config_deactivate(sc->sc_subdevs[i]);
                    408:                sc->sc_dying = 1;
                    409:                break;
                    410:        }
                    411:        return (rv);
                    412: }
                    413:
                    414: int
                    415: uvisor_detach(struct device *self, int flags)
                    416: {
                    417:        struct uvisor_softc *sc = (struct uvisor_softc *)self;
                    418:        int rv = 0;
                    419:        int i;
                    420:
                    421:        DPRINTF(("uvisor_detach: sc=%p flags=%d\n", sc, flags));
                    422:        sc->sc_dying = 1;
                    423:        for (i = 0; i < sc->sc_numcon; i++) {
                    424:                if (sc->sc_subdevs[i] != NULL) {
                    425:                        rv |= config_detach(sc->sc_subdevs[i], flags);
                    426:                        sc->sc_subdevs[i] = NULL;
                    427:                }
                    428:        }
                    429:
                    430:        usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
                    431:                           &sc->sc_dev);
                    432:
                    433:        return (rv);
                    434: }
                    435:
                    436: usbd_status
                    437: uvisor_init(struct uvisor_softc *sc, struct uvisor_connection_info *ci,
                    438:     struct uvisor_palm_connection_info *cpi)
                    439: {
                    440:        usbd_status err;
                    441:        usb_device_request_t req;
                    442:        int actlen;
                    443:        uWord avail;
                    444:
                    445:        if (sc->sc_flags & PALM4) {
                    446:                DPRINTF(("uvisor_init: getting Palm connection info\n"));
                    447:                req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
                    448:                req.bRequest = UVISOR_GET_PALM_INFORMATION;
                    449:                USETW(req.wValue, 0);
                    450:                USETW(req.wIndex, 0);
                    451:                USETW(req.wLength, UVISOR_GET_PALM_INFORMATION_LEN);
                    452:                err = usbd_do_request_flags(sc->sc_udev, &req, cpi,
                    453:                    USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT);
                    454:                if (err == USBD_STALLED && sc->sc_vendor == USB_VENDOR_SONY) {
                    455:                        /* some sony clie devices stall on palm4 requests,
                    456:                         * switch them over to using visor. dont do free space
                    457:                         * checks on them since they dont like them either.
                    458:                         */
                    459:                        DPRINTF(("switching role for CLIE probe\n"));
                    460:                        sc->sc_flags = CLIE4;
                    461:                        err = 0;
                    462:                }
                    463:                if (err)
                    464:                        return (err);
                    465:        }
                    466:
                    467:        if (sc->sc_flags & VISOR) {
                    468:                DPRINTF(("uvisor_init: getting Visor connection info\n"));
                    469:                req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
                    470:                req.bRequest = UVISOR_GET_CONNECTION_INFORMATION;
                    471:                USETW(req.wValue, 0);
                    472:                USETW(req.wIndex, 0);
                    473:                USETW(req.wLength, UVISOR_CONNECTION_INFO_SIZE);
                    474:                err = usbd_do_request_flags(sc->sc_udev, &req, ci,
                    475:                    USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT);
                    476:                if (err)
                    477:                        return (err);
                    478:        }
                    479:
                    480:        if (sc->sc_flags & NOFRE)
                    481:                return (err);
                    482:
                    483:        DPRINTF(("uvisor_init: getting available bytes\n"));
                    484:        req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
                    485:        req.bRequest = UVISOR_REQUEST_BYTES_AVAILABLE;
                    486:        USETW(req.wValue, 0);
                    487:        USETW(req.wIndex, 5);
                    488:        USETW(req.wLength, sizeof avail);
                    489:        err = usbd_do_request(sc->sc_udev, &req, &avail);
                    490:        if (err)
                    491:                return (err);
                    492:        DPRINTF(("uvisor_init: avail=%d\n", UGETW(avail)));
                    493:        DPRINTF(("uvisor_init: done\n"));
                    494:        return (err);
                    495: }
                    496:
                    497: void
                    498: uvisor_close(void *addr, int portno)
                    499: {
                    500:        struct uvisor_softc *sc = addr;
                    501:        usb_device_request_t req;
                    502:        struct uvisor_connection_info coninfo; /* XXX ? */
                    503:        int actlen;
                    504:
                    505:        if (sc->sc_dying)
                    506:                return;
                    507:
                    508:        req.bmRequestType = UT_READ_VENDOR_ENDPOINT; /* XXX read? */
                    509:        req.bRequest = UVISOR_CLOSE_NOTIFICATION;
                    510:        USETW(req.wValue, 0);
                    511:        USETW(req.wIndex, 0);
                    512:        USETW(req.wLength, UVISOR_CONNECTION_INFO_SIZE);
                    513:        (void)usbd_do_request_flags(sc->sc_udev, &req, &coninfo,
                    514:                  USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT);
                    515: }

CVSweb