Add entries for Epson multifunction scanner/printer/card readers,

with all functions supported. This is done adding usb device IDs
to the table of recognised devices (because there is no standard
'scanner' class, so no other way to recognise them), and with
a small change to the uscanner attach routine that prevents
reconfiguring the whole USB device while we are dealing only with
one of its USB interfaces.

The latter part has been suggested by Steinar Hamre in
http://www.freebsd.org/cgi/query-pr.cgi?pr=107665 , i have
only added a bit of explaination to the code.

I have personally tried this on the Epson DX-5050 and DX-6000
devices (on the US market they have different names, CX-something).
I have good reasons to think that, possibly with the mere addition
of more USB ids to the table in uscanner.c, this should work with
all Epson multifunction devices in that family (from DX-3800 to
DX-7000 - these units are in the 50-120$ price range).
More details on related topics (SANE configuration, OCR, etc.)
at http://info.iet.unipi.it/~luigi/FreeBSD/dx5050.html

Manpage updates coming soon.

Approved by: re, imp
MFC after: 3 days
This commit is contained in:
Luigi Rizzo 2007-10-05 07:26:39 +00:00
parent da31a86a8c
commit cf1a10e8c0
2 changed files with 38 additions and 6 deletions

View File

@ -1198,6 +1198,8 @@ product EPSON STYLUS_895 0x0602 Stylus Photo 895 Card Reader
product EPSON 3500 0x080e CX-3500/3600/3650 MFP
product EPSON RX425 0x080f Stylus Photo RX425 scanner
product EPSON 4200 0x0820 CX4200 MP scanner
product EPSON 5000 0x082b DX-50x0 MFP scanner
product EPSON 6000 0x082e DX-60x0 MFP scanner
/* e-TEK Labs products */
product ETEK 1COM 0x8007 Serial

View File

@ -210,6 +210,8 @@ static const struct uscan_info uscanner_devs[] = {
{{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_3590 }, 0 },
{{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_4200 }, 0 },
{{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_4990 }, 0 },
{{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_5000 }, 0 },
{{ USB_VENDOR_EPSON, USB_PRODUCT_EPSON_6000 }, 0 },
/* UMAX */
{{ USB_VENDOR_UMAX, USB_PRODUCT_UMAX_ASTRA1220U }, 0 },
@ -314,12 +316,28 @@ static int
uscanner_match(device_t self)
{
struct usb_attach_arg *uaa = device_get_ivars(self);
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;
return (uscanner_lookup(uaa->vendor, uaa->product) != NULL ?
UMATCH_VENDOR_PRODUCT : 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 UMATCH_VENDOR_PRODUCT; /* ok we found it */
}
static int
@ -331,20 +349,32 @@ uscanner_attach(device_t self)
usb_endpoint_descriptor_t *ed, *ed_bulkin = NULL, *ed_bulkout = NULL;
int i;
usbd_status err;
int ifnum;
sc->sc_dev = self;
sc->sc_dev_flags = uscanner_lookup(uaa->vendor, uaa->product)->flags;
sc->sc_udev = uaa->device;
id = usbd_get_interface_descriptor(uaa->iface);
ifnum = id->bInterfaceNumber;
#if 0
/*
* This was in the original driver, but we cannot change the
* configuration of the whole device while attaching only to
* one of its interfaces. This can kill other already-attached
* driver, and/or possibly prevent this driver from attaching
* if an error occurs in set_config_no.
* If a device need setting the configuration, this must be done
* before attaching drivers to the various interfaces.
*/
err = usbd_set_config_no(uaa->device, 1, 1); /* XXX */
if (err) {
printf("%s: setting config no failed\n",
device_get_nameunit(sc->sc_dev));
return ENXIO;
}
/* XXX We only check the first interface */
err = usbd_device2interface_handle(sc->sc_udev, 0, &sc->sc_iface);
#endif
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) {