Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/usb Bunch of changes to make the Palm Tungsten T work:
details: https://anonhg.NetBSD.org/src/rev/690d8100f137
branches: trunk
changeset: 550281:690d8100f137
user: nathanw <nathanw%NetBSD.org@localhost>
date: Sun Aug 03 21:59:26 2003 +0000
description:
Bunch of changes to make the Palm Tungsten T work:
* Mark the actual Handspring Visor as type "VISOR" and all others
"PALM4" (notably, the Sony Clie 41 changes from Visor-type to
Palm4-type).
* For Palm4-type devices, use the GET_PALM_CONNECTION_INFORMATION
query instead of the GET_CONNECTION_INFORMATION query, and interpret
the returned data structure appropriately. This permits attaching a
ucom device to newer devices such as the Tungsten T that do not
support the Visor-style query (data structure definition gleaned
from the Linux 2.4.21 visor.c).
* Crank down UVISORBUFSIZE from 1024 to 64 to avoid a problem where
the Palm device and the USB host controller deadlock. The USB host
controller is expecting an early-end-of-transmission packet with 0
data, and the Palm doesn't send one because it's already
communicated the amount of data it's going to send in a header
(which ucom/uvisor are oblivious to). This is the problem that has
been known on the pilot-link lists as the "[Free]BSD USB problem",
but not understood.
XXX It would be better for the Palm protocol to be handled entirely
in userland via ugen, since the serial protocol abstraction isn't
really adequate for the amount of structure that's here, and the
64-byte limit is just a workaround. The pilot-link tools aren't up
to the task yet, though.
diffstat:
sys/dev/usb/uvisor.c | 195 ++++++++++++++++++++++++++++++++------------------
1 files changed, 123 insertions(+), 72 deletions(-)
diffs (294 lines):
diff -r 59f1380d252e -r 690d8100f137 sys/dev/usb/uvisor.c
--- a/sys/dev/usb/uvisor.c Sun Aug 03 21:40:13 2003 +0000
+++ b/sys/dev/usb/uvisor.c Sun Aug 03 21:59:26 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uvisor.c,v 1.20 2003/04/11 01:30:10 simonb Exp $ */
+/* $NetBSD: uvisor.c,v 1.21 2003/08/03 21:59:26 nathanw Exp $ */
/*
* Copyright (c) 2000 The NetBSD Foundation, Inc.
@@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uvisor.c,v 1.20 2003/04/11 01:30:10 simonb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uvisor.c,v 1.21 2003/08/03 21:59:26 nathanw Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -117,10 +117,23 @@
* Unknown PalmOS stuff.
*/
#define UVISOR_GET_PALM_INFORMATION 0x04
-#define UVISOR_GET_PALM_INFORMATION_LEN 0x14
+#define UVISOR_GET_PALM_INFORMATION_LEN 0x44
+
+struct uvisor_palm_connection_info {
+ uByte num_ports;
+ uByte endpoint_numbers_different;
+ uWord reserved1;
+ struct {
+ uDWord port_function_id;
+ uByte port;
+ uByte end_point_info;
+ uWord reserved;
+ } connections[UVISOR_MAX_CONN];
+};
-#define UVISORIBUFSIZE 1024
+
+#define UVISORIBUFSIZE 64
#define UVISOROBUFSIZE 1024
struct uvisor_softc {
@@ -137,7 +150,8 @@
};
Static usbd_status uvisor_init(struct uvisor_softc *,
- struct uvisor_connection_info *);
+ struct uvisor_connection_info *,
+ struct uvisor_palm_connection_info *);
Static void uvisor_close(void *, int);
@@ -157,9 +171,11 @@
struct usb_devno uv_dev;
u_int16_t uv_flags;
#define PALM4 0x0001
+#define VISOR 0x0002
+
};
static const struct uvisor_type uvisor_devs[] = {
- {{ USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_VISOR }, 0 },
+ {{ USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_VISOR }, VISOR },
{{ USB_VENDOR_HANDSPRING, USB_PRODUCT_HANDSPRING_TREO }, PALM4 },
{{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M500 }, PALM4 },
{{ USB_VENDOR_PALM, USB_PRODUCT_PALM_M505 }, PALM4 },
@@ -171,7 +187,7 @@
{{ USB_VENDOR_PALM, USB_PRODUCT_PALM_TUNGSTEN_T }, PALM4 },
{{ USB_VENDOR_PALM, USB_PRODUCT_PALM_ZIRE }, PALM4 },
{{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_40 }, PALM4 },
- {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_41 }, 0 },
+ {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_41 }, PALM4 },
{{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_S360 }, PALM4 },
{{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_NX60 }, PALM4 },
/* {{ USB_VENDOR_SONY, USB_PRODUCT_SONY_CLIE_25 }, PALM4 },*/
@@ -201,6 +217,7 @@
usbd_interface_handle iface;
usb_interface_descriptor_t *id;
struct uvisor_connection_info coninfo;
+ struct uvisor_palm_connection_info palmconinfo;
usb_endpoint_descriptor_t *ed;
char devinfo[1024];
char *devname = USBDEVNAME(sc->sc_dev);
@@ -231,6 +248,12 @@
sc->sc_flags = uvisor_lookup(uaa->vendor, uaa->product)->uv_flags;
+ if ((sc->sc_flags & (VISOR | PALM4)) == 0) {
+ printf("%s: init failed, device type is neither visor nor palm\n",
+ USBDEVNAME(sc->sc_dev));
+ goto bad;
+ }
+
id = usbd_get_interface_descriptor(iface);
sc->sc_udev = dev;
@@ -245,7 +268,7 @@
uca.methods = &uvisor_methods;
uca.arg = sc;
- err = uvisor_init(sc, &coninfo);
+ err = uvisor_init(sc, &coninfo, &palmconinfo);
if (err) {
printf("%s: init failed, %s\n", USBDEVNAME(sc->sc_dev),
usbd_errstr(err));
@@ -255,53 +278,86 @@
usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev,
USBDEV(sc->sc_dev));
- sc->sc_numcon = UGETW(coninfo.num_ports);
- if (sc->sc_numcon > UVISOR_MAX_CONN)
- sc->sc_numcon = UVISOR_MAX_CONN;
+ if (sc->sc_flags & VISOR) {
+ sc->sc_numcon = UGETW(coninfo.num_ports);
+ if (sc->sc_numcon > UVISOR_MAX_CONN)
+ sc->sc_numcon = UVISOR_MAX_CONN;
- /* Attach a ucom for each connection. */
- for (i = 0; i < sc->sc_numcon; ++i) {
- switch (coninfo.connections[i].port_function_id) {
- case UVISOR_FUNCTION_GENERIC:
- uca.info = "Generic";
- break;
- case UVISOR_FUNCTION_DEBUGGER:
- uca.info = "Debugger";
- break;
- case UVISOR_FUNCTION_HOTSYNC:
- uca.info = "HotSync";
- break;
- case UVISOR_FUNCTION_REMOTE_FILE_SYS:
- uca.info = "Remote File System";
- break;
- default:
- uca.info = "unknown";
- break;
+ /* Attach a ucom for each connection. */
+ for (i = 0; i < sc->sc_numcon; ++i) {
+ switch (coninfo.connections[i].port_function_id) {
+ case UVISOR_FUNCTION_GENERIC:
+ uca.info = "Generic";
+ break;
+ case UVISOR_FUNCTION_DEBUGGER:
+ uca.info = "Debugger";
+ break;
+ case UVISOR_FUNCTION_HOTSYNC:
+ uca.info = "HotSync";
+ break;
+ case UVISOR_FUNCTION_REMOTE_FILE_SYS:
+ uca.info = "Remote File System";
+ break;
+ default:
+ uca.info = "unknown";
+ break;
+ }
+ port = coninfo.connections[i].port;
+ uca.portno = port;
+ uca.bulkin = port | UE_DIR_IN;
+ uca.bulkout = port | UE_DIR_OUT;
+ /* Verify that endpoints exist. */
+ hasin = 0;
+ hasout = 0;
+ for (j = 0; j < id->bNumEndpoints; j++) {
+ ed = usbd_interface2endpoint_descriptor(iface, j);
+ if (ed == NULL)
+ break;
+ if (UE_GET_ADDR(ed->bEndpointAddress) == port &&
+ (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
+ if (UE_GET_DIR(ed->bEndpointAddress)
+ == UE_DIR_IN)
+ hasin++;
+ else
+ hasout++;
+ }
+ }
+ if (hasin == 1 && hasout == 1)
+ sc->sc_subdevs[i] = config_found_sm(self, &uca,
+ ucomprint, ucomsubmatch);
+ else
+ printf("%s: no proper endpoints for port %d (%d,%d)\n",
+ USBDEVNAME(sc->sc_dev), port, hasin, hasout);
}
- port = coninfo.connections[i].port;
- uca.portno = port;
- uca.bulkin = port | UE_DIR_IN;
- uca.bulkout = port | UE_DIR_OUT;
- /* Verify that endpoints exist. */
- for (hasin = hasout = j = 0; j < id->bNumEndpoints; j++) {
- ed = usbd_interface2endpoint_descriptor(iface, j);
- if (ed == NULL)
- break;
- if (UE_GET_ADDR(ed->bEndpointAddress) == port &&
- (ed->bmAttributes & UE_XFERTYPE) == UE_BULK) {
- if (UE_GET_DIR(ed->bEndpointAddress)
- == UE_DIR_IN)
- hasin++;
- else
- hasout++;
+
+ } else {
+ sc->sc_numcon = palmconinfo.num_ports;
+ if (sc->sc_numcon > UVISOR_MAX_CONN)
+ sc->sc_numcon = UVISOR_MAX_CONN;
+
+ /* Attach a ucom for each connection. */
+ for (i = 0; i < sc->sc_numcon; ++i) {
+ /*
+ * XXX this should copy out 4-char string from the
+ * XXX port_function_id, but where would the string go?
+ * XXX uca.info is a const char *, not an array.
+ */
+ uca.info = "sync";
+ uca.portno = i;
+ if (palmconinfo.endpoint_numbers_different) {
+ port = palmconinfo.connections[i].end_point_info;
+ uca.bulkin = (port >> 4) | UE_DIR_IN;
+ uca.bulkout = (port & 0xf) | UE_DIR_OUT;
+ } else {
+ port = palmconinfo.connections[i].port;
+ uca.bulkin = port | UE_DIR_IN;
+ uca.bulkout = port | UE_DIR_OUT;
}
- }
- if (hasin == 1 && hasout == 1)
sc->sc_subdevs[i] = config_found_sm(self, &uca,
ucomprint, ucomsubmatch);
- else
- printf("%s: no proper endpoints for port %d (%d,%d)\n",
- USBDEVNAME(sc->sc_dev), port, hasin, hasout);
+
+
+ }
}
USB_ATTACH_SUCCESS_RETURN;
@@ -358,41 +414,36 @@
}
usbd_status
-uvisor_init(struct uvisor_softc *sc, struct uvisor_connection_info *ci)
+uvisor_init(struct uvisor_softc *sc, struct uvisor_connection_info *ci,
+ struct uvisor_palm_connection_info *cpi)
{
usbd_status err;
usb_device_request_t req;
int actlen;
uWord avail;
- char buffer[256];
- DPRINTF(("uvisor_init: getting connection info\n"));
- req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
- req.bRequest = UVISOR_GET_CONNECTION_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,
- USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT);
- if (err)
- return (err);
+ if (sc->sc_flags & VISOR) {
+ DPRINTF(("uvisor_init: getting Visor connection info\n"));
+ req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
+ req.bRequest = UVISOR_GET_CONNECTION_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,
+ USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT);
+ if (err)
+ return (err);
+ }
if (sc->sc_flags & PALM4) {
- /* Palm OS 4.0 Hack */
+ DPRINTF(("uvisor_init: getting Palm connection info\n"));
req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
req.bRequest = UVISOR_GET_PALM_INFORMATION;
USETW(req.wValue, 0);
USETW(req.wIndex, 0);
USETW(req.wLength, UVISOR_GET_PALM_INFORMATION_LEN);
- err = usbd_do_request(sc->sc_udev, &req, buffer);
- if (err)
- return (err);
- req.bmRequestType = UT_READ_VENDOR_ENDPOINT;
- req.bRequest = UVISOR_GET_PALM_INFORMATION;
- USETW(req.wValue, 0);
- USETW(req.wIndex, 0);
- USETW(req.wLength, UVISOR_GET_PALM_INFORMATION_LEN);
- err = usbd_do_request(sc->sc_udev, &req, buffer);
+ err = usbd_do_request_flags(sc->sc_udev, &req, cpi,
+ USBD_SHORT_XFER_OK, &actlen, USBD_DEFAULT_TIMEOUT);
if (err)
return (err);
}
Home |
Main Index |
Thread Index |
Old Index