diff options
author | Antoine Jacoutot <ajacoutot@cvs.openbsd.org> | 2007-11-06 17:25:16 +0000 |
---|---|---|
committer | Antoine Jacoutot <ajacoutot@cvs.openbsd.org> | 2007-11-06 17:25:16 +0000 |
commit | cfddda913e038af98a1295d2a7380cd21135b32a (patch) | |
tree | a9c8a62871fb1a6b611770d68a4399bb4bc11844 /sys/dev/usb/uscanner.c | |
parent | 02d94f19405e7d91ea2347c4d18a77341f08f185 (diff) |
- from FreeBSD:
add support for Epson multifunction USB devices (i.e. scanner/printer/card
readers) by adding their IDs to the table of recognised devices (because
we don't have a "scanner" class) and preventing uscanner attach routine to
reconfigure the whole USB device while we are dealing only with one of its
interfaces.
- add the Epson Stylus 3850/4050 ID in the process
feedback from mbalmer@ and jmc@
ok jsg@
Diffstat (limited to 'sys/dev/usb/uscanner.c')
-rw-r--r-- | sys/dev/usb/uscanner.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/sys/dev/usb/uscanner.c b/sys/dev/usb/uscanner.c index 2894342717d..f34f26bb48b 100644 --- a/sys/dev/usb/uscanner.c +++ b/sys/dev/usb/uscanner.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uscanner.c,v 1.36 2007/10/11 18:33:15 deraadt Exp $ */ +/* $OpenBSD: uscanner.c,v 1.37 2007/11/06 17:25:15 ajacoutot Exp $ */ /* $NetBSD: uscanner.c,v 1.40 2003/01/27 00:32:44 wiz Exp $ */ /* @@ -176,6 +176,7 @@ static const struct uscan_info uscanner_devs[] = { {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_640U }, 0 }, {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_1650 }, 0 }, {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_2400 }, 0 }, + {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_DX3850 }, 0 }, {{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_GT9700F }, USC_KEEP_OPEN }, /* UMAX */ @@ -259,12 +260,28 @@ int uscanner_match(struct device *parent, void *match, void *aux) { struct usb_attach_arg *uaa = aux; + usb_interface_descriptor_t *id; - if (uaa->iface != NULL) + if (uaa->iface == NULL) + return UMATCH_NONE; /* do not grab the entire device */ + + if (uscanner_lookup(uaa->vendor, uaa->product) == NULL) + return UMATCH_NONE; /* not in the list of known devices */ + id = usbd_get_interface_descriptor(uaa->iface); + if (id == NULL) + return UMATCH_NONE; + + /* + * There isn't a specific UICLASS for scanners, many vendors use + * UICLASS_VENDOR, so detecting the right interface is not so easy. + * But certainly we can exclude PRINTER and MASS - which some + * multifunction devices implement. + */ + if (id->bInterfaceClass == UICLASS_PRINTER || + id->bInterfaceClass == UICLASS_MASS) return UMATCH_NONE; - return (uscanner_lookup(uaa->vendor, uaa->product) != NULL ? - UMATCH_VENDOR_PRODUCT : UMATCH_NONE); + return UMATCH_VENDOR_PRODUCT; } void @@ -276,20 +293,16 @@ uscanner_attach(struct device *parent, struct device *self, void *aux) usb_endpoint_descriptor_t *ed, *ed_bulkin = NULL, *ed_bulkout = NULL; int i; usbd_status err; + int ifnum; sc->sc_dev_flags = uscanner_lookup(uaa->vendor, uaa->product)->flags; sc->sc_udev = uaa->device; - err = usbd_set_config_no(uaa->device, 1, 1); /* XXX */ - if (err) { - printf("%s: setting config no failed\n", - sc->sc_dev.dv_xname); - return; - } + id = usbd_get_interface_descriptor(uaa->iface); + ifnum = id->bInterfaceNumber; - /* XXX We only check the first interface */ - err = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface); + err = usbd_device2interface_handle(sc->sc_udev, ifnum, &sc->sc_iface); if (!err && sc->sc_iface) id = usbd_get_interface_descriptor(sc->sc_iface); if (err || id == 0) { |