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

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

1.1       nbrk        1: /*     $OpenBSD: umsm.c,v 1.16 2007/06/19 23:59:27 jcs Exp $   */
                      2:
                      3: /*
                      4:  * Copyright (c) 2006 Jonathan Gray <jsg@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: /* Driver for Qualcomm MSM EVDO and UMTS communication devices */
                     20:
                     21: #include <sys/param.h>
                     22: #include <sys/systm.h>
                     23: #include <sys/kernel.h>
                     24: #include <sys/device.h>
                     25: #include <sys/conf.h>
                     26: #include <sys/tty.h>
                     27:
                     28: #include <dev/usb/usb.h>
                     29: #include <dev/usb/usbdi.h>
                     30: #include <dev/usb/usbdi_util.h>
                     31: #include <dev/usb/usbdevs.h>
                     32: #include <dev/usb/ucomvar.h>
                     33:
                     34: #define UMSMBUFSZ      2048
                     35: #define UMSM_CONFIG_NO 0
                     36: #define UMSM_IFACE_NO  0
                     37:
                     38: struct umsm_softc {
                     39:        struct device            sc_dev;
                     40:        usbd_device_handle       sc_udev;
                     41:        usbd_interface_handle    sc_iface;
                     42:        struct device           *sc_subdev;
                     43:        u_char                   sc_dying;
                     44: };
                     45:
                     46: struct ucom_methods umsm_methods = {
                     47:        NULL,
                     48:        NULL,
                     49:        NULL,
                     50:        NULL,
                     51:        NULL,
                     52:        NULL,
                     53:        NULL,
                     54:        NULL,
                     55: };
                     56:
                     57: static const struct usb_devno umsm_devs[] = {
                     58:        { USB_VENDOR_AIRPRIME,  USB_PRODUCT_AIRPRIME_PC5220 },
                     59:        { USB_VENDOR_DELL,      USB_PRODUCT_DELL_W5500 },
                     60:        { USB_VENDOR_KYOCERA2,  USB_PRODUCT_KYOCERA2_KPC650 },
                     61:        { USB_VENDOR_NOVATEL,   USB_PRODUCT_NOVATEL_EXPRESSCARD },
                     62:        { USB_VENDOR_NOVATEL,   USB_PRODUCT_NOVATEL_MERLINV620 },
                     63:        { USB_VENDOR_NOVATEL,   USB_PRODUCT_NOVATEL_S720 },
                     64:        { USB_VENDOR_NOVATEL,   USB_PRODUCT_NOVATEL_U720 },
                     65:        { USB_VENDOR_NOVATEL,   USB_PRODUCT_NOVATEL_XU870 },
                     66:        { USB_VENDOR_NOVATEL,   USB_PRODUCT_NOVATEL_ES620 },
                     67:        { USB_VENDOR_QUALCOMM,  USB_PRODUCT_QUALCOMM_MSM_HSDPA },
                     68:        { USB_VENDOR_SIERRA,    USB_PRODUCT_SIERRA_EM5625 },
                     69:        { USB_VENDOR_SIERRA,    USB_PRODUCT_SIERRA_AIRCARD_580 },
                     70:        { USB_VENDOR_SIERRA,    USB_PRODUCT_SIERRA_AIRCARD_595 },
                     71:        { USB_VENDOR_SIERRA,    USB_PRODUCT_SIERRA_AIRCARD_875 },
                     72:        { USB_VENDOR_SIERRA,    USB_PRODUCT_SIERRA_MC5720 },
                     73:        { USB_VENDOR_SIERRA,    USB_PRODUCT_SIERRA_MC5725 },
                     74:        { USB_VENDOR_SIERRA,    USB_PRODUCT_SIERRA_MC8755 },
                     75:        { USB_VENDOR_SIERRA,    USB_PRODUCT_SIERRA_MC8755_2 },
                     76:        { USB_VENDOR_SIERRA,    USB_PRODUCT_SIERRA_MC8765 },
                     77:        { USB_VENDOR_SIERRA,    USB_PRODUCT_SIERRA_MC8775 },
                     78: };
                     79:
                     80: int umsm_match(struct device *, void *, void *);
                     81: void umsm_attach(struct device *, struct device *, void *);
                     82: int umsm_detach(struct device *, int);
                     83: int umsm_activate(struct device *, enum devact);
                     84:
                     85: struct cfdriver umsm_cd = {
                     86:        NULL, "umsm", DV_DULL
                     87: };
                     88:
                     89: const struct cfattach umsm_ca = {
                     90:        sizeof(struct umsm_softc),
                     91:        umsm_match,
                     92:        umsm_attach,
                     93:        umsm_detach,
                     94:        umsm_activate,
                     95: };
                     96:
                     97: int
                     98: umsm_match(struct device *parent, void *match, void *aux)
                     99: {
                    100:        struct usb_attach_arg *uaa = aux;
                    101:
                    102:        if (uaa->iface != NULL)
                    103:                return UMATCH_NONE;
                    104:
                    105:        return (usb_lookup(umsm_devs, uaa->vendor, uaa->product) != NULL) ?
                    106:            UMATCH_VENDOR_PRODUCT : UMATCH_NONE;
                    107: }
                    108:
                    109: void
                    110: umsm_attach(struct device *parent, struct device *self, void *aux)
                    111: {
                    112:        struct umsm_softc *sc = (struct umsm_softc *)self;
                    113:        struct usb_attach_arg *uaa = aux;
                    114:        struct ucom_attach_args uca;
                    115:        usb_interface_descriptor_t *id;
                    116:        usb_endpoint_descriptor_t *ed;
                    117:        usbd_status error;
                    118:        char *devinfop;
                    119:        int i;
                    120:
                    121:        bzero(&uca, sizeof(uca));
                    122:        sc->sc_udev = uaa->device;
                    123:        devinfop = usbd_devinfo_alloc(uaa->device, 0);
                    124:        printf("\n%s: %s\n", sc->sc_dev.dv_xname, devinfop);
                    125:        usbd_devinfo_free(devinfop);
                    126:
                    127:        if (usbd_set_config_index(sc->sc_udev, UMSM_CONFIG_NO, 1) != 0) {
                    128:                printf("%s: could not set configuration no\n",
                    129:                    sc->sc_dev.dv_xname);
                    130:                sc->sc_dying = 1;
                    131:                return;
                    132:        }
                    133:
                    134:        /* get the first interface handle */
                    135:        error = usbd_device2interface_handle(sc->sc_udev, UMSM_IFACE_NO,
                    136:            &sc->sc_iface);
                    137:        if (error != 0) {
                    138:                printf("%s: could not get interface handle\n",
                    139:                    sc->sc_dev.dv_xname);
                    140:                sc->sc_dying = 1;
                    141:                return;
                    142:        }
                    143:
                    144:        id = usbd_get_interface_descriptor(sc->sc_iface);
                    145:
                    146:        uca.bulkin = uca.bulkout = -1;
                    147:        for (i = 0; i < id->bNumEndpoints; i++) {
                    148:                ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i);
                    149:                if (ed == NULL) {
                    150:                        printf("%s: no endpoint descriptor found for %d\n",
                    151:                            sc->sc_dev.dv_xname, i);
                    152:                        sc->sc_dying = 1;
                    153:                        return;
                    154:                }
                    155:
                    156:                if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
                    157:                    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
                    158:                        uca.bulkin = ed->bEndpointAddress;
                    159:                else if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT &&
                    160:                    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK)
                    161:                        uca.bulkout = ed->bEndpointAddress;
                    162:        }
                    163:        if (uca.bulkin == -1 || uca.bulkout == -1) {
                    164:                printf("%s: missing endpoint\n", sc->sc_dev.dv_xname);
                    165:                sc->sc_dying = 1;
                    166:                return;
                    167:        }
                    168:
                    169:        /* We need to force size as some devices lie */
                    170:        uca.ibufsize = UMSMBUFSZ;
                    171:        uca.obufsize = UMSMBUFSZ;
                    172:        uca.ibufsizepad = UMSMBUFSZ;
                    173:        uca.opkthdrlen = 0;
                    174:        uca.device = sc->sc_udev;
                    175:        uca.iface = sc->sc_iface;
                    176:        uca.methods = &umsm_methods;
                    177:        uca.arg = sc;
                    178:        uca.info = NULL;
                    179:
                    180:        usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
                    181:            &sc->sc_dev);
                    182:
                    183:        sc->sc_subdev = config_found_sm(self, &uca, ucomprint, ucomsubmatch);
                    184: }
                    185:
                    186: int
                    187: umsm_detach(struct device *self, int flags)
                    188: {
                    189:        struct umsm_softc *sc = (struct umsm_softc *)self;
                    190:        int rv = 0;
                    191:
                    192:        sc->sc_dying = 1;
                    193:        if (sc->sc_subdev != NULL) {
                    194:                rv = config_detach(sc->sc_subdev, flags);
                    195:                sc->sc_subdev = NULL;
                    196:        }
                    197:
                    198:        usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev,
                    199:                           &sc->sc_dev);
                    200:
                    201:        return (rv);
                    202: }
                    203:
                    204: int
                    205: umsm_activate(struct device *self, enum devact act)
                    206: {
                    207:        struct umsm_softc *sc = (struct umsm_softc *)self;
                    208:        int rv = 0;
                    209:
                    210:        switch (act) {
                    211:        case DVACT_ACTIVATE:
                    212:                break;
                    213:
                    214:        case DVACT_DEACTIVATE:
                    215:                if (sc->sc_subdev != NULL)
                    216:                        rv = config_deactivate(sc->sc_subdev);
                    217:                sc->sc_dying = 1;
                    218:                break;
                    219:        }
                    220:        return (rv);
                    221: }

CVSweb