diff options
Diffstat (limited to 'sys/dev/usb')
-rw-r--r-- | sys/dev/usb/uvisor.c | 64 |
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); } |