[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     ! 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