summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2006-03-14 10:08:46 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2006-03-14 10:08:46 +0000
commit2c7bb5cae47f94f24e143ab9155badbf02ba4fc9 (patch)
tree855fbc055cae216f7e22be7b35430270cdc9ef35 /sys/dev
parentf1b4579e7371207694d65ebddc123aab63c14991 (diff)
add support for the Sony CLIE PEG-T625 and potentially a range of other
unusually behaved CLIE products. they attach as palm4 type devices, but they stall on a certain init command. now we catch this stall and use it to switch the way we use the device to somethig more appropriate. from Andrew Smith
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/usb/uvisor.c64
1 files changed, 48 insertions, 16 deletions
diff --git a/sys/dev/usb/uvisor.c b/sys/dev/usb/uvisor.c
index d6c6aa227ab..a341234c614 100644
--- a/sys/dev/usb/uvisor.c
+++ b/sys/dev/usb/uvisor.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: uvisor.c,v 1.22 2005/11/28 20:53:22 deraadt Exp $ */
+/* $OpenBSD: uvisor.c,v 1.23 2006/03/14 10:08:45 dlg Exp $ */
/* $NetBSD: uvisor.c,v 1.21 2003/08/03 21:59:26 nathanw Exp $ */
/*
@@ -136,6 +136,10 @@ struct uvisor_softc {
USBBASEDEVICE sc_dev; /* base device */
usbd_device_handle sc_udev; /* device */
usbd_interface_handle sc_iface; /* interface */
+/*
+ * added sc_vendor for later interrogation in failed initialisations
+ */
+ int sc_vendor; /* USB device vendor */
device_ptr_t sc_subdevs[UVISOR_MAX_CONN];
int sc_numcon;
@@ -165,9 +169,19 @@ struct ucom_methods uvisor_methods = {
struct uvisor_type {
struct usb_devno uv_dev;
- u_int16_t uv_flags;
+ u_int16_t uv_flags;
#define PALM4 0x0001
#define VISOR 0x0002
+#define NOFRE 0x0004
+/*
+ * This flag is a combination it is used to reassign the probe value later on a
+ * failed PALM4 request if the error is STALLED and the vendor ID is SONY
+ * Note that the init routines have been ordered to try PALM4 first allowing
+ * reallocation of the sc_flags so that the Visor routine may also be called
+ * It is important to also skip the free check for effected devices though, hence
+ * the combined flag value.
+ */
+#define CLIE4 0x0006
};
static const struct uvisor_type uvisor_devs[] = {
{{ USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_VISOR }, VISOR },
@@ -248,7 +262,8 @@ USB_ATTACH(uvisor)
usbd_devinfo_free(devinfop);
sc->sc_flags = uvisor_lookup(uaa->vendor, uaa->product)->uv_flags;
-
+ sc->sc_vendor = uaa->vendor;
+
if ((sc->sc_flags & (VISOR | PALM4)) == 0) {
printf("%s: init failed, device type is neither visor nor palm\n",
USBDEVNAME(sc->sc_dev));
@@ -419,32 +434,50 @@ uvisor_init(struct uvisor_softc *sc, struct uvisor_connection_info *ci,
int actlen;
uWord avail;
- if (sc->sc_flags & VISOR) {
- DPRINTF(("uvisor_init: getting Visor connection info\n"));
+ if (sc->sc_flags & PALM4) {
+ DPRINTF(("uvisor_init: getting Palm connection info\n"));
req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
- req.bRequest = UVISOR_GET_CONNECTION_INFORMATION;
+ req.bRequest = UVISOR_GET_PALM_INFORMATION;
USETW(req.wValue, 0);
USETW(req.wIndex, 0);
- USETW(req.wLength, UVISOR_CONNECTION_INFO_SIZE);
- err = usbd_do_request_flags(sc->sc_udev, &req, ci,
+ USETW(req.wLength, UVISOR_GET_PALM_INFORMATION_LEN);
+ err = usbd_do_request_flags(sc->sc_udev, &req, cpi,
USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT);
+ if (err == USBD_STALLED && sc->sc_vendor == USB_VENDOR_SONY)
+ {
+/*
+ * Here we switch personality in the driver to a basic Visor type with the flag set to
+ * avoid the Free Space checks, this is ONLY done if the PALM4 command STALLED
+ * and the Vendor of the device is Sony
+ */
+ DPRINTF(("switching role for CLIE probe\n"))
+ sc->sc_flags = CLIE4;
+ err = 0;
+ }
if (err)
return (err);
}
-
- if (sc->sc_flags & PALM4) {
- DPRINTF(("uvisor_init: getting Palm connection info\n"));
+
+ if (sc->sc_flags & VISOR) {
+ DPRINTF(("uvisor_init: getting Visor connection info\n"));
req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
- req.bRequest = UVISOR_GET_PALM_INFORMATION;
+ req.bRequest = UVISOR_GET_CONNECTION_INFORMATION;
USETW(req.wValue, 0);
USETW(req.wIndex, 0);
- USETW(req.wLength, UVISOR_GET_PALM_INFORMATION_LEN);
- err = usbd_do_request_flags(sc->sc_udev, &req, cpi,
+ USETW(req.wLength, UVISOR_CONNECTION_INFO_SIZE);
+ err = usbd_do_request_flags(sc->sc_udev, &req, ci,
USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT);
if (err)
return (err);
}
-
+
+/*
+ * Skip the free bytes check if NOFRE flag is set (part of the CLIE4 mask
+ * some CLIE_40 devices that stall on the PALM4 commands also hang the serial
+ * devices if subjected to the free space check
+ */
+ if (sc->sc_flags & NOFRE) return (err);
+
DPRINTF(("uvisor_init: getting available bytes\n"));
req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
req.bRequest = UVISOR_REQUEST_BYTES_AVAILABLE;
@@ -455,7 +488,6 @@ uvisor_init(struct uvisor_softc *sc, struct uvisor_connection_info *ci,
if (err)
return (err);
DPRINTF(("uvisor_init: avail=%d\n", UGETW(avail)));
-
DPRINTF(("uvisor_init: done\n"));
return (err);
}