summaryrefslogtreecommitdiff
path: root/sys/dev/usb/uscanner.c
diff options
context:
space:
mode:
authorAntoine Jacoutot <ajacoutot@cvs.openbsd.org>2007-11-06 17:25:16 +0000
committerAntoine Jacoutot <ajacoutot@cvs.openbsd.org>2007-11-06 17:25:16 +0000
commitcfddda913e038af98a1295d2a7380cd21135b32a (patch)
treea9c8a62871fb1a6b611770d68a4399bb4bc11844 /sys/dev/usb/uscanner.c
parent02d94f19405e7d91ea2347c4d18a77341f08f185 (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.c37
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) {